summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.rst102
-rw-r--r--MANIFEST.in13
-rw-r--r--PKG-INFO140
-rw-r--r--README.rst110
-rw-r--r--copyright138
-rw-r--r--doc/source/Tutorials/Sift/sift.rst315
-rw-r--r--doc/source/Tutorials/array_widget.rst246
-rw-r--r--doc/source/Tutorials/fit.rst635
-rw-r--r--doc/source/Tutorials/fitconfig.rst207
-rw-r--r--doc/source/Tutorials/img/arraywidget3D_0.pngbin0 -> 35724 bytes
-rw-r--r--doc/source/Tutorials/img/arraywidget3D_1.pngbin0 -> 23956 bytes
-rw-r--r--doc/source/Tutorials/img/arraywidget5D_0.pngbin0 -> 34473 bytes
-rw-r--r--doc/source/Tutorials/img/arraywidget5D_1.pngbin0 -> 24553 bytes
-rw-r--r--doc/source/Tutorials/img/custom_config_scale0.5.pngbin0 -> 186529 bytes
-rw-r--r--doc/source/Tutorials/img/custom_config_scale1.0.pngbin0 -> 181099 bytes
-rw-r--r--doc/source/Tutorials/img/custom_config_scale2.1.pngbin0 -> 183066 bytes
-rw-r--r--doc/source/Tutorials/img/fitwidget1.pngbin0 -> 31627 bytes
-rw-r--r--doc/source/Tutorials/img/fitwidget2.pngbin0 -> 106983 bytes
-rw-r--r--doc/source/Tutorials/img/fitwidget3.pngbin0 -> 26141 bytes
-rw-r--r--doc/source/Tutorials/img/fitwidget4.pngbin0 -> 121846 bytes
-rw-r--r--doc/source/Tutorials/img/fitwidget5.pngbin0 -> 29784 bytes
-rw-r--r--doc/source/Tutorials/img/stripbg_plot1.pngbin0 -> 41420 bytes
-rw-r--r--doc/source/Tutorials/img/stripbg_plot2.pngbin0 -> 45619 bytes
-rw-r--r--doc/source/Tutorials/specfile_to_hdf5.rst323
-rw-r--r--doc/source/changelog.rst1
-rw-r--r--doc/source/conf.py255
-rw-r--r--doc/source/description/img/sift_bench_cpu0.pngbin0 -> 43625 bytes
-rw-r--r--doc/source/description/img/sift_bench_cpu_kp.pngbin0 -> 29356 bytes
-rw-r--r--doc/source/description/img/sift_bench_cpu_res.pngbin0 -> 27730 bytes
-rw-r--r--doc/source/description/img/sift_bench_gpu0.pngbin0 -> 44086 bytes
-rw-r--r--doc/source/description/img/sift_bench_gpu_kp.pngbin0 -> 28994 bytes
-rw-r--r--doc/source/description/img/sift_bench_gpu_res.pngbin0 -> 30067 bytes
-rw-r--r--doc/source/description/img/sift_dog1.pngbin0 -> 53704 bytes
-rw-r--r--doc/source/description/img/sift_match1.pngbin0 -> 210886 bytes
-rw-r--r--doc/source/description/img/sift_orientation.pngbin0 -> 34425 bytes
-rw-r--r--doc/source/description/index.rst9
-rw-r--r--doc/source/description/sift.rst399
-rw-r--r--doc/source/img/silx.icobin0 -> 4286 bytes
-rw-r--r--doc/source/img/silx_large.pngbin0 -> 293645 bytes
-rwxr-xr-xdoc/source/img/silx_small.pngbin0 -> 9002 bytes
-rw-r--r--doc/source/index.rst47
-rw-r--r--doc/source/install.rst306
-rw-r--r--doc/source/license.rst10
-rw-r--r--doc/source/modules/gui/console.rst9
-rw-r--r--doc/source/modules/gui/data/arraytable.rst23
-rw-r--r--doc/source/modules/gui/data/dataviewer.rst7
-rw-r--r--doc/source/modules/gui/data/dataviewerframe.rst7
-rw-r--r--doc/source/modules/gui/data/img/DataViewer.pngbin0 -> 37627 bytes
-rw-r--r--doc/source/modules/gui/data/img/DataViewerFrame.pngbin0 -> 41699 bytes
-rw-r--r--doc/source/modules/gui/data/img/NumpyAxesSelector.pngbin0 -> 9537 bytes
-rw-r--r--doc/source/modules/gui/data/index.rst19
-rw-r--r--doc/source/modules/gui/data/numpyaxesselector.rst7
-rw-r--r--doc/source/modules/gui/data/textformatter.rst7
-rw-r--r--doc/source/modules/gui/designer.rst1
-rw-r--r--doc/source/modules/gui/fit/backgroundwidget.rst27
-rw-r--r--doc/source/modules/gui/fit/fitwidget.rst18
-rw-r--r--doc/source/modules/gui/fit/img/bgwidget.pngbin0 -> 68544 bytes
-rw-r--r--doc/source/modules/gui/fit/index.rst32
-rw-r--r--doc/source/modules/gui/hdf5/examples_hdf5widget.rst6
-rw-r--r--doc/source/modules/gui/hdf5/getting_started.rst226
-rw-r--r--doc/source/modules/gui/hdf5/h5node.rst9
-rw-r--r--doc/source/modules/gui/hdf5/hdf5contextmenuevent.rst9
-rw-r--r--doc/source/modules/gui/hdf5/hdf5treemodel.rst9
-rw-r--r--doc/source/modules/gui/hdf5/hdf5treeview.rst9
-rw-r--r--doc/source/modules/gui/hdf5/img/Hdf5Example.pngbin0 -> 98584 bytes
-rw-r--r--doc/source/modules/gui/hdf5/img/Hdf5TreeView.pngbin0 -> 38565 bytes
-rw-r--r--doc/source/modules/gui/hdf5/index.rst46
-rw-r--r--doc/source/modules/gui/hdf5/nexussortfilterproxymodel.rst9
-rw-r--r--doc/source/modules/gui/icons.rst346
-rw-r--r--doc/source/modules/gui/index.rst21
-rw-r--r--doc/source/modules/gui/plot/dev.rst204
-rw-r--r--doc/source/modules/gui/plot/getting_started.rst491
-rw-r--r--doc/source/modules/gui/plot/imageview.rst15
-rw-r--r--doc/source/modules/gui/plot/img/ImageView.pngbin0 -> 174050 bytes
-rw-r--r--doc/source/modules/gui/plot/img/LimitsToolBar.pngbin0 -> 2331 bytes
-rw-r--r--doc/source/modules/gui/plot/img/Plot1D.pngbin0 -> 26947 bytes
-rw-r--r--doc/source/modules/gui/plot/img/Plot2D.pngbin0 -> 59679 bytes
-rw-r--r--doc/source/modules/gui/plot/img/PlotWidget.pngbin0 -> 32084 bytes
-rw-r--r--doc/source/modules/gui/plot/img/PlotWindow.pngbin0 -> 47112 bytes
-rw-r--r--doc/source/modules/gui/plot/img/PositionInfo.pngbin0 -> 3401 bytes
-rw-r--r--doc/source/modules/gui/plot/img/StackView.pngbin0 -> 126723 bytes
-rw-r--r--doc/source/modules/gui/plot/img/StackViewMainWindow.pngbin0 -> 126821 bytes
-rw-r--r--doc/source/modules/gui/plot/img/colorScale.pngbin0 -> 1653 bytes
-rw-r--r--doc/source/modules/gui/plot/img/colorScaleBar.pngbin0 -> 4667 bytes
-rw-r--r--doc/source/modules/gui/plot/img/fftAction0.pngbin0 -> 91165 bytes
-rw-r--r--doc/source/modules/gui/plot/img/fftAction1.pngbin0 -> 38847 bytes
-rw-r--r--doc/source/modules/gui/plot/img/linearColorbar.pngbin0 -> 6585 bytes
-rw-r--r--doc/source/modules/gui/plot/img/logColorbar.pngbin0 -> 8575 bytes
-rw-r--r--doc/source/modules/gui/plot/img/netCounts.pngbin0 -> 18711 bytes
-rw-r--r--doc/source/modules/gui/plot/img/plot_and_backend.pngbin0 -> 39491 bytes
-rw-r--r--doc/source/modules/gui/plot/img/rawCounts.pngbin0 -> 18437 bytes
-rw-r--r--doc/source/modules/gui/plot/img/roiwidget.pngbin0 -> 38771 bytes
-rw-r--r--doc/source/modules/gui/plot/img/shiftAction0.pngbin0 -> 29092 bytes
-rw-r--r--doc/source/modules/gui/plot/img/shiftAction3.pngbin0 -> 25949 bytes
-rw-r--r--doc/source/modules/gui/plot/img/tickbar.pngbin0 -> 2080 bytes
-rw-r--r--doc/source/modules/gui/plot/index.rst130
-rw-r--r--doc/source/modules/gui/plot/items.rst63
-rw-r--r--doc/source/modules/gui/plot/plot.rst16
-rw-r--r--doc/source/modules/gui/plot/plotactions.rst20
-rw-r--r--doc/source/modules/gui/plot/plotactions_examples.rst93
-rw-r--r--doc/source/modules/gui/plot/plottools.rst36
-rw-r--r--doc/source/modules/gui/plot/plotwidget.rst173
-rw-r--r--doc/source/modules/gui/plot/plotwindow.rst30
-rw-r--r--doc/source/modules/gui/plot/profile.rst20
-rw-r--r--doc/source/modules/gui/plot/roi.rst17
-rw-r--r--doc/source/modules/gui/plot/stackview.rst24
-rw-r--r--doc/source/modules/gui/plot3d/actions.rst10
-rw-r--r--doc/source/modules/gui/plot3d/dev.rst38
-rw-r--r--doc/source/modules/gui/plot3d/glutils.rst67
-rw-r--r--doc/source/modules/gui/plot3d/img/Plot3DWidget.pngbin0 -> 11811 bytes
-rw-r--r--doc/source/modules/gui/plot3d/img/Plot3DWindow.pngbin0 -> 20571 bytes
-rw-r--r--doc/source/modules/gui/plot3d/img/SFViewParamTree.pngbin0 -> 19705 bytes
-rw-r--r--doc/source/modules/gui/plot3d/img/ScalarFieldView.pngbin0 -> 42407 bytes
-rw-r--r--doc/source/modules/gui/plot3d/index.rst83
-rw-r--r--doc/source/modules/gui/plot3d/plot3dwidget.rst15
-rw-r--r--doc/source/modules/gui/plot3d/plot3dwindow.rst15
-rw-r--r--doc/source/modules/gui/plot3d/scalarfieldview.rst50
-rw-r--r--doc/source/modules/gui/plot3d/scene.rst84
-rw-r--r--doc/source/modules/gui/plot3d/sfviewparamtree.rst13
-rw-r--r--doc/source/modules/gui/plot3d/toolbars.rst29
-rw-r--r--doc/source/modules/gui/plot3d/utils.rst12
-rw-r--r--doc/source/modules/gui/plot3d/viewer3dvolume_example.rst7
-rw-r--r--doc/source/modules/gui/qt.rst8
-rw-r--r--doc/source/modules/gui/update_icons_rst.py90
-rw-r--r--doc/source/modules/gui/widgets/framebrowser.rst19
-rw-r--r--doc/source/modules/gui/widgets/index.rst19
-rw-r--r--doc/source/modules/gui/widgets/periodictable.rst37
-rw-r--r--doc/source/modules/gui/widgets/tablewidget.rst42
-rw-r--r--doc/source/modules/gui/widgets/threadpoolpushbutton.rst14
-rw-r--r--doc/source/modules/gui/widgets/waitingpushbutton.rst13
-rw-r--r--doc/source/modules/image/bilinear.rst9
-rw-r--r--doc/source/modules/image/index.rst13
-rw-r--r--doc/source/modules/image/medianfilter.rst7
-rw-r--r--doc/source/modules/image/shapes.rst8
-rw-r--r--doc/source/modules/image/sift.rst8
-rw-r--r--doc/source/modules/index.rst14
-rw-r--r--doc/source/modules/io/configdict.rst8
-rw-r--r--doc/source/modules/io/dictdump.rst8
-rw-r--r--doc/source/modules/io/index.rst25
-rw-r--r--doc/source/modules/io/nxdata.rst8
-rw-r--r--doc/source/modules/io/octaveh5.rst10
-rw-r--r--doc/source/modules/io/specfile.rst83
-rw-r--r--doc/source/modules/io/specfilewrapper.rst12
-rw-r--r--doc/source/modules/io/spech5.rst11
-rw-r--r--doc/source/modules/io/spectoh5.rst8
-rw-r--r--doc/source/modules/io/utils.rst8
-rw-r--r--doc/source/modules/math/combo.rst8
-rw-r--r--doc/source/modules/math/fit/bgtheories.rst10
-rw-r--r--doc/source/modules/math/fit/filters.rst18
-rw-r--r--doc/source/modules/math/fit/fitmanager.rst18
-rw-r--r--doc/source/modules/math/fit/fittheories.rst8
-rw-r--r--doc/source/modules/math/fit/fittheory.rst8
-rw-r--r--doc/source/modules/math/fit/functions.rst26
-rw-r--r--doc/source/modules/math/fit/index.rst25
-rw-r--r--doc/source/modules/math/fit/leastsq.rst16
-rw-r--r--doc/source/modules/math/fit/peaksearch.rst10
-rw-r--r--doc/source/modules/math/histogram.rst21
-rw-r--r--doc/source/modules/math/index.rst13
-rw-r--r--doc/source/modules/math/medianfilter.rst11
-rw-r--r--doc/source/modules/resources.rst7
-rw-r--r--doc/source/modules/test/index.rst20
-rw-r--r--doc/source/modules/utils/array_like.rst7
-rw-r--r--doc/source/modules/utils/decorators.rst7
-rw-r--r--doc/source/modules/utils/html.rst7
-rw-r--r--doc/source/modules/utils/index.rst11
-rw-r--r--doc/source/modules/utils/weakref.rst7
-rw-r--r--doc/source/overview.rst33
-rw-r--r--doc/source/tutorials.rst17
-rw-r--r--doc/source/virtualenv.rst203
-rw-r--r--examples/animatedicons.py155
-rw-r--r--examples/colorbar.py62
-rw-r--r--examples/fft.pngbin0 -> 1432 bytes
-rwxr-xr-xexamples/fftPlotAction.py194
-rwxr-xr-xexamples/hdf5widget.py753
-rw-r--r--examples/icons.py108
-rwxr-xr-xexamples/imageview.py153
-rw-r--r--examples/periodicTable.py81
-rw-r--r--examples/scatterMask.py153
-rwxr-xr-xexamples/shiftPlotAction.py113
-rwxr-xr-xexamples/simplewidget.py108
-rwxr-xr-xexamples/spectoh5.py88
-rw-r--r--examples/stackView.py58
-rw-r--r--examples/viewer3DVolume.py209
-rw-r--r--qtdesigner_plugins/README.rst40
-rw-r--r--qtdesigner_plugins/plot1dplugin.py84
-rw-r--r--qtdesigner_plugins/plot2dplugin.py84
-rw-r--r--qtdesigner_plugins/plotwidgetplugin.py84
-rw-r--r--qtdesigner_plugins/plotwindowplugin.py84
-rwxr-xr-xrun_tests.py391
-rw-r--r--setup.cfg5
-rw-r--r--setup.py745
-rw-r--r--silx.egg-info/PKG-INFO140
-rw-r--r--silx.egg-info/SOURCES.txt848
-rw-r--r--silx.egg-info/dependency_links.txt1
-rw-r--r--silx.egg-info/entry_points.txt3
-rw-r--r--silx.egg-info/not-zip-safe1
-rw-r--r--silx.egg-info/requires.txt2
-rw-r--r--silx.egg-info/top_level.txt1
-rw-r--r--silx/__init__.py43
-rw-r--r--silx/__main__.py66
-rw-r--r--silx/app/__init__.py29
-rw-r--r--silx/app/setup.py40
-rw-r--r--silx/app/test/__init__.py41
-rw-r--r--silx/app/test/test_view.py135
-rw-r--r--silx/app/view.py326
-rw-r--r--silx/gui/__init__.py29
-rw-r--r--silx/gui/_glutils/Context.py63
-rw-r--r--silx/gui/_glutils/FramebufferTexture.py164
-rw-r--r--silx/gui/_glutils/Program.py202
-rw-r--r--silx/gui/_glutils/Texture.py308
-rw-r--r--silx/gui/_glutils/VertexBuffer.py266
-rw-r--r--silx/gui/_glutils/__init__.py41
-rw-r--r--silx/gui/_glutils/font.py152
-rw-r--r--silx/gui/_glutils/gl.py165
-rw-r--r--silx/gui/_glutils/utils.py70
-rw-r--r--silx/gui/_utils.py102
-rw-r--r--silx/gui/console.py214
-rw-r--r--silx/gui/data/ArrayTableModel.py610
-rw-r--r--silx/gui/data/ArrayTableWidget.py490
-rw-r--r--silx/gui/data/DataViewer.py464
-rw-r--r--silx/gui/data/DataViewerFrame.py186
-rw-r--r--silx/gui/data/DataViewerSelector.py153
-rw-r--r--silx/gui/data/DataViews.py988
-rw-r--r--silx/gui/data/Hdf5TableView.py414
-rw-r--r--silx/gui/data/NXdataWidgets.py523
-rw-r--r--silx/gui/data/NumpyAxesSelector.py468
-rw-r--r--silx/gui/data/RecordTableView.py405
-rw-r--r--silx/gui/data/TextFormatter.py222
-rw-r--r--silx/gui/data/__init__.py35
-rw-r--r--silx/gui/data/setup.py41
-rw-r--r--silx/gui/data/test/__init__.py45
-rw-r--r--silx/gui/data/test/test_arraywidget.py320
-rw-r--r--silx/gui/data/test/test_dataviewer.py281
-rw-r--r--silx/gui/data/test/test_numpyaxesselector.py152
-rw-r--r--silx/gui/data/test/test_textformatter.py94
-rw-r--r--silx/gui/fit/BackgroundWidget.py530
-rw-r--r--silx/gui/fit/FitConfig.py540
-rw-r--r--silx/gui/fit/FitWidget.py727
-rw-r--r--silx/gui/fit/FitWidgets.py559
-rw-r--r--silx/gui/fit/Parameters.py882
-rw-r--r--silx/gui/fit/__init__.py28
-rw-r--r--silx/gui/fit/setup.py43
-rw-r--r--silx/gui/fit/test/__init__.py43
-rw-r--r--silx/gui/fit/test/testBackgroundWidget.py83
-rw-r--r--silx/gui/fit/test/testFitConfig.py95
-rw-r--r--silx/gui/fit/test/testFitWidget.py135
-rw-r--r--silx/gui/hdf5/Hdf5HeaderView.py192
-rw-r--r--silx/gui/hdf5/Hdf5Item.py421
-rw-r--r--silx/gui/hdf5/Hdf5LoadingItem.py68
-rw-r--r--silx/gui/hdf5/Hdf5Node.py210
-rw-r--r--silx/gui/hdf5/Hdf5TreeModel.py581
-rw-r--r--silx/gui/hdf5/Hdf5TreeView.py204
-rw-r--r--silx/gui/hdf5/NexusSortFilterProxyModel.py152
-rw-r--r--silx/gui/hdf5/__init__.py44
-rw-r--r--silx/gui/hdf5/_utils.py247
-rw-r--r--silx/gui/hdf5/setup.py41
-rw-r--r--silx/gui/hdf5/test/__init__.py39
-rw-r--r--silx/gui/hdf5/test/_mock.py130
-rw-r--r--silx/gui/hdf5/test/test_hdf5.py480
-rw-r--r--silx/gui/icons.py360
-rw-r--r--silx/gui/plot/AlphaSlider.py300
-rw-r--r--silx/gui/plot/ColorBar.py790
-rw-r--r--silx/gui/plot/ColormapDialog.py506
-rw-r--r--silx/gui/plot/Colors.py359
-rw-r--r--silx/gui/plot/CurvesROIWidget.py975
-rw-r--r--silx/gui/plot/ImageView.py860
-rw-r--r--silx/gui/plot/Interaction.py300
-rw-r--r--silx/gui/plot/LegendSelector.py1087
-rw-r--r--silx/gui/plot/MPLColormap.py1062
-rw-r--r--silx/gui/plot/MaskToolsWidget.py615
-rw-r--r--silx/gui/plot/Plot.py2925
-rw-r--r--silx/gui/plot/PlotActions.py1386
-rw-r--r--silx/gui/plot/PlotEvents.py166
-rw-r--r--silx/gui/plot/PlotInteraction.py1493
-rw-r--r--silx/gui/plot/PlotToolButtons.py280
-rw-r--r--silx/gui/plot/PlotTools.py313
-rw-r--r--silx/gui/plot/PlotWidget.py267
-rw-r--r--silx/gui/plot/PlotWindow.py766
-rw-r--r--silx/gui/plot/Profile.py741
-rw-r--r--silx/gui/plot/ProfileMainWindow.py99
-rw-r--r--silx/gui/plot/ScatterMaskToolsWidget.py529
-rw-r--r--silx/gui/plot/StackView.py1033
-rw-r--r--silx/gui/plot/_BaseMaskToolsWidget.py1138
-rw-r--r--silx/gui/plot/__init__.py71
-rw-r--r--silx/gui/plot/_utils/__init__.py104
-rw-r--r--silx/gui/plot/_utils/panzoom.py156
-rw-r--r--silx/gui/plot/_utils/setup.py42
-rw-r--r--silx/gui/plot/_utils/test/__init__.py41
-rw-r--r--silx/gui/plot/_utils/test/test_ticklayout.py78
-rw-r--r--silx/gui/plot/_utils/ticklayout.py224
-rw-r--r--silx/gui/plot/backends/BackendBase.py474
-rw-r--r--silx/gui/plot/backends/BackendMatplotlib.py821
-rw-r--r--silx/gui/plot/backends/BackendOpenGL.py1631
-rw-r--r--silx/gui/plot/backends/ModestImage.py174
-rw-r--r--silx/gui/plot/backends/__init__.py29
-rw-r--r--silx/gui/plot/backends/_matplotlib.py64
-rw-r--r--silx/gui/plot/backends/glutils/GLPlotCurve.py1317
-rw-r--r--silx/gui/plot/backends/glutils/GLPlotFrame.py1039
-rw-r--r--silx/gui/plot/backends/glutils/GLPlotImage.py707
-rw-r--r--silx/gui/plot/backends/glutils/GLSupport.py192
-rw-r--r--silx/gui/plot/backends/glutils/GLText.py222
-rw-r--r--silx/gui/plot/backends/glutils/GLTexture.py239
-rw-r--r--silx/gui/plot/backends/glutils/PlotImageFile.py149
-rw-r--r--silx/gui/plot/backends/glutils/__init__.py44
-rw-r--r--silx/gui/plot/items/__init__.py43
-rw-r--r--silx/gui/plot/items/core.py839
-rw-r--r--silx/gui/plot/items/curve.py192
-rw-r--r--silx/gui/plot/items/histogram.py288
-rw-r--r--silx/gui/plot/items/image.py385
-rw-r--r--silx/gui/plot/items/marker.py241
-rw-r--r--silx/gui/plot/items/scatter.py169
-rw-r--r--silx/gui/plot/items/shape.py121
-rw-r--r--silx/gui/plot/setup.py47
-rw-r--r--silx/gui/plot/test/__init__.py71
-rw-r--r--silx/gui/plot/test/testAlphaSlider.py221
-rw-r--r--silx/gui/plot/test/testColorBar.py240
-rw-r--r--silx/gui/plot/test/testColormapDialog.py68
-rw-r--r--silx/gui/plot/test/testColors.py94
-rw-r--r--silx/gui/plot/test/testCurvesROIWidget.py153
-rw-r--r--silx/gui/plot/test/testInteraction.py89
-rw-r--r--silx/gui/plot/test/testLegendSelector.py143
-rw-r--r--silx/gui/plot/test/testMaskToolsWidget.py295
-rw-r--r--silx/gui/plot/test/testPlot.py633
-rw-r--r--silx/gui/plot/test/testPlotInteraction.py167
-rw-r--r--silx/gui/plot/test/testPlotTools.py203
-rw-r--r--silx/gui/plot/test/testPlotWidget.py967
-rw-r--r--silx/gui/plot/test/testPlotWindow.py138
-rw-r--r--silx/gui/plot/test/testProfile.py183
-rw-r--r--silx/gui/plot/test/testScatterMaskToolsWidget.py313
-rw-r--r--silx/gui/plot/test/testStackView.py209
-rw-r--r--silx/gui/plot3d/Plot3DActions.py362
-rw-r--r--silx/gui/plot3d/Plot3DToolBar.py119
-rw-r--r--silx/gui/plot3d/Plot3DWidget.py341
-rw-r--r--silx/gui/plot3d/Plot3DWindow.py94
-rw-r--r--silx/gui/plot3d/SFViewParamTree.py1467
-rw-r--r--silx/gui/plot3d/ScalarFieldView.py1385
-rw-r--r--silx/gui/plot3d/ViewpointToolBar.py114
-rw-r--r--silx/gui/plot3d/__init__.py45
-rw-r--r--silx/gui/plot3d/scene/__init__.py34
-rw-r--r--silx/gui/plot3d/scene/axes.py224
-rw-r--r--silx/gui/plot3d/scene/camera.py350
-rw-r--r--silx/gui/plot3d/scene/core.py334
-rw-r--r--silx/gui/plot3d/scene/cutplane.py374
-rw-r--r--silx/gui/plot3d/scene/event.py225
-rw-r--r--silx/gui/plot3d/scene/function.py471
-rw-r--r--silx/gui/plot3d/scene/interaction.py652
-rw-r--r--silx/gui/plot3d/scene/primitives.py1764
-rw-r--r--silx/gui/plot3d/scene/setup.py41
-rw-r--r--silx/gui/plot3d/scene/test/__init__.py43
-rw-r--r--silx/gui/plot3d/scene/test/test_transform.py91
-rw-r--r--silx/gui/plot3d/scene/test/test_utils.py275
-rw-r--r--silx/gui/plot3d/scene/text.py534
-rw-r--r--silx/gui/plot3d/scene/transform.py968
-rw-r--r--silx/gui/plot3d/scene/utils.py516
-rw-r--r--silx/gui/plot3d/scene/viewport.py492
-rw-r--r--silx/gui/plot3d/scene/window.py420
-rw-r--r--silx/gui/plot3d/setup.py44
-rw-r--r--silx/gui/plot3d/test/__init__.py62
-rw-r--r--silx/gui/plot3d/utils/__init__.py28
-rw-r--r--silx/gui/plot3d/utils/mng.py121
-rw-r--r--silx/gui/qt/__init__.py61
-rw-r--r--silx/gui/qt/_macosx.py68
-rw-r--r--silx/gui/qt/_pyside_dynamic.py158
-rw-r--r--silx/gui/qt/_pyside_missing.py274
-rw-r--r--silx/gui/qt/_qt.py229
-rw-r--r--silx/gui/qt/_utils.py44
-rw-r--r--silx/gui/setup.py51
-rw-r--r--silx/gui/test/__init__.py108
-rw-r--r--silx/gui/test/test_console.py91
-rw-r--r--silx/gui/test/test_icons.py116
-rw-r--r--silx/gui/test/test_qt.py144
-rw-r--r--silx/gui/test/test_utils.py77
-rw-r--r--silx/gui/test/utils.py428
-rw-r--r--silx/gui/widgets/FrameBrowser.py307
-rw-r--r--silx/gui/widgets/HierarchicalTableView.py172
-rw-r--r--silx/gui/widgets/MedianFilterDialog.py74
-rw-r--r--silx/gui/widgets/PeriodicTable.py825
-rw-r--r--silx/gui/widgets/TableWidget.py488
-rw-r--r--silx/gui/widgets/ThreadPoolPushButton.py233
-rw-r--r--silx/gui/widgets/WaitingPushButton.py243
-rw-r--r--silx/gui/widgets/__init__.py27
-rw-r--r--silx/gui/widgets/setup.py41
-rw-r--r--silx/gui/widgets/test/__init__.py45
-rw-r--r--silx/gui/widgets/test/test_hierarchicaltableview.py117
-rw-r--r--silx/gui/widgets/test/test_periodictable.py163
-rw-r--r--silx/gui/widgets/test/test_tablewidget.py61
-rw-r--r--silx/gui/widgets/test/test_threadpoolpushbutton.py129
-rw-r--r--silx/image/__init__.py27
-rw-r--r--silx/image/bilinear.c20006
-rw-r--r--silx/image/bilinear.pyx335
-rw-r--r--silx/image/medianfilter.py111
-rw-r--r--silx/image/setup.py46
-rw-r--r--silx/image/shapes.c19516
-rw-r--r--silx/image/shapes.pyx295
-rw-r--r--silx/image/sift.py1
-rw-r--r--silx/image/test/__init__.py42
-rw-r--r--silx/image/test/test_bilinear.py142
-rw-r--r--silx/image/test/test_medianfilter.py76
-rw-r--r--silx/image/test/test_shapes.py334
-rw-r--r--silx/io/__init__.py45
-rw-r--r--silx/io/configdict.py540
-rw-r--r--silx/io/dictdump.py366
-rw-r--r--silx/io/fabioh5.py1151
-rw-r--r--silx/io/nxdata.py535
-rw-r--r--silx/io/octaveh5.py176
-rw-r--r--silx/io/setup.py88
-rw-r--r--silx/io/specfile/include/Lists.h51
-rw-r--r--silx/io/specfile/include/SpecFile.h291
-rw-r--r--silx/io/specfile/include/SpecFileCython.h28
-rw-r--r--silx/io/specfile/include/SpecFileP.h74
-rw-r--r--silx/io/specfile/include/locale_management.h23
-rw-r--r--silx/io/specfile/specfile.c21782
-rw-r--r--silx/io/specfile/specfile.pyx1273
-rw-r--r--silx/io/specfile/specfile_wrapper.pxd77
-rw-r--r--silx/io/specfile/src/locale_management.c64
-rw-r--r--silx/io/specfile/src/sfdata.c775
-rw-r--r--silx/io/specfile/src/sfheader.c787
-rw-r--r--silx/io/specfile/src/sfindex.c551
-rw-r--r--silx/io/specfile/src/sfinit.c827
-rw-r--r--silx/io/specfile/src/sflabel.c649
-rw-r--r--silx/io/specfile/src/sflists.c184
-rw-r--r--silx/io/specfile/src/sfmca.c336
-rw-r--r--silx/io/specfile/src/sftools.c550
-rw-r--r--silx/io/specfile/src/sfwrite.c587
-rw-r--r--silx/io/specfilewrapper.py371
-rw-r--r--silx/io/spech5.py1634
-rw-r--r--silx/io/spectoh5.py304
-rw-r--r--silx/io/test/__init__.py53
-rw-r--r--silx/io/test/test_dictdump.py249
-rw-r--r--silx/io/test/test_fabioh5.py236
-rw-r--r--silx/io/test/test_nxdata.py305
-rw-r--r--silx/io/test/test_octaveh5.py165
-rw-r--r--silx/io/test/test_specfile.py431
-rw-r--r--silx/io/test/test_specfilewrapper.py220
-rw-r--r--silx/io/test/test_spech5.py820
-rw-r--r--silx/io/test/test_spectoh5.py197
-rw-r--r--silx/io/test/test_utils.py510
-rw-r--r--silx/io/utils.py500
-rw-r--r--silx/math/__init__.py31
-rw-r--r--silx/math/calibration.py178
-rw-r--r--silx/math/combo/combo.c29857
-rw-r--r--silx/math/combo/combo.pyx238
-rw-r--r--silx/math/combo/isnan.h45
-rw-r--r--silx/math/fit/__init__.py39
-rw-r--r--silx/math/fit/bgtheories.py440
-rw-r--r--silx/math/fit/filters/filters.c20519
-rw-r--r--silx/math/fit/filters/filters.pyx412
-rw-r--r--silx/math/fit/filters/filters_wrapper.pxd71
-rw-r--r--silx/math/fit/filters/include/filters.h45
-rw-r--r--silx/math/fit/filters/src/smoothnd.c317
-rw-r--r--silx/math/fit/filters/src/snip1d.c149
-rw-r--r--silx/math/fit/filters/src/snip2d.c96
-rw-r--r--silx/math/fit/filters/src/snip3d.c186
-rw-r--r--silx/math/fit/filters/src/strip.c118
-rw-r--r--silx/math/fit/fitmanager.py1071
-rw-r--r--silx/math/fit/fittheories.py1374
-rw-r--r--silx/math/fit/fittheory.py161
-rw-r--r--silx/math/fit/functions/functions.c27541
-rw-r--r--silx/math/fit/functions/functions.pyx986
-rw-r--r--silx/math/fit/functions/functions_wrapper.pxd170
-rw-r--r--silx/math/fit/functions/include/functions.h68
-rw-r--r--silx/math/fit/functions/src/funs.c1265
-rw-r--r--silx/math/fit/leastsq.py902
-rw-r--r--silx/math/fit/peaks/include/peaks.h32
-rw-r--r--silx/math/fit/peaks/peaks.c17746
-rw-r--r--silx/math/fit/peaks/peaks.pyx176
-rw-r--r--silx/math/fit/peaks/peaks_wrapper.pxd41
-rw-r--r--silx/math/fit/peaks/src/peaks.c255
-rw-r--r--silx/math/fit/setup.py89
-rw-r--r--silx/math/fit/test/__init__.py46
-rw-r--r--silx/math/fit/test/test_bgtheories.py169
-rw-r--r--silx/math/fit/test/test_filters.py137
-rw-r--r--silx/math/fit/test/test_fit.py382
-rw-r--r--silx/math/fit/test/test_fitmanager.py498
-rw-r--r--silx/math/fit/test/test_functions.py272
-rw-r--r--silx/math/fit/test/test_peaks.py146
-rw-r--r--silx/math/histogram.py593
-rw-r--r--silx/math/histogramnd/chistogramnd.c28300
-rw-r--r--silx/math/histogramnd/chistogramnd.pyx1245
-rw-r--r--silx/math/histogramnd/chistogramnd_lut.c48804
-rw-r--r--silx/math/histogramnd/chistogramnd_lut.pyx426
-rw-r--r--silx/math/histogramnd/histogramnd_c.pxd299
-rw-r--r--silx/math/histogramnd/include/histogramnd_c.h313
-rw-r--r--silx/math/histogramnd/include/msvc/stdint.h247
-rw-r--r--silx/math/histogramnd/include/templates.h30
-rw-r--r--silx/math/histogramnd/src/histogramnd_c.c301
-rw-r--r--silx/math/histogramnd/src/histogramnd_template.c260
-rw-r--r--silx/math/marchingcubes/marchingcubes.cpp21483
-rw-r--r--silx/math/marchingcubes/marchingcubes.pyx239
-rw-r--r--silx/math/marchingcubes/mc.hpp724
-rw-r--r--silx/math/marchingcubes/mc.pxd51
-rw-r--r--silx/math/marchingcubes/mc_lut.cpp316
-rw-r--r--silx/math/medianfilter/__init__.py30
-rw-r--r--silx/math/medianfilter/include/median_filter.hpp139
-rw-r--r--silx/math/medianfilter/median_filter.pxd38
-rw-r--r--silx/math/medianfilter/medianfilter.cpp23404
-rw-r--r--silx/math/medianfilter/medianfilter.pyx383
-rw-r--r--silx/math/medianfilter/setup.py59
-rw-r--r--silx/math/medianfilter/test/__init__.py36
-rw-r--r--silx/math/medianfilter/test/benchmark.py122
-rw-r--r--silx/math/medianfilter/test/test_medianfilter.py244
-rw-r--r--silx/math/setup.py97
-rw-r--r--silx/math/test/__init__.py51
-rw-r--r--silx/math/test/benchmark_combo.py204
-rw-r--r--silx/math/test/histo_benchmarks.py269
-rw-r--r--silx/math/test/test_HistogramndLut_nominal.py571
-rw-r--r--silx/math/test/test_combo.py168
-rw-r--r--silx/math/test/test_histogramnd_error.py512
-rw-r--r--silx/math/test/test_histogramnd_nominal.py933
-rw-r--r--silx/math/test/test_histogramnd_vs_np.py848
-rw-r--r--silx/math/test/test_marchingcubes.py188
-rw-r--r--silx/opencl/__init__.py46
-rw-r--r--silx/opencl/common.py561
-rw-r--r--silx/opencl/medfilt.py269
-rw-r--r--silx/opencl/processing.py275
-rw-r--r--silx/opencl/setup.py44
-rw-r--r--silx/opencl/test/__init__.py41
-rw-r--r--silx/opencl/test/test_addition.py135
-rw-r--r--silx/opencl/test/test_medfilt.py175
-rw-r--r--silx/opencl/utils.py112
-rw-r--r--silx/resources/__init__.py310
-rw-r--r--silx/resources/gui/icons/3d-plane-normal-x.pngbin0 -> 743 bytes
-rw-r--r--silx/resources/gui/icons/3d-plane-normal-x.svg18
-rw-r--r--silx/resources/gui/icons/3d-plane-normal-y.pngbin0 -> 791 bytes
-rw-r--r--silx/resources/gui/icons/3d-plane-normal-y.svg18
-rw-r--r--silx/resources/gui/icons/3d-plane-normal-z.pngbin0 -> 681 bytes
-rw-r--r--silx/resources/gui/icons/3d-plane-normal-z.svg20
-rw-r--r--silx/resources/gui/icons/3d-plane.pngbin0 -> 1134 bytes
-rw-r--r--silx/resources/gui/icons/3d-plane.svg16
-rw-r--r--silx/resources/gui/icons/animated/process-working-00.pngbin0 -> 778 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-01.pngbin0 -> 789 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-02.pngbin0 -> 785 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-03.pngbin0 -> 785 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-04.pngbin0 -> 766 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-05.pngbin0 -> 777 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-06.pngbin0 -> 784 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-07.pngbin0 -> 783 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-08.pngbin0 -> 762 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-09.pngbin0 -> 781 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-10.pngbin0 -> 771 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-11.pngbin0 -> 768 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-12.pngbin0 -> 759 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-13.pngbin0 -> 767 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-14.pngbin0 -> 778 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-15.pngbin0 -> 760 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-16.pngbin0 -> 754 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-17.pngbin0 -> 782 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-18.pngbin0 -> 775 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-19.pngbin0 -> 764 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-20.pngbin0 -> 764 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-21.pngbin0 -> 772 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-22.pngbin0 -> 769 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-23.pngbin0 -> 773 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-24.pngbin0 -> 757 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-25.pngbin0 -> 759 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-26.pngbin0 -> 774 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-27.pngbin0 -> 766 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-28.pngbin0 -> 760 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-29.pngbin0 -> 777 bytes
-rw-r--r--silx/resources/gui/icons/animated/process-working-30.pngbin0 -> 775 bytes
-rw-r--r--silx/resources/gui/icons/arrow-keys.pngbin0 -> 669 bytes
-rw-r--r--silx/resources/gui/icons/arrow-keys.svg3
-rw-r--r--silx/resources/gui/icons/camera.pngbin0 -> 348 bytes
-rw-r--r--silx/resources/gui/icons/camera.svg18
-rw-r--r--silx/resources/gui/icons/clipboard.pngbin0 -> 736 bytes
-rw-r--r--silx/resources/gui/icons/clipboard.svg14
-rwxr-xr-xsilx/resources/gui/icons/close.pngbin0 -> 2243 bytes
-rw-r--r--silx/resources/gui/icons/close.svg68
-rwxr-xr-xsilx/resources/gui/icons/colormap.pngbin0 -> 1583 bytes
-rw-r--r--silx/resources/gui/icons/colormap.svg13
-rwxr-xr-xsilx/resources/gui/icons/crop.pngbin0 -> 642 bytes
-rw-r--r--silx/resources/gui/icons/crop.svg6
-rw-r--r--silx/resources/gui/icons/crosshair.pngbin0 -> 1196 bytes
-rw-r--r--silx/resources/gui/icons/crosshair.svg40
-rw-r--r--silx/resources/gui/icons/cube-back.pngbin0 -> 737 bytes
-rw-r--r--silx/resources/gui/icons/cube-back.svg18
-rw-r--r--silx/resources/gui/icons/cube-bottom.pngbin0 -> 833 bytes
-rw-r--r--silx/resources/gui/icons/cube-bottom.svg18
-rw-r--r--silx/resources/gui/icons/cube-front.pngbin0 -> 708 bytes
-rw-r--r--silx/resources/gui/icons/cube-front.svg18
-rw-r--r--silx/resources/gui/icons/cube-left.pngbin0 -> 712 bytes
-rw-r--r--silx/resources/gui/icons/cube-left.svg18
-rw-r--r--silx/resources/gui/icons/cube-right.pngbin0 -> 701 bytes
-rw-r--r--silx/resources/gui/icons/cube-right.svg18
-rw-r--r--silx/resources/gui/icons/cube-top.pngbin0 -> 767 bytes
-rw-r--r--silx/resources/gui/icons/cube-top.svg18
-rw-r--r--silx/resources/gui/icons/cube.pngbin0 -> 953 bytes
-rw-r--r--silx/resources/gui/icons/cube.svg19
-rwxr-xr-xsilx/resources/gui/icons/document-open.pngbin0 -> 2676 bytes
-rw-r--r--silx/resources/gui/icons/document-open.svg126
-rwxr-xr-xsilx/resources/gui/icons/document-print.pngbin0 -> 1427 bytes
-rw-r--r--silx/resources/gui/icons/document-print.svg54
-rwxr-xr-xsilx/resources/gui/icons/document-save.pngbin0 -> 535 bytes
-rw-r--r--silx/resources/gui/icons/document-save.svg36
-rwxr-xr-xsilx/resources/gui/icons/draw-brush.pngbin0 -> 1466 bytes
-rw-r--r--silx/resources/gui/icons/draw-brush.svg30
-rwxr-xr-xsilx/resources/gui/icons/draw-pencil.pngbin0 -> 1055 bytes
-rw-r--r--silx/resources/gui/icons/draw-pencil.svg39
-rwxr-xr-xsilx/resources/gui/icons/draw-rubber.pngbin0 -> 1154 bytes
-rw-r--r--silx/resources/gui/icons/draw-rubber.svg43
-rw-r--r--silx/resources/gui/icons/edit-copy.pngbin0 -> 2191 bytes
-rw-r--r--silx/resources/gui/icons/edit-copy.svg75
-rw-r--r--silx/resources/gui/icons/first.pngbin0 -> 1177 bytes
-rw-r--r--silx/resources/gui/icons/first.svg26
-rwxr-xr-xsilx/resources/gui/icons/folder.pngbin0 -> 2583 bytes
-rw-r--r--silx/resources/gui/icons/folder.svg120
-rw-r--r--silx/resources/gui/icons/image-mask.pngbin0 -> 852 bytes
-rw-r--r--silx/resources/gui/icons/image-mask.svg20
-rwxr-xr-xsilx/resources/gui/icons/image-select-add.pngbin0 -> 2531 bytes
-rw-r--r--silx/resources/gui/icons/image-select-add.svg10
-rwxr-xr-xsilx/resources/gui/icons/image-select-box.pngbin0 -> 3036 bytes
-rw-r--r--silx/resources/gui/icons/image-select-box.svg121
-rwxr-xr-xsilx/resources/gui/icons/image-select-brush.pngbin0 -> 3300 bytes
-rw-r--r--silx/resources/gui/icons/image-select-brush.svg123
-rwxr-xr-xsilx/resources/gui/icons/image-select-erase-rubber.pngbin0 -> 1638 bytes
-rw-r--r--silx/resources/gui/icons/image-select-erase-rubber.svg18
-rwxr-xr-xsilx/resources/gui/icons/image-select-erase.pngbin0 -> 2286 bytes
-rw-r--r--silx/resources/gui/icons/image-select-erase.svg21
-rwxr-xr-xsilx/resources/gui/icons/image.pngbin0 -> 2572 bytes
-rw-r--r--silx/resources/gui/icons/image.svg7
-rw-r--r--silx/resources/gui/icons/item-0dim.pngbin0 -> 305 bytes
-rw-r--r--silx/resources/gui/icons/item-0dim.svg4
-rw-r--r--silx/resources/gui/icons/item-1dim.pngbin0 -> 674 bytes
-rw-r--r--silx/resources/gui/icons/item-1dim.svg4
-rw-r--r--silx/resources/gui/icons/item-2dim.pngbin0 -> 233 bytes
-rw-r--r--silx/resources/gui/icons/item-2dim.svg4
-rw-r--r--silx/resources/gui/icons/item-3dim.pngbin0 -> 582 bytes
-rw-r--r--silx/resources/gui/icons/item-3dim.svg8
-rw-r--r--silx/resources/gui/icons/item-ndim.pngbin0 -> 947 bytes
-rw-r--r--silx/resources/gui/icons/item-ndim.svg26
-rw-r--r--silx/resources/gui/icons/item-object.pngbin0 -> 836 bytes
-rw-r--r--silx/resources/gui/icons/item-object.svg14
-rw-r--r--silx/resources/gui/icons/last.pngbin0 -> 1111 bytes
-rw-r--r--silx/resources/gui/icons/last.svg26
-rwxr-xr-xsilx/resources/gui/icons/math-average.pngbin0 -> 571 bytes
-rw-r--r--silx/resources/gui/icons/math-average.svg9
-rwxr-xr-xsilx/resources/gui/icons/math-derive.pngbin0 -> 593 bytes
-rw-r--r--silx/resources/gui/icons/math-derive.svg10
-rwxr-xr-xsilx/resources/gui/icons/math-energy.pngbin0 -> 645 bytes
-rw-r--r--silx/resources/gui/icons/math-energy.svg22
-rwxr-xr-xsilx/resources/gui/icons/math-fit.pngbin0 -> 768 bytes
-rw-r--r--silx/resources/gui/icons/math-fit.svg33
-rwxr-xr-xsilx/resources/gui/icons/math-normalize.pngbin0 -> 653 bytes
-rw-r--r--silx/resources/gui/icons/math-normalize.svg44
-rwxr-xr-xsilx/resources/gui/icons/math-peak-reset.pngbin0 -> 1420 bytes
-rw-r--r--silx/resources/gui/icons/math-peak-reset.svg55
-rwxr-xr-xsilx/resources/gui/icons/math-peak-search.pngbin0 -> 2163 bytes
-rw-r--r--silx/resources/gui/icons/math-peak-search.svg56
-rwxr-xr-xsilx/resources/gui/icons/math-peak.pngbin0 -> 829 bytes
-rw-r--r--silx/resources/gui/icons/math-peak.svg39
-rwxr-xr-xsilx/resources/gui/icons/math-sigma.pngbin0 -> 744 bytes
-rw-r--r--silx/resources/gui/icons/math-sigma.svg91
-rwxr-xr-xsilx/resources/gui/icons/math-smooth.pngbin0 -> 1243 bytes
-rw-r--r--silx/resources/gui/icons/math-smooth.svg27
-rwxr-xr-xsilx/resources/gui/icons/math-substract.pngbin0 -> 845 bytes
-rw-r--r--silx/resources/gui/icons/math-substract.svg54
-rwxr-xr-xsilx/resources/gui/icons/math-swap-sign.pngbin0 -> 1007 bytes
-rw-r--r--silx/resources/gui/icons/math-swap-sign.svg57
-rwxr-xr-xsilx/resources/gui/icons/math-ymin-to-zero.pngbin0 -> 666 bytes
-rw-r--r--silx/resources/gui/icons/math-ymin-to-zero.svg40
-rw-r--r--silx/resources/gui/icons/median-filter.pngbin0 -> 694 bytes
-rw-r--r--silx/resources/gui/icons/median-filter.svg70
-rw-r--r--silx/resources/gui/icons/next.pngbin0 -> 1092 bytes
-rw-r--r--silx/resources/gui/icons/next.svg23
-rwxr-xr-xsilx/resources/gui/icons/normal.pngbin0 -> 1264 bytes
-rw-r--r--silx/resources/gui/icons/normal.svg33
-rw-r--r--silx/resources/gui/icons/pixel-intensities.pngbin0 -> 1145 bytes
-rw-r--r--silx/resources/gui/icons/pixel-intensities.svg26
-rwxr-xr-xsilx/resources/gui/icons/plot-grid.pngbin0 -> 446 bytes
-rw-r--r--silx/resources/gui/icons/plot-grid.svg13
-rw-r--r--silx/resources/gui/icons/plot-roi-above.pngbin0 -> 999 bytes
-rw-r--r--silx/resources/gui/icons/plot-roi-above.svg4
-rw-r--r--silx/resources/gui/icons/plot-roi-below.pngbin0 -> 988 bytes
-rw-r--r--silx/resources/gui/icons/plot-roi-below.svg4
-rw-r--r--silx/resources/gui/icons/plot-roi-between.pngbin0 -> 1021 bytes
-rw-r--r--silx/resources/gui/icons/plot-roi-between.svg4
-rwxr-xr-xsilx/resources/gui/icons/plot-roi-reset.pngbin0 -> 2063 bytes
-rw-r--r--silx/resources/gui/icons/plot-roi-reset.svg67
-rwxr-xr-xsilx/resources/gui/icons/plot-roi.pngbin0 -> 903 bytes
-rw-r--r--silx/resources/gui/icons/plot-roi.svg52
-rwxr-xr-xsilx/resources/gui/icons/plot-toggle-points.pngbin0 -> 484 bytes
-rw-r--r--silx/resources/gui/icons/plot-toggle-points.svg52
-rwxr-xr-xsilx/resources/gui/icons/plot-widget.pngbin0 -> 1093 bytes
-rw-r--r--silx/resources/gui/icons/plot-widget.svg18
-rwxr-xr-xsilx/resources/gui/icons/plot-window-image.pngbin0 -> 1188 bytes
-rw-r--r--silx/resources/gui/icons/plot-window-image.svg4
-rwxr-xr-xsilx/resources/gui/icons/plot-window.pngbin0 -> 955 bytes
-rw-r--r--silx/resources/gui/icons/plot-window.svg11
-rwxr-xr-xsilx/resources/gui/icons/plot-xauto.pngbin0 -> 626 bytes
-rw-r--r--silx/resources/gui/icons/plot-xauto.svg39
-rwxr-xr-xsilx/resources/gui/icons/plot-xlog.pngbin0 -> 679 bytes
-rw-r--r--silx/resources/gui/icons/plot-xlog.svg45
-rwxr-xr-xsilx/resources/gui/icons/plot-yauto.pngbin0 -> 676 bytes
-rw-r--r--silx/resources/gui/icons/plot-yauto.svg34
-rwxr-xr-xsilx/resources/gui/icons/plot-ydown.pngbin0 -> 701 bytes
-rw-r--r--silx/resources/gui/icons/plot-ydown.svg30
-rwxr-xr-xsilx/resources/gui/icons/plot-ylog.pngbin0 -> 772 bytes
-rw-r--r--silx/resources/gui/icons/plot-ylog.svg40
-rwxr-xr-xsilx/resources/gui/icons/plot-yup.pngbin0 -> 667 bytes
-rw-r--r--silx/resources/gui/icons/plot-yup.svg39
-rw-r--r--silx/resources/gui/icons/previous.pngbin0 -> 1151 bytes
-rw-r--r--silx/resources/gui/icons/previous.svg23
-rw-r--r--silx/resources/gui/icons/process-working.mngbin0 -> 15966 bytes
-rw-r--r--silx/resources/gui/icons/profile-clear.pngbin0 -> 917 bytes
-rw-r--r--silx/resources/gui/icons/profile-clear.svg43
-rw-r--r--silx/resources/gui/icons/profile1D.pngbin0 -> 347 bytes
-rw-r--r--silx/resources/gui/icons/profile1D.svg18
-rw-r--r--silx/resources/gui/icons/profile2D.pngbin0 -> 1403 bytes
-rw-r--r--silx/resources/gui/icons/profile2D.svg21
-rwxr-xr-xsilx/resources/gui/icons/remove.pngbin0 -> 680 bytes
-rw-r--r--silx/resources/gui/icons/remove.svg62
-rwxr-xr-xsilx/resources/gui/icons/rudder.pngbin0 -> 877 bytes
-rw-r--r--silx/resources/gui/icons/rudder.svg24
-rwxr-xr-xsilx/resources/gui/icons/selected.pngbin0 -> 1411 bytes
-rw-r--r--silx/resources/gui/icons/selected.svg39
-rwxr-xr-xsilx/resources/gui/icons/shape-circle-solid.pngbin0 -> 562 bytes
-rw-r--r--silx/resources/gui/icons/shape-circle-solid.svg5
-rwxr-xr-xsilx/resources/gui/icons/shape-circle.pngbin0 -> 722 bytes
-rw-r--r--silx/resources/gui/icons/shape-circle.svg5
-rwxr-xr-xsilx/resources/gui/icons/shape-diagonal.pngbin0 -> 461 bytes
-rw-r--r--silx/resources/gui/icons/shape-diagonal.svg5
-rwxr-xr-xsilx/resources/gui/icons/shape-ellipse-solid.pngbin0 -> 541 bytes
-rw-r--r--silx/resources/gui/icons/shape-ellipse-solid.svg5
-rwxr-xr-xsilx/resources/gui/icons/shape-ellipse.pngbin0 -> 743 bytes
-rw-r--r--silx/resources/gui/icons/shape-ellipse.svg5
-rwxr-xr-xsilx/resources/gui/icons/shape-horizontal.pngbin0 -> 301 bytes
-rw-r--r--silx/resources/gui/icons/shape-horizontal.svg5
-rwxr-xr-xsilx/resources/gui/icons/shape-polygon.pngbin0 -> 819 bytes
-rw-r--r--silx/resources/gui/icons/shape-polygon.svg22
-rwxr-xr-xsilx/resources/gui/icons/shape-rectangle.pngbin0 -> 337 bytes
-rw-r--r--silx/resources/gui/icons/shape-rectangle.svg25
-rwxr-xr-xsilx/resources/gui/icons/shape-square.pngbin0 -> 417 bytes
-rw-r--r--silx/resources/gui/icons/shape-square.svg25
-rwxr-xr-xsilx/resources/gui/icons/shape-vertical.pngbin0 -> 294 bytes
-rw-r--r--silx/resources/gui/icons/shape-vertical.svg29
-rwxr-xr-xsilx/resources/gui/icons/silx.pngbin0 -> 2048 bytes
-rw-r--r--silx/resources/gui/icons/silx.svg37
-rwxr-xr-xsilx/resources/gui/icons/sliders-off.pngbin0 -> 1111 bytes
-rw-r--r--silx/resources/gui/icons/sliders-off.svg118
-rwxr-xr-xsilx/resources/gui/icons/sliders-on.pngbin0 -> 691 bytes
-rw-r--r--silx/resources/gui/icons/sliders-on.svg106
-rwxr-xr-xsilx/resources/gui/icons/spec.pngbin0 -> 1044 bytes
-rw-r--r--silx/resources/gui/icons/spec.svg56
-rw-r--r--silx/resources/gui/icons/test-png.pngbin0 -> 233 bytes
-rw-r--r--silx/resources/gui/icons/test-svg.svg15
-rw-r--r--silx/resources/gui/icons/view-1d.pngbin0 -> 881 bytes
-rw-r--r--silx/resources/gui/icons/view-1d.svg17
-rw-r--r--silx/resources/gui/icons/view-2d-stack.pngbin0 -> 710 bytes
-rw-r--r--silx/resources/gui/icons/view-2d-stack.svg15
-rw-r--r--silx/resources/gui/icons/view-2d.pngbin0 -> 304 bytes
-rw-r--r--silx/resources/gui/icons/view-2d.svg13
-rw-r--r--silx/resources/gui/icons/view-3d.pngbin0 -> 1073 bytes
-rw-r--r--silx/resources/gui/icons/view-3d.svg17
-rwxr-xr-xsilx/resources/gui/icons/view-fullscreen.pngbin0 -> 1829 bytes
-rw-r--r--silx/resources/gui/icons/view-fullscreen.svg70
-rw-r--r--silx/resources/gui/icons/view-hdf5.pngbin0 -> 1347 bytes
-rw-r--r--silx/resources/gui/icons/view-hdf5.svg14
-rw-r--r--silx/resources/gui/icons/view-nexus.pngbin0 -> 1332 bytes
-rw-r--r--silx/resources/gui/icons/view-nexus.svg69
-rwxr-xr-xsilx/resources/gui/icons/view-nofullscreen.pngbin0 -> 1799 bytes
-rw-r--r--silx/resources/gui/icons/view-nofullscreen.svg95
-rw-r--r--silx/resources/gui/icons/view-raw.pngbin0 -> 641 bytes
-rw-r--r--silx/resources/gui/icons/view-raw.svg21
-rwxr-xr-xsilx/resources/gui/icons/view-refresh.pngbin0 -> 1184 bytes
-rw-r--r--silx/resources/gui/icons/view-refresh.svg34
-rw-r--r--silx/resources/gui/icons/view-text.pngbin0 -> 872 bytes
-rw-r--r--silx/resources/gui/icons/view-text.svg19
-rwxr-xr-xsilx/resources/gui/icons/window-new.pngbin0 -> 698 bytes
-rw-r--r--silx/resources/gui/icons/window-new.svg39
-rwxr-xr-xsilx/resources/gui/icons/zoom-in.pngbin0 -> 1612 bytes
-rw-r--r--silx/resources/gui/icons/zoom-in.svg107
-rwxr-xr-xsilx/resources/gui/icons/zoom-original.pngbin0 -> 1518 bytes
-rw-r--r--silx/resources/gui/icons/zoom-original.svg107
-rwxr-xr-xsilx/resources/gui/icons/zoom-out.pngbin0 -> 1567 bytes
-rw-r--r--silx/resources/gui/icons/zoom-out.svg101
-rwxr-xr-xsilx/resources/gui/icons/zoom.pngbin0 -> 1448 bytes
-rw-r--r--silx/resources/gui/icons/zoom.svg95
-rw-r--r--silx/resources/opencl/addition.cl36
-rw-r--r--silx/resources/opencl/bitonic.cl557
-rw-r--r--silx/resources/opencl/medfilt.cl141
-rw-r--r--silx/resources/opencl/preprocess.cl567
-rw-r--r--silx/setup.py53
-rw-r--r--silx/sx/__init__.py99
-rw-r--r--silx/sx/_plot.py274
-rw-r--r--silx/test/__init__.py80
-rw-r--r--silx/test/test_resources.py97
-rw-r--r--silx/test/test_sx.py174
-rw-r--r--silx/test/test_version.py49
-rw-r--r--silx/test/utils.py284
-rw-r--r--silx/third_party/EdfFile.py1223
-rw-r--r--silx/third_party/TiffIO.py1268
-rw-r--r--silx/third_party/__init__.py28
-rw-r--r--silx/third_party/_local/__init__.py36
-rw-r--r--silx/third_party/_local/six.py868
-rw-r--r--silx/third_party/setup.py48
-rw-r--r--silx/third_party/six.py49
-rw-r--r--silx/utils/__init__.py0
-rw-r--r--silx/utils/array_like.py593
-rw-r--r--silx/utils/decorators.py71
-rw-r--r--silx/utils/html.py60
-rw-r--r--silx/utils/launcher.py303
-rw-r--r--silx/utils/setup.py43
-rw-r--r--silx/utils/test/__init__.py43
-rw-r--r--silx/utils/test/test_array_like.py453
-rw-r--r--silx/utils/test/test_html.py61
-rw-r--r--silx/utils/test/test_launcher.py204
-rw-r--r--silx/utils/test/test_launcher_command.py47
-rw-r--r--silx/utils/test/test_weakref.py330
-rw-r--r--silx/utils/weakref.py361
-rw-r--r--stdeb.cfg4
-rw-r--r--version.py118
811 files changed, 407372 insertions, 0 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..2e98df3
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,102 @@
+Change Log
+==========
+
+
+0.5.0: 2017/05/12
+-----------------
+
+ * Adds OpenGL backend to 1D and 2D graphics
+ * Adds Object Oriented plot API with Curve, Histogram, Image, ImageRgba and Scatter items.
+ * Implements generic launcher (``silx view``)
+ * NXdataViewer. Module providing NeXus NXdata support
+ * Math/OpenCL. Implementation of median filter.
+ * Plot. Implementation of ColorBar widget.
+ * Plot. Visualization of complex data type.
+ * Plot. Implementation of Scatter Plot Item supporting colormaps and masks.
+ * Plot. StackView now supports axes calibration.
+ * I/O. Supports SPEC files not having #F or #S as first line character.
+ * I/O. Correctly exposes UB matrix when found in file.
+ * ROIs. Simplification of API: setRois, getRois, calculateRois.
+ * ROIs. Correction of calculation bug when the X-axis values were not ordered.
+ * Sift. Moves package from ``silx.image`` to ``silx.opencl``.
+
+
+0.4.0: 2017/02/01
+-----------------
+
+ * Adds plot3D package (include visualization of 3-dimensional scalar fields)
+ * Adds data viewer (it can handle n-dimensional data)
+ * Adds StackView (ex. Visualization of stack of images)
+ * Adds depth profile calculation (ex. extract profile of a stack of images)
+ * Adds periodic table widget
+ * Adds ArrayTableWidget
+ * Adds pixel intensity histogram action
+ * Adds histogram parameter to addCurve
+ * Refactoring. Create silx.gui.data (include widgets for data)
+ * Refactoring. Rename utils.load as silx.io.open
+ * Changes active curve behavior in Plot. No default active curve is set by default
+ * Fit Action. Add polynomial functions and background customization
+ * PlotWindow. Provide API to access toolbar actions
+ * Handle SPEC, HDF5 and image formats through an unified API
+ * hdf5widget example. Inspect and visualize any datasets
+ * Improves mask tool
+ * Deprecates PlotWindow dock widgets attributes in favor of getter methods
+
+
+0.3.0: 2016/10/12
+-----------------
+
+ * Adds OpenCL management
+ * Adds isosurface marching cubes
+ * Adds sift algorithm for image alignement
+ * Adds octaveh5 module to insure communication between octave and python using HDF5 file
+ * Adds silx.utils module containing weakref and html-escape
+ * Adds silx.sx for flat import (helper for interactive shell)
+ * Adds HDF5 load API (supporting Spec files) to silx.io.utils module
+ * Adds SpecFile support for multiple MCA headers
+ * Adds HDF5 TreeView
+ * Adds FitManager to silx.math.fit and FitWidget to silx.gui.fit
+ * Adds ThreadPoolPushButton to silx.gui.widgets
+ * Adds getDataRange function to plot widget
+ * Adds loadUi, Slot and Property to qt.py
+ * Adds SVG icons and support
+ * Adds examples for plot actions, HDF5 widget, helper widgets, converter from Spec to HDF5
+ * Adds tutorials for plot actions, spech5, spectoh5, sift and fitmanager
+ * Improves right axis support for plot widget
+ * Improves mask tool
+ * Refactors widgets constructor: first argument is now the parent widget
+ * Changes plot documentation and add missing module to the documentation
+
+
+0.2.0: 2016/07/12
+-----------------
+
+ * Adds bilinear interpolator and line-profile for images to silx.image
+ * Adds Levenberg-Marquardt least-square fitting algorithm to silx.math.fit
+ * Histogramnd changed to become a class rather than a function, API and return values changed
+ * Adds HistogramndLut, using a lookup table to bin data onto a regular grid for several sets of
+ data sharing the same coordinates
+ * Adds legend widget and bottom toolbar to PlotWindow
+ * Adds a line-profile toolbar to PlotWindow
+ * Adds ImageView widget with side histograms and profile toolbar
+ * Adds IPython console widget, to be started from PlotWindow toolbar
+ * Adds Plot1D widget for curves and Plot2D widget for images
+ * Adds ROI widget for curves in PlotWindow
+ * Adds a mask widget and toolbar to plot (2D)
+ * Renames silx.io.dicttoh5 to silx.io.dictdump
+ * Adds configuration dictionary dumping/loading to/from JSON and INI files in silx.io.configdict
+ * Adds specfile wrapper API compatible with legacy wrapper: silx.io.specfilewrapper
+ * Transposes scan data in specfile module to have detector as first index
+ * Set up nigthly build for sources package, debian packages (http://www.silx.org/pub/debian/)
+ and documentation (http://www.silx.org/doc/)
+
+
+0.1.0: 2016/04/14
+-----------------
+
+ * Adds project build, documentation and test structure
+ * Adds continuous integration set-up for Travis-CI and Appveyor
+ * Adds Debian packaging support
+ * Adds SPEC file reader, SPEC file conversion to HDF5 in silx.io
+ * Adds histogramnd function in silx.math
+ * Adds 1D, 2D plot widget with a toolbar, refactored from PyMca PlotWindow in silx.gui.plot
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..4334bba
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,13 @@
+include README.rst
+include CHANGELOG.rst
+include copyright
+include MANIFEST.in
+include run_tests.py
+include version.py
+include stdeb.cfg
+recursive-include silx *.pyx *.pxd *.pxi
+recursive-include silx *.h *.c *.hpp *.cpp
+recursive-include doc/source *.py *.rst *.png *.ico
+recursive-include qtdesigner_plugins *.py *.rst
+recursive-include silx/resources *
+recursive-include examples *
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..7a6c11c
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,140 @@
+Metadata-Version: 1.1
+Name: silx
+Version: 0.5.0
+Summary: Software library for X-Ray data analysis
+Home-page: https://github.com/silx-kit/silx
+Author: data analysis unit
+Author-email: silx@esrf.fr
+License: UNKNOWN
+Description:
+ silx toolkit
+ ============
+
+ 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 `HDF5 <https://www.hdfgroup.org/HDF5/>`_ file format (with support of `SPEC <https://certif.com/spec.html>`_ file format)
+ * histogramming
+ * fitting
+ * 1D and 2D visualization using multiple backends (matplotlib or OpenGL)
+ * image plot widget with a set of associated tools (See `changelog file <https://github.com/silx-kit/silx/blob/master/CHANGELOG.rst>`_).
+ * Unified browser for HDF5, SPEC and image file formats supporting inspection and visualization of n-dimensional datasets.
+ * Unified viewer (silx view filename) for HDF5, SPEC and image file formats
+ * OpenGL-based widget to display 3D scalar field with isosurface and cutting plane.
+ * image alignement (sift - OpenCL implementation)
+
+ Installation
+ ------------
+
+ To install silx, run::
+
+ pip install silx
+
+ To install silx locally, run::
+
+ pip install silx --user
+
+ On Linux, to install silx with pip, you must install numpy first. Unofficial packages for different distributions are available :
+
+ - Unofficial Debian8 packages are available at http://www.silx.org/pub/debian/
+ - 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/
+ - Arch Linux (AUR) packages are also available: https://aur.archlinux.org/packages/python-silx
+
+ On Windows, pre-compiled binaries (aka Python wheels) are available for Python 2.7, 3.5 and 3.6.
+
+ On Mac OS X, pre-compiled binaries (aka Python wheels) are available for Python 2.7.
+
+ The latest development version can be obtained from the git repository::
+
+ git clone https://github.com/silx-kit/silx.git
+ cd silx
+ pip install . [--user]
+
+ Dependencies
+ ------------
+
+ * `Python <https://www.python.org/>`_ 2.7, 3.4 or above.
+ * `numpy <http://www.numpy.org>`_
+
+ The GUI widgets of the silx package depend on the following extra packages:
+
+ * A Qt binding: `PyQt5, PyQt4 <https://riverbankcomputing.com/software/pyqt/intro>`_ (using API version 2) or `PySide <https://pypi.python.org/pypi/PySide/>`_
+ * `matplotlib <http://matplotlib.org/>`_ for the silx.gui.plot package
+ * `PyOpenGL <http://pyopengl.sourceforge.net/>`_ for the silx.gui.plot3d package
+
+ Most modules and functions dealing with `HDF5 <https://www.hdfgroup.org/HDF5/>`_ input/output depend on the following extra package:
+ * `h5py <http://www.h5py.org/>`_
+
+ * `ipython <https://ipython.org/>`_ and `qtconsole <https://pypi.python.org/pypi/qtconsole>`_ is required by silx.gui.console.py
+
+ Supported platforms: Linux, Windows, Mac OS X.
+
+ Documentation
+ -------------
+
+ Documentation of releases is available at https://pythonhosted.org/silx/
+
+ Latest documentation (nightly build) is available at http://www.silx.org/doc/silx/
+
+ To build the documentation from the source (requires `Sphinx <http://www.sphinx-doc.org>`_), run::
+
+ python setup.py build build_doc
+
+ Testing
+ -------
+
+ - Travis CI status: |Travis Status|
+ - Appveyor CI status: |Appveyor Status|
+
+ To run the tests from the python interpreter, run:
+
+ >>> import silx.test
+ >>> silx.test.run_tests()
+
+ To run the tests, from the source directory, run::
+
+ python run_tests.py
+
+ Examples
+ --------
+
+ Some examples are available in the source code repository. For example::
+
+ python examples/{exampleName.py}
+
+
+ License
+ -------
+
+ The source code of silx is licensed under the MIT and LGPL licenses.
+ See the `copyright file <https://github.com/silx-kit/silx/blob/master/copyright>`_ for details.
+
+ .. |Travis Status| image:: https://travis-ci.org/silx-kit/silx.svg?branch=master
+ :target: https://travis-ci.org/silx-kit/silx
+ .. |Appveyor Status| image:: https://ci.appveyor.com/api/projects/status/qgox9ei0wxwfagrb/branch/master?svg=true
+ :target: https://ci.appveyor.com/project/ESRF/silx
+
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Environment :: Console
+Classifier: Environment :: MacOS X
+Classifier: Environment :: Win32 (MS Windows)
+Classifier: Environment :: X11 Applications :: Qt
+Classifier: Intended Audience :: Education
+Classifier: Intended Audience :: Science/Research
+Classifier: License :: OSI Approved :: MIT License
+Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
+Classifier: Natural Language :: English
+Classifier: Operating System :: MacOS
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: POSIX
+Classifier: Programming Language :: Cython
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Topic :: Scientific/Engineering :: Physics
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..38ce368
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,110 @@
+
+silx toolkit
+============
+
+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 `HDF5 <https://www.hdfgroup.org/HDF5/>`_ file format (with support of `SPEC <https://certif.com/spec.html>`_ file format)
+* histogramming
+* fitting
+* 1D and 2D visualization using multiple backends (matplotlib or OpenGL)
+* image plot widget with a set of associated tools (See `changelog file <https://github.com/silx-kit/silx/blob/master/CHANGELOG.rst>`_).
+* Unified browser for HDF5, SPEC and image file formats supporting inspection and visualization of n-dimensional datasets.
+* Unified viewer (silx view filename) for HDF5, SPEC and image file formats
+* OpenGL-based widget to display 3D scalar field with isosurface and cutting plane.
+* image alignement (sift - OpenCL implementation)
+
+Installation
+------------
+
+To install silx, run::
+
+ pip install silx
+
+To install silx locally, run::
+
+ pip install silx --user
+
+On Linux, to install silx with pip, you must install numpy first. Unofficial packages for different distributions are available :
+
+- Unofficial Debian8 packages are available at http://www.silx.org/pub/debian/
+- 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/
+- Arch Linux (AUR) packages are also available: https://aur.archlinux.org/packages/python-silx
+
+On Windows, pre-compiled binaries (aka Python wheels) are available for Python 2.7, 3.5 and 3.6.
+
+On Mac OS X, pre-compiled binaries (aka Python wheels) are available for Python 2.7.
+
+The latest development version can be obtained from the git repository::
+
+ git clone https://github.com/silx-kit/silx.git
+ cd silx
+ pip install . [--user]
+
+Dependencies
+------------
+
+* `Python <https://www.python.org/>`_ 2.7, 3.4 or above.
+* `numpy <http://www.numpy.org>`_
+
+The GUI widgets of the silx package depend on the following extra packages:
+
+* A Qt binding: `PyQt5, PyQt4 <https://riverbankcomputing.com/software/pyqt/intro>`_ (using API version 2) or `PySide <https://pypi.python.org/pypi/PySide/>`_
+* `matplotlib <http://matplotlib.org/>`_ for the silx.gui.plot package
+* `PyOpenGL <http://pyopengl.sourceforge.net/>`_ for the silx.gui.plot3d package
+
+Most modules and functions dealing with `HDF5 <https://www.hdfgroup.org/HDF5/>`_ input/output depend on the following extra package:
+* `h5py <http://www.h5py.org/>`_
+
+* `ipython <https://ipython.org/>`_ and `qtconsole <https://pypi.python.org/pypi/qtconsole>`_ is required by silx.gui.console.py
+
+Supported platforms: Linux, Windows, Mac OS X.
+
+Documentation
+-------------
+
+Documentation of releases is available at https://pythonhosted.org/silx/
+
+Latest documentation (nightly build) is available at http://www.silx.org/doc/silx/
+
+To build the documentation from the source (requires `Sphinx <http://www.sphinx-doc.org>`_), run::
+
+ python setup.py build build_doc
+
+Testing
+-------
+
+- Travis CI status: |Travis Status|
+- Appveyor CI status: |Appveyor Status|
+
+To run the tests from the python interpreter, run:
+
+>>> import silx.test
+>>> silx.test.run_tests()
+
+To run the tests, from the source directory, run::
+
+ python run_tests.py
+
+Examples
+--------
+
+Some examples are available in the source code repository. For example::
+
+ python examples/{exampleName.py}
+
+
+License
+-------
+
+The source code of silx is licensed under the MIT and LGPL licenses.
+See the `copyright file <https://github.com/silx-kit/silx/blob/master/copyright>`_ for details.
+
+.. |Travis Status| image:: https://travis-ci.org/silx-kit/silx.svg?branch=master
+ :target: https://travis-ci.org/silx-kit/silx
+.. |Appveyor Status| image:: https://ci.appveyor.com/api/projects/status/qgox9ei0wxwfagrb/branch/master?svg=true
+ :target: https://ci.appveyor.com/project/ESRF/silx
diff --git a/copyright b/copyright
new file mode 100644
index 0000000..a9b99ae
--- /dev/null
+++ b/copyright
@@ -0,0 +1,138 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: silx
+Source: https://github.com/silx-kit/silx
+
+Files: *
+Copyright: 2004-2017 European Synchrotron Radiation Facility
+ Data analysis unit (silx@esrf.fr)
+License: MIT
+
+Files: silx/io/specfile/src/* silx/io/specfile/include/Lists.h silx/io/specfile/include/locale_management.h silx/io/specfile/include/SpecFile.h silx/io/specfile/include/SpecFileP.h
+Copyright: 2004-2016 European Synchrotron Radiation Facility
+License: LGPL-2.1+
+
+Files: silx/math/histogramnd/include/msvc/stdint.h
+Copyright: 2006-2008 Alexander Chemeris
+License: BSD-3
+
+Files: silx/gui/plot/MPLColormap.py
+Copyright: Nathaniel J. Smith, Stefan van der Walt, Eric Firing
+License: CC0
+
+Files: silx/gui/_pyside_dynamic.py
+Copyright: 2011 Sebastian Wiesner <lunaryorn@gmail.com>
+ Modifications by Charl Botha <cpbotha@vxlabs.com>
+License: MIT
+
+License: MIT
+ 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.
+
+License: BSD-3
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of the <organization> nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
+ HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+License: GPL-3.0+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
+
+License: public-domain
+ You can use this free for any purpose. It's in the public domain. It
+ has no warranty
+
+License: LGPL-2.1+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ .
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+ .
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ .
+ On Debian systems, the complete text of the GNU Lesser General Public
+ License can be found in "/usr/share/common-licenses/LGPL-2.1".
+
+License: CC0
+ Statement of Purpose
+ .
+ The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work").
+ .
+ Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others.
+ .
+ For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights.
+ .
+ 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following:
+ .
+ i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+ iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and
+ vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof.
+ .
+ 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose.
+ .
+ 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose.
+ .
+ 4. Limitations and Disclaimers.
+ .
+ a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work.
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::
+
+ <IPython.core.display.Javascript object>
+
+
+
+.. raw:: html
+
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4nOy9d3SUV5qvW/f8cc86d2bcbbuNU4eZc+fcOzN3Zk3obkfAZJRj5aqvclAo5YCIkkAIgYgGB2yDcY4EkYSIQkhIQjkCyhKIZLvd3Y4Y7Of+Ufo+SiBhywPTM6f3s9ZvofqqSiqJJenRu/f7bpVKIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFgHBJVKtWASqX6WqVS1apUqsf+pK9GIBAIBAKBQHBX0alUqqsqlcquUqn+QaVSvaRSqT5VqVST/pQvSiAQCAQCgUBw96hVqVSbAm7/N5VKNaxSqXL+NC9HIBAIBAKBQHA3+T9VKtV1lUoVddP111QqVcl//MsRCAQCgUAgENxtHlGpVKhUqidvur5K5a8M3sx/V6lU99yUvx7jmoiIiIjIf508qlKp/g+VQCD4s2GiApg38ngRERERkf+98qhKIBD82TDRJeCbK4CPqlQqarNT6FicTceSTDqWpNOxJJ3Teel05iXTvsRHy8J4mhd4aV7gpTXXR1teEo0LvDTM99K4wEvTongaF8bRMN9LfY6HhvleWhbG074gno758XQuSuRsro/uwhR6VqRyptBH96oUelen0bs2lb51KfStSWWwOJ3B4lQGVqXQWxBPd14cDSkSHVleOtJ9HNGaOBhjZl+Yia1TNbw0WctzT0Tx3BMRvPBUFC9Pi2XLDDWvzlKzbZaG1+aoeSNIy1tBGt6dG8O7syN4Z1Y4786O4L05kbw/N2rMfDBXw/tzNLw7K5Z3ZkXzzqxo3psT7b8vKJod4dHsioxlb6yW/WoNe2OiOaCJ4aBWzSGdhoNaNWXaWI4YtBwx6jhi0HJIp+GoSU+5ZBwzVQ4rVQ4rJ2wSFVYzxy0myiUjFVYzx8wGjpr0ynX5/Ry3mKiwmjlhk6i0W6i0W6iwGqi0m6hymDnplKhymKm0m8aINBILFVbzLR9zzDgsPzgn4+M4bHdwzO3hhNfDUYed43aJoxYDxywGyiUdFZKWCklLuaTjsM3AEafEEZeFo06JIzYTRy1GKgK+HpUWM1VW/+d08+dV5TBzwmbkhM3IcYuecklHuaTzf44uKxUOC8ftEsesJo6Y9Rwx6zlmNSk5ajGOxMwRs6TkmMXKcZudo5KFIyYzhwxGyq02KuwO5doRs0S51Ua51eZ/nsnMYaPJf19gzBIHtUbKtEYOaAzsVxvZrTHwQaSODyJ1vB9p4M0wLa8Fq9k6J5q3ZgfzYXA4pWodZTo9R8wSVfEuyr02TmXEUZ+VwKnsOBrn+2helERLfjJty1JoW5ZCa14SLUsS/d+b8zw0zvPQPJKWbA9NOfE05fhonp9Iy8IEmhfE05jjpW1xPG2L42lZ5KFlkYumBXaaF9hpnu+gdYy05NhpW+CkfaGLtgVOWnLsNC900rLIRetiN21LPLQudtOyyDXmtcYcB6dynNQv8tC1MYvzb+ZyubSIiwcK+ah8FR9Xred31Zv4Q/Vm/lC9mU9rXuD3jev5qGoNQ/tW0P7CAo7O9/JK8FxemR3CSzPD2DY7ltfnatg2O5oPY7R8qNawXaNlh9afnVod+8yScrtEb2C3wcgurZFdehslBrs/OoldWgM71Dr2a43s1WrZr46lVKOmTKulVK9nv+HWlJlNlBoNlBoNlJlN7NVp2aWO5YDJOGb26XWUGg0cMBkpNRrYp9fxYWQUH0bGsD0qlh2aWHZq1ezSR1OeaKdpoY+BNfMYXD+P/nWZ7HTNlgXwnrv3q0YgEPxnpFalUm0MuP3fVCrVedUPawK5R6VS0bEkk6HChQwVzmeocB5DhfM4V5TF0Ip0Bpan0rsskZ6lCfTk+xhYns5gYQY9+cl05frozkuib1kqvUtT6M5LUq71L01lcGkqQ/n+f88VpHJxTRZX1ucwvDaDSxuzufJcDldemMdHL2bz0fPz+HTTfD7dNI/fbczmyupULhWl0J3jZnBhEv3ZqdSYbFTpHJRH23l/lpm3ZljYNlXHtqkaXp+m4505Rt6apeOdOTreCzLwfoie7eEmdoYbKQnVUhIcw66gaEqCY9gdEsueUDV7wzS3ZE+Int3BekqCdOyaq6EkSMveMB17wzTsC9dSFqPlkFrPMb2J4wYj5XodlSY9JyUjJyUjVWYDVWYD1RYTtTaJaouJKrOBWptEvdM2Zpo8Tpo8ThrdDhpcdhpcduqdNhrdDuocVk7ZLcp9p+wW5TGNbofyXP/zrTR77bTEOWiNd9IS56DZax8jzpG4aHQ7lPctf8wxE+f6wWlNTaHaG0ddoo+mJB+n4rw0eJ2cclmpc1mpd0o0Ok00Ok3UOyWqPVZq4p3UJrg4Fe+k1mPnlMtGQ8DranLaaXY5aPLYaPLYRn0+8u1Gt/99N7gsNLqtNHkcNMX7X1OD10md206t03pLTrlsI3FQ63BSY3dQY3dwyumi3u3hlNNFjd3BSauNereHRm+ccq3W4aTe7aHe7VGeG/g+5FTb7FSZbVSabJwwWjlusHHEaGWfWmKfWmKv2sqOaDMfRBh4N1TLjuBw9odHc1xv5oRZosbuoDklnrokNx3zkzm9MJWORcmczUunZ1kGfSuzGCjOZqA4m/6iTPoK0+kpSKV7iY/uJT56R9K32Ef3khS6c9PpyUujd2kqPfkpdOX6GFieysDyVPoKfPQVJNCz1EvvUi+9+XH0j5G+PC8DS+MZXJbAwNJ4+vK89CyNo3dZPH0FCfQvT6SvIGHU7YFCn3K9Ky+OM0sTObs8iQsvL+QP2wv5+sQGvqpaz9X6jXzTspnrbVug7XVoe51v27dx7cwmvm5+lt8fL+bc60tpLEzlnchQ3goO47VZYXwQqmNnpInt4Xr260zs1xsoNRg5YDRRZjJz0CxR7nBSZjJTZjJz2GLliNXGIbONQxYPh61efyQnh0xWygwSx802jplMHDfoqTAaqDSbqLBYOG69NSfsNuXtSoedcovEYaOBE3bbmCm3SFTYrJyw26iwWSm3SJRpdBxS6zmo1XLYpOGopOOIVUNduoszuWlc2bSMS88to3/1Aj4whwoBFAj+TNGp/PP/rCqV6u9VKtVmlX8MzIM/4Ln3qFQq2hYlM1CQxcDyDAaWpzOwPJ2holTlB3XPUi/d+R66cz0jMpdO7xIf3YsS6F3iY3BpKgP5KfTlJvl/weQm+R+3NI3BPP/1gfykHyWAfQvjGFjgoystkWqjlZN6J+XRdt6cquXVyXpefjKGl5+M4pWnonltmprXp6t5a5bGL4HBOnZEmNkZbmRXiIZdQdHsnBs1SgLHys45anbO0bBjtpqdc9TfK4DHDXpF+GqsZqotJkUG5bcrTXpqrOZxBfDmBAreWAIoy2Jg/I//9wvguPE4fnDulADWj7ymOoeVRodfAmXBa/LYaInzC2G9U6ItwUWj28opu0m5r95ppcHroMHrVF5bndtOndvOSZuZartEjcOiCGCd20m1zc5Jq41qm51ah5M6l3vCAnjK6RolgSetNk5abRMSwPdnB7M7OJwjaj3H9AZOmCXqE92c8rlom+ejc0EK7QuTOL0kle6l6eMKYG9eMj0j35s9ixPpWZhA1+Jkupak0Z3rl7/uvGTOLkm8IwLYnT9aAnuXxdOzNG5cATydn0B7XhynV/sY2jqPPx4p5osTa8cRwK1c73qWbzs38k39Br4+sIkLW5dzLM7KXoOet4LDeDc4mp1RerZHqNmrMbBPp1ckUBbBuymAx60WjklmRQCPWy0cNZsmJIAnjDqqDDoqTTqqbHqqnEYq3BaOe5wcsNh4K8LC5lkmVv02hqRfThUCKBD8GeNTqVSDKv88wFqVSvX4D3yeXwAX+wLkz/8L4BYBXOqiO8/NUH4q55el07fYR8/CBPoW+/xVvrwU+pck0bfYR/+SJIbybwhg7xIf/Xm+HyWA/YviGVjg40xKPCcNFkUAtz0Vw8tPqHn+N+E8/5tQXnwsnC2To3htWixvzlSPEsBdESZ2hWjYOTeKHXMi2Tk36nsFcMds9Q8WwAqjQZG9sQSwymz4XgGsc1ipc1hvkcDbCeDNFcP/XQVQ/vwb7FaanHbqHOZbBLDOYb5FAFvjnbcVwCqrSZHA8QRQlrmJCqAsjbWOG++vymKdkAC+O3Muu+aGcihGyxGtjuNGk/9rk+hUBLBtgY/TS1Lpyk+7rQD25iXTsziR7kUJ9CxM4OyiJM4uTh0lgGcWJ9wRAezK89Cd7x0lgN353nEFsH2Jl+ZFLpqXu+l6PoVPDxbx2fHV4wogvRvh7PPQ+gIcf5k/vL+WUxkJHLbbeC88gneCIvgwPJb3QqLYq9WxV6tjv94wqhL4HymAFTbrhAWwymygxqSnRtJRYzdS7bJQ6XFRotGybU4U+X83i6xfzSJp0kwcP50hBFAgEEwY/xLwIjfnlvs4t9zHwNJ4+vPjOLfcx1BBovKDXf6BP7gs4ZaM9YuhPz+O04vdnM310lfgY6gomYtr0rm0NoOPns3k441p/O65DD59PpM/bM7ijy9m84dnM/l0fao/q5O4tDyO4UUeBud56U5x0ihZqdFaqIy28P5MPa9N0fDyE+G8+mQErz0dxRtPhvPO1Ei2T49m58xYds+MZc/sGHbNiqZkbjS7gsaOvBy8Kyia7bMj2B0aSUlIBLuCwykJ8d/eHxnLgWgNpVFqDkRrKIvRclRnolxn9i/RGSQqjRYqjWZF/k5KBqotemqsBmrtek45DJyyGqizGKi3GmmwmWi0m2lySDTYTDTYTDQ5JJocEs1OCy0uq3J7rAQ+p8Vlpc1jH/XcVreNNo9debvd66Ajzkm710GLyzpumhyS8tw2j51mp4Umh5UOr4cWp4NGm5VGm5Vmh50Wp2PMjLeMfMpuGTNjS6qdU3YTdQ7zqGXdeqf19qL678xYr6/Gah4z430+Yz222mrmmGTkqNnAEZOew0YThwxG9sfq2RejY0+kjpJwf3ZH6PlgbjTbg2MpCdewJ0pDqVrHSZeTugQXLaleOrLiOZOTQM8iHz2LkunJS+N80XwuFi9ieFUOg4UZI9szkuhdlkh3vr8615XnpjvXo3w/y9/78ve6LHSDyxIYKkhkqCBx1M+D233P9+f7K32BlT//x/TQszTulvTmJ9C/JIn+Jcl05PloL0rm4vYiPj20kU+OP8tnjZv5svElvmx4jqtNz3Gt5QXofJHvOl7gu/YX+bx6PZfLiqgujudApsSbxkjeC9dTEuHgg2lG9kVZ2B9j5oDawkGthUM6K0eMVo5b7Bw1mzhiMnLEpKfcYuK41cwxaewcMug5bDRwxGTkqNnEMcnsF0CjiXKDkUrJQpXFqrw9ZizGUX901Dgs1Dj81+U/QE5IBk7azNS5JKptBqosOmqddk46XOxV23h1eiwbfhtB0kPP4Lp/Mrb7p6O9d7oQQIFAMGHuqgB25cXRnR/PQGEy51amcGltBpfXZfLxxiw+3pjGJ5vS/RL4Qga/fz6T32/I4HfrUvwp9nGxwEtPhkR3mp2zSXYaJSsn1WaOhuonLIC7g2IoCR47u0Nilf2BO+bckL+dQWHsCg5nd2gk+yJi/uwFsM3tosXpoNlhp8lu+1ECKFc6b069UxozYwlgg8s2quoZuGfybglgrU0aM+MJ4FiPrbFJHJOMARLobxYpVRvYH6tnb5Se3RH+7Ik08GGQmh3BOkrCDZSEa9gXbeCE3UGNx01jkoe29EROz0uke2HSiABmMLg8m/NF8zm/ch5DKzIZWJ5Of0EK/cuT6F0WPyJlXnoCKnfnC5M4X5ikyN5YuasCmJdM35Jk2hcn0Lwsnp5X5jP4Tj6/K1vDV7UvcLXxZb5ueoFvWl/gevtmvu14kW87XoTTL3GteTOf1Wyk9+1c2jbO41iOh7fConh7Tgy7Qy3sCtNTEq5jT6SBfdEG9scYOaAxUi7ZRgngMclIucX0JxPAkzazkjq3nUaPk3qXk2qnnYMGG++H61n1b0Gk/vw3xD30W6SfPIbl/snYfjYD3X1iCVggEEycuyqAvcsSR6p/qZxflcrldZmjBFCWwE+eS+N3m9L5dH06n6xN5nfrUvhkVSIXlnk4k2LgTLKFMz4bjZKVyhgjh4I0ExbAPcFjL/fKEijvD9wxJ1KRPzklIRHsDY/+sxfAVpdTEcDbyd/tBHD8PY+WMTOWADa67RN633dCAO9Eau0Wyi2mEdEwcnSkY/iAxkip2i8oeyL92RtlZHuQll2hJnaFGtgVpmVPpIFyyUaV00V9opuW1AQ6s3x0LUime6G/qaN/WeZIE1c2QysyGSzMYLAwjYHCZGXZta8gnt78OAaWxjNUkMjwimTOFyZxbrlPkcGbhe9uCmBvXjL9uSl0LEqgeYmHznUpdG/O5uOSFXxVtYmrdZu52vwiV1tf4HrHS1zvfJHrnS/y3ZmXoHMrV5tf5NKelQy8UUDDynTejAxj26xgdoeb2BWmHVMAj5mtHDEZOWw0cNio46jZMCLnfxoBlO+rdVpp8Dpp8npo8MRT7fDwYZSJF5+JJvNvn8F6379h+smv0f/0Ccz3T8U6aTrae58SAigQCCbMXRXAoaJUzq1M48LqTC6uyeDK+iyurM9SBPCjZ1O5siGFyxuSuLI+mU/WpvLxmiR/ViYwvNRNV5qJsylWTidaqTdJnIg2/CgB3BuiZk/ordkdEqtU/uT9gTuDwtgxN5Ttc0LYMTeUnUFh7A6N/LMXwCa7jRang1aXkza3SxHCiQjgWJW7BtfYy7/jLQE3eUZ3Psu5mwI4XuVyPNkb87EOKxU2ieNW88hyo4VjkoWDuhEJjDWxN8rI3igj+6JN7AqV2B1mZ1eoxPYgLTtD9BzU2iiXHNR4vDT6EmlLS+ZsTjpd89PpWpJBT14afUszGFqRxfmV2SPJ5NzKNIaKkhlckcTgCh/9I8u75wuTuFCUwoWiFM4XJnFpVRoXV6YyvCJZWRa+mwLYszSB7rykkS7kJNoXeWjPc9FR4GH45Ww+27+Srys28mXDc3zevIkv2p7nq/aX+KLjRb4+8zL0buPbs6/yx4pn+X3ZeobfXs6BRAPva8N4LzSMXZHaEfkzURpr4oDazEGdmSNGiUMGPQf1Og7qNRw26kYqgf/xAlhtl6i2S4r8nXLZOG60cEhjY3u4iaX/HEzq/5qF9W9CMPw8CPXDc9E8NAPTI7OwPDId7b2/EQIoEAgmzF0VwPOr0hkuzuDimiwurc3kyvosPtqQzSebskcJ4KX1Pi6vS+KTtal8tNrnT1E85/Nd9GVZ6U6zczrRSp3RzIlow49aAt4Xeuu4l71hmlF7/2QBlOXvw9nBbJ8TIgRwRAAbbVZanA7a3K4fLYDjxzpmxhJAuXnl5txNAZxotXDMRh+nzT/XcEQCyy1WRQDLtH5B2Rftz/4YMyVhFnaHOdgZbGF7kJ4dwQYOqG0cNTo46fRQn5BIa2oSZ+dl0jU/g7OL0+lakkJPXhqDhZmcX5nNheIchldlMVycwbmVKQwVJTNUlDRKAC+uTFWk73JxOpdWpSlCKH//300BPJPnoys/hZ78FM4ujqN9sYPOfBcDzybz+10FfHl0HZ+depY/ND3L75s38kXHS3zW8QJfnN7Mdz1buN61hS9rNvFF+SY+KVlNfb6Pg3FG3g0JYUdEjFI93RulVyqA/5kEsMZhodZppTHORVO8m2q7xJ7QGN6fFcMLT4YS/8iTWCY9jeVv1Wh+FUX0o+FEPTgL3cMzkB6djmHSY0IABQLBhLmrAjhcnMGF1ZlcWpvN5XV++QsUwCsbUri8PpmL6xK5tNbHx2tSbhHAwRwHvRlOTidaOWUwURljpDzceMcF8MNZ4f7l36DoWwRwx9xQSkIi/uwFsMFqocXpoN3jpt3jvqMCOJE9gP+VBfCE3XKLAB7SS2MK4O5wK3vCnewMtvLhXAPbg/Tsj7FwxGCnyuGmPt5HS0oyZ7IzFAE8uziZ7tzUUQJ4oTib4eIMzq9K5dzKFM6tTGZgZF/f8IrkUQJ4ZXUGl4vT/0MF8HRuIl35KfQvTaNrSTynFzo4s8RJ/+oEPv0wny8OreEPNev5tGE9nzZt4vOOV/hj+4t83vkS13pe4erZV/iq/gW+rnqez8o20rUuh5NZLt4JC+aD0Eh2hKjZFaZld4SWPZE69sXoOGKUOKjXUabTUqZT/0kFsNZppc5tpyXRS3OCh0qLkXenBbPliSCK/n4Khr/8R2Lu+S3S/2sg+lcxhD0STvgDM9A8NB3zz5/B9MjjQgAFAsGEuUelUtG+0HWL1MlCeHMC9wsF/kKQuwflqsKlVWlcWJPChTUpXFqXxqV1aVzZkKHk8vp0Lq1L4+LaVC6sSeH8mhSG12cwvDaVC8XJDOd7GVrkpjvVRleijVavnWqLg3KtjT3hRt6eFcsb02J46fFgXnl8LlufDOadqeG8+XQwO2ZEsntOLPvmxlAyM4yd00PYExRDyZwoSuZEsTc4lv2hGg6E69g9N/qW7A3SsGeumpLZMeyaHTnynGj2h0ZTGhZDWWQ0h6KjORIbS7lazQmdhiqdlpN6HdUGPbUmI6fMJmpNxltSZxlbAOVrsry1uKw0O220uG7TaGHzS1lgR64sbu1eB20eO61umyKFrW4bHXFOOuKctHnsigzKj2t12xSRvDVOpfu3yW6jze2iw+vhdHzcqGqgvDzc7LDT6nLS4fXQ4fXQ7nHT7LDT7nErzSRNdhv1Fok6yUytTaLBZafJ46RhZPSL3GQhj8eRx+K0xnvGjLwUHNgUUuew3nY5epSgOaw02K3K11dudpHTaLMqr7feIo267+a0upzK/7n82HqbjZNWJ1UWB5WSnRNmGxUmK4c1Bg5rDBxS65Uc1hjYF6MbaQwxsivUwM4QI9uDjOyNtFJu9lDjTqDRl0RnVgqns1PonJ/G2cXpdOdm0r8sm8Hl2QwVzuP8ynnKUrCcgUIfA4X+7vzh4jQurE7n0trMEUEcnfNFKYowBkZuHAn8I7Evz0tfnoeBpSN/LC710Z+XQM/ieGUQde/iJHoXp9zIkjh6cz10L4qjZ2EcpxfE0bnQQ/MCO4ObM7j83mI+r1jBN6dW823TJmh5C9rehM434MyrcPol6HgFGl7keuVz/P6DVfRuzGGPxcCbYWZen23j/QgnH0SaeSsklp2xWkoNBkp1Bsq0Jso0Ekf1Ho4ZPIrkHTHd2A9YbpHGlMIjVolDNonDdgtHbRaO2a2U263+YdBWKyetNmpsdmrtDmrtDirtZuq9/oanOquGJqeBTq+NVo+TRpeLOpeXvbEWtkwLJeP/noN90nS0f/UE5geewXDfZHT3T8b48HQMD00j9sEpRE2aTPSDUwh/6GkhgAKBYMLcdQG8uDZVEcDL69NHyV+gAJ5bncz5del+EVyVpAhgT5qdrkQbbXEOTtndVBpdlEZbxhXAtyaHsH16BCWzY9g7J5rds8LZNSOU3XOj2TU7kl2zI/2SFxzLvhA1e4Njb80EBbBS75c/OdUGvSKCP1QA5duBAtjksN5xAWz3Omj3Oka9LT/OL50WRQZHx6FIkCw4HV4PnXHecQUwsFooX5NlsNXlpNlhV6RSPt1EFrPA/XW3E8CWODctcW6avS7l7ZtnJI4ngIGPkTt366zSqCaXVpeTVpdzXAGUX//NaXE6lD8E5P+jOqt1TAE8GOs/9eGI1shhjYGyGC37ImJuK4BHjS6qHF7qExJpz0iiMyt5wgI4uCLpFgEcLk67JRdWpTE4zs+Dm38W+EXQqwjgQH4i/XkJ9C5JGFcAu3MT6M6NuzGjcH48pxfE+fcDrvLStzmVzw8V8M3JVVw7tY7vml/lu7Zt0PE6353eynenX4Gzr0Pbq1D3Ml+VbuTCa0s5mmbnjTANr87U8264mfcjDLwVEs32aDWlBiP7tUYOqM2UaSSO6FwcM7g4ajYpFb5yizRqrt/NOWwxc9BqHiWAxx3+WX43C+Aph5Mqh0SD1+Hfw+oy0+ax0xnvoS0+nnp3PMdMTl6cHMryf3ga+wNPorvnSbQ/eRLTg9PQ3vc0poemY350JqZHZqB5cCqxD04h9sEpRE4STSACgWDi3FUBDBS9QOELFL/h1cmcL05iqDiJgeJkBlf5OFeUyPk8D+cWexjM9jCQ5qErJZ7W+CTqHT7Kjd5xBfCdqWF8OC3cXwWcFcme2RHsmR3BgXDdKOHbH6phf6hGqQoGZqICWGXQUaXTUqXTUqnVKJmIAMr/Bi7DNtikCQtg4PKvLHTyx2l2WkbJ3s3i51/qlcZZGraPqorJewHbPe7bjoaRZepmobr5/sCK3Y3OYPuYAijP36t32miJc9OeGMfp5MRRUtjsdY15WkpgZFlscNn9Y1qsZmolkyK5gfsdxxPABqtlzDTZbZwym0Y9rlaSxhTAWtBAhxIAACAASURBVIeHKouDcoNEaZSa0ii1XwLHEcCSMP9cu6Mmf0dwS2oC7Rm+CQngqArfqtQbsrc6/ZZcLE7nXMD3fWBziPzzYPQYmQQGl/l/HvTlykkcVwC7cpPoyk2ie2ES3QtT6MpJoisnib78VJrmW2hb5uCPO3L57vAqvqtYzfX6tVxrepbrrc9zveMVvul8Bc6+xXcdr3GtaSvXajbzh0Nr6NyUxoF4M7v0Wt6PjmV7rIb3I9XsijWxT2thn1qiNFaiNNbEYZ3EEb1ZWeI9ajZRbpEUCRxLAA+ajRyQjByySf7qn8PGCZeDE3YbVfaRIeIOJ3VOF3VOF/Uu/x8mrfEeOhMSaI+Lo9mTQIU5nj2xdrZM05Dx15OJf+gJtPc9jvr+pzE+PB3rL+egfWAK5odnYHl0FtIjMzFMegbDA1MxPDAV7QOThQAKBIIJc1cFcLxq383yd26Vj8FVPvpXJTGwMpGhFQmKAPZlOOlJctCR4KLBFcdJs4eDavu4AvjuM+F8OC3cXwWc6Ze/vXMiORhpoDRMy74QNftC1IoAylXBwExUACu0ak5o1KPkr0qnnZAABu7dk0Ws3mqesACO/X6MyseRK3pypS/wcbKIyjI4OrZbRC+w2hdYHZTvCxwaLVcNx1syDTzxpM5hVWRvPAGstUnUOaw0e120JXjpTEq4YxXAwNcsfz7jCWC9RRozjTYrdZKZBqvFL7hWCzVm85gCWO+Op9rm4pjerAwcv90S8K5Q/z7Bgzozx602mpLjaE1LmJAAnl+VOmbGqwAOj+wRlEVPXvIdqwJ4bnkig8v89/cu8Wc8AexenOYXwCUp/lE2C9LomZdCz7wU+hen0ppjo22JnY9fm8c3JQVwZCVXa1fwTcMqvmnZwLX2l7nauZXrZ97kavs2vmrdwrfNm/mqaj2Db+ZQs8jFQaeBdyJDeTcinLfDIvgwUsc+jY29sWb2x5gpjTVxSGvksM6k7PU7bDSMqgaOlTKTgVKzQRHA4047lW4nlQ47Jx3+E2L84uem3uWm0eOmye2mNS6OzngfTW4vtTY3+9VOts3UsupfQvBMehLp3seJuOfXBP3lvxH208cw/3I2uoenIf18FuaHZ2B6aDrGSc8gTZqG5cHpmCY9IwRQIBBMmLsugFc2ZCgCKO8JlOUvUAAHVibSW5RIf1HCKAHsz3TRm+ykM9FNncPDCYOT/VHSuAL43rQIPnjGXwXcNSOcvXMi2Tc3irIIPftC1OwJimH33Gj2BMWwNzj2juwBPBYbzfHYGEUC5aXgiQigLFqykDXazdRZTHdMAAObReT7At+W5S+wEWV0bswBDKz0yUu5YwmgLD7ya2x1OW8RJaVi5nEq+/5kAWzyOMcUwMDxMbLsyRW/O7EHUH5N8musk8zjCmCdZB4zDVYLdZJZWQ6ut0hUm0xjCmClZKfCZOWozkRZjFbJeAK4M8TInkgDBzT+WYINPs+EBXC4OO0W+Rtr/5+8B/BmAVRGPY2xB/B8oY+hAn+jSM9i7/cK4JncFM7kpnF2YRrdCzLoyU6jNzuN7mwfnfOctM23MrTRx2dvL+Lq/qVcrc3nan0R15rWcrXjZb7ueJVrXe9wteMNvmrfCp1bud60iSu7c+nbmMGpLDvvRs/l3chQ3g4LY0e0ib1qG3tipJGGGyOHdAYO640jTSFaDup1o2RwLAE8YNSPEsAKl4Mqj4sqp+MWAWxwe2jxxtPi8tLuTaDd6+OU3UOF0clr02Ip/MfZZP5iCo5JUzDdNwXtI9MIvvcxgn/yW6S/mYvpF7P84vfgNIyTnsH8wDNYJ03H/tBM7I/MFAIoEAgmzLgCKJ8QEPhDf3BZAucLRgvhQKGPnuUJ9BYm0rvCR39xCgOrUzm3No3hdT5/h++6JC6tS+Ly+lQur0/nwuq0gF9A6f55gStSuVCYzMUVyVwqSuHCMg9DuQ6G5jvpzbRzOtFCo8VMtVbPkbAYPpwezbtTY9j2WAivPjaX1564UQF8f0Y4H8yMYPvsCHbOjaAkKJLdI8K3NziWkjlR7JwVwfYZYewNjlWksGROlH+P4JxYv/zN8l/bPTea/aGxlEWoKYtQczAqhoNRUX4JjI6mQqtWqn5VOq2yB1BuDKkxGhTZCay21VtvCOF40lVnMSlCIS8tTjTyx5arcO0eN2fivHRYbHSOpGMkbVYb7Q4H7S4nHSPLn+1xHtrjPHTEe2l1+ZtBmqwWWqxWWm3+57SZLbQazbQazbSZJFqNBiUtJn+azAbqTTrqTToapBERtpuot0nK5/lDEri8K0vhWF3BciZyLF297aYl9ZF9irIQys098t6+8V5jrcmoiK8ijzYLlRYzVVaJkzYLlZKNE2YrVZKLKslFpdnNUa2dgzES+yMMlERGURIZxc7QWHaGatgRrPN3AkfbOaRzcszk5oTVS118AvUJ8XSkpXA2J53eRdkM5S9koGC+PyvmM7Ayh4HieQyuzmFozXzOFy/kwqrFDK9cwPmVNwZHD61I96coVRkZc64oiXNF8ZwvTODccrnCl6A0eQwuTR5JqpKB/BT6cpPoXeKjLzeJgfwU+vOS6c9LVkRQOZs4P5me/GS6cn105fo4sziBM4sTOLskkTOLE2jJdtK5MI7Laxfy+RtF/LF8DV/XPsfVxs182fISX7W/wh/bXuKLjle4enYb353exvWWV/jm5At8WrKKoZcXU+KI5Z3IUN4OiWRPhI294TZKo+yUxdo4oDdSZtVx2OoXvkMGfcCIGH/GbAKRrByR7ByzOjlusVNhdXDS6vD//1okqi0m6qxmml3+rRan4810xNnpiPdSZU5kT5Sbt+Y6WPB3YSz8Vy1p/6Qm+uGphD/8DPqfPYl0/xOY73sc832PY7r3MUz3Pobz4ak4H56K65Fn8Px8OnG/nIn7V+IsYIFAMHHuiAD2FiaOEsDBNWmKAF5a71ME8NK6lFsE0D+g9oYAXipKUQTwXJ5zXAH8YFoU70yJZutvgtj62zlsezyIt6eEjSuAewL2/QVK390WwGqDnhqjQZG4wKXWBptJkcC7LYCyBMpVu06P+3sFsH1kibfN61YEUN7z12K30Wqz/UkEcKzq3e0kcKICKH+tAsXvbglghckyIn9OTphcYwrgrjD1DxLA9tTkHySAg6tzOF+8kOGVixheuYBzRdl3RQD785Lpy02iPy95lADKYvh9Anh6UTxnFifQluOmfb6H8yuz+fjlPD49tJIvKzfw9ann+bzpRb5ofYnP2l7iy84tfHP6Vb47vY1vW7fwTc0LfFG6nitvFXAwycT7mgjeDotgd7hESZiZvRFm9kdJ7NMY2G/SUma+IXry8u/tloG/TwBrbRINdgutHn+3fbvbTEecm3ZvAgeiHWx9RsPaf40g7W/mkPF3kST8P+GEP/AUoT97Gl2A/Jnvexzp/icUIbQ+8JQif95fzMAiuoAFAsGPQJkDePPZn+MJ4PDyJGXT9/nCJAZXJNG3wudPURIDq1MZWpvO+XXpXFifdIsAXlqXxnBx4LKTXwCHClO4uMIvf5dXpnKxwHtbAXxvagRvPR3Jll/P5ZVfz2Lrb+fw5tMh3yuAB8J1HAjXURqmvUUGv08AD4T7Iwvg4ZgYjsbEjCuAckewLID1lhvyFyiA8h69W2O5IwIoS4m8bNnssPsrfOMIYJvdTpvTMUoA27xuOuK9nI6PozPO668O2u1+CbRYaTNbaDGYaDGYaDWaaTHolTQb/Wk06e+IAI53KsdYp4PcrhFkPAE8ZTYpX686yazI3p0QQFn+TtosnDBbOW6UqDQ7RwngoVgLpZFGdkdFjxLAnSH+YdDfJ4A9C7MYzFtA/7Ic+pflMLBiPv1F8xgonqdI4LlVCxheuYjzRfNH5C+LwcKMuyqAgdcCq4DjCWD7fI/yb+s8Fz35yQyuyeCjPUv57Ohqvj65kS8bXuCr5s183v7yKAG83raFa3UvcfX4s3y+dy01eXGUODS8FRXO9lA9H4YY2B1mZG+EiT2xOvYb1JTq1UrXb4XNOioTEcBKi5mTlpE9qi47HfEeTid4R7Z5eDhlj+P16RqW//0Mkh98HNdDz+D+5Rxsv5hD+E+fJOS+J9Hd+xjGn/4W072PId3/BNYHnsI26Wl0f/VvmO97nLhfziT+V7Pw/mIGhvvFIGiBQDBx7lGpVHQu9tyy1288AbxQmMzwihsZKkpmcFUKQ8WpDK1O4/z6TIY3ZHFpYzaXnk3hyrPJigBeWJPkn/m3KkU5lWBwRQoDhckMLk/mUlEqV1alcWVVGpcL4xle6h5XAN+dEs4bT4bz8r/O5qV/ncGW38zmjaeCxxXA7TPDxx3/8kMFcH+ofx+gvAfwqFqtNIGMJYA1RgM1RoMiDKfMJmU/3g+LdMcE8OY9d80267gC2Gqz0eqw0yp39LqdtHr8S8Gn4+M4m5jAmTgvnS4X7Q4HLZKFFqOZZr2RZr2RFoOJZr1OSZPBnwaj7o4IYLXFpOwVlPfuVVtMEx4+fbsl4JubP+6UAFbbrUoqTBbKDWYqjPaRODmmc3BYbaUs2sye6Bj2RMewO8J/nq28D3A8AWxN9nE6O5XuBZkM5M6nNz+bvqXz6Fs+j74V2fStzKJ/VTb9q7IZWjmfcysWcG5FDoOFmQwWZjKwPP2OCOC5gnSGlqUpIji4NFW5fbMc9i7xjSuArfNcnF4UT+fCOJqzHDRnOWjMsXLh9Sw+Lyng+tF1ULeZb5te5lr7Fr7p2Mq1zpEKYOerfNf2CtcaN3K9biMDb+ZSXRDPbpeO1+eGsT1cz55Ik3JEXJnByEGTYdTAZ3kUzLhzAG8jgNUj+1rb49x0xHtoj4ujw5vK7lAzrzwdScYvn8Zx/6/R/MW/oL3/GXSTpqN7YCaa+6aivXcq+p/6BVCu+NkfnIzz4am4H52G65FnlNuen0/H+zezhAAKBIIJc49KpeL0Eu+oqp58AsBYAnhxRYpyduiFopGN4qvT/FmTzvCGLC5unMflTfO4simNjzaOnPax1sfwap+/6WNlsnIuqf+Q+iQGCpK4vDKNj4rT+ag4ncuF8f59gHeoArhjVoTS/BEofBMRwH0hUewLiVIE8JhGw3GNZlwBHK8JRK76yU0gjXazcm10zHdEAMeaU3c7AWyxWmmx22gZkaBml18C27xuZbBzp8dNp8tFh9NJs1mi2WCiSWegSWegWW+kSadV0qj3p96gvSMCGDgGxn+KiI0aq3ncc4YnKoCBTS6yBN4pAaxx2Khx2BQBPKY3Ua63ctxg47jBoQjgwRiJvTGx7I2JZU+kjt0RekrC/B3AtxPAzqwUuuZn0L8kh978bH8KsuktzKK3KJO+lVn0rcxisCiHocL5DBXOY2B5BgPLM+gvSLsjAnh+ecYoCRxalqbcDhRDWQLHE8C2HDcdC7x0LPDSOs9Fc5aD+kwzg8/7+MO7i7l+oBhqXuDbxpf4tn0r1zu2KhJ4/fQ2OLOFa+0b+aZlAx/tW8GZV3I4sSiO18PC+TBSR0nUDQE8ZDBy2GigVKPmgFbDQb3ulpM/JiKANbaRDnWvi2aXnSaHm1rJxyuPRbD0f07Fef9jGO97HPW9T6F+cCaaSTPRPTAb0/0zkX42A/O9TyjLvrZJT2N/cDKOh6YQ/6tZeH4+XakIen4+nYS/nSsEUCAQTJh7VCoVZ3K9o6p6wyuSxxXAS0WpytFRF1eOLOWuSWd4bQbD6zK5uHEelzbl8NHz8/nouXQ+3pSqCOD54kTOrfIxVJQ0In8+BgqT6Svw0b/Mx5VV6Xy8OoOPV2dwZUUCFwu8d6wJZH+YVln+lbuBJyqAe4Ii2BscqQhguVbLCZ1uXAGUq361JqNSDTwl6ZXGj8ARMPK10THdEQGUZ+8Fzt9rddjHFcBmi79C2CKPQXE5lMgy1Oqw0+lyccbjoclkpklvpFGrp1Grp0lnoFGrUdKg86dOr7kjAlhrk6h32pQRMM1el3JtrPyYJeCb9/3dKQGsddoVATxulDiqM3JMZ6Fcb6Vcb+eYzsERjY1DsRb2xarZF6tmT6SOPZEGdoebKAkzjyuALUmJdGT6l4H7Fs+jJy/Ln2VZ9CzPpGdFhiKBAyvmMVQ4n8Hl2SPyl07fstQ7IoDDhZmcX54xSgBlKTxXkH5LJfB2ewDbctyKCLbP99CaY6NjqZELLyTz2btLuHp4DV9VrIf2V/m2/YYAfnvmNeh9lW/7n+fq2bVcq3+er4+/yIU3V7HTrOfN0Eg+DNWyK0zPnggtpTFaDqi1owQw8DSQie4BrLH5tyQ0u+zUmA1U6SXefCKS+ZN+i+t//COxf/GvxN43mehJM4h5KIioB2ajuW821vvm4PjJTByTpmB/cDL2Bydjm/Q0tklPY33gKaT7n8DysydxPDQF1yPP4H50GtaHxRxAgUAwccZtArlZCG8s+fr37ckzwy6sTuPjjVkjSVPyycZUPtqQzO82pPDJ+hQ+XpfMxVWJXCjycaEo+YZYLkticKn/DOJLK5O4UuzPpeVuzufbGciR6MmQOJNkotlupFqn4UhYBO9Mj+SNaTFsfTqcbU+H8vqUcN6bFjnuHEBZ5OQh0KVhWkrDtKM6g5VZgLOi/fI3O3BkzO3nAH6fAMoSGFiFCxw3crPgKWNdRuRBaYAYEQpZQuTlXfn5Y42LCTyNI/B9yh9HHnZ8uzl9LXZ/c4gsfe0OBy1WK02S5K8YjrxdbzRSq9MpclRjNNxSEa3SaTmhUStfoxqj4ZaGGflzku+X7ztlNnFcp6PSaKbWaqfB6abO7qTKJNHk9tLo8ijXTtkc1FrtNHvilPsaXR7qHS7qHS5O2Ry3pN7qGCVtt5O8H5MGs4V6k0Sd0UyNwcpJg4UTehsVOivHdDbKYi2URpvZH2WiNFJPaaSe/RE69kfo2BeuZV+4ltJIPYfVEuV6O5VmN/WuJBrcPtoSUjidnE5XWhZ983LoWzyP/iU59OcHNIOsmE9/Yc5IA4h/D+DQiqzvrQAOjnMW8PCK5FEjoYYKEm/ZD3jb5KeNJIP+3DT6c9OUETFDSzPpWuDj7PxEzuQk0J7poTHNXwVsyTXSv8HO1dIkvi6P55vmZK62ZvDl6UV80b2ez3o281nXm1zreYvvzr7Fd60f8E3te/y+9A26Nz3LTkccu9SJ7I5MpjQynaOR8zkWlcpBdSSHNFEc1kZzRBfDUX0sR/WxnJD0nJD0VJh1HDdpOW7Scshu4KDdwBGrhmPWaCqtsdTatbR6JVo8Nho9Xurd8ZTp7WyP9rDiSSfOR8OxPxyK4d7paO+ZjP6nU7E/Mgf7I7OwPTwT088mo7/3SVw/n47n59OVJV/nw1NxPDQFx0NTFCl0PDRFLAELBIIfzYQF8NzKNM6tDBgS+z0C+Mn65FECOLwikeEVSTdOFShI9lcRliXcVgBP+4w02QxU6zQcDg3nnemRvP5MNFueCuPVp0J4bXLYDxLAPUExowZBj1UBvFMCGLj0K1cAx5qBF5hAMQuc9acIxMhjAt9HoKgFnrwhJ1Dwbt7XJo88CVzq/D4BPO1231YAT+n14wrgKbOJaoOeSq1GkT3566Mskwc0rcj3yQJYazJSoddTZZJGCeBJs+UWwZMl8L+aAB6IkSiNNv8oAexMSuNsaiZ983LoXZRN3+J59OXdaAaRBfB80ULOFy1U9gD+ewVQvv5jBXAgL53+3DT6lqTeVgCbUx00ZdppWWSlt9jJV3vS+fpYKteasvmmdSFXO5fyZffzfNG9jc+73uFaz1t82/Um37a/zbW6t/jjoS30vbiW3V4X74abeSfIzK5gFwfCfJSGOhUBPKSJ4oguRpHACrPulsgCeMyuo8Khptqhpc5ppN5uoN4mUW1zcszoYMuUYFb9SzAZ/ysS3U+mY7h3Jpq/moL6L59C95Mp2B6eje3hmdgenon5gSkY7396XAGUq4KOh6YoewKdv5gmBFAgEEyYcZtAApd5Ry/5pjNcnOE/ImpNBhfXpCsDn69sSFHy0YZkrqxP4uN1SXy8Lpkra3wMjywjnS8M+FgFyZwrSGaoIHFMAezLNtGVZqIz0UCjVc9JrZpDIWG8OTWMVydH8PITIWx5IoitTwYrY2DGEsDAQc/yPkBZ/G7OnRLAwHOBZXkJlCH5xIhmh31U1SvwJIrApceblyZvFsbAwcuBCZTB8eYDBg46vp0AtjscSvdvi9VKs8VCkyQp/zaYTNQZDOMKYGBVT/786y3SqHl7N0vfzR3VlUYjVSaJGotNkbwai40Gp1uRu0AJ/M8ugBU6qyKAhzQ2DqqtlMVaKIs2UhZtpDRSz75wLXvDNOwJVY8rgK3xyXT4UjmTkkFv9jx6FmbRuyib3tx5N5pBls+jtyCbweU5I8lW9gAOLE9nYHmqP4XJI1s0EhksTBxXAANPBpEzUQHsz00ZJX89i5LpXpjEQF66In9n5yfSmR1Ha1oc7ekptGTF0b4ojo+25fDVvmV8W7uGb+s3cK3lBa6dfY9rXTu52rObb3rf4JueV7jetYVv21/h69rn+Gh7Ic1rk/nAGMzrobN4PyyMPZEmSkK1lMVGUxYbzUF1DIc0sRzWqjmsVXPcZOC4yUCF2cgJycQJycQRm4ljDolqj43aOLv/nF+vizZfEvXeRPZpnLwxR0/Go7/G9pf/hOknU4j9iymYfzYH0/0zMd0/HfvDc3E8OhfXL+bi+VUwnl/NxfOrubcVQLn5w/3oNBwPTUF372+EAAoEggkzYQEcLs5guDhjRP4yuLQ2Y1wBvLzOx0drfXy0NonLqxMZLorn3PJ4hgoSbhHA84VJ4wrg2VQjHQl6Giw6qjSxHAwO5fXJIWx9OpzNjwXx8mNz2PJEkNIE8n0CGHju790UQPmaPAy61mRUTgkJHA5986iWQLGTR5EEVsdkIQysCgbOrRurqnjz8WaBFcPA/YG3WwK+WfzkNJrNNEkSTZJEo9lMvdH4owWw3iJRYzRwUq9Tvpby27IEVplMnDRbqJas1FrtylJvnd15iwA2ON3/pQTwsNbOYa3dL4IxJg7GmEYJ4O6Q2HEFsCUuifZE/zJwT1Y23Qsy6VmYRc8SfzOILH+9Bdn0L5OT+e8SQLn6J9/+sQJ4s/x1L0yiPzeNMzkJnMlJoGuBj9Pz4mlLj6czPZXm9ASaM92c25TFH99fyneVm/i2+kWuN27h+ukPuH62hGvdu/m6922u9mzjWvdWOPsy11qe4w9lhQy8MY+9cRG8HTuTd8Jnsz0slh3B0RyIVlMWo6EsRsMhtY5Dah2HNXrKDWaOGyUqTP7xPZWSjaN2M+VOC7VxDuoSXNTHeWjwxHPSGUeZ3smmJ8JZ9v/NxH3vv2H4H/+C+f7p6H86A+uDwRjvm4Hp/uk4HgnC8qC/+ud4dDauX4zkNkvAsgDK3cDan/5aCKBAIJgw4zaBXC5OHzMXVmdycU0Wl9ZmcnldFpfXZSpHvd2Y95fE5XU+Lq5J4MqaRK6s8XGpOIFzhV6GCuIYXOY/Mk4WwOFC/zFTYwlgT6aBMykG2uN11EtaTsRGUxYUwrangnj5iRCe//VsXvz1TF767WxefzJoXAEMXObdOSuCHTPD2TEzXDnqLfB4uDslgBXqWOV4uMAlzsAE7hMM3NMni2CdZFaESd4DFygUskQp3b1jLAHf/FhZ/OS35b2CgdfGE0BZ+BrNZpot/tNAGkwm5bYsgRNdAg6s+lXptFRqNZzQqBX5C5TpakmiWrKOkkC5EnjK5hglf40uz396ATyu9eeYzsZRvVPJYbXEoVizIoC7Q2LZFRQ9rgA2e320JSTTmZRGd2YWXfMz6F6QSffigGaQZVl0L82kJy+DnrwMevPT6S9IZ2B5BoOFGfQtS/anwEdfQQJ9BfH0F8SPK4By9a8vz0tvroe+PO+EBVA+Gk6WP3nZt3dxCqfnxXMmJ4HuhUmcyUmgM9PLmbQ4WlJtNCSbaVlsp3dDCtcOb+CbYxu5enIz11rf5Hrne3xzdgdf9ezky+4dXOt9D/rehq5X+fbUBj4/vJK21T7KEnW8FTGbrdODeWdONKWRWkojtRyI0lEWredgjIGDMQaOaiXK9VZOmBxUmp2ctLg5YXdQ6XZyKs5LnddLjctDudnFjggjW56JJv3Rp/FMehLHgzOwPzQH6YG5yhJw5H9/HO09k3E+GozrF8F4fhWM969D8P510G0rgPK/1geeUmL82eNCAAUCwYT5dwvglfVZtxXAy6sTuLw6URHAwWVeBpbGKfuFzi9PYbgwlQtFKbcVwLY4rSKAB+YG8+qTc3np8WBFADf/ZhavPTH3ewVw1+xIdswMZ/uMMLbPCFMaP/YEHBV3pwTweGwMFerYUQI4VmPIePvfAgUwsLEkcC9g4H7B8SJ/TPl58nPkjxO4BFwnmb9XAAOFr8Vqpd5o/MECOF4TiFwZDZQ/WQDl2/I5yzUWyygBlJeC5Wpgnd2pyF+T2/tfRgDL9XaO6p0cM7g4ZnBxRGPhsFoaJYA750aNK4BNnkTaEvzLwF0ZmZzNSR9XALtz0+nOTacnL42+ZWk/WgDlt++EAMqVv7PzEzk7P5GeRcmjBPDs/EROZ8VxOs1JW6pEfZKOhhwTp4u9fF22lq+PbOCryuf4pnkb19vf4OrZ9/mqew+fd+/hWs926H8Pet6AxhegehPntyzmZI6L9zURbJsVyQehBvZHaMYVwGM6CydMDqokFyctbiodTkUAT3niOGl3c9Dg4OWng1n1T9Nw3vPP6P/in9H85VNo/uoZbA+FYLh3Jsb7ZhHzfz2F6f7pJPzPKNL+QUvGP2rJ/CcdGf+oJu0fYm4rgPYHJysnhFgfeArpwaeEAAoEggnjnwO4NP6Wg+GHi9OUYc3y7eG1GQxuSOX8pgwuPZfF8LPpDK1J5vyaFC6M5OJqfy6vTuJScQKXiuO5uMqfCysTuFDk4+LKlFFNIBdWpHGxKJ3LK9O4vDLVfxzc8jiGl7oZIF8tuQAAIABJREFUmGenK81Ce5yJU0Y9x6NiKJ0TpgyC3vzPM9n8L9PZ8pvZvDM1nDefDub9GeHsmBNNSXAM+8LV7A9Xs31mODtnRYyq+I2XXbND2TU7lJI5YeyeG66MfymZE8aeoAgORmo4HK3jYKSGsshYjmjUnDDpqTDqKNdrqDDqqJKMVBh1VJoNVElGKs0GKow6aszGUUuc8nLwmLIgmak16Dml11NvNCqiJS+z3rz3rt74/7N3n9FV31ei93n3rPXkccE045Zk5t65M5lMJokd2zSBBAj1cqTTe1PvvQvRQfTeuwAhhIRAIAn13nvvdIPtZCZ3ZhLb2N/nxdH5WwLhhITMXXct7bX2kv5HR2fphV581t6/vX8KeoxGuvR6YTDDCrR2jWZKBc9auWtRKoXP6dR93+adLrv0+imf0W0wMODra2n5TqDQ+lntMgWdUgUdEjmtEhktYinN3hJaJDI6lWraZApq3T2pcvegQSyhUf79iphGuZh6qRd1EpHwWrNSSpNCQpNCQpXEnXKZO2UyT4qV3hSrpZQYtJQbdFTojTRrfGlT+dOtDKBXFUiXzpc2vYlWnZEWrYEmtY5GlZYmte6F2aI10KY3Cb/XrNHTqNLSoNTQpjfRYfShVWd8ZS3gcrGaYm81BSJLFnppKBNrKfPWUCJScdtDQZG7nAJXKSUiFRUSHdVyI/VqX1qNwbSbg2nzCaTTf6INHBZOb3QofTFhDCRGMpAcQX9qOANrIxhMi7SAMDV2Yll0NGPrYxjfEM3o+vCJDBMwOLY+hLEXAM56vduUTAnmbkoId1NCeJAWzsN1ETxaH8n9tWHcXxsm/OxOcjDjSUHPPY8lBjKaEMCd5GDGEgMZifdnINpMf5SJ/ggj/eEaukNkdAVL6Y6W05Og5D8uJvP1za1Qu4f/bNnF79t38+2d0/xx6AxfD17k6dBVng7k8G3/FcvKmLZ9fHE1mbGDkVSHGzm73Jtsez35HhryPTRkO0i4KdJwU6TiqpM3Bd4qbnlLKVfrqNIZqdTpqdN5UqdxptVXR2dgELWGAA4vFpH0D7aEv2+D4q1PkL29GK93liCavxjvtz5FNnsJijnLUM9fgWaBLZoFthjeXY3h3dUY37NHt3AlmgW26N9eiWGBHbp5K9DMsUEzx2bK95NTNnsGgDMxEzPx8vFCAFrxd3dLCA/Sw3m0I5KHu6J4tD+KxwdjeHIghkd7I3mwM4z76cE82BbMo62Wc3yWDOThVj8ebvWd+Or3FwNwKEJLj7+KRoWMSk8vCta4/kkAZq/2INfBk+vOIm44i7g6gb/c1e5ThkFeBoDXHdzId/KgyF3MbQ+JJT3FlHp7U62UUaWQUiETU6WQUqtWUKWQUqOSU6tWUKOSUzUJgNNdFTcdABsVcprk8ueQNRluQtVNqRSmca3Pk1+fPLnbqdMJ5/aslTwr9CbjcXJah0A6dTpaVSo6dTp6TSbh5116vfCefo2aQbWSAZWCPqWcXoWMTqWUNrmYRm8PGqUi2rVy6mSelLg6TlRQZdTK5FSJJVR4eVMu8qJeoaROrqBOrqBGKqNGKqPew5Mmd08aPL1okEppVilp1Zto0Opp0Bpp0Zhp1frQqfGlU+NLu9ZMi9ZAi9ZAs0b/g/B7EQAt2NNNAaDls/52ACz11lDqpabYU0mRu5xCNxm3XCQUuskoEakoF2uplhtp1PrTrPf/QQD2J4XTnxouIHAoNYrhVMuuwNF10RMIjHohAEcnrnJ7NqcD4HhqiIA6K/oepIVzLzWUe6mh02JvNCGAkXh/huP8GIr1ZTDGR8DfcJzf9wCMMtEXbqAnTENXiIruKBW9cSru7g3m87Px/OHWZr5u3sMf2/fx9dAxvho4ydcD5/l2MJdvB3P5biAH+s/AwEn+q2QT/351A6P748nykHLWVsQ1FwV5rkpynGQUeOsoFGvJ91SS5yYh19WDQomcMpWWSp2eZrOGZpOSMqWaXHcJx21ciP97G/ze/g26Ob/B67Vf4/XGx4jmLsJrzqfI59kI8NO/s0pA3/ftXydM76/B8O5qdAvsML69EvM7q/F51x7j2yunxd8MAGdiJmbiL40XAtB6U8dkAD7eFc2TAzF8vj+GJ/uiebInkkc7wyYmewN4sCmARxut6cf9zT7c32zmwRYLAh9tC+TR1uCXAuCdOAPDkTp6/FU0KeVUibwpdHD7swCYs8aDa44e5Dl6kDNR+btm7yFMAN9w9HopAOY7eViugnPz5raHhBKRjDKRlHJvbwF01jaldeDD2t61Vv0mL4aePB38IgA2KRXTVtgmt2AnI9D6M2vF0Pp7HVotPUajAL9noTe50jd5wGNydhsMQoXR+pndBoPw88mVwl6Vkv5J8OtQSGhVWtr4dTJPysWuVCo8KZW6UeTlRolcSplSTZlSTYlcyW2pnCKJjGKZgmKZghK5knKVhnKVhlaxgg6RnBaRlAaRhEYvKY1SFS0qHS0qHc1qIy0aE61aM61aM80avZB/Dv6mA2Cb3iRUAdv0JtoN5on3/u0AWOKlptRLPaX6Z91fedtDQamXmkqpnnq1L41a3xcCsD8hgr7EMPpSLNmfGs5gSiRDKTEMpUYxkmbJ0XWRLwTgyHSVvhfkZABa0WeF33T4G47zmwI/K/Ymg3AyAHsjjPSG6ekJ1dEVqaY7RkXfBgPjB0L4tyupPK3bwzfN+3nac5Sv+4/xTf9Zng5m8+1gHk8HrvHdQAYMn+GPNdv5r8JtfH5hI3laJSdXOpFl7022g4SrjlLyPdXc8lJzU6TiurtUAGC5Wke1wUiLr5lmHxN5ngqO2jiz4Z+X47fwYzRzPkI5+2O8X/sN3m8uQjpnMdI5i1HPX4H2bTt0C1difM8e0/trMH/ggN9PnfH/Oxf8/84Fnx87Yv7AAe18W0wLV+H73hr8P3DE/M5q1G8tmwHgTMzETLyyeCEA72wOFvLh9gg+2xnFk90W/H25P4bPd0fyeGc4j9NDubfBj3sb/Hiw3o+H6yZyvQ/3Npi4u9HI/c0+PNji+xcB0HoTSG+AmmaVgmovMUWO7i8EYMZSJzJtXbiyyp2r9u7krHEjd42bAMDJwx4vC8BbLiLLGcAJAJZ6yanwllPh5U2DXEa9TEqtREy9TEqTUkG9TGqp4CkVNCrkltcnzvRN3n337GDHswB8rr06AT4r3J5dxzIdAK3VOivwrO1ca/65ALRe/2b9eyYPgUz++zqUSjoVStoVCpoVchoVMqqVUqrVMqp0Coo1Ego0YmqCjbRGh1IZHEBVcAjVIaFUBAZR5h9AqZ8/eSo115QqchVKrsrkZEtl1Kn1NMt1NMm0NEk0NEu1tMq1NMnUNMnUNCvVNKjVNGo0NGm1NKi0NE7kXwrAdoNZaB9bQWj5vL8dAItFKkpEqinVP+v+yiJ3udAKrlP50KDxeSEA++LD6UsMozc5VEDgYEokg8nRlkrg2si/GQDvJAcL+Sz+rAAcivV9Dn99kUbhtcmv90eZ6YvwoTfCSE+4gZ4ILV3RKtriFPRvMfPoRAxfl+/m2/qDPG07zNPew3zTd4LvBiwA/HYwj+8GL8HgGb5p3MVXldv59+vbKArXcNbdkYt2HmSuEpHtYLklJM9NRr6nkpsiBTc8vSlRqKnSGakxmqg3+lKt9eX0Ki82/9KWyJ9+inr+x8jnfIJ0zmLkby1F/tZStHOXW9q3C2zRLVyJ/p1VAv58fuwo4C/g713x/YnTDABnYiZm4r8lXgjAsY2BjG8K4s7mYB7tiOTJ7hi+2BvHF3ui+HxHOI+2BPFgUwAPN/hzN8XE3RQT95JNPBDSwHianvH1eu5uNHF/sw+PtgXy2baQlwLgvQQTo9EG+oO0tKiV1HhLuO3k8ScBaL0K7soqZ7JXOXNt0v6/fCdvYRn0ywDwtoeEIncxBa5eFLmLKRcrqZaqqPb0pkkqo1Eipd5bTKNESotcQaNESrNMTotcQbNMTqNESuvEWpdnJ39fBMAWtWoKrqzoe/bMnhWB1vN/k0FoxZt1gXOn7vulzr0m03O7/aznDJ/NHqORfh8f+sxmobVsxd/kimSHVkt3UCwdQQk0B8XRGBxHXXAs5aExlITFUBabSP2WrTTv3EXPieMMnDtD+4mjdJw+Tsfp47SdPErL8cM0HztEz/nTdJ45QeuJI9Qe2EPV3p3kRYRxIySI6/5+XFeruCmTUyyytI2rRN5Ue3tRJfGkWiqiWiamTq6gXqGmQakREPinqoHPArDT5CtUAa0t4XqF+m8KwNueSm57KKbg74ajFwWuUoo9lZR5a6iSGWjQ+NGk83shAHvjwuiJD6EnyZK9yaH0J4UzkBTFQHLEcwMh0wFwKCWIkWlyOgDeWft9tW9ypW88KWjKs7XCNxLv/1z7d3LFrz/KxEC0eSJ96IkKpDfKn94of3rCDXSHa2gKldAer2Zwmz//kbOJp7f38LTuAE+7DvC09zDfDWTzdPAG3w7d5LvhHP7YfwoGD/FVy07+s3IrAydjqEv1J8vemytrxOR7aMhxlpLrIqHAW8MtLyWFEjmVWgMVGj3FCiVZq8Qc/9iFyHc/wm/hx+gWLkI0dwke822QLFyJZqEDqjm2GN9YgXnOSrRzl6NZYIv2bTuh/Wt6fw2+P3HC76fO+P3UGfMHDpjeX4P+7ZUYJ84B6ufbopu3wvL7MwCciZmYiVcULwXAL/fE8eWuSJ5sD+PBpgCh6ncn2cjdJCP3k4w8SLTk/SQ9Y2t1jK3T/VUAvJ9oFgDYqlFRK5ZS7Oz5ZwHwyipXrqxy5spKJwGANxy9ptwE8tcAsEKiokamfikAtk1zp6x1198PAfDZNqsVe1a8WdE33RCIFYDWK9w6dTp6jEb6zGb6zGZ6jEbh9T8FwAFfX/p9fKZUGSfD1Po3DUavpyd2K22xm2mN3Uxj3CaqEjZStXYr5Wlbadx3mK5T56g/epzSvftozThD68WztF48S3PGaRrPnaTh7Al6rmZOyd6cyzSfOETzgd3Upm+kNCyEIpOZYrGMYpGIMk8RlSIPqrzcqfb2oELiQa1MTp1cJSDw/3YAvuwZwJ7YUHriQ+hODJ4CwP6J4ZDBlPC/GQAnY88KwGfP/L3oDGBfpJG+SOMzCPShJyqY3qhAeqMC6Qkz0RWqpTVUTnuMiv6NZn5/eR3fFOzk25q9PO06wDc9hywVwKF8vh26ybdWAI4d4+uOXfyhNp0HV1Lp2xNLrrOcXGc5RWIj11zl5LnJuC3Vc1OkoFAip0Kjp1Sp4ZZYwslFzqT/L1uMr/0MzZxfoVq4GLe5S3Gdb4PXO6vRLHRAPXsFxh8tw+dNWzRz/vwzgDNDIDMxEzPxt47XZ82axVBaEI+2RFgWPW8O5sHmYO6st5zbe7IjiC93h/LbPaF8sTeUz/eF8nh3CI82+fAwzczDJAMPY408iDFwL8bAeKyJO3FmxpPMDMfpGEvU83hjIJ9vDZnAXzD3tgRyd6slxyfy7tZAnqSH8iQ9mMfbgni43si9tbopV8FZ7wIudrbc+3tmsStHfr2ak7+x59ynTlxY7MSVZa7kLHcld4UbN2zduLnKjXx7d66v9uCms5h8J2/hHOCLAHhjjQs37B25vtqBG/aO3HRwptDZjWI3T0rcRZR5elPm6W15dvGgyktEvURCg1RKo0xGg1RKvUQy7fBGq1o+bbZpFM+91qJU0KpSvhQAnz0TOLlCN7mK2KbX0RLoR2OgLw1GLc06Da0aNd0qDb0aLUM6A30qDa0yCS0KKe0ajaXSZAyhzTeCzuBE2sOSaA1LoTVmE62xm2lO3E5z4nYaE3dSnZxOedJWSpO2UJG6ldoNO2nedZD2A4eo37GLpn17aTm8n47jhxm4cJbG0/tpu3iM1gtHaThzgJaMI3RknqAr6xT9uecZuJZBT/YZ+nLO0ZeXSdfVC7RnnaPn6kUGrl6i/+xpOg4coHnzNsr9I6jQB1Oh9Oe2u4YCbxVFYjmlYgUVUiVNCg0tCi2N0ombWZRyarUKqvQyarRKmnQ+tBj8aDH40az3pVFrFp5bjf60GPxo0vnQqDbSMmmy2ApH67Txs9mmMdCu0tKm1NCqUNMgUVMnUdGgMFIvN1AlM1DmpaPYQ02hu5JiDy233bUUuqq55azgppOcGw5iClylwiR6uVhJg9ZIk95Ip48PPf6+9AX6MxAWzGBEKEORYfRGhtATFULXpByKj2EoPka4LcRyb3A0Y6mRE2m9oSOU8dRQhhMDGEsMFBA3ucI3nhTEneRg7qWGcn9tGI/WhfAoLZCHawO4l+zLnUQz4wkm7ib5CN+PxRsZizcyGmtiKNaPwWh/+iN96Y/0ZSgmgOHYQOH52eyONNAbqaM3UkdfhI6+SBUd4TK64tS0JSgZ3BvEv2dv4g/Fe/lj/WG+ajnJ095MvunN5Ov+LLiTzzdDV/hmMAMGz0Hfcb6sWMfnN5JoCFeSI3Yiy8WJ664yCrzkliXQKm/KdSIKVVKy3UQctXEm4APLeT7x658ieWMRstlLkL65GMWcZcjfWops9hLkby2dQN9yNG8vw/SBHaYP7DC8twLzj1fi93f2+P/9Gvz+zh7fn67G/OOVmD6wwzhxy4d6zqfIXv8QxZu/QTtvMbr5S9DOWyysgVHP+XRmD+BMzMRM/EXxHAAfbgnhweZg7m20rG55siOI3+4JEwD4ZG8In+0M4tEGMw9TjDxM0PEwxsCDaD33ovSMRuoZjTYwEqt/IQDvbw3i3jZL3pnIe9uCXgqAl5a7vRQAc+1chTN/1gXQL5oCzndwJX+NEzfsHclf4/RCAJa4iyh19XwhAK3PUyD4AgBOmyolrSrl1LN1k1rA0wFwumvapgNgh15HV4AvHX5mOg16OjVaetRaBlQ6hjUGhjQGepUa2qSWKeRGtY5q33Dqg2NoiUikM3EDXclb6EzdSmvKVprXbqdp/S5LbtxNRfIWKpK3UJWWTt2mnbTuOEDP4RN0HDxM4649NB+wALDt6H56zh2n6cwBuq+cpif7DC0ZR2g6d4imc4foyT5D79WzdF85TUfmCct7Lp+hO/MsXVnnGCvM5UFJPp/dzufejauMXb5A5+49NG7YRGVMAtc1Rm7INVz3kpLvIaHIU0KDTEOr0kCDt4IGiZxG6cSQjtoysd2gMdGk86FZ72uBntYsPFtR+KcAOHnwxJqtar2Avxa5SgBgvdxAnUxPpVRPqUhLsYeaIg/V3xSAg3HRFgQmRFmui0uKYTQ56s8GoPVM37PP91JDeZgWzMO1ATxI9Z+CvjuJ5ikAHI0zMBJjfA6Ag9H+DMUE0BfhM212RxotCIwwWAAYoaEjXE5vnJauJB1dm808PJHAV0V7+KrmIF83H7PcBdxzga97Mvl2+BpfDWbxdOgSDF2AobP878bt/L50I70b/Sj08SZH4sY1VykFXkqq1XoqNDIq9TIuurqyf/Eq0n5mgZj0zcV4/X8fI31zMcq5Nijn2ghn/2SzlyCbvQTVvOWo59ugXWgjAE//7nJMH9gJ6LOmFYjaBUsF6MnfsAyVzABwJmZiJl5lvD5r1iwG1wYKAHy0NXQCgYE83h7I5zuDBQB+uTuEJzssS50frDXwIFHPg1gNDyN1PIjQcidMw0ioJYcjNS8E4INtwdxPt+TdibyfHvzSADy9yIXDv1rFiY9Wc/YTRzIWOXJpkSNZSxy5stSJ3GVO5K1w4pqdM9dWunHD0YvrDqI/C4A3HZzJX+NE/honbjm6UOTiLgCwXCSmXCSmzNObcnevFwLQ+lqDVEqT3AKpF2GvRSWjRSWbUhFsU6toU6ueG8aYjL1nAWh9ntwGng6AlqEQI70GAz1qLb1KDf0KDUNyPYNKE31KM10KI20KA61aM03GACrDE6iJTqEhfh2taVtpXr+Nlg3p1K3dQnXaFqrXb6VmwzaqN6VTnrqZytQtE/jbR8/+owydOkP30cO07NtD+5H9tB/bR9vRvfScO0rHxWMC9tovHRcQ2JV1SnhuPn+YtovH6L18hv7MM/RmnWXg+iWG8i8zcCuLwZuXGbyRyXB2Br0ZJ2k7up+q9WkUBIVwU60nT6LkppeMKomKBqmWOm+lBYHeChqlCssgj0JJncogILBRa6ZBY6JBY5oCQSsAmydWy1iHTJo1+ikgnNJWVukE/DXLlAIAa6U6aiRaKiS6/zYADsRGMRhnuS1kODF6ohIY+UIAjiR9j7/J6Hv2+U5yMPdTA3mQ6s/9FL8pALSmgL9YPcPRBgGAVuD1R/oyEOVHb7j5ueyOMNMVacnecDN94Ub6w3V0hiroi9UzkGigPVnLYHoQf7i+kz+W7+Kruv1813nGshy6+yJfD1zhq8ErfDN0GUYyYSyTrzoP8ceGPYwfjaEmXssto4xsFy9uihRUqo1UaFWU6VTss1lN4j8uJuCdD5G9+THer32C6Ee/mQLAZyuAVgDq3lk+BYDG923x+ckq9O8ux/DeCgzvrcD4vi3G921RzV2Ees6nKGd/jHL2x6jnfIpu/pIZAM7ETMzEK4vXZ82axUBqgADAz7aF8Tg9nM+2hfDFrpCJ9m8YX+4O4cvdITze4mup/iVouB+l4l64nDFfCWM+YoZ8xAz4yRgKUDAYqmQkdnoAPkwP4cF2S96byAfbQ14KgBeWuXDyEycO/qsdx369kjMfO3DukzV/VgvYir8XtYBvOblzy9GFmw7O3HJ0Eap/t109KHbzpMJLQpVYRpVYRrWX9JVUABvlYpoUElpUMto0Ctq1Sjp1Wjp135/je3bdy19TAezS6uhQyumQy+iQyOgUy+mSqOiUGWlTGKlVmmnQhdAUGENb7Hqa4jdyO3YdpQkbKU+y4K4iZSMVKRu5HZ9MQUwcBTGx3I5PoDQpmcq166het4mm9O20795N9/799B47RNfRfbTs30HPqQP0nNlP58nd9F04TP/V00ILuPPySToyT9B28RhN5w5Rd2oftSf3Un96P3Wn9tGTcYiBS0cZyDpOx+UjtGYdpiPvJHVZB2nLPc7o7UuWvHWBuzczuXPjKgNnTtO6ew+VKalky9RcdhVzS6qkVKygzFtBlURJlcQy1FMpVVMt11KvNgpZq9Q/B8MmjYnGiaXS9Qo19Qq1MGTSOGnyWMChUkujRC5kg0RNvVRNpZeKSi+VZeefh/q/BYD9MZH0x0QyEBchXBk3nBjxQgCOp4ZMAd8PDXaMJ/oK1b7JOQV+MTqGY3QMRekZjrNU/HrDzXSHGukONdITZpo2u8J96Ij0pyPSn+4If/rDfBkMNdMfpKMvWMdAhJHOcA0t4SoeHozm366l8Pvb66DlMN92nuKbrrN81Z/F10PZ/HH4Ct+O5sDdq3w7fIFvek/x76VbuXMxla4dUVwTy8jzlFEmN3HDQ8YZe1fC/udiNAs+weutxcjmLEf65mKh7auca4PkjUVoFtiinr9iAn4rJs77rcTwnq1Q8dMuXCZUATVvLxVSvWAJ6gVL0E3c+2t4exn6BUuFnAHgTMzETLyqeA6Aj9PDeZwezpPtYQL+rAD87e4QPtto5mGakQexKu5HKLgXKmNQ78Gg3oMBvScDZgnDfnJGwlQvBOCj7d/fHHJ/Ih/uCP2rAHj6N2t+EIC5dq5Cxe9PVQBvOblT4OTKLUeXaQFY6S214E8ip8Zb9krOADbKxTTKxdMCcPJqlskTt3/NGcAurZZ2tYIOpZQ2uZw2uZx2uZo2tZk2fQCV+iAq/aKojUymPnUbtSnbKIhaT2nsRioStlCTuo3atVuoXbuFsrgUimPiKI6KpjwunurkRGrS1lGzfiON27bRsiOdtl07aN23g+Z926jbuZGOY7voOrWH9uM76T53gI6LR4Rzf9YqYOPZgzSePUj96f00nj0onA9sP73XgsAJALZnHaE3/yyt2UfpyTvFcP55RvLOMp57lke3cxktzmOsKI/ha1n0nDpBSXQMBX6B5MhV3JQoKBIrKZVaskyipFyspEqmoU5loF5tpE5loFqupVapp15tpFFr/pMAbFBqnssmhYYGsez7nABghUhJuaeCEpGKYg81t91Vf3MA9kVHWBAYG85gfOQEAsP/bABaBzcmA9A6xDGW4DOl4mcF4GicYQoAh6K1DEbqBAD2hJnoDjXSFWIQIPhsdoaZaY8MpCMykO7wQPpD/RkM9WUoyEifn5a+YC29YXraApUMb/Tni8xo/i0/EZoPQMcJvu06wzeD2XwzfJU/DF3h69EcuJPD05GLfDVwmj+07OH3JXt4mLGVIp2Om2IVFUofzq90YcevbDAu/AjpvEW4zbFF/JYN0jcXC+f8tG/bIX9rKfp3VqF/Z5Ww88+y8sUe4/t2UwCoe8cG4/u2AvxU8xejmPsp8jmfYH7fDt+JNL+7AuNCm5kK4EzMxEy80rC0gJP8uLchhDsbgxhPD+HO9lCeHIjhi4OR/HZ/BL/dEcwXW/35YrM/X2wI5HGqL/cildwJljDiL6Jb7Ui3ypkOjTOdBm86feR0BisZStIxnKrh3iYzD7f68Xj7923lZ/OLHaH8Lj2cf0sP5XfbQvh8g5nP0gzci1UzGq5iIEBOm0pKrUjE7TVOnPuVA6d+4cSRf7LjyD/ZcuJfVnP+IycyPnYka6krV5d7kGvrydUVrmQvd+GavYdwE8jkzFnlJgyFXLP3IGeVG9ftXci3d+WWgzuFTp4UOnlyy8GdImcRt128KPeUUSGSU+mloEoko04iE1q+k9M6JfvnZKNs6pVvk+E2XVqveGtRKr/f5WfQ0WJQ0KZVUi8WMajSMqLSMSjVMijT0a800iTTUi/XUm/0pTYwgqqQaGrCYqkMi6E0KIJbPkHk6MyURcbSkJxGc9pGqpNSKY9LpCIxmcqkFKqSU6lMSqEiMZnyhCQaN2yiJDaexg2baN60hYb1GymOiaI0Loaa1GTqN6TRvGUjLTu30rpnO827tlGbvpG6nZtpP7Sb7mP7qU7fQP+ZowwiEwMXAAAgAElEQVRnnKT3zBH6Mo4zfPkM3eePMnD5ND0XjlN/fA/tF44ykHeG5oz9VBzdSnvmYfqvnaY98zD1Z3bTdukQd4oyuVecxcjNDNouHWLkZgYPq3J5WJXLWPkV+m+dZ+jGORqPpHMz0Id8uYJ6DwXNLnJqXeRcV5nJFCm5qfWlzBxCsdGfSqM/NXp/6gw+tOp9aVObaVUaaFRpqZOrqJOrhFbvdPizZo1URrVESpVYQqWXnAqRjFJ3S5a5KylzV1PuoaHcQ0OBu5p8dzXXXZVcd5Jx3VFKnr0XJe4KyjyklHvKqPFS0qSwtJd7fUwMBvgwEuzPWEQwo5ETGR3KUEwI/THB9EUHWaZnowLpiwlmIC6UoYRwhhLCGYgLZTQ5itHkKEaSIhlJimQ4MYKRxDBGJrV6xxIDheXMk/E3+bq2wUgTw9E+jMb6MRrrx0iML8PRPgxH+zAYaWIw0sRAhJH+cMMLsztYM21O997eUB29oTp6QrR0B2voClLTGiKhf5OOO4cDoewQ1J+D5svQc53v+m/wzVAe347m8t34Fbh7Ae5d5PfdJ/mq/TDf1eyme52KfP0aznvYE/I/liObvQj5nDXoFrigfcsez9eW4vnGMrzn2CCduxz5fFtUb9uif8cO47sr8Xt/Ff7vr8TnHRtM7yzH98drML2/5vtJ3wkoquevENrHVjAa37PH8O5qtG/boZizBPlbi1HMXYTsrY+RvfUx6gWL0L27GN27ixHN/vkMAGdiJmbipUMA4P2NodzdFMyd7aHc3RFmufHjQARf7gvny+1BfL7Fj883+fHZWl8eJBoZDZEx7OtFv9GdbpUz3SoXOjQudBnF9PirGIgyvDIAjkWoGQxU0K6WTQHg6X91FgB4/OerOPehI2c/tOfSIicuL3HhyjJXspY5cXmpI1dsnbk6cR+wdRn0dQeRAMC8NZ4CAPNWO3NjtQs317hNAWChk+cUAFaI5P/HAGhd6jy54teiVNJjNtKu09IgljCoNdGvMtHiraZdpqdT40urTzAtAaF0RCXRm7yerqQNNEYnUR0aQ4lfKHl6X66b/CmLjKUmPpm6pLVUxCRQGhlLZUIyVYkpVCelUpWYQmVCMhXxSdSmpFEel0jzhs00pG2gMiGZurRU6tJSaVifRsPGdTRuWk/91g3UbFlPzZb1VG1ZR3X6Bpr2ptOyfwdNe9NpP7KX3lOHGcw4Qe/5Y3SdOUzHmUP0XDhOd8Yxmk7tpy3jCDd3pdB4bi+jty4wdOMcHZeP0HH5CH25p+jNOUl39nF6c04ykHeGsYKLjN+8wIPyq9yvuMpI6WUGCjIYKbjA6PVz1G1OoSDAhxuunhS7i6nwUlEgM1EoN1OmDaBcF0iZxpcqrS91Wj/q9RPnALVmGpV6GpSa5wBoXTfzsgAsdVNQ5q4W8ocAWOouEQDYrLQMmLwKAA4nRljQNwHAkaRIRpPCpwXgYIyPUAkcjvMT9vf1hRsYiDAyFGX+PwxAGV2pCob3+PJd0T6oOQ3Nl6Anj2/78vhmOJenI1f5diwL7mbCvUy+Gc+E/tPQfJB7+0Io8vPgiP0K/H68FNncJUjn2KOc54h6th1eb9jgNXs54rnLkc5djmzeChTzl78QgIZ37IR7f60QNL2/Rrj/VzVvubAiRrgSbuFKlHOXWnLeYiRvfoT3679GOvtDlPN/g2rBx3i88bMZAM7ETMzES4dlCjjZnwebwri3OYR7O8O5vyuCJwdieLI/nC/2hvFFeiBPNvvyeIMP95P03InVMuAvplfvQYfKmU65Gx0yV1rl7nQZpfQFahhP9GU4Wc/IWu3EDkDLRPGTHUEvBcD7cZopAKzz8qLYwZlzHzpy8pfOHPonOw79zJaj/7KKMx85cvY3DlxY7ETmMlcu27hy2caZyzbOZNo4CAjMW+Mp7AO0toOtFcKrK12nALDA0YMCRw8Bg0XOIso8pAIAKz2l1Iql1InFz6V18GNyvioATr5319oablGoaVEZqPNWUuUhpUvrR5PcSL3alxZzGO2hcbTGptKcsJaOtZtpj0+jLTqFcv9wCowBXNeYyZJrKfANpjQ0ioqIWCqi4ymNiKE4LIryuMRpszYljfq162nfkk5d6jrKYhNo3LCOxg3raNq4nqbNG2javIGGbRup27aRhu2bad23g7aDu+g8spfOI3vpOLyHhgkEDl04SefpQzQc2knryf10nD1M1/mjtJ8/Qsu5Q9Se2knH5SMMXj9L26VDtF48yP2SKwznn2cg7wxdV47Rc/UEg9fP8rD4CnduXeR+yRXGSy4zWHiBvtsXGC7J5FH1NcaunqZpzyYuqqRckHqRI5FR5KmjWhlAnTqQKrkvVVITtUozdSof6tVGGjQmy9lApY56pYZamZJamVI462dtB0+XfwqApW4qIW+5qbjhpiLPRUGeo5Q8BwnXVosodpM/B8A2jeGVAHAgLpTB+DABgWMp0YynRDI8aQJ4LDFQ2Nc3+Ro3a04G4EiM7xT8vQwAe0K00+Z07+0L0wsItEKxI0ROS5Q3/Zv0fH1tJ5Qfh/oL0JXDt705E63gbL4dy4Z7WXx3Pws+y4HRDGg7xn9kbKAkSMqGD3+JbuEiZPNW4D3bHvHsVcjftEEyZzniObZI5q1AOoFA+TybFwJQu2D5tDeBWNvF1rODmgW2QhVQt3Al6vk2qOYtQ71gKYq5nyKd/RvEb/wK+dwPUS34GO+3fjEDwJmYiZl46Xh91qxZjKROTAGnR/DZvhieHIjj8f5oHu8L4/GuYB5t8uHBOgP3UrXcTVAzEimnU+9Fi8SNeg93Ktc4UeXgTJWrM61qSwXwTrIPIyk6RtN0QvVvOvj9KQA+iNdyJ0rLcLCKTq2CBrGYEkcXzn7izPGPXNn/85Xs+7ktB36xkqMf2pNh486FFW5ctHXnkp07V+w9yVkjImei3Xt1pStXbJ3JWuFE1gonrq50JdvORcirK13JXelI3konbqx24ZaDOzfXuE1pCZe4iSnzkFog6CGhxltCrbf3c2lF3eR8VQBskEqF6l+9REKjTEaLQk2jzECLxpfRyER+l76PkbVb6EjdSNeGbXRv3U1d2lbK4tO4HRFPqW8Y5cZgirX+FOsDKDUGUeUfwU2tLzdNART6BlMcGE51ZDy10YncDgqnMCCUW37BFAaEcjsonOLgCLo2bKVj3WZaUtZTF5dMfXwKlYnxVCYlULs2hfoNaRYEbt9M+foUqjevo23/TjoO76Fl/w4a92yjed92uo4foPPYfhoP7KDx8C5aj++j5cQ+Wk8doOv8UbovnaDl3CHqz+ym9tROGs/t5UFpNvdLrlB9YjtdV47Rm3PSUvUrvMRYwUVGrp9jLD+D8cJLjBRcYODmOfqLLzJcnkV34XnGq3N4WHed9pzj3NqfRnZiGHkiDVmOEoo9tNSIzdR6Gaj10FAr0lInVlOt1FGh0lGu0lCtUFnOgkoVQpWvVqYUqoLP5nQALPOQU+Yhp9RNQbGLgtvOcoqcZOS7KLjuqiTXScY1Bwm59t7krvKkyEUq/A/WeClpVRvp0JleCQB7o4PojQ4SEGgF4GC8/5Qzf9aBj+9v6DAL17b1hOroC9MzEGFkONqHoSgzQ1HmlwagFXTP5g/9jhWClkqgimZ/ER3hMj47EMt/XN7M09sH+K71NE87z/LH/ot8NZTJ16NX+e5uHk8fXOPpZ1kwdh66z/CHrD1cMygJeu9/IXptEZL5Tri9sQqX15YiemMxsgV2yOavsnydt8KSc5e9EIA+H9gLrd3JgyLyt5ainGuDZoGtcDuItUWsfdsO9XwbYY2M6QM7tAuXoZz3Cdp3FmF4fynq92bOAM7ETMzEy8frs2bNYnRtEI+3RfF4RxSfH4zni0MJfLYvis/2hvLZziAebDBxN1XLnWQ14/EKhsLltKpENHh6UOnoxu3ljpTaOVHh5EabRkKPv4qReD2jqXrG1ukFAH6xyzJZ/DIAfJig4260jpEQtQDAUidXzn7qwvGP3dj3LyvZ888r2Pcvdhz+cDWnFjtxctEaTi5aw6kla8iwdeairQt5DiKhwnd5uSOXlq3h4lL7KSAU2sR2DuStdOL6KmdurnHj5hq3KRXBEjcxpe4SSxXGXUy1l5gaL6/n0roCZnK+KgC2qdV0Gwy0qdVUeXpSL5HQqtRQK1XTqDMxEhPPw23pDKzfQH1cPE1JqTSlraM6LonSiBjKQqIpMwVToQ+iRO1HkdqX2xo/buv8yVeaKND7U2wOpjwwgtqoBOqiEyn0C+GmOZAbRn9umgMp9AvhdkAYbSkbqI1OpCoijoqwGKoi4mhYt5b6dWupS0ulJi2FmrQUKtYlU7NlPfXpm2g/sIuOw3to3redxj3baNyzjZ6Th+g8tp+6vdtoOrKbrjOHaT99kK7zR+m5cJzOC8doyzhC5bFttF06JLR/mzP2M5B3ZtoK4P2SKwxeP8tY0SVGCy8yVJDBUNFFRksuM1qWRe+tcwwVX2K8Ipuem2fpuHiEW6GRXJJrueatoVhipFSkpdxVQZW7imqRgkq5hjKFhlKFiiq5kmqJnGqJfFKVTyFUBZ/NPwVAK/4KHaXkuyjIc1GQ6yQjd42YXHtvclZ6UOAkptjVmzIPKbXeKto0Jjr15lcCwL6YYOF1KwJHk8IZmLixw7oL0Dr1OxmA1hs7ukO09IXp6Q83CPizngl8GQD2hemnzeneOxBhFD5vMgJ7ApV0B6sY3eDP46Px/GfuVr5pOMw37Sf4Q/9Z/jh4ia9Gsvn2bj7fPLjB159dgjsZMHCJsf2pnHB3xu+dn+H5mg1ec11xedMel9eXI5q9COl8WwGA8vm2KBbYoVyw4oUA9PvJxDVv76wS9gXKZi9B8sYiFHOWoX3bTqgKWiuCqnnLUc5dimreMjRvL0O7cNnEsMjHaBZ+iu7dxcgWfDgDwJmYiZl46RAA+CQ9mic7o/niUAK/PZLEZ/uieLQnhEc7Arm3zsB4spqxRCXD0RJ6g0TUi92odHKheKUTBUscKVnhRpWzN10GFX2BGgZjVIym6hlfbxDav1/uDuXL3aEvBcBHiXoBgF06JY0SCWXOliXQxz5xZ88vVrLr5yvY8ws7Dn64mmOLHDjyySqOfLKKo4tWcXq5Axm2zuRM4C/bzoXLyx3JtHEg08aBbDsXslY4cXm5I1krnMi2cyHHzoFrdo5cX+VMvr0r+fauAgBvObhT7OotALDMbeL+WZHouXyZc4EvC8BmhYJOnY5WlYpGmYweo5Gx0BAq5WIq5BIafQ3UhwdQExFEeWQwVVGhVEeHU+YfQKnJhypTEMVqMyUqX0pUvhQpzBTIjOSJtRSofbhtCqLcP5yqoChqwmKpCYulOCCMQt/g76uDAWGUBUfSkphGeUgUVeGxVIXHUhEaTfPG9TRtXE/D+jTq1q+ldl0qletTaNmdTtveHXQe2iNUAJv2ptN2cBftR/bSdngPbUf30n7yAJ2nD9GTcYyBy6fpu3SStnOH6bx0nL7cUwzdOMdA3hmqT2yn9tROHpXnvPAMYFfuCUZvX2KsOJPRwouM3MxgrOAid29fZqzoEmNFl7hbdsWSJdk0HjlAwdpUsrRGciVarnnIKXaRUeYip9JDRoVERblcTZlMSZVcKawE+r7Kp/iBfB6A5Z4KAYBW/BU4SLjhLOeas5wcRyk59t7krPbiqp37cwBs15rpMvi8shbw5ByMD2MoPoT+WF9G4v2nAHDyWcCBaDO9EZblzN0hWqFSNxl7LwvAl0nr5w1EGL+HYoiOkXAT/cFqeuM03NkZxO8uJPOH6l08bTvMH3pP88fBC3w1ks03927x9cMb/P7eaf44dAp6z5MfpCThF79E/cb/xPP1lbjNdsX5TXtc37JDNHcRknnLkcy1Q7bADsUCO1QLV6F5Z+ULAWh+f7Vwrs8CO8vOQOuyaOsAiOn9Nc8slV6MYs4SVPOXCNPCmrcXY3h/KcYPliGZ96sZAM7ETMzES8frs2bNonebLw8PhvP5kSh+eziWfz8Yz+8PJfF4azifbQjm0dpgHiT5czfWTJ+PjHa1hGIHZ67brOHKx6u4/JEd15c5UubkQadWxoCvivuxOu6uNXJ3o0lo/z7ZEcRn6QF8uTt0SiXQMhwSzOc7wvliRyhfpofwZJMPj9YbuZ+g426klpEgFd1qOS0ibyrsnTn1oROHfunKjn+wZfs/2LDrn2w5/GsHjnzowPFPHDm5yJnTS5w5v9ydC8s9OG/jzEUbFy4tdyVzhRuXbd25bOtOlp0H2atEXF3tRfYqEVl2Hlyx9xby6movclZ7kbvKkwInMbccvS0TwQ4elLiIKHPzptTDizJPbyq8JFR6S4WKkBUGk7NO/sPZoFQIdwS3qHQ0yfU0y8y0SfW0S3V0SRR0SaV0ySU0K9xp0XrQESzhdzui4PJRamVGqiV6GpQ+VMkM1CjNtPqHU28MpFxlolRtokLnS7nWj3KtH2Uaf4pVlupfsdafUmMQt/UBVAZGUhcWR11EPJXBUZQHWiaEr+l8uG7woyoijtroRGqiEoTKX0VYDNWR8dTHJlOXlEZD2kZqktMoiY2nPCGJvn17adi2kdZd22jfv42GXRsoXhdD0doouo7uonrnOmp3b2Ag4zCDmccYuHSUlhO76Di3n77Mo4xOtHN7c04ydOMc44WXhIpfy4UDjNzMYDj/PIPXzzJ04xyjty5wvzSL0fwzDOQepe/qYfquHWes6CL3Sq8wdjuL4eJshouzGSzJYbAkh5HibJ6UXeVxYRbV21LJDfblnErGaWcPskVyCuUmirwNFLhrKBebKZbohSyVaCmTqCkXq6mSqIT/gRpvCdVeYqq9pFR7yanxUlLjpaRCpKTUQy7s/iv00HDTQ0O+u5obbipL69dZPqUFnG3rxg37748hVHrIaFEZ6NQb6TbpGAjQMxJiZjwqgPHoQMajA7mbEMpYQggDsQH0RfvRG+XLQGQIA5GhDESGMhgVxlB0OEPR4QzHRDyXI9ERDEWFcicugnsJUdxPimQ8LpjRmEBGov0EdA1GGugP19EbpKEvUEN/kJaBYB2DIXqGQg2MhJsYjTAzFunDaISZkXATA8F6+sOM9IeZn8veEOMLsy/URH+YmYFwHwYjfCf+lgCGIv3oCzXRE2ygx1/LYICGsWADg2E6eqMNjG8Mg5vH+Lb0FF+3ZsLQDbhXyFd3b8K9bGjfwtc1e7ibuRPZO//Kyv/nn1C+54jo9eV4v7EU5Wu2aH9kj/5HLhjm2aJfsBTjQhvM767A5z1bYXWLz3u2mN5Zbpn+fd8O/w9WY3jXMuyhnGsj7A+07hC0Dn8Y37O3VAjfWIby9aUoXvsE+Wsfonjjl6hm/ys+7y7C970lBP54NQEfrMb/PQc082xnADgTMzETLx2vz5o1i750Px4fiuDzI1F8eSiGfzsQx+/3J/BkcxiP1wfzKCWQ+/G+3I0y0mdW0KaSUrjKiZxFq7n0azsuf7SK68ucKXf2tADQT8G9GC131xq5s8E4BYCPtwf+WQB8vNHMw3UG7sVrXwkAzy1z4sKyqQjMXOH2SgFYLhJPWRI9XVqB92xOD0DNBACNEwDUCABsE4to13hRJbbniy3h/G5HFMNxftxy9KbEXUG9wkyNwkSV3EiNzo9KtZkypZFyrQ/lWh8KZXoBgLeVPhSqfCxtYJ0/xYZAofpXHRpDZXAUFUGRFAeGk28K4IbRn5KgCEqCIigODKc8NJqykCjKQ6OpDI+lOjKeiqgEahJSqYhPpigqhuKYONrSt1G/eT3N6Ztp3rGB2m1rqd6WQu32tZRuTKDlUDr9Zw/Se/YAdQe3ULI9hc6z++nKOEhf5lEGc04xdO0Mo7cuMHj9LF1XjtFwdg/tmYf5rCKX9szD9Fw9wZ2iTO4UZTJ04xytlw4wfP0Ug9eOMZB7lIHrJxkrusid4svTAnC4OJs7xZk8KM1mNPsU7Qd2UJwYzXlvKRfdvLno5E2eo4xbzkoKXdWUiHXcnsgSsYZSsYoybxWVYuWkZeHiaQFY7qmgxF0m7P4rnMDfXwPAwUDDDwKwP8afvmg/BiJDGIwKm5JD0eECCifnYEQog5EhjMeGczc+knuJEQIAR2P8hUreZAD2B2npD9IyGKJ/5QDsCzU9B8DhKH+GIv0YjPAVfrcvyMBwkJ7xMDND4Ua6I3UMpPjzu4wtUHUKui7CaC7cv8bTe1kwngG1W3mUuZZbcT5I5v8Cp//3X3F7YzGiN20QzV6C7M0VKF9fhep1J9RvLUMzd5EAQL8PVhL4U3t83rOdgkHf9+3wfc9SGVTOtRHuDJbNXoJizjJU85ajfdtuyv5AzVsr0MxejvrNxahnf4Jmzkfo53+EYcFvMC38FPPC5RgX2KCbsxzvH308A8CZmImZeOl4fdasWQxvD+DzAxF8cTCSL/dG8rvdUfzbzmgerw/mcUoAD2J9GAvTMuCvpl2npUokIfPj1Zz++XKO/+MSLn/iwPUV7pS5edOul9HrJ2c0Rsl4qpbx9Ybnzv+9CIBPtofxJD2Yz7cG8dkGEw/S9IzHqBgLUzHoL6dLJaPZ0+uvAuCFZc5cWu4qIPBVANB6N7AVgdZ8JQBUqGiWa2iTqWiXKeiSyumSyqlzdaJVJaLK2xFyz/Bfe9dxZc0yLny6krxV7lSJdVRK9ZSJtZQpDJTK9ZTI9QIAb4o1VOj8KdcGUCg3kS8zcEOq57pMT6kpmNumIG6bgij2DaEiKJLK4Cjy9L6WNTEGP4oDwykLiaIiLIaSoAjKQ6OFSmBpcCQVEXHUxiZTn5hGdXwy1fHJNK5bT3VKEnVpqTRtWUvD1rW0791M58F07lw8zlDGEbpO7KHlyHb6Lhzm7rVz9F44TPeFQ3RlHKTn8lH6sk9QfWI77ZmHGSu4yL3iLAbyzlB3epelpVtwkd6ck/RcPUFf7ilGCzIYyD3OyI2TjN86w1jheUYLLzBaeHFaAA6UZtNZfJ6m/JP03jrH+O0s7hddoX3fbmpTUsk3BXDF3ps8ewmFDgoK3ZXc9LBkgYecQg8pRe5SSjwkwv9DpacXVSJvqkQSKj2lVHnKqfK0nPsrdpNS5KakyE0pTP1ed1V+P/zxEgDsMesZCjIyFubL3Zgg7sQEcTc2WADgUHwQg3GBDMQGMBT9fdVvMCpMwF5PaOBz2RsSSH94EEMRQYxEhTAaE8xYbNBEBkxq8ZosCAzRTan8DYcZGQ4zvjQAfygHwn0YCPdhKNJPqPpZfzYY4ctQpB+jkf6MhPlzNzKI0Rh/eqMNdMao6d6g5b9y0qB5N/Tsg8ED0L8VGrbSszaIE072hLz3MxRvfIr0LVs831iO29zFuM1fhMd8Gzzn2+E1zwHFnCXTAtD6fcj/cCT47x0wv7sCwwLLIIfkjUV4v/YJ8reWollgK6yFsbaGrTsB1XNtLTlvGdoFSzG8uwSfnyzF7+9s8P2JDbq3l6F461O8f/Qxq2f98wwAZ2ImZuKlw3IGcHsgvz0QyZf7I/hydzi/2xHBl1vD+Sw1gMdJftyNNDAUoKDbJKdWqqbAUcSpX6zg6D8u5/A/LCPzUxfy7CzDEa0GCV1+EkaiFYykaBhbpxcAaIXfiwD4eOImkCdbAi3t37U6RqMUjIQoGPCT0amU/sUAzFjuIlT/rO3fV9UCngzAUg8vIacDYI1UMm1OC0C1iial5Uxgm0xBu0xuaf9OVADrxR40qyX87x1pDMUEcMPNkVw7V27Ye1LmablarEyspVbvT4XKRLFMR4nKUgUs0/j+RQC0DoDcDgizQC8sRsBfdWQ8leGxEzCMpToygdrYZGpjk6iNTaI+JZXKxHjq01Lp3LGJ9h0baU1fR8uO9VRsTmIo4wh3sk7RdWovzcd20HR0O13nDtB5/gBdGQfpzTpGX/YJBvLO0H/tNL05J2m5cIC2S4cYzj/PeOElhvPP0519/PshkNIsBq+dYDT/FOO3zjBelMFY0cUfBGB3+UU6izNoyjtOe/5ZRkuucC8vi/GMM3Tt2k2uRMeVNWJuOMq54SIlbyJvuIjJd/HiprMXt928KXEXUerhRYWHaAKBFgBWesio8pRT6i7jtquEIjclha4Kbk3Cn3X442UA2OtjYDjYxHi4H3et+JsEwOGEYIYTghmKD2I4xtLunQzA/ogQ+sKD/3/23is6ygNN1+Xs2bPXzJ5pHMjY2G13t3MgJ+WcpZIqVymUpCpJFVSlnCWCAwYMmAwmiJxBJOWccwQBAmUJIcChPbPPWWfOzXMuiipD2/QeZtxnzoXetd5F1f+X1uLyWV94v1/4Tlwst0w689WNeD33EnUMpRoYTotlOE3/1JLHzwBoqfw9DX+/FQBa4M8Cev1J2meqgpZngyl67sXFMJioZzjDwGBmDHezIrm1PpTHB+OhYQu0b4Oe7dC8hn+5nkmuuyfxr71H1CufIP7H1QT+kwPB83wJmL0K/znLCZxrQ+AcR0Sz3VDNcyJynr211at5zdHqmDdciP2DJ4a3PVDPd0A1y7zIYVn6sMz8Pb31GzbX2TobKJvhYPZMG0Lm26FaYIvmD/ZE/8kR9dv2SGeuIPB3i/H9h0W4/B9TADilKU3pxTV92rRpjGyJ5cfd5qsfP26J48eNcTz+wsiDrBgm06MYNoXRp5HQFSqi2F/GeQdf9rxvz6537dn7vjOnVwdw2VVIqUBCS4SYLq2EvhQp97KCGVynYnKzju+2GZ+clDM9FwAnNxl5uMnAo6/05vbvmjD6E2TcM8i4HSWxAmCNh+8LA+BpJ38r8F1wCeSia5AV+H4rAKwQCCkPCKLMP5Ay/8DntIFFv+rnA6CUNqWUTrmULpnUCoB3QkNolgjpUgVTHyqlWOTNdX8vSnylFHmLqRAoKRUoqBSH0RihozpYTYkklFKFuQpYG6GnWqWlMlRLiUJDoUJtdrCG8kgD5VFGKmPiqNTFWwGwRGuiTB9PqS6Owt7B5mIAACAASURBVCgDRdGxlOriqIlPpTYhjZr4VKrjUqg0JlFpeMpPKoX1KenUpqfRsnYNvVu/4sbWDbRvXEvbxrW0bv+Sm4d3cOfYHm4f30PviT3cOrmX7qM7zfB3Zj+3zh+g9/wB2k7uouvsPm5ePGi1ZSP45sWD9OefYLDwFAMFJ+m7doSB60cYzM9lqOAIQ8UnGCk7+9wW8N3yi/SXn2G08Sq3q8/RXXqKW+VnGavOZ7LsGuN55ylPSOWiVMV5LwmXvEXkeZl9xSuIq14CrnkKKPL5+XRgpb+AmkAhNYFiqgUSagQyagQyyv2llPpJKPZTUOQrp+AJ+F31VfwMfi8AgLejI83t3/gYxlJjGUszMpZmZCTdyFCGkYHMnz2YlshAaiL9KQlW+LsVZ/hV3zYZ6DVquRUbzW1jDH3xMQylGhhJNzKSbrBGvQykaLiXFEmfyVz5s7R9LeD3ogBoAb2/9N2E6GfgbyBZ94t28ECyjsEUvfX7cIaBoRw9g2u03Fsfwf3tsVC5C2p3QM1WvjttpOercGLnf4Tk794i/OVV+P+9Hd5/b0vIfD+CZq8kaM4yxHNXI53tiHyWK+rXXZ+Z9YucZ0/EXDuiXnci5g0XdL93I+YNF8Ln2BI20+ZJnp/5PrAlD9ACgOHzXa1bv8GzHJDMsEcywx7pLBtCXrcn4i0HYt5zRv1He0LfWIXP//wIt797F7f/9iGufz+VAzilKU3pxTV92rRp3N9i5F93JfHn7fF8vymWHzcYebhWx2R6FA9S1AzqlNwMFdAsCeCsvYCDi1zY+rYtO/7kzIFPfDhtE8RlNzGlQVKaI0V06ITcThFzN1PJwNowKwD+uCPeCoG/BoAPNsYyuVHPww067q8LZzQnlLtxEvp0Em5pxHQrJP9hALzoISLPXcRlD7E5VPeJfwsArAoSUxkossJfiW8AJb4B//klkBAlrcFi2pRCOhVCuuRibkjN7pFJGdTp6IlQUSoKoFgYQKEgkDJ/OWX+cmpEYZQFKikXhlAYpKAwSEGRKJjKUA2VoRryRSEvvARSoNFTbkig0phEuSGB6rgUGpIzqTIlU6aPpyg61hoN05iURZ0xlfLoOCoMCdQlpNGamUNzZiZtOTm0f55DxxdruL19I/f2baN9+wba926mN3cnd0/tp+PQNmp3fM6tU/u4e+EQA3lH6Dm9l+bcbeZMvwLzMkjjkW00H9vO7cu5/NBYwGT1ZWuFsD//BA+qLzFafJKB64e5d/Ug9/KPMFZxngc1l5+7BDJy7bi5glh5juGWfIbaC+lryGe4oZAHjWU8LsrnzsGDnJGHccorkAvuZl9yDyDP3Y/Lbn7ke/pT5O1HiW8AFX4BT6qAYqoCxFQHSKkOkFLuL6XEV0yRr5wiX7k19sUCfS8KgHdi1AwYNYwkaBlPMzKebmI83cRIupHhTBODWSaGsuPMTk9iMC2JgdRE+hJN3I6Ppdekp0sX9Qt3a6O4YYjmhk7NDZ2aW0YNQ6kGRjNMjKQbrEHPg6lR5ipgXIS19fs09L0oAFpA79f8NPwNpujpT9L+qgfSteaA6jQN9zKiGcjS0pcRxd0cLZzfw78d3sj4xiT2O31IzIx/JmyOHeGve6GY4UPoPBnK16QIZ3ggmbUC2ezFhM1YQeSrdmhecSF8pvk+79NLIDFvuBDzhgtRr5sXRMJmrSZ05irCZtoQNteRqDe9iHnLB80bnlboe7r6Z7kprJjjjGKeC8GvO6H+ozvaDzyIW+yD7iM3VG/Z4vrf38H5v/0Jr39YiHS+8xQATmlKU3phTZ82bRrD21L4cXcGf96ezJ83aPnp82h+XBfFREooI/Eh3IpS0BIaSK1UxDEbXw4t92D7uzZsf2c1ez+y56KDL9fdA6gMDHoyA6hkJDWcsZwIxtdF8PgrLd9//XMMzIMteia3xTK5LZb72wyMfq1l7Cst32808cPGWL7/ysDD9ZFMrFExkqyk36TgjlZGu0JMnUBAsZsn+z91Y+dHXnz9J0crAO5Z6M6BZd5P4M+PY3Z+nHIK5IxTEGddBNa270XXIPLcRVzxlHDRNYgrnhLOOvpz2t7XDIRP4mIuOPlYw6Et5+KueQaR7y2i0FdCsb+MMn8pFYESygOCKA8IojJQRKM8mJbgMGpEUmpEUqqFEutcYLNcRrPUfDmkQSSiUSy2fm+SSGiWSq0XQzoUSgaidNxQhNHg70erOJBmqR+1Ai9qg7z5PjuT9uBQKgVyqoWh5LsF0iAKpkkSSoMomHJ/MeUCCfneAgp9gygKFFMillMqUVAqCaYmJJJKRQR1qhjaYuJoi4mjWKGiNExNpVpLdZSe6hgDlVE6KjRaWuOSaTElUR2lpzUumfaEVOp1JtriU6jXmShVaajS6GgxJdEQn0RTShptGVk0p2fQmJpGS1YWNzZsoDEzk+qMNLo2bqB780Ya1q+h/stsBo7vY+D4Plp3bKBj39f05u7k3ulv6Tm6k45D2+g9uZfBS0foy8ul99Ihes5/y40LB7hz5QgjJWe5fTnXCn6DhacYLj7DWNl52s/tZaTiPOPVlxitvMBg6RlGKs5zJ/8Y49WXmKy/yv2aPIbKznK34Ay3r1+mv/gawxX5jFUXMtlQwnjtZUaqLjJSfY7J5osMVh6neudnnFCqOeIRwklXGWecJJxd6c11JwGXVntQ6OnPFQ8vLrg7czHAjUsBXpQKgykJUlIcqKAwQEaBv5QCfyn5fhKu+Yi46i3kmo+IfD8JhYHBFAhCuOKt5IqHkjwXBRcdZFx1VlDsac4MrPST0h6sokcdTY8mhnvx8QwkxTGYomUkQ8t4to6RTA2jmTGMZcUymhFrBsI0E4MpsfQn6RlMNjGQZOSmPprOqEg6NRq6omLojtY/sZZ2tYqOqBA6o0Pp0YVxJy6SuwkaxrJiGcvSM5qpYyhNQ3+yeePWUgF82hYgHE6KZiQ5huGkaAYTorhniuSeSfMLD8RH/6rvJqqtwdIDKdEMpsZYo2Wefj6Qqud2gnne8X6Onom10TxcH8kPX2h49IWWB5/n0Je2hnyJjoTZDmhnOCN61ZGgV2wRvmqHfLYTspl2iF9ZTcgsO0Jm2RD+xBGzV1vbvU9XACPn2T+zAKKe74DyleVIpi8l7DVnIn/vheZtH8Lf8CB4njPy2Q7IZtkjnWmHZIYtyrlOhL3uhnq+Ddrf22N814O4RQK0n/gT8o47gvmrCZi7Eq/pn+D4d2/j8T/eYY1jyBQATmlKU3phTZ82bRpDWxP5fmcaP2yL5/vPo/lhrYbH2WqGjMHciZbTKBFQ4ufJFVcPDix1Y98iZ7a/a8PO92zZ97HDCwPg5FYDD78x8vAbIxPfxDK2Rcf4Rt0LAeC3C93Z9bE3W95xYsu7DnzzgTN7F3k8FwDPuQZaAfCCS6C5sucussLgeWeBdSnk0pOLIRb4s9wPfh4A1kmDrZD39Dbw09vBtWIZdRL5cwHQAn+WPMBWuZx2uYJOWTA98lB6FHI65WK6w8T0Rihhz1Z6NZHUBAop85NQFRRCrTCMuiAF9UIlNQKZ+YydTyBFfkKK/UUUB0kolSgokyoplQRTHRxBU6Sexkg9FYoIisUhVEfE0JGQSnlENAVKFdcUoVRG6ajTm2iKTaDREE9NtIFmYyKtcck0GuKpiIyhUq2lIzGNruQMWkxJ1BrjqUtIojE5ldrEJGoTk2hMT6ciIYGmrCxaP19PXXYmHV99Sd/uHXTv2EjlFxnUb17LrUM7aN+7mdot6+g6uI1bJ/fSf/4Q984f4vbp/dy6cNA653fnyhH6rh7l3vXjjJSctVYHLTmBty/nMlZ1kcHSM/QVHKf3ai4DJacZq7rIWNVF+otPcbfwBP3FpxgqO8to5QUGKs4xXJ3HUNUlhqvzGKu9zkRDMUOVV7lTdJHhygLGa0sYKitiqKCC4s372CpWcyDEwH4fJbvs/DngGMAppwDOuwm57CnksruAy+4CigRyCgNkFAbIyPeTWH3dV/wMAF73FZMfoOC6v5LLXgouuyvIc1FwyVH+XADsjdEzmJTESFoSI+kGxrMN5ginNVom1hh4sDaeiZx47mcnMJIex1CqkYFkA0MpcQwmm+g1xFgBsD1SQ1tEFC0qNS2qCBpCFDSGKmhWBdMWGcJNQyS3jBqG0/SMZJg9lBZtbgPHR1pn/562Bfx+hj8Nd40RvwkAPn1txPJsKFXHQJqRgTQjIxlaRrM0TORouL8mhoefJ3DG24eti51IfXMl4f+0mvBXnw+Ayhk2BM9cTeQcOzTzHIiab2+t9lliXywwqJptQ9is1ShfWY78paXIX1qK7OXlyGfZEvqaKxFvehL5ey/C3/BAtcAd1QJ3Qua7oJjjiHKuEyHzXdC8YY/2bWdi3/NA94Efqrc9CJhlg8f0RTj9/bv4T3+fyLdX8pl9IDVrtk4B4JSmNKUXlnkLeHMcj75J5vHXRh6vi+a7nGgeZ0cxYAjlZoSM6oAArrq6cdbWmb0LndjzqSM73rNl1/t2fPup0wsD4MNtsTz8xsij7SYebDcytkXH/U36FwbA3Z/4sPVdZ7a+58j2D13+KgCedzO3dy0AaGn7Wj6fdxZY5wMvufpbz8ZZbgVf8wx6LgBWi+TPVPmqhRKqhRLrEkBVkPjnc2HPAcCn4c8aCi2T0yFVclOpokchp1UcyN2YUCYSDXDsW+rFQir9BZT7SykPUFAnUlEdYG4LVvlLzFdMvAIo9hdRKpBQKpJRJlVSJlVSIlZSE/IkIiY0inJ5OGUyFbVqHc2xCZSFR1EYHE5+sIrqGAP1hjjqtEbqtEZqog00GuJpMSXRbEykXmeiTmvkVuZa7mSvpz0hlZrYOGriEqiNT6QqLp6quHga0tJozMyk6/PPaf/yc6oz0qjLyaJj0wYK00z0HviGO4d30rDFnAfYtmcTfSf30XtiDzeO7eLG8d30ntxL7/kDz4Q9W1q+fVePWjMA+/NPMFBwksHCU3Rd/JaBktOMVl5gvPoSQ2VnGSg5zZ38Y4xVXeRB3RVGKs5zt/AEN68d4VbJMfrKT3On7DR3Ss9yr+ISfaWX6S3Mo/vaee6VFTNWV8NYQxMTnb20FVZQcuA4dbmnuZC0hn2yKHZ6ydhj48tRRyEX3GTkOYu54ib+BfRZbIG/K15BVgi85ifjqq+cPE/5vwsAb+tiGUpOZjQ9mbFMIxNrjDxcb+LBOj0P15t49FkSD9cl8WBNEqMZ8dYq4HBqPEMpcdyK1dIVraZTo6E1PJKm0AjqlWHmc3cKBfXBcprCgmmNCDW3gmOjzQCZqmM4Tc9wuo7B1Bj6E9TW2b+nPZqitXo4KdraAv4tANASMm2FvzSt+f+UYWAoPZbRTB0PcvQ8XKtnPMfE/bVpbF/uQNqbS9DNWo7qFSfUc3yeC4CKV1cTPHM16rn2RM13JOZ1R3S/d0P7puszABg5z56wWasJmbES2fQlyF9aSujMVYTOtiV4rgNhr7tZoS/0NVdC5rsgmWGLZIYt0pl2qBa4o3nbB+0fXTD8yQ39e16o/+CD4nU3vP55Gf4vr8DzHz4gfMFi1q7yIlcSTseGTVMAOKUpTemFNX3atGnc3WhkcmsiDzcZeLgmmocZUTzKjOFeTDg9YcGUeQm4aO/GieVm+Nu70IldH9iz50MHDix0fmEAfPQE/h5tNzG5w8T4Vj0Tmw0vBIAHFnmw+xMftr3nwrb3ndj+oQv7Fns+FwAvuJth7y8XQS64BFrnAC3fLXeDLb7iLuC6l/C5AFjq/8sg6Hqp4oUAsFUu/+XtYImUbkUot0IiaBeLaBD4MmLS8L/WZcA3X1Hs5UGlv4BKgZxiHwlVgmAqfEVU+Uuo8DXPKhZ6CygVSCgPklEmlv8CAMtlKspkKmpCo2iM1FMdEUN5eBRlT1yujqFWZ6RObzK3hKP01MbEUq8zVwTb4lOsLeDulExupGXTYkqyAmC1KZ4Ko4lKUxyN6el0rF9P52ef0bg2h7rsTOpysqhfl0PHti/p2LWR+s1rqf4qmxuHtnM/7zidB7bScWgb3Ud2cO/8IUauHOfWhYPWmBcLAN6+nGttAT8NgYOFp+jJO8i9opOMVJznfk0ew+Xn6C8+xb2ik9YW8GjlBe4VneTmtSMM1F/kXs0F2q7l0nDhEHXnDtBTeIGewsv0llxjpL6GB60tjLV3MtZ3m4E7vYx0d3O/u4eus5eo3raPgyodG1d6sMfGj1OOEi7ZS7jmIjeD3RP/Gvxd9gy0QuAVHwmXvaVc8pCR5yb/DwPg5HrDMwA4uTb5SZafGQBH0hIYTo3ntlFHV7SaDrWaplAVdYpQKkQyyoVSqqVSauVyGoKDaQkP5YYuil5DDHfj9U8g0MhwWixDqbr/MgAcSIlmICWaoTStGQDTdYxmGhhO13E/x8T3nyXzw+epjGSm0GU0sf59G0zzlhM124bQmR6EzfP7qxXAkFk2aOY5EP2aE9oFTuh+74bu925EL3C2wt/Tc3/KV5YTMmPlkysgLkS84Wat+innOlnbv8KXVyF6ZTWSGbaoFrgT9QdfYj/wwfS+D/r3fAhd4IlkpjOe/7icwJdXEjB9IdnL3TkiDqZYr6X7y8wpAJzSlKb0wjJfAvkyhvHNsdz/Usf9TA33UyIZMoXTFaKgMUjGVbsAji9259sPHDm4zJ3DKzz5dqEr337qwqHFri8MgI+3m/huZzzf7Yzn4c447m8z8ODr2BcCwENLvNi70I9v3nflmw+c2fmxG98u9X4uAF7yFFsrfRYItPiMgx+X3IRc9jD/5rK7gCvuAi67BXDZLYCrHoHke4v+KgBaAqDrJPJn5v4s1UALHD4PAP/yJFyzVEqzWEKnLJhuWQgdEjHtUiHDRjXfpSfQIg+kSuBPtSCIUl8xBZ5CCj2E5uUUHyGVfmLK/cVUCeVUihRUiZVUyoIplwVbAbBYpKBEHEJ1iIY6VQz14VrKQ9UUKlVURMZQHaWnRhtLdYyBqmg9pSoNpSqNtQpYrzPRmZROgz7OWgWsjYmlOkpPQ3wS9YnJVgCsiounNTubpqws6tLSqM5Io2ndGtq+/JzmL9bTtHEtDV+v48b+rYycOUT3gW3UfL2WofOHGc47ynDeUfrOHuDG8d0MXDO3dy1n3yyRLxYAtFQCLSA4WX+VO/nH6L2aS1/BcfNJuFLz+be7hSfovZpL79Vcbl8/yq2C0zRcOkd7/hVuVRZzr66C0dZ6RlpqGG+vZ7Knkce9TXx3q5nHfa1M3Gvm0VgXE/eaedjfyr+N9PJ/32pnojSf3QIx3zh4stfGk6NLPchzfLIo4iHgsmegtdL3NPxZ3l3xCuKSp5CLHiIuuku55CrjkrOcPCfFcwHwRpSW/oQEhlISGErVMZqpezL7puPB2lgm1yXwYE0CEzmJjGclWquAo+mJjKQlcMektwJgnSKYCpGM697+XPX05bpXAIV+gZQGiqkUS2lRqWiLiOBWrI6+OAMDSXGMpJlby4NJ0QwlRv3ClgUQSwvYvBii+U0A0GIL+I1kmOcSH641B9l/tz6J77/IYDwzlXKZih1LXdHOXEL4jNUEz3BC8JIHohnPrwCq5jqimmv/pP3rSPRrDtb2b+Q88zKIBfrkLy1F+cpy6zyg7vduaN/yIPJNd8Jed3tm9k82y95aCQyZ72Ku/r0TQNaqYJIXi4l5xxfhK04IfueM8CVnVK95YnzHh8uRelozk7j9eQLD2+KmAHBKU5rSC2v6tGnT6P0imrFNBsa/0DKeoWY8OYK7ulBapVJq/MRcWuVL7seu7HnHntyVXhxZ5c3Bxe4cWOj6mwDgxDexTG4x/k0BMM9L8gwAPg2Bp+19n10K8Qi0AqBl+aPAR/xXl0As8FcnkVMhEFLmH/hCSyDtSiVtCgWtcrl1JrBJJKZFKKVdJOeGUsHNUAUD+nBGTTFU+rvTJJNQFRBIkVcQhV4iCtyDKHL3twJgpUBKrST4GQCskIdQJjXDX75AQoU83Fz5C9GYcwJD1VRERFOp1podpbO6ODSSkjD1MwDYlZxBvc5kXRCxwGBTYgoNSSnUxCVQYTRRHZ9AW04OLU9cn5NFXXYmDWtzaFi/huZN6+jcbT4PV//1Om4e3sH9vOP0nznAzeO76T6yg/4Lh5koOMNQ/knuXjtmXQSxxMBYMgEtt4KHik4zXn6B3qu53Mk/xlDZWR7UXWG4/Bx9BcfpyTvI3cITDJScpvdqLu3n9lJ/ch9dhaXcKq9ioL6ekeZmHnS28qCriQfdDTzormW8s4KJ7ioe99Uz0lPKZH8dj/vr+Wm0lf9nuJPv2yug/wa5IaHsdPVit40rBxc5cc7ej4tu/lYItFT6LACY5yF45t1FjyAueoi44Cb5dwHg85ZAfm0G8H72z23gsYykXwBgrVxJWZCEq56+5Ll5ccnFi6sefuR7CygRiKhTKGgMCaHXoOWOSU9/ovlU3Gh64nMB8G+5BPI8APzuszgero3l+8+SebQ+nXuJcZz3EPLluzZEvboU1Qw7FK864/+KN6K5/s8FwPB5TkTMd7QCYNR8e2vbN3yOLaEzVxH86grkLy1F9D8/RTZ9Cer5DtY4mOg33VC97kLwPGeUc52stnwPnueMaoE7xg9FJC9WstZORepSKdF/9EPwO0cC/tkZ6aueJH+s5LNVwVQak+lek0TfZwZGt+mnAHBKU5rSC8u8BZwdxo/rovg+O5r7pkhGdBHciVBREyilwDOQ43befLvcmV2f2nFgqRsHl7mz/1MX9n/izKHFrlxy9KPAM5AakZgbaiV9+tD/7Qzg4x1xfLcznke74nmw3cjkNhOPtyTxeHMC330Vx+M1Gh5lRPAwKYKx2DDuapS0yKRUC4K47uHLgScxMJYZwG8+cGbPQncOLrfAXwDH7f054RDACTt/Tjn6WVu/loUPS+XP8t06H+gcxCXnIPJchFx2FXLFTcRVd6EVBgt9g8yLFQFCSvyCKHvS6rXkAf5l1c8Ch5YW8C9avTKZGfh+xZ1KJa1SKe1yOTcjIuhVR9GtUlMnkVPsL+K6VwDXPAXk+wop9Bc/s1Va4C+lXBxKfUgUNYpIKiRhFAcqKBUGUylV0RQaQ0NwFA3BUTSGxdAQGk2pNIyKEDU1kVrqNHpqovSUh0dRGqamOCyMsogIKjUaarVaq+v1eio1GjqSkuhOTaXJaKQmKppGvYEGg4FqbQyNJiMjmzdRF2ekNTWZzpxMWjJT6VqfQ++mL3h46jCFaSbKc5K5e2Q3/ae+ZeDsQToOf0PH8Z3czcvlQVUed/OP03pqF+1n9tBz8QC3ruTSe/kwXef303v5MP2FJxmvvMhw6Vn6C08yUnKWW5cPMVJ4mpHCs9y7fpJbl05wO+80g0V53Mw7S9e5s7SfPUvXhQv0XL7E/Y4qJrtreXSjnsnuWu53VPHjnRa+623kYU8d4+2V3O+o4nF3DT911/AvN6r5ob+J74fb+fHBTf51opefBrto2rObvWI56z+x4cgST44scuW0ix8nnXw47eLHJW8RFzyDuOwr4bKvhDwfMRe9hFzwDOK8RyBnPYWc9RRy2k3EWVcJZ5ylnHOUcs5RQoG3gmI/BRUCOa2h4XRrNHTHqOlPjGUw+clsX1osY5lx3M+OM28AZ+oYy9JzPyeWscwExjOTmchJ5H52HCPpBu4lxnAnTkOPNpJaeQjlQcFccg7i3GoBl+3FXLYVctVeSIGblHpxOC3KCLo1kdw26riXqKM/JYbBNC0jqU+3eFW/yAN8ehHEUgHsj4tiKFHLUKKW/rgoKwT2x0UxEB/NYEKM9f3TcTIWmOyPi2QwQcNoipYHmUYmMmKZSI3i/1qj51/So5hMS2IwOYMGdSIblogJe2UVilnOKGa7IZ3rgniOI9KZdtaZvYi5dkTMtbPO82lec0T7pqu1xRs5zx7NG+5Evu5OxGtuqBd4EPm6u/XOr/xVW8Lnu6Je4EHMWz7EvOWDfLYD4ldtkMywRTbLHtErqxH8bjlhr7sR+porqgXuxH0sIWOFioxV4SQtUaJ7NwjpDFuUM2ww/sGZbzyUnJCpaclOpuszEzc3Griz3TAFgFOa0pReWE8AMIIf1mp5nBnNiC6CwehIboaEUeTuzzlb8+bv3sXO7PrUiYPL3Dm03MPaAj68xI2LDr7kewioForoiVRwRxfCcIrqNwHABwkqRg2h3NUoaZXLqAkUku/px8GlPuxd6PfMDODeRR4vDIBPzwFatoP/KwDQsgjyl+5QKOhQKOgJDeVGeDjNMgV1QiklvgFc9zK72F9CmVBBpSSE4kCF+SatJIwyUQgVkjDqQ6KolkdQKgymSCCnXBxKY1gMNbIIqiQqqiQqahSRVMsjKAhSUKoIp0QZTmlwBKVhaqrUWqo1OsoiIiiPjKQqKoo6nY56vZ4Gg4FKjYY6nY4KtZqyiAgq1GpajCaq1GZQvJGZwZ21ayiPjqIuzkiVQUdjSiI9n62h+7M1NGal0vJFDt3bv2Lg0C569nxNx66NdO/bwtjVEzwqucDw1eM0HvyazpO7GSk8zeD1E/Tl5XLj7H56zx/g7uUj9F89xsC149y9fITbFw9x++IhRgvOMn71NONXzzJ08QS3zxyh68wRus4fo+3cUbquned22TXG2uqYuNnCo1utTHRWc7+jygp6E53Vz3y2vBtrLuG7zkq+76rgcV89jwZa+G68mz+P9fAvwz38UF/NzYOHOBOhY9Mndhxc5cPhVR4csfHilFMAl7yknHcXcdFTwkVPCRc8xJx3F3HOTcg5NyFnPII44xHEaTcRZ1zEnHaScNZBwlkHMfle5uzA8gAZLSEqutRquqIjuZdgsALgSLrxSbXvxQGwXhlGhTCEC44CTq7048hiHw4t9ODwIk9OrPAm30tCqUBGiyqCHm0Ut4067iZoGUiOsQLgYILmVy+B/C0A8GmPpeq4n27gcbaRn9bG8UO2iRtaLYXCEHat8Cbsd4sIpWn2CQAAIABJREFUedUG0Uu2BP7OFsFLqxHNsEE6y4bgV1eYc/tmrSZirp012kXzmqO13Rs+x9Z8AWTBz+fbQuc4ETrHCclLq1DOtCd0jhMxb/mg+4Mf0b/3Rr3Ag5D5LshnO6CY40jwPGcrBIa/4YHmbR907wpIXCgnZUkwKUsVxH4YSNhrzkhfWYb+LWcOCDTkx6RRm5jFna/WcPurVPo2JnBrY+wUAE5pSlN6YZljYDIj+S5by2SqhoEoFX3hKjqkSq44eHF8mTP7FrmyZ5ELuz915dByD+sM4IGFruQudeeCvQ/X3QOsAHhbG8xQcthvAoAT8WGM6EPoUyusAFjg5c/BpT7sW+TPN++7PrME8h8BQIut0TD/BQD4PLfL5XQqldxUqegOCzPHvviYg6bzvQXkewso9pdQGiSnXKSkVBhMtTzCWvF72uXiUCqlKqrlEdQFa6iVR/4qANZF6igLiaRYoaJAEUZRcDgloZFUqNVUajRURUVRr9fTGBtLs8lk/dxgMFCv11Ov11OmCqdeq6MtIYH6WAM1Oi2tyUk0JMRRF2ekMSWR1qw0apPjKY3Tc3fnFto3rad765d0frOBG3u30H9sL3dP7OPGsV3cOrmXoSvHuHf5CHfzcum7dJg7Fw9xNy+XwWvHGS8+y+0LB7lz8RB9lw5zNy+X/itHGS84S++Rfdw8eojuIwdoP7yPztO53Lh0kv7SqwzUFzPYWs5Idw3DN2oZu1HHRGc1Y20VjLSUMdZWwURnNUNNJYy0lFlBcKytguGGQh52lPOos4yHt2t5dK+J70Y6+WGki5+Guvm3W138r7oa2rbvZu1SezYtdWL/UlcOrfTkuL0/FzyknHUVcc5N/IzPuoo46yritHsgp90DOeUq5LSziFOOYs7YizljL+K6p4xCH/MIQnNwGF1qNZ1REealjCQjQ6lGRjNMVsB7EQC8oVPTEKyiUhTKeYcAjq3wYf8nnuz4wIWdHzqzb5E7F12DuO4rpj5YRadGw019DLeNMQwkxDwz42cJfP5bA+B4mp6xVB0jyTGMpmi5n27gu7WJfJcTz2RWAvUqNac9hHz5sQthLy1H+aodgn+2we8fV+L7T8sQzliJdJbNz8HNlirfE/CznHqzAKF6vgORr5uDnOWv2qKcaY9ypvnWr+wVG5Qz7VEv8EDzhiehc5zM7+c6IZtlj2KOoxUGxa/aEPl7L3TvCoj/REryYiWJC+XEfyxC/64/mjdd0L7tyLoVQVyPTqU6KYfWzBzublhD34Z07m5I5taGqRnAKU1pSi+u6dOmTaMvWcV4sppBQzhdMimtQjElzj6cWuLK4U+dObDEmwPLfDiwzIfDKzzJXenFwcXuHFrszpFlHpyz9eKam791BrA3WsFgUuhvAoDjphCGtEruRMpplcuoDRJR6B3A4eV+fLtEwI4P3dn+oQs7P3Zj/xKvFwbA884CLrkJrZdBrnhK/ksAsFUu/1W3yWR0BQfTFRxMo1hMsac3he7elPoJKPITPrGYAj8RBX4iKiRhVMsjqJZHUCYKoVwcaq0K1irVNKm01IdEUSYKoV5phsBaeSR1wRrqgjUUiYIplIRQJA8zVwHD1NRE6anXGqmJiaE6Oprq6GgaY2NpS0igIymJOp2O8sjIZ1rAN9PSqdean7clJXIzK5NqvY7qWD0tKUl0rcmiNSuNm1+uZ2DbZvq2bqRlXSa3tmygf+833Ny1mZ6dmxg6+S0/FF3g0fUztOzfzM0Te7h77iADF3MZuXKc8eunGLlynLvnDvKg8CyjV0/Qd/YAt0/v5+aJPTQd3E7twd20nT9Fz5UL3C7IY6Kpgu8763ncWctkRyUP2isYaythrK2E0dZSxtoqGG0tZ6SljNHWcsbaKhhqKmG4uZTR1nJz9a+twvzb5iLGWwuZ6K5goreWyXstPL7Xyg+DnfzU1wmjd/m3Ozc4kBDHOndv9ix0Y/enruxf4slxuyCO2wVx0kHESQcz4J12Mrd6zzhLOeUayEnXAE44B3LS0fy703YiTtsJueouocDbfEquSRlKR0QE7WoVfXE6BpLMQc/jWfFMrk1+YQC8qdfQHBZJtUTFGVtfDi725Mv3HMl+azXZb65g/Z9Wc9DGl9POAspEShpCImiP1HAzJoo+g5bhpBgriFk2fp8+Bfe3AkALBE5kxDKZZeLRmmRGs5PpMsaya6UbKW8tJfLlj/D97x8he9kewXRb/H+3koB/XoHo5WXIXl1B+BxbIubaoZ7vYA1zjnnDxVr5swCh5jVHwuY6ophhh3j6SuSv2lorgVFvehH1ppf1xm/IbEeCZ/3c/lXOdUL9ljcRb3qiWuCO/r1AEj6VkbYslOTFSkwfiQmf54DhbTcyPvVnj08YpxTR1CQk05KZSntGEj2ZCfRmJ3JnbQo92clTADilKU3phWVeAokLYcgUzp0oJS1BQup9A7myyoXjnzqT+6kbuSsE5K4K5PBKgXUJ5NASDw4tdufock/O2Xpx1dWPCkEgnSopvdEKBhJDfhMAHDMGMxij4HaEjDaFnDqhmCIfAbkr/J8BwF2fuPPtUu//MABe85ZxzVvGVS/pfwkAWraAf+EnANgmk1EjEFDk4UWxpy8Fnj4UPAl5LgmQUhIoo1ggpUISRqVUZQW/MlEINYpIapVqapVqa6WvShb+3BbwtSA5xQoVFWEaqjU6GnQmGvVx1Gq1VgBsMhppT0ykOzWVWq2WmpgYmk0mWuLiqNfr6UxMoi5GS51Ox43MDPrWraVSG0NjYjxNSQk0pyXTmpVG3+YNDG3fQsfaLLq/XMfgzq307fiam9s3cmvPFsbPHOanootM5p2gYccX3Dy+m4ELhxm8mMvQpSPWDeHBi7lMFp5l4MJhmvdtomX/ZjoObaP16G7aL5+jt7qEuw2VDDdX86ingT/3tjDZVsX9piLGGgp40FTAo+YCHreVWKHvZ9Art9oChePtlTzoqmKksYDR5nzGO8sYv1HN5J0mHvY18+NQFz/0d/GvAz38n/29lBzay0G9kb2LPNj5sQs7P3bh8Ep/jqwWcNxOyHE7ISfsRZxylHDaScoZZxknXQTPAOAJeyGnbIWcsg3iqruEfC8JJb5iGhUhtIeH0xYZZgXAkfQ47mcn8HBdyn8IAFtUamqk4Zy28WHfIndy3rYhYf4S4ucsJPWNpexc5sFhWx+KAxXUKsJpV2m4oYmiTxtjBcCxVJ21Kve3BsDRFK219fswO45HOfFM5CRyJymB8tAIMt5eSPSMDwj53Qf4/Y+FiF6yJ+hle/PCx8s2iF5ehuTlpVbIi3nD5ZmMP8umr+Xcm+Y1R0Jm2yN7xQbx9JUoZ9pbZ/70f/RH+7bvM/d9Q2Y7Iplhi3y2OQvQ8H4QhveD0L0rwPihiKRFCtKXh1kBUP+WO2kf+7PZQcn5UCOFugTaMtPoWZ9JT3YKXWlGutPiuJWZQkdK0hQATmlKU3phTZ82bRo3jCEMxIbRGymnwV9AtWcA55fYcfRjR44sdOfYaiHHbCQcWR30DAAeXuLB0eWenLXxfAYAb0bJ/6YAWOwbSO4Kfw4sDWTnRx7s+Mj1PwWAee4irvvIue4j55q37P93ANipVNIsFlPp50eRhxel3v5ccXHnulcARX5CyoMUlIuUVIjNyx0VkjBKgpQUBsgoE4XQGmmgMSzGOgdomQuskqgoF4ZQLgyx/t21AClF0lAqwjTUqnXURhuoidJTrdFRp9NZq4BNRiMdSUn0pKXRGBtLa3w8jbGx1rnA4pBQGnR6ejMz6UxNoSUhnvbUFLqyMmhMjKciVkdDaiLdn62hc102rdnp3Nr8Jf3bv6bzq/Xc2rmZieMHGDq+n3tH93D78E76ju9l8Nwh7p3+lrun9tN3ch8DZw8ylneM74svMHrpKDdyd1C6IYPqLWvp+HYLdy4d40ZlAf2djQx3tzDc08j9njoe9TQw2VHJeF0+41VXeVCVx+P6q3zfVMBws7kKaG31NpdaP4+0lFlbwY9v1jHYmM9Q83XGOkoZ66niwe1GJu808dNIDz8N3WDyVgs/3O2mq/gK1zdtZv8SH3Z8ZN5c/3apL4dXCjhmK+KYrYjjdmJOOkg55SjjtJPcCoDHnQS/AMArbuJfBcA7Ju1vBoC1sghOrfZm70I3UhesQDfzY3Svfohpzsd8/akT+1a6UxigoEauojU0kh615hcAOJ6m//8EAIeTohlN0TKREcvjNQk8XpPAeFYibbFaLgZJiZ39DhEvv0vEjMUoZzoinG6H6FVHxDMdkMywNwPg9CWEz7G1Rrf8ZcZf2KzVRC9wRvumK5rXHAmeZYf05dWIp68keJYDka+7W+f+ot70Qv6qLZKXVlmXQmSz7Ame54z6LW8SF8pJWqQg4VMZcR9LSF6sJH15GEmLFJg+EpOxUMwG2xC+9ddRYsykMS2HOxs+4+5X2dxZl0p3qonuVBO9qcm0xSdMAeCUpjSlF9b0adOm0RMRwK0IIU1yfy64eXLCwYN9y13Yt8yLfcu8ObTMn8PL/Ti6wo8jq7w5vMKTw0s9yV3qyZFlHs/EwHSqpNyKUTKcHM5oViTja6N4vCGW7zfH8f22RL7flsjjbxJ5+E0Ck9vimdgWz/gWEw++NvHTlkT+vNkcBfNgbThjWSEMJcq5GyvjpkZEizSI2oAAit08ObbMl0MLA9j5jgs73nFk9/suHF7szZGlPpxY5ccpmwDO2Jl92tZ84u2EjZcV/i64BJph76nZv0tuQvNSiFOgFQDN8CfmilsQhb4SCnzEFPgEmu0roNA7gIqnzr9Z8gBrxbJnwqHrpQoa5cE0yKRWN8plNCnkNCnkNMikNCnkNMpl1nddEeFUisVUiEQU+ftT4OtPvk8ABT6B5s3fJ3E0pQHBlAeGUhFkBj/L8oelFVwpVVmrgkUCOaXCYJpUekokERSLIigMUlEkUlEsDqdMFkGRKJiasAga1dG0ROtoUGuoiYikOjqaer2eJqORlrg4moxGGmNjqdVqaTAYaDIaaTaZzHN/ej1dKSm0xMXRYDDQGh9PvV5Pe2IiPWlp3MrK4kZ6OjczMriTk8OtnAx61qRz7+svuPnNF7RtXUfrN+vpPbSVwVN7GT6zn/6jO+k/upP2/ZvpP3+IietnufHtTjp2bqNh00badu2keedOWo7mcvNKHoOVZYw11jLZXsNkWxWTbVU8aK3kQWslEy0VjDaUMNpQwkh9MYM1BfRXXae/4hqPmyuZbCjjfn0JDxrLmGipYLihmOGGYgYbixlsKmGoudQ6I3i/tYKxtgrG2iu531PLxI067t+s4/G9Vr4faOfRQBvDN2oYa62mIONzvnAPZM0KN75Z5sHOhW4cW+7HiRX+HF8VwFH7IHKdhOS6BHHUTcRRNxFHnMQcdRRx1E7MSZsgzjtJueoaSKFnIBV+gbTIpLQqpdyIVnPbGEN/YiyjGfGMZcYxnvUk+iXHxHi24ee7vRlxDGUkMJxpYjgrlsEMPfdSdNxOiOKmKZrmCA21SjXnnQM5uMqfjZ8EoH11KfqXP8U4cyHZbyxl83u2nHbyp8BfToUkjIYQNR0aHXcMOgbjjYwmxzGSFMtwooHRFAMD8RoG4s3gNpSkZjjZDIPm57+Me3kaBvvjop5AYDT3EsLoT4hgIDGSkWQtoyk6RpONjCYbmUiN4/ucZCbT42hXadi70I+1b3gQ+o8LCZmxkpDXHPCfvQrBfHsEs+0RzbBH/ooT0TO90c32xLDADtObzsQucEQz15bo15zQv+lGxHxHIl5zIXS+CyHznFHOcUT68mpkr9gQMtsR1TwX1As80L7tS8RrboTNdTZD3ys2yF+1RTHDBvnsFUT+0QX1u16Evysg4n0R6g9lxC0OJ2WZivSlKnIWKflsWTD7AiI5pojiSkwi1elZNGZn0fl5Djc3rKF9bRo1iSbqEhNoSEqjxDAFgFOa0pReXNOnTZtGR7Af3cFB1Ir8OGHnxIFljuxb7sb+5d7sX+7D4eV+fxUALUsgFgDsjVZYAXBsjYZHXxr4bpOJ77Ym8N3WhOcC4J+/TuDPm018/5Xh3wWABxcFsONdF7a/48iu9104tMSb3GU+HF/lxylbAaftA6y+5CbktL2vNQvwomsQ+b6KXwXApyuAV9xE1gqgGf6eBcAiH8FzAdDyzAKADTKlFfiehj0L8FkgsDUkmLbQEBpkUsqCgigRCCjw9SXfx498H/PyR4GPkEJfCUV+Ukr8lZQGBFMaYN7yrZSqqA+JolaptraEy0Qh1pawGQgjyA8MIV8QSmGQGf7K5RpqQmMoFofQEBlFm9ZAuy6WGlU4ZcEh1MTE0GAwWFu9FgCs1+tpS0iwLoG0JSTQGBtLV0oKHUlJtMTF0Z6YSEtcHLeysriTk8Pt7GxupKfTnZpq/jc9mbsb1jG8fRNtX2XTtCmb9h2fc+/4LgZO7qH/xG76Dn/DvSM76Dm8k9HLp3mUf5G6LV9R+vkaKjd9Sdv+PXQc/paBgivcr6vkYVsDD9rMAGiBvvGmsmegb7ypjPvN5QzVFnK34ip3SvJ42FjOw8ZyJpvKedhcwURLBYN1hQzWFTLQUMTAEwgcbi5lsLGY0SZzhXCiq4b7PbVmCOytfzIL2MHjwXbGbtUz0VXL7eOnyY0ysN7Bky3L3dm1zIvcZb4cWepL7gp/DtsIOGQfxCFHMwTmugSR6yjiiIOQI7YiTtoEcc5R8gsAbAuWvTAADmcmMpIV9wwA9iXF0BsXQ6s6mrpgDRdcgjiyWsDWJUHoZiwjZvoiYl76mITZn5L9xlIO2/hx0VNCkUBJtSyMFpWaW7oY+k0GhhONDCcangHAwYSo/zQADsVHMJgYyVCS+knrV89YaiwjSbGMpZh4nJPJUIKJS+4BrP2DM8Z5zub27dse6D8RoPrAl8A3nRHMdSBolj3SmY5Ev+aNYYE3utdsMLzugP41e9RzbJ6cfXMm6g1XIl93JWSeM8FznVDMdkDy0qpn4l40b3iiXuBB6BwnQmab5wMVM+yetIDtUcxZSeQf3FC/40P4uwIiPxAS9bGMpBWRpC5XkbY0hM9XhrLVKZLToSbyohMoTcikPjuH5jVZdHyWzc0N2bTmpFAWq6XSqKc+MZmqxNQpAJzSlKb0wpo+bdo0GoQCGgVBFHv6cniZC3sXOrF3qTsHVvpxaHUAR1b5k7vShyPLvX8VAM/beXPV1Y/yAAHtoWJuaGQMJoYxnBHOSHYkD7/Q83ijkUdfx/F4S/xzAfCHTXH8uMloDYK+nxP2XAA8vMKXvUsC2PK+C1+/58i2D13Yt8ybg6v8OGIXwDGHQE44m33KKZBzroGcsPHinFMAp+x8rOHPv3YWLs9VRJ6LkEvOQVxyDuSyq5DrnmKuewm57iW0AmCRfxAlfkHPBUBLEPTTIdEtwUqalQqalQoaZFLqpRLqpRLr95ZgJZ3hKtrDQin28X4Cfj5c9/bmurcvhX7mub+yQDmlAgWlAnMenMWW6l+VLJwqWTgVkjBqFJGUi0MpFQZTF6yhPiSKwgAFV/zkXPVTUhikokympiZUR7PGRLMmlobIKOrC1dSqIqmPVFOn1ljhry0hgdb4eJpNJhpjY2lPTKTZZKIjKYnO5GTru7aEBCvkdSYn05uZaf1sWSDpTk2lJy2NgS/W0ZmVQu+Xa+jbvYm+A1sZPL6bu8d2MnhqLyNnv2X45F7uHdlB5+7ttO7cQcXmryj7+ivajxyg7+p5JqqLmKgrYaKhlNG6YkZqixiuzWewpoDhuiJG6osZayxloqWCB62VPO6sZaKlgrHGUuu7+41ljFUXcr+2mAeNZTxoLGOssZT+mnyz6wvN8Pek+jfaWs6D9iq+623k+9vNPLzVyGRvA4/6mvlhsIOfRsyxMD+MdPHnoU7+pauRgYI8Lq/JJGuZHZ8tsmP7Ynd2LfRk9yIvdi8TsGdlELtWi9hvH8C39n4csBVwyFZAro2QE6sDOWMv4rJzAAUeAir9g2hTyOkIVbwQAI5kJTCSlcRodjyjOeYq4ECa4UkVUEd7lJaG0GguuYk4ahPI1594oZm+kPB/+gTVP3+CesZS4l634+vlAeS6yLjgq6BMKKNJGUqPJoLbumj6TToG4rQMxusYTtIxnPQE4J4A4FCS+klr+N8PgCMJWsZNMdyPi+JBQgyTqdE8SI/h4Zp4HmQlMJGdTn9iBjWyKNLnLybklWUIX16FcJYt0gUuyN90I2COLbLfuxA0z5agmasQzliJco49qrn2xMxbRfSc1WbPN1/+UM+1J+oNV8LnOyOfZY9sph2ymWa4C53jhPZtX7Rv+6J5wxPFDLsnFT87QmY7EjbXGdU8F1TznAiea0fE225E/NGHyPcDiVkoxbBUScrqUNJWKshcKWW7h4rjMhNXdckUxadSlZZFw5pMmtem0/VlOp2fJdOQYaA0NpLq+BhaM1JoW5M1BYBTmtKUXljTp02bRoW3H+Xuvlxx8OLwMne+XeLJ3qWeHFodQK5tIMdsBH8VAM/ZenHFxZcy/wDaQkTc0MgYSAi1AuDk5zoefRXLo6/jzBD4HAD8tUsgfw0A9ywJ4OsPXNj8viNbP3Jh73JvDtr4c8RBwDGnIE64PrHzzwB41tGfEzZenLT1/sVtYMuVkCvuEi67irjoFMhFJwGXXYXke0meugQioNA3iOIAIWUBoucC4K/5eRVAy7OWYCWtIcE0ymWU+PqQ7/OzC3z9KRGIKAuUUhYopyxQaYbAgGBK/JWU+Cv/X/beMjrOA0vXrbPWvTPTncTMmHR3utNhs8XMUCpJJSqVVKASM6NlO8Y4dkwBM7Nsi5mZwZZkW4ymJE0zZ+DMnPPcH+X62k7bM52e7pnbZ2mvtZdK9ZUl/7HXs96933cLo16dA/j58W+5u5xqLyVVngqKXWTku/hS4OJHibuKCm8NNfIQmgMiaQ+OpkGlocZPSY2fkubAIJqDQ2iPjaUrIUGAuI64OGH3ry4khDvJydzfsoXe1FT60tK4m5JCf3o63YmJwhhYpwg2R0YKgHg3JYXW2Eg6UuMZPrCb4WMHuHN0N51HdvLg3GEGLxxl5PJXDJ07wt2vP6Vm507KPtlFfsZW6r86ymDuLcarixhvKGGisZSx+kJGanIYqcnhUVMpg1U5jNZpn081l/Oko4Zvuur4rqeBqeZyxuqLGasvZrKpjEctlYxW5DFWmc9EbRGTdcVMNJYyXFcoKIBjreVMPIuHedhVw9PuOr7pbeRpbyOPeht4eLeex/eaBAXwV+Pd/Hqih9+O9/CPQx38Q38bfTcvscXIjKT317HvY3MOfGTDoY9sObTOmUPrJRzcJOVLAye+MrDnmL4zJw3EnNZ35YKeC1eM3F4AwA6ZD90K3x8MgBMZCUxuiWViSxTjGZGMpES8QgEUs+89GwLf+ADFjz9A/sZaFAsNCVttxa51Er408+KSrQ8lLp40ennTpfKnNyiAgYhghqKCGY4OYSw+lPGEkGcQqAXAkThdPuAfD4ATMWE8jgzjUXQoj2ODeZyk4XGKhieZUTzZEs90RirNqihuWHoTPutjZPP1cJ1vjOt8Y6SLTZEuNsX5jQ24zd2EdO5GvOdvRr5QX2vuWGFKyDJ9AhfpEbzEgNCVZgQtNyNgiTGqZVrTh3SuPtK5+njON8R/iTmq5VaE/MSR4LccUK+wFuBPtsAY/yXmKJdZolhqgf8S82cAaIPqZw4EvOtK6FpvojfLSTL0ZYuJLzst/DjlHsRNdTxF0YmUJ6RQm5pGQ2YSTZlxdO1Kojk9nPrkYGrjg2lNjeLuJ+l0bsuYAcCZmqmZ+sE1SyQSUWBqQ66+JVfWW3BqnY02ZHm9Haf0xZwzduOCoYSzevac2WjzUgC8ZmD7AgDeCfBkONaP0RQFY+kqHn0SwpPd4TzZF8WTfVF/FAA+/SSAR1uVrwTAU5scObpezKfvWbD3XVM++8CCLzbac9zQmdOmLpyzcOO8pSvnn0HgTRt3Lhs5cMPcRVAAb1m5/YcAmGUq5raFK4X2nuTaSJ7dBdYCYKmL+w8GwFftADZ5ewnw1+jlSbWrhAqxs6AAFjo6UuzsQqW7F1XuPpS5eFHm4kO5REa5i1xonZmjQuonBELrrn+UuflS6OxJvqOUYhcZJVIlJe4qSqVqyr0CqJIFUa8IpTkgnEZ1IA0qDQ0qDc2BQTQFBdMaHS0od+2xsYICqBsJdycmCnt9DzIz6U1N5V5GBl0JCUJ0zJ3kZGFE3BEXR19aGr2pqTREhNC3PZ2JI5/Rd2gXnQc/ofuL3QxeOErfqQPcOb6PrqO7aPpsC2WZ26jb/TlNB7+gL+s601XljDeWMVhfyEhzKRPNRQzXZzNcfYvpxnxG6wp+r/C1VPCko4YnHTVMt1Q8A8ZiRmoLGaktZLSmkKHSbAZLbjNUnsNoVb72eX0Row3FjDaXanf9ump4cqeeJ3fqedpdp3UMd1Qx0VXNRFc1493VTPXWa00hg618M9LBt6Pt/GashX8d7+Z/9jRw1MuLjM1G7PrIlH0fWPHZh7YcWOPM52sl7F/vzlE9B77Qs+VrPSdO6DtzSk/CBT0XLhu6ctvMWQDATl/ZDwbAiYw4JrckMpUZx2RmtACAL9sBPLPZiQMf2hE4ew2K1z9G9sZ65AuNCFptQ9qHznxuIOWMhRcF9i7UukvpUMi5o1FxPyyQwcgghqK0Bo7xBG3/ZwHwm4hIvokO45vYEL5JDuRJWgAP08J4uCWOybRU8sX+HP3AFtXffIDvfFPcF1riOd8cn4Xm+C20wHeuIV6vbUAxT4+ARUaELDUmbLm2Q5cbELRYn5ClhkS8aUnISgs0S03wW2SI11w9XGdtwm32ZjzmGQhj3+C3HAhcbYdquZWQCShfZIpymaWwDyhfZIp8qTGqn9ig/Kk9mvfcCFvnRay+nFQTObvtVBxxDeaGOoaiyBRq0zJpyNxGy7btNGQm0ZARQ+u2aGqTAqgFAfNAAAAgAElEQVRJVNOWEU3vzmQGPt1G5/a0GQCcqZn6KytjkUiUJxKJHoq0/3hdvvf8f4hEou0ikeiRSCT6J5FIVC4Sid7+3mfmiUSiSyKR6Hcikeg3IpHolEgkev0H/B1miUQiTus7cXaj9r7v6fW2nN1oz+n1tpzf7MgFPScu6jtzQc+J85sdXwmA2eYOlDk5vwCAQ4lyxtJVPNkZxuNdYTz+NJJv9sfw5EAMjz+PEQDw4ecxPD4Qx7efaV3AT/ZGM71dw0SmirEkJYOx/vSF+NLu60ODuwdl9i6cWGPLkfftOPSuFV+tsePkRmdOb3bm9GatA/iiiYRLpi5cNpNw2cSF65YSsiz+uL5pIeaWuZjbFs/fAxaTa+NEnq0zBQ5OFDk5USIWU+7iQrnY9QXHr+7+b9UzMKx196TRS0aTt6923OvrTYdCTr2HlBo3V+o9POnwV3FHHUKdu4w6dzmtsgBK7N0oc/GgwtWLcoknJc5a9a9aKqNc4kmpWEqpWEq5xJNKN2+qpXKavANo8FRRJ1VQLfWnSupPjqM7OY7u5Dp7kO/mQ4G7jCIPOXlSD0p95RT7yCiR+VKpUFLk7UNHVDS1ARoq/BWU+/nTFBJKW0QkHVHR3IlPoC0ikkqFkraISB6kpdMaHkFndAz9ySl0RsfQExdPf3r6CxExjeHhgmP4+bNxHXFx3MvcQt+u7XRsTaZrezIDhz9h5Nhexk/u58GXB+g7epDGHXu4HbWVivTDdFw+w93Cy0w0FDDdXMx4fT7TzcWM1uYyVpfHREMB4/X5jNXlMVydy1R9Ed+0VfOwsYzRKq2y97i5gm/ba+gvvMFgWTbDFbkMlmUzVJ7DRGMpo3VFjNYVMdlUJhhIdCaS6ZYKppq1o+GBugIG6goYrC9kqOHZjmBjsRAcrXMTP+6p48mdWh72Vj9TBntoLSzg+qGv2COPJMPWl+T1dhxca8+xNbaceM+Cz9dYcGCDDceM3DlhJOW4vpRja504q+/KdTNXcq2llLl40alQcidATU/wywFwKj2KqYxIpjLChda5gKfSY5hMi2Q8JZzhhFCGE0J5EB1KhzqIBp8AbpiIObXRgb0f2eI/60N8Z6/Bd4Ee8qWmaFZbEvu2Fdvet+PoZjEFDp5UOLvTLlfTLg+g019Df3AIgxGRjMVFa40aieHabMAENcOxCh5E+jEcowW8BxFqHkSoBefv8+5frYIYxnh8BOMxUTxKjuCb9DC+zVDyzRZ/frUjlKmMUDpCA9j9rhExizYRvsgK99f0cH3DEPfZhnjNNcJ7njF+841RLjJBs9iEoKVmhC03J3KVBRFvWhK4wuyFHEDlYkNkczcim7sRr1nr8HxjLbK5G1EsMiDyLQeifuKMZoklsjkGeM/SQ7XcCuVKa5QrrVGstMZ/lbblq63RvC9G854E1TsuBL3jRvRHniSvl3HQPpBTXmHcUEdRnhBHY0YiDVuSad6WQesnmTRsSaY6JY7yxEhq0qKo3xJLx54Uej5Lp/fzTNr2ps4A4EzN1F9Z2YlEoh0ikUgiejkAJom0UCcWiUQfikSiHJFINCISif7uuc8UiUSibpFItEkkEhmKRKJBkUh0+Qf8HWaJRCJObLLnzAY7Tqyx4swGO85tcuDcJgcu6jtz2dCFy4YuXDIQc8lA/F8OgMPxftyP8uVOoDetPtpLICW2zpzd6MTXa5w59K4VRz7QQuCXH1tzapMj5wydBQC8ZOry3wqA33cBN3l70Sr3oc1PRp3UnVp3Nxq9vOlWabijDqHG1ZtqiQ9NXkpK7N0EuKtw9aLE2Z0yFw8q3bxfCYD1Hkpq3f2pdtXecq1wk1Pk6qNtNy34lXj5U+qtoMjbh0qFkgp/BZUKJfWBQS+8bgwOoTE4hCqligp/BR1R0bRFRNIUEkpjcAhtEZF0x8bRHBpGe2SUAIddMbGCAURnFNGNfO8kJ9MWE0NfWpoAife3ZtKakkh7ZhJ3dmYweGQnQ1/tYfirfXR8up3i5ESywqIo37Kfu19e5UF+Fv0l1xiqus10czHTzcUMVd1mpCaH0dpcJhoKhB6rK2C6oZiHjWVM1hUzWpXPeE0hU/UlTNWXcL/4JiOVeQxX5DJckct4TaGgDD6/OzhaVySohMM1BQzXFDBUnS/A33BjMSNNJYy1lAmtywt82FUjAOD03SqePmji18NdTHa3011aQeH+E1xN2MVRaSA73zdn98/02P9TPfZ9aMq+tZZ8qS/hmIEbx/TcOb7OmTN6Eq6ZSsi1llIq9qTDX0GPWvWDAXAyNV54PpkWyVhyBMMJodyPCnkBAE9vcuSzj+1QzP4I+Zy1+C3QQ7bYGNVyC8JWmZL8tgV7PrQhy9yFQjsxLT7aO8HtcjV9QcEMhEcwGhslAOB4QvB/CgAnYiN5lBTOk9QQnqT68yhVxnSamr5If0qkbiSvWEfg6x/h/4bRKwFQvcSMoKVmBC8zJ3yFBVGrLQUA1F36CFxhJgCg/0J9fOdtQj5/sxAVE77ajvDVDqgXmQsAqFxm+UoAVL/rhPIXTih+Zk/g22KiPnIneb03xyXhXPGPIz80idrkJJozkmjMTKH1k0zad26jJjWeisRoatLiaNwaT/P2RLr3pXP3wBb6Dm6ldW/KDADO1Ez9Fdf3AfB/iLTKX/xz780WiUT/LBKJvJ59/8tnf279c5+xFYlE/0ckEi37I3/vLJFIxNfrrDm1zoYTa6w4u9FeUP4uG7pw1diVq8auXDGScMVI8l8OgIOxvvRH+NAd4EmzlwfVYglF1o5cNnTj5AbXF24Bf/5LEwEALxi7CAB4yVj83wKAL3MBt/rKaJX70CzzotbdjXoPKa2+cnoDQ+hRBVMp9qDC2ZNaN19KHdypcNWOfCvdvCkVSwUV8FUAWOPmR5XElwqx1iBSJpFR4aWg0ltJhbeSMh8l5TIV5TKVAICVCiVVShWNwSFUq9RUKpQ0BAXTFBJKU0goNeoAqpQqOqNjBPhrj4yiNTyCppBQmkPDaIuIpDM6hpawcDqiommN1nZbTIxgCmkMDxegrz89nb60NLoTE+lNT6M+Lpq7u7YyeGAPw1/s5d6RPdw9uJui5Bguhmi4HBpK74mLTGUVMV1dxFD5Te4XX2O6oZDHzSU8KLnOaFU2Y9U5TNUX8LCxiIeNRUw3FDPdUMxIZR4jlXmMVRcwVl3ASGUeA6XaMe9kXTFD5TkMV+TysLFMcAvromEGKnN5UJEj9EBlLoNVedp+pvy97FSc7vWj7lrtqPhuA4/v1vKov55vB9r5h/FBfjc6yERtE/038in75ABb15qT9pON7PzZJna9Z8TuD005ssmZr/QkfL3ZjRPrxQIA5li5/8kAOJEaw2RqPNMZsTzKjNWOiTNiGYoPeQEAs0xdOL3JkYNr7Qmc+zHKOWvwn6+Hz3wD/BaboVywmfAleqS+qc/JDdbcMHGkzl1Gg4ecFh8FvYFBPAgLZzha69IdTwgTAHAkTslAlP8PB8C4cKYTQnmYGMyjJCVTyX4Mxiip85Vy2tiU4Dm/RP637yP9m424v26I2ywjpHO08Ocz3wT/BSZollkQstyC0BWWRK6yIvpNKyLfsiJwhZlw9k2z3BTlYkMB/OTzN6NYZEDAMhNCVlsSvNyK4OU2KBeYIptjgM9sfe3e36sUwF+KUf/CCeVP7Qn7pROJGzzZbuTLZb948sPSqY7fSlNaGi1bUmjamkrHru107dlBeUIUJbHhNG9PpWN3Gl17M7h7IJO+g1vpP7SNlj3JMwA4UzP1V1zfB8CfPHvv4+99rkYkEh169lolEol+/b3n/49IJPo3kVZVfFn9rUj7n4Sul4tEIo5+rN39O7XOhgt6TlwyEHNmgx3nNztyUd9Z6At6L4+B+UsC4GiigoEYP3qDZbTJtEHQpXZiLupLOLZWzL6fmfDZz405+K45h98358QGe87o6yBQ2xeNnP9bAPBlLuB2PznNMi/qPHTwJ6NHHUBvYAitMiWlDq6UOrhrx7+OWsDTwp127Ku9/CH9dwGw2lVOlcSXKnc/qqT+VHorBQAs9VZQ6q2gxMufQi9vYcyrgz7daLdGHSCogTql7058AnfiE+iMjqExOEQAv66YWO7EJ9ARFU1ndAzdsXHCjqBuBFwfGkpzZCT1oaE0RUQIu4MdcXG0xcXSlZrEyOf7GD30OU1bt1CRkkxhYjxFWzPoOP4lE3k3eVJZxEDuVQYLrjJaksV42S1Gim8wVnqT75pKhfceVufxuLaAJ3WFPK4vZqq2kHtFWdwvvqnd6asuYLAsm8GybCbrinncXEF/4Q3uFWVp4bC2UDCN6JQ/nVFEt0s41azNBxxpKmG0ufQFte9Rdy3TndXaaJhnRpFH3bU86arlV71NfNvXpHUL32/m8WArvxrs4F/H7vEvvZ2Uf7KXywGRHHWSkf7OZra9o8+nH1px4GNbDq914thaJ05t0kYbZVtqzwC2yf3oUir+ZAB8si2eJ9viebw1gYHYIPojgmhXBdIo03DL3JULemK+WGNHxLw1BM9dT8ACPTxnGeA1x1ires3dTMj8jez4mQnH1tmRZ+VCib2EaoknXUoVvYFB3A8LZjQ27NkuoBYAR+NVDMUofxAATsaHMRUbxHRcME+TI/jVljgeJUdR5unNKSNbUlZ9jM+PP8L7DQMkr5ngPssU99nGeM4zwWe+Cb4LzVAsNCVklQ3hq6wJX2VN1GprolZbEvmWlXD6LWilOaolRigWae8D+8zZgGzuxhcuhagXmaJaaIb/PGP8F5igWKg9+fYyAPRfZYvyp44E/dyZsF86kanvyQF7JSfcgiiNTKUuOZPWtK00J6fQnJRI27YttO/cRtuOrZTFR1IWH8nd/Tu5f3gX9w/v4sHRndw/8gn3Dm+naddMDMxMzdRfc30fAPWfvbf0e5+7LhKJrj17nSoSiR685Gc9FYlEIa/4PVuf/dwX+su1lpzZYMfZjfZc1HfmkoGY0+ttObdJm6mn6/+/7ACWO0heAMD9vzDh8PuWfLXGhuPr7Tit58A5Q2fOGzlx3siJC4ZO/y0A+DITSKuvjEZvD2qlrjT7eNOlVHBXE0inQk2tmzdljlrwK7ZzpcxRmzlY5uJBjYevoAKWuXj8UQBYLfWn2kNBmYcfZR5+lHr4UeLlL3SlQkljcAh1mkDqA4NoCQunRh1AmdyPOk2gAHn1gUHUBmjoiYvnbkIi3bFxNIWECrt/d+IT6E1MEmCwJy6etpgYmiMjqQ4MpEqjoTY4mObISBrCwoRnrdHRWlNIfBwt8THc+SSTzq1bKY6OoyA6jvy4JHpOnGAs5waPyvMYKbnGvaLz9OecY7ToBtMVOYwUXmek8Dq/aS5ntOgGY8VZTFfk8LAyl4eVuUxV5jFepVX7BsuyBRVQtws4Vl3AdEMp94qyuFeUxXBFLkPV+QzXFLwAe88DoC5AerKpTLgMojsVp1P+XtYP26v4rquBX/c18t39Jqbu1zI9WMvjoUb+9fE9eDTAaE4eTYePczE4lrR3NpP5883seteMve9ZsP8DW774ULvvetnImdsWrhQ5utPqK6dT4f9nUQAfxATSFx4oAOBtCzcu6TvzxUc2RM1bQ9jcDQQu0MdzliGes03wmWWEcr4RwfP1yVhlyMEP7Lhu7ECuhT1ljq50+Cu4E6ChL1jDSEyoAIDjiQHPxsCqHwiAITyKC+RhQhDfpkbxTXoCQ5ERnNKzYufP9QmZ+y5uf7cG19eNcX7NDLfZpkjnmOA5zwTZAlN8F5qhXGRGyCobwlZaEbbSioiVlkSsNCdslblw6SN4lQWKRQYoFhmgXGyIcrEh6qXGBK+yIOwta8J/YoN6kSmK+SYo5pugXmJBwFJLrfnjFQAoW2JJ0M+ciH5fwl4LGcdcA7jsG0JNfCqNqem0pmbQlJBES3wSrVszaNqaTsOWVKpT4qjPSBIA8MGR3TMAOFMz9X9R/VcB4EsVwOMb7QSVT7frJ4QpG0mEEfBlQ5f/cgAcipPTH+FDj8aLZi8PalxcKbJ25JaljHP6nuz/uRkH3jEVAPDYOltObbbnrIET5wwdOWfoyHkDx/8WANSpfs9nAjZ4auGvxl1Ct0pJX1AgvYFB1Em9KLJ1plLsQY2rTADA25b2FDpIqPHwpVoqo9LNmyp3n1cCYKmjp9BlLj6Uu/pS4u5LqVROqYcf5TIVlfIAqv0DqVEH0BwaRo06gGqVmjpNICUyXwHmmkPDaA2P4H5qGsOZW2kNjxBAcSA9g+7YOBqCggV1sD4wSDCL6KCvJSpKUP7KlEraYmK4m5IiBEi3xcRQGxxMVaiGmugIysMjqE7aSs+Brxg9e42p3DzGCm4zXJTFQNVFBmsv8LDmNpMlNxktuMbjylweV+by4PYFxgqvM150g4niLCaKsxgvusFQ/nUGS24yWVfMeE2h1uRRW6QNeG4s407uFQZKbzNeU8hYdQGTddo4mLH6YsEE8qitiicdNS81gejuBY+3ljPaXMpQQxFDDUWMt5YLu4CjzaXaEXFjGd+11/Ftdz0Puyq415nDQG8uQ/2FPByu5umDBv7XYD//1tfP3cs3SXnPgK2/0GP7z43Y8XNjdv/CnM/fseDkRmcuGTpxy1xCoYMbLTLfHwyArzKB3IsKoDdMIwBgtqU7lw3EHH3XjOjZHxIxbwNhCw2RzTbGZ44Fnm8Yo1pgSdACc6IX6LH1LTPOb7TghqEFhTZOtPrK6VapuaNRaSNhYoK059ueAaDWCfzDAPCbpGC+TQ7hN2kxDIaFUuHiQeL8d4iY8wHKNz7S3vmdZ414vh1ucyzwmGuK13wt/MkXmaNabE7QCiuCl5kTvMyc0GVmhCw1JmiZMUErzQl7y5qQ1Zb4LdDDf6E+qiVGAgAGrjATOmCxmRb+FpkTssqO8LccUSy1eCkAKlbaIl9qS9p6Pz6zDOGGKoGSmHTqU7bQkZlBZ2YabakptCWm0JO6lZYtaVQmxVESG0nbji30HdhDz75P6Pv8E/oP7uD+kR3cO7yd/kPbZgBwpmbqr7z+q0bA369ZIpGIQ2stOL7BhpOb7J7d0HV5ZZ8zduWMoYQzemLO6Ik5py/mspEjt620SlWHype+UAWTKSEMJikYS9fwZGckj3dG8vjTGL7ZH8+jfbE8/EzbU/u1/fCzeB7tiuPJ3jge74llelsI4xkaxpICGIhW0RukoNVbTo3YkyIrMZfMPTmuL2Xf+5YceN+Cgx9acfgjS05vduKCoZgrRhKuGbtw3UT79aqJE9dMnV+IfcmykJBtIyXbRioEQWdZSLhh6kKWqQs3zSTcMpdw28KVbEuJEAOTbycm304sXAIpcXSl3MmdSrEH1RIv6txl1Et9afCQ0+ytoFWmotHTj1o3H/Kdvcl1klLu4c5kUigTsYHckXvQ5OBBnZUPRUbu5Bk5kG9mS6GdJbm29uTbiYVRcL23P40yJUWOrs8ugkgEZ3Cdlx/V3nKqveVUePiQ7yShwNmVGh/t+1VevlR6yqj2llPjq6AjIorm0DBhB7A+MEgwdejGuncTEgXzh04B7ImLpz0ySuv2TU4RVEKd+tcaHkFteBINMVtoT8igLSaOlrAw2kIDaA8JoCsshLtxSXTGpFETmEBpQAylsQnkxERRnJzI3WNfMHr1ApM51xnLv8FYQRZjxbeYqMxlrDqP75oLmay4zr3sM9zPOctw4RUe5FxiKP86A7lXGSm8xURJHmNFOXRfOcd4WS6Pa0uYripkqOgW9wpuaGNeKvOEbMDRhmIGa/K5X5nDdEsF3/U0MFxTwIOKHOEz0y0VAvzpnMITjaXC++MNJYJq+LKeaC5jqqdWyAoc66hkrKOS8U5tfMyj3gb+fqyH7wbaGG4t46hvEEkfWBIx5wPSF+uxdZE+Rz5y4MhGO46bWHPF0oYiBwf63V0Z9JFyX+3LQJiK0eggJpMimEyOZColiqn0GCYyYhjb8vseT0lkMiWFqbQkJtNimUiNYiQxjKH4EO5FBtOuUtHoqyDXRsIVYzFH1zqQsMyAsLkbUM/agHyWAb6zjfB8TR+PH23C8+82EDDXgNAlpux934aja+04b+JGldSfZpmSDl8/BoPVDIeqmYgLZiIxlLHEEAbig3mQEsG9pDDuRgbQF6piIEjFcJCakSAlj2LDeBwXzkRMCOMJYUwnBfNNih+PkwN4khJJm384FwxcCf7RGlSvbUQ+Ww/pQn3cFhvgvkQf6bwNeM9ej/9CfTTLTYXRbuAKM4JWmhO4wgzNclMUiwzwm69P4Go71Cus8V9iLoQ6e88zRLPK9g+euf3oQzxf+wjVIkM0y8wIXG6OeoUlsR96EvCmHfJlVshX2CCdb4b3fCsiVrpywCCIM85RlIQlU5+cTGtmCi2ZsbRkxtK8JYG6pBSq41IojAqjJC6MqpQY2nel07NvG/2HtnP/yCfaPrqN+0czuX80k/Z9MzuAMzVTf831KhNI3HPvzRK93ASy7rnPWIv+BBPIobUWnNho+ycD4FUTZ7KtXSmXeNKh8uVusB/jSUE/GAAf747nyV4tBP5HAHjRzINjeu4CAB76yJojH1txapMj5w2cBQDU9b8HgC/cAf4PADDP1pV8u2fn2J4BYKmTGxXO0hcAsM5dRq2bDw0ecpq8/Klzl1Hl4kmxm4w8Z3eqfbz47c5kHiaG0uUrpdpaQpWlFyUmHhSYOVNoYU+hnTX59o4U2LtQKpZS4epFraecOi8/qtx9KBVLKXZyo9jJTXAIV3j4UOkpo1zqTYGzK4ViN0pcPSh186Rc6k2tzJ96uZIGRQCVftodP924VzfSbQwOoSsmlt7EJPqSkumKiaU9Mor2yChhL/B+ahp9Scl0REXTHqkFSd0ouCMqmpqweGqjUmiOSqAhLIKGoCBaggKoV/nTpAmgOSSC+pBoytRR5KvDuR0SRuOuHfR9cYSRi2cZvHiG/ounGMu/wXjhTSZKs7UAWJnLWNk1xkqvMFp8heHCS4yVXOdJTQH3bl+i/9ZFhgtuMlVWwMOKIobzbzGQf4OR4tsMFd7kft51hkqzmajWZv7pRrljjSUM1xUyWJPPeEMJj9qqGKktZLAqj9G6IqaaywUIfB4AdZdFnr8t/DwsPt9TrRU86m3g6b1mnt5rFu4G6/pxXyPfPmjlSX8TE13V1O7/imPuQcQv38T21cbsXGnMoQ/sOLzBlmPGVly2sCXf3p4+qTsDPp5/cQBMXG4oAKDfbEN8Zxvh/YYhXq/p4fWjjajn6BO8yJidb5tx+H1zTus5UCH2osnDlzZvLx4EyBkK8mMsUs1oTAAj0WoeRKnoi/bjXrQ/QzFKRqPUjIerGA9TMhmq4lFsGA/jwpmIC2UiKYKHqRF8m6riUXIQUwmRlIr9OfKRHZofr0P52uY/AEDv+ZvwmbMBvwV6QrRLwDITYZdPN/INWW1JyCorNKtshew+3Sk3n/lGAgDqnskWGOMzZwPyuRvQLDVBs8wMzTIz/JeYEv6OBP/llsiWWCBfYYPPEmsUy+2J/akbX1iEccUjkarYdJrS0mjflkZLZixNGbHUp8ZQHZ9IVVwSFYnRVKfG0pCZRPenW+k9oFX9ZgBwpmbq/456XaRV+D4Waf/xxjx7verZ8ySRVuFzFolEH4hEomzRy2NgOkUi0UaRSGQgEokGRH9CDMzR9Vac3GTHqc32goP2nKHzS/uskUR7r3STE6c3O3NmsxPXzVzItdU6Vlv9venWyBiMUf5gAHyyJ4Gnn8bz9NN4Hn0SxsSWwFcC4HkTd77e7CYA4OGPbfhirQ0nNzpwTl9rZLlq9Fy/AgBvWbn9Qb8KAHWn4HTKW5GThFInV8rFWvircvGkysWTGldvaly9qXLxpFriRY2rN5ViD8qd3CnzkpHn7kpHlAYuHGQ6NZg6dzuy9a3JN5JQbq2g1E5GiZ2UXFtbSsRauHt+969c4imEURc7uQlO4WqpjCIXd0rdPCl18xRe1/j4US9X0uivptFfTY2PH4USKdUKFbUBGlrDI2gJC6chKJgyuR/tkVH0JibRn5xCX1IyreERNAaH0BAUzEB6BoMZW6jTBNIaHkF/cgo9cfF0xcRyNyFRUAxrI6KpjYilIiCUEj81JXIVdQHBdMck0BQWSb6fkhx/NZWx8dSkpfHg+BGe5lzl8e3L9J4+yp2zX3Dv0nEm864wVXyDR2W3eFh+i/HSG9zLOc1w0UUmyq4zmH+Be9nnGMi9zHRFHhOl2QzlZzGQc4OBnBvcv32Njiun6b11iQd51xksvMl4VYH23FvT7+8CTzSXMdVawXRbpRDzogO70bqiF/b/JpvKBACcbqkQMgJ1kPiwtfKVADjUUsp4ZxWT3TVMdtcwfaeOJ/1NfDfQxq8G25nqqWWqp5ZvH7Tyu+5OSvcfJvLtjaT91ICdb5uy+21jDnxkxRd6lpw1syPbzolODy/6ZD70q/3+YgD4xTpHklYYET5vI5o5m/CfY4R8jjF+88yQzzHG9w19/F/fiGLWRlKWrWXHyo85+IvN3DKxptzOmQZXMV3eYnplLgwGeTEaqWAyTsPj1BAmEryYinNjKtKd8TAJI2oJwyo3piPkTEcHMh4dzGBcKCMpMUxnxPM0LZrx+CjalBp2vG1E6OwP8XtjM7JZhnjPMcZznjFe803wXmiIapmJVt1boId6qbFg8gh900ro4FUWqJcao1psjGq5FYqlFsI9X/kiU/wWmxGw0oaAlTYol1kKwc4By0wIWm5C6CotPAatsMBvsQmqVTZ4zjfEY74xPkstCXrbjfiPZHxq5E+2IoWa2N10bN1D5/btdO3IpHlLAtUJUZRGhVIWFUV1fDxtO7bQsTuT7k+3039wF/cO7ebe4U/oP7RN24cz6T+cQf/hDFr3Js4A4EzN1F9ZmYpeYsgQiURnnz3XBUE/FmmVv3KRSPTz7/2MeSIt8P29SCT6rUgkOi36E4Kgv9hgzWk9h+fME+JXAtb3JngAACAASURBVOAZQxdO6Ys5tcmJU5ucXgDAcoknrf7edAX4MBCt+MEA+HRvIt/sS+CbfQk83hHOZGbQKwHwnLEbX21yfQEAv1xny4kN9pzV07qXrxj+vv9cAFhg766FP0dX4RZwhYvHCwBYLfESwO95GKwUe5AndaPYz4OhrTFwfh+D8UpKnc24qWdJjoGEchsVZQ5KSux9yLF1fAEAn+98O7H2HJ3z76Niqtx9KJZIKXP3oszdi1I3Tyo8fATVr0kRQJMigFqZP4USKQ2aIOoDg2gICqYhKJj6wCDqNIGC8nc3IZGumFjqNIFUKVXC7t/91DTqNIF0RscwnLmVrphYOqNj6IyOoSMqmubQMOoiIqmLiKRSHUyxPIBimZoaVSj1IdFUBISS5etPdkAAnXt3cP+rQ4xcOs7j/CtM3j5P79kj3L9yjPHs80zkXmSy4DIPi68xXXSV8cLLDBddZLDgPAN55xkrucpI0VW6r55kqjyXidJsBnKv05d1mTvXLnDn2gV6bpxnsCCLifI8pquLGCnPZbDkNlONZb8f27aUM91WyaOOasbqixmuKeBJRw1PO2uFTECdM1in9I3VFzPVXM6jtioetVUJo97nx8HP91hjCQNNxYx1VAoXQ6bv1DHVU8vTe838ZriTp/eaedzXyHcDbfzLxAAdN66x01rCbj079q+xZc/PTdj3vilHNllyxsSem7bOtEpl9Pj40hfwlwPAL9c7kbzSmIj5m9DM2YRirjF+c01QLLDAf54pfrMN8XttA36vryd+0RrSl3zMjrc2cH6TGTnmdlQ4OdLu7U6Hjxt3VJ70BvvyIELJYLyGqXQ1Eym+DEV6MhAuZTTch4lwP0bDfBmP0d4KfhAXxFBSBOOpMUwlJtAbGkmhi5zoxevwf+0DvGZrTSkec8zxnvvM8btAq/LpdvgCV5gRstqSoJXmL7Qu7sV/gYFwts1vsRl+i82EW74BK21Qr7B+4blqiRGapUaErbYidLU1IausUC3X7gB6zjfEc4EJPkstiXzfh0wDFSfEYVREZdKavpeu7Xvo3L6Djm3baEhNoDIukuKIYMpjwqlLTqBjdyade7bS/el2eg/s0PbnW2cAcKZmaqb+bDVLJBLx1SZbzug7CvEp543Ewvff79MGYk7qOXNigwMnNjhwaqMDFw3suWkhptjJjRY/L7o1Mobj1D8YAL/5NIlvP0vk288SebIzgultIa8EwDOGEr7Y4MKn71nw+QeWHFljy9cb7Dm+3o4zm7Xu5csG2r6k7/hKAMyykHDT0pVbVm7ctnYn20b6SgAsdJBS6CAVlDfdLeAqVy8B/nRdKfZ4luknpczRjVIHV8oc3bjuYsP97TFw80se7Y2gNVhMkYsJt03tyDHxIN9aTYGdmjw7Odm2EgocJRQ6SIQxr04J1OUBVrh6USqWCjuB1d5y6nwV1Mr8qfSUUePjJ4yFq73lNPipaFZqaFYHUeX/+92/lrBwumJihdGuzvBRow4QXMLNoWGUyf2oUqoE5a85NEyAP52KWKcJpDxAQWWgigq1hmKZmjwPJdnSAC46+nDDS0Xjlky6P9/LgzOHuHf+IN3n9jOWc4rHJZd4XHKJqYJzjOeeZiz7JENZXzNw/UuGsr5m/NYJxosvMlJ8iZGiy4wWX2Gk6CoPci7Rcu4ruq+eZig/i6G8mwzl3WSyNJ+pygKGi24xUnybiYp8xirzGSrNZqA8R9jjm2wpZ7yplLFG7Q6fLvRZt9M3WJXHcE2BAIHjDSWCM1gHhM//mVcB4Gh7BVM9tTy8Wy/sA0711DLZXcNUTy2/GmznN8Od/Hqog6nRdqYG22n46hiXVGHs3WhL7JxfsuuXxhxYZ8nXhnZcsZZQ6+lPq0xJb4DiLwaAX21wJmWVCZELNhM0Tw/lPBP855niP98cxXwzFHON8X99I/LX1uE3ax2KWWvRzF1H+k8M+OwjS44b2nPLyZ1csTtlcj9qg0PpiEugd8dOOvfsoe3TPfTs3EnX1nSaI0JpDlRzJzyIybRYHmXGM5EWzlhaCOMpkTTJgrliJmbH2wbIXvsQzzn6SOZaIJlrhes8a3zmWOA3xxTVXEMClpigXmpM2FvWRL1tT8RPbVEuNhTy/AJXmBG8ykLbKy0F1U++yBTFUgtUy60E+FMusxSgULnMUrgfHLrKkqAVFgQsNcVnvgHSufqIX1uP5wITFKvt2WMdz3n/7ZREpdOWuY2uT3bSnL6FhpQ0GlLSqIqLoyI2ivKYSBrTEun8JEMAQK3xYyd9n++k9/Ot9H6eqe2DGfQeTKP3YBrNe+JnAHCmZmqmfnBpg6A323HWwOmPAsBT+s6c2Oz0AgCe17PlhpkTRY6uAgCOxAf8YAD8dl8y3+1P+pMA8OhaO77eYM+xdbac3mSvzTPUdxT63wPALAuJAH9/DADq9u50t4CrXLWK3/fhr8zRjRJ7CcV2LhTZiim2c+G6iw3Tn2+BsouMbFPRHOhAibs5ORaO5Jl5kWcZQK6NklxbX27ZScizFwvjXt2eX7nEkxxrR4qdtJdCdEHRFa5e1PkqaPBTUS9XUu0tp1bmL3xf56ugzlch7ADWqTXCKLcjKlowcfTExVMfGCRcCdFd/dBFwdxPTdMaPQI0VClV2ssfsXEvAGCRnxelal/KlGoKvdXclvhzXazglkcgpYFxjB47wdSl03Qd30PdkQweFl1gLO80Y3mnmSo6z2T+WcZzTzN6+wSDV7/g3sVDDFw5ymjWMcaLLzJVeYPpypvczTpB+6UvuXP9NM1nv6Tn2hnGS3IYK8phpOA2U2UFPK0v437uNfqzrzBYeJPJmiImqgvpL77JSG2hVrlrKRf2ACcaSxmuKeB+eTaDVVqjyEClNh7mecDT3RDWfa+7DqLbDXyZCWSwuUQwfoy2VzDeWcXjvkYmuqoZaSvnm/st/G60m9+OdDE60sKvv33Aw4oyqrbs4riNN5krN7LrF0bsX2vB14Z2XLZ2pcZTSatMyR3NXw4Av94oJnW1KVEL9QQAVMw3w2+eGf7zTFHMNUbxxib8Xl+Px4/W4fnj9fi8vo7o5ZvZ+o4Z+9dbc9LUgXPWYkqVQbTEpzG0+wDfXrjOdzklPC2o4De5RTy9cI2u1AxaIiLpig7n0dYkvtuZzKOtUUxlhDKRGkWFRMlXay2JX/Qx0h99hMdcI1zmWeEy11oAQP85pmhmG6JaZIR6qTFRb9sT+44TUW/b479Qn9A3rQh7y5rQN60IWW1JwDIT1EtM8F2obd0tX/UK6xfUPx0AqpZrx8dhqy0IXWWJZpkZioWGuL+xAecfr8P+bz7Cc4EJ6p84cdhlC7fD91OdtJXOT7bSuX07DSlp1CYmU5uYTEWMFgAr46JpzUyhZ7d2/Nu1dxt3PtuhHf8+GwHPAOBMzdRM/blqlkgk4ri+wx+YPa6Yu3PJ1PXZSTVXLpu5ccXcnXMGdpzeZMuJNVac+NiSEx9bct3AkVsmYortXOn0k9MfqGIoOoDRZA1j6RoefRLOk11RPNkXy5N9sS8FwKnP4pn+NIHHnz3bA9wWxqOMIEaj/RkM8aNXLafRS0aFiwc5tmJOGbpwdL2YPb80Y/975hz6yPoPdgCvGDpz1Uj79bKRA1eMXwTB62ZiwQiSZ+9Fto1UC4Q2nlyz9uKqlSfXLN25biUl28aDXDtP8uw8KbT3pNheSqmjlDJHKeVO7r8f/bp5U+XqRaXEkyonKaW2LlTZu1Hv6EGdnTt9n0fw2/w9UH2K/pgQKiXu5Jo7c93Cg2u2Mq45eJNl685tKzHlthIqnLU/XweQFc5SrZnEzuUF53G1RPs7a3z8BOB7Xvmr8fGjzldBo79aeN4WHEZLYAhd4VH0xyVyPyGZjtAIquUKusKj6I2J5250HLX+Ksq8ZLRF/B4UOyJjaQuPpjUshrbweNrCEmnQxFCtCKfcN5gav2jq5LHkugdy2cGHcw5eXPPT0LhjF/1fH+PexbPcvXiSuzfO0HXhS8ZunuRx3jmeFlzgUd4lxm6fZeTmGQZvnGH41kUGbpyj//o5RvKuc+/KKcZvX+ZJ0S0Gb5yj++yXtJ08zGjeVSYKb/C0Op8nNQU8rMxltCSLsfJbTNfkMVZ+iwcFVxguucFkVQ6TVTlMVecyXZPHw9p8HtUVMP3M8DHeUML98mweVOQI41/dLqBuD3CquZyRphL6KrNpy7/M3fJbDDUUMVBXIIRD63IBJ9srmWitZKCxgoHGCkZaa5juaWayq5Gp7iamupuY7mnmSV87397v4jdDd/n1w3tMDrTwvyfv8KSukKyUBDTzf0n6W5Yc/oWE0x+6k2XiQbOvN63+nrSpfOkLD2QwVpvzN5Ea9awjmMqI5GGmtqe3RDyLhYnURsSkxzCVHsdUWjKDsVH0h0fS6q+hwUdBgb07WRaufLneiYxVpsQv0CdyngHBs03QvGGC4nVj/GYb4zfbEPk8PWTzN6NZoo/P372Ps+hNguauJ+Wn1mx734ktax35wkVDx/Fz3L91m+HSQr5preEfO5r4t65W/md3Mw8by6i+8AWFX+6l9uTn/HNVPr+7eZl7aen0x8bTF5HIoTWOJK3cRMiitbjPX4f7ckPslxggXm6GxyorZIuN8ZtvSOBCY61B45nZQ+f6DXi2F6haYiREu4T/xIbIn9mhXmmGcrkJimXG+C81QrHMGOVyE1QrTFEsM0axzBj1SjOC3rIiYK4BQXON0SyyImCJNcqlNsiX2uL82kbEr28g8E1LMja6c0OZSnF4Cm3pSXRuiaNzSxKNiUlUx8RTERlHSUQMZXHx1Kal0LFrK137tnJn/5aXdve+9D/o+k8SZgBwpmZqpn5wzRKJRBzTs+e8kfiFPq3nwMlNdoI7+NRme07rOXBigwXH11lyap0NZzfYcX6TA9f0Hbhp7EyRrYQOuS99GiWDUeo/CwA+TApkIlrDQIiaDn8V9Z5yisUenDQQc2SdM7vfMeWzd804+KEVR9dYv3QH8LKB078LgLoxsO71VQs3LltIuWLpwS07b3Kd5JS5Ksmx9SDPzpMCOw+K7aWUOLhT4uBOmaObsANYLfGiRuxJtbMHxXYuQmeZWFEulvJvxV9AzZdQcITeiEDq3TwpsXYj28qbW7Zyshx9yLJ247alMyVWzhRZOVFkKxZg7/k9Q53aWGznQr6VIzmW9hRLpFR4+AiRLzoDSIOfiiZFAK3qIFrVQTQrNXSFR9ERGkF7SLjwtdZfxYPEFDrDImkJDKFZE0xPZAx9sQnUaTTCzmBHZCw9sYncjU+lRhVKsZeaEm8N5b7BlMmCqFJGUeAZxCUnGbe9A6iMSOTuZwfpPniAB6ePM3jtLEO3zjFeeoOJoiuM3TzJ6PWvGbn2FSPXTzKcdUoAwPvXzjBy+xJTxbcZuH2Z0duXuHvuaxqOfErXmS8YvnmBh0U3mSzKYrIoi6nSW0yW3dZ2RTbDJTcYK7/FZFUO0zV5DBVfpz/3IuMVt5mozH4BBCdrCgRVTwd8OtOHTvUT7gBX5jJQVyBk/z2ozedBbT5DDUWMNJUIAdGT7ZVMtFUw3lLBcEs1DxrKGWiseAH+dK8f3W3laX8H3z3o5tvJXr4d6+ZfRjv514E2xnOzCHlzHVHLDTn4nhun13txxcCVKjcXWuUefxYAHIqL5l5ElACA+XZu3DCXcGS9IymrTIheoEfoPH00s41Rv2GMYq4ZfnNN8J1riOfsDXjMWY/t/7sGt7kmyJZZ4fjjD/FctJFEAwldx88zeiuH/3W/nX8ebuW3g/X8ur+ab5vL+baugum6Z4acjnImuip52lfLdz3l/ENXBb+tzqX9q73cCAtB/fr7yH78LoqFG5Eu1MdzpQXOi01wXWqOxwpLZIuNkS80Imip6e8dvt9rzXJTIn5qS8wvHIn+uYMQBaNcboJ6pRkBq8xRLjfBb4khvov08VmwGdlCPfyXGqFeaUbgm5aErbQhbKkN/vPN8JlrgudsI1xnG6BcZUPoz5343DqAC96x1CV+SkfGHrq2ptO5JYn2tGTq45Ooio6jIjKO2sRU6jPSaNm+hTufbefuwRkAnKmZmqm/fAkj4O+bPU5ttufERluOb7B5AQJPbrTkxHorTq61fhYEbcdVPXtuGjtTaONCu6+M3gDFXwQA2/2U1HvKKXKWckLfmcNrndj9jin7fmmqHQOvsX7pDuB/BIDXzcTCe1kWEi6ZunDB1JULpq5cs3Qny8aTfAcfsm2k5Np6kG8rpcjOnWJ7N4rt3Shy1DqBBRewkwc1Th5UOLhR4eJBqVjKNXNravyU0HIZar/mn67upidQQZ2LlBILCTmW3mTb+XHTwYdbVm5kmztRbulMvrk9BdZOL7iLn4e/CmcpxXYuFFg7kWvlIACgLgqm0lNGo7+aZqWGFlUg7ZoQ2jUhtKqDaAkMoSUwhLbgMDpCI+gMi6QjNIK70XHcjY7jTlQsXeFRtASG0BQQRHNo6O+vfcQm0hObSHdMEtkSb67ZuVMgVVImC6LUJ5B8n0BuSpVk+wdTG5fC3T37GT1xnJbPdtP91UGGb5xlPOcCowWXGM05x2jWCQYuHeH+hUM8uPQVg9dPMJx1mrHsi4zlXGGq4AYjude4c+U0HaeO0HHiMN2nv2As+zLTBTcYzb7MVPFNpopvMv7sIshE6S2mKnOYqMxmsOgaI6VZTFXnMlp2k/v5lxkrv8V4xW3GK24LiuDEcyPc5yFQt9+ncwgPVeczVK0FvrEWbSD0cGOxAIDDjcWMtZQJF0LGW8sZb9Eqfw8ayrlfX8Z4R70Af7qe7mnmcW+bFgLH7/Lb6T5+N9gCYz38U3sDke8ZErLSgM/ed+XsZhnXTKTUSl25o/HTZnD+JwFwOD6G+5HRtCkCafBRkGfrynUzFw6tcyB5tQlRC/UInqeHarYRiteNUMwzRz7XBO85BrjNXo9k1hpcFlrhNN8aqzcMsVmwgXB9N87Gb2O8rJgnLZX881gzfz9Sxzf3S5nqymew7BYjJTk8qMhlsL6Qyd4apu83MD1Qz/jdEp7cq+Ifh5voLb1Awf6duP/oXSR/+w6yhXo4zd6MeKExLovNcV9qhddyLQD6LTIkeJUZYW9ZC8HOIasthdGv77xNL7iCdXmAyuUmBKwyJ/BNS1QrTJEvNsBnwWZ8FmzGd5E+qhWmBL5pSchPbQhYbIZ6gdkzA4oRHnON8VlsSsjbjiStkXLeK47coDTaUvfSs3Uv3ZnpdGak0JaaQn18EtUxiVRGxdOcvoWW7Vvp3L2NvoPb6D+ynTv7M2YAcKZmaqb+ovVKADyj76gFvufUvzP6jpzVt+X0JltOrrXm5BorTq6x4spmO7KMnCiwFtMm8+Gu2p+BSNWfBQAn4lSMhCvp1/jTIvOj2s2bfAdXjus5cWiNI7t+YcKn75hojSAfWwk7gOc3O76wA/gqALxupo2I0T27biYWFMBL5u5cMddC4C0r7Y5gjo2UPBt3Cm3dKLJzpdjejQJHCSXOWoWuRuxJrZMHNY5Syuy07xdLpJy3tqExMgI6b0DZYb45kUqbnzeVdmKKjJ3INfcix0ZO9v/H3ntGV33g57rcm5tJJidmxgUDtsdtMpMp8bjbgHrvvfcuJHoVICQh0bsECCGEKuq996221XvXVtldFYH7zCQnyTnP/bDRNtjmZCZ3cu75oHetd63/f29J8PFZ76+ZuVNm6ECVnjXNhjZUG1hQY2JNi60LQgd3hA7utNm70WChWj69ViJusLCnzsIOgZMbLa6etLh6qvf/dfsG0uMXRF/ATgaDdzEQFEp/YIga+p70Wto3uu8gQ7v30bdzF+2+AQh9/Onfu5fRw0dUu/72HaJr527a/EOocvKi3M6TRo+dNHvvotFjJ4VO3hS6+9EVHsV03A3mU1KQpN6l7/p5hhOusViVw2pjIXNlacwUJCEtTER0P46JtGtM3Y9nJu8u4sIUFqryWKkvZam2mLGcFAYyEulJvM7E/bsoSnNYqilCWZGHtDRbnQDKawqQ1RaiqC9mvqmMlY4aRJXZiCqz1eVfuaAEaUMRssZiNQgqm8uQN1eolztLhTXMNlcw01SuLgfPNleoS8LKrgZmhFUo+gQsjwiR9zYy216NpKsOcWet6vrH4xRQ0SdA3iNA1i9UA6B8oF0NfsqhTpRDnU9B4Ofycb5ZmuKzqQ7+XTHC/5wZIULflsA3NIj6B1PufOhEjqY9QntbJoN9/iIAKD16iJn9B9UAWGFiR66eDTc+tODo69rs2bSN4Oe34btRE6+NWni/oIfbC9q4Pq+B3U8+xHrje1hvMkX3x7p89FfvEarjQtqJi4wUl/NwVMjnky08nGpkfqSC2e58RhszmagrYKqhlLnOOqT9AhQTbShF7cin25BNC5DPNPFQ0cXscCUD5TnY/v37GP31r3B6SRPLn2hg/aIOji8b4bLFCLdXjHDbrIX3Fk1C3zZk789VALg26BH6hiF7f26qLgP7bNqB32ZN9WqYZwGg12YNfF/RZudbRuz6B1P2/NIc/62G+G0ywOk5Dew27sDpBW28XjFg3zs2RGu4UxJwHMG+CAZOxDAaEcNwVCQDJ8PpPXaSziPhtB8JR3j4BIMxMQxdiGHs6mlEt6IR3T61DoDrWte6/su1ccOGDSR8YvK9YY90DStSt1s8DX8aVqRtNyHlExOSPzAm5bFzPjWlUNOSKiNr+tzdGPP3ZnqP71+sB3A2xItxf086XdwR2DhRZmLN3W2WxL1nwblfanPpH7W59lt9br5rSOIHJqR8YkbGpxZkbVc5c5v5MwEwW9P8W/DTsSJb05wCIyfyjFzINXSmwMiJYlNXKs3dVMmcsSMVxg5Um9hTY2pHlZkd5Za21Fo7ILBxotXSiXYzR9rNHCnXMaFAz5giS2uynO0ZuXIWWpL5Oi+G+ev7GfR0RWBgTu0Oc0o17CnRc6Xc2JVqI1Uq2GXupEoSrZ3Ui6aFDu60O3rQYGH//cXTTh40u3gg9PBB6OGjLgWvlX97/ILoDwyhPzCEXv9gJg8dZepwGMN79tMduJMOv0D6Q3YzvGc/7b4BNHt40+Lpo04F+/bsoWfXbtW+QE9fal09qXb2VANgpoENeaaO1Dj703sqmr7z55iOv8FM0i2kaYksFqajKEplJiuBxapMVuqzmcq/iSj/JuLc24juxzGVEcvU/XhEOXeYyUtClHuP8awkRjLuMJqdjKgok/nKfObL81CW5TJXmMFcYQayshwk5TnIKvPUJWBlQwmS2gI17M3W5DFTnct8SzkPOmsR1xUgritAUl+IrLEYWWMxksZSZO21SNqqGa8tZKymgMn6YuZaKr93I3ixtwlpdz2Srjp1yVfe24ikq465jhqk3fVPn4PrbkTWL0Tc04KktxXFYAeyfiHKoU4Ugx3IB9qRD7SrQXB1dpBH4kFWpzv4RtrPH2eH6LyTQYSRJ3tf0+Lib81J3WZFnbER/a4OfxEAlB87wuyBQ/T7BtPh5kOZkQ3ZOlZc/dCMg69rErrpU/xf+BTPn2jg9pwGzhs1cfipBvY/2YbNCx9h/eKHWG3SJOR9V274RjFX08Rqfw+Pxtr5bKaZpdEaJhuymazOYa6mGHlLA4vjnchFXTyQDPJINsSXiiG+Ug7zlXyAf3s4xleKHh5K2lkVt7E60Uvg++5o/OgDjDdqYbfJFJdXbXB+2RT3Lap7u26bNfB6TZM9vzYl9G1V8hewVZuArdoEvarL7reMOfBLC/Xwx1ovYOArqvKv/2u66p4/n61a6l7AwNf1Cf25CaE/NyHkbWNCfm6D/8/Msd2oidXG7Ths0ibgLSPO6fuR5LiP9qOn6Tt2itETx5mMjKA/7CTdRyLoOnySnmPR9IWfYSDyDGPnzzN29SyTsWcQxYczdfsEY9dPrgPguta1rv9SPRMA03ZYkvypmdprEPhkD2DaR6ZkfGJO9icmFGhYUGVkTa+b618cAOdCvRn393xqCGQNAM/+QksNgDd+Z8Cd941J/tiUjE9V4LfmZwFgloYZeTpWFOqrroVkaZiRoWlJmqY16Vo25OjZUWDkpAbAUiMHKowdqDK2UwNgqaWNCgCtHNUAKDR1oErfnAIDE0rt7Cn090R89wb/Vp/A51mRLFzbz4iPBwIDc+o0LCjebkuJtrMaABuNHOixdKHTzp1WO1caLVV/v83ejXZHD5qsndTPa25zdEfg5EabuzdCDx91/9+zegD7Q3YztHsf/SG76fQPotM/iNF9B2lwcafTP0gNgyN7DzC0ex/DBw/SHbqLVv8ABF5+NPsE0Oq3k2pnbyrsvcg0sKHM1pOBPceR3E5g9u5tRm9eYyDuIuN3Yvm8Kp+VymxmshKYyb+NuOQOw/evMJETqy7/TmfeQJR5G1HOHUQ5iQym3KA9/jIdt68wW5KNvLoIRXku0qJMxAUZLFYXMl+Zz3B6AnOlWUgrclkSlLEgKEPZUMJcdR7TVTnMt5SjaCpFXFeAoqmU5fZq5mrz1RAobShC2lCEpLGU2eYKpgVljFTlMVqdj6ixVL3y5ck9gPPdjerUb7a9Wp32rQ2CSLvrkfU0qAFQ2tWArF+ItK9NDX7SvranAFDWL0Qx2IFyqJOVqT5Wpnr4bK6br2T9/H52EGVtK7e8jnD4Hwy58p4N2TqONJqY0O/qwJDf/3cAVBw/ytzBw08BYJa2JVc+NGP/G5oEb/rkKQC0f24Hdhu3Y/dTFQDavPQRwe/YctPjJH2J5XwzPMznI118PtmGtLcIUUs2g8WpTJXnsSho4L+PTbI6O8i8tJ9FcT+rskH+sDDGvyxO8HvZAHw2yb8tD/OvS0P889IAvxePcczkIDobNTDcqIPV80Y4vGSB28sWeGw2fwoA9/7GjNC3DQl53QC/zZr4bdYk8BUddr9l/NQQSMBWbfy3aKnenzEEstb7t/MtI4LfNCTwdX18f2aK+8tG2Dynge3zmri9asi+39kR0IWSdAAAIABJREFUZ72LLO8wBiMvMxx5hsmT4cxGR9N75Bidh8LpPBRO7/EYBiLOMRx9nvGL5xi/dobJuJjHAHhsHQDXta51/ZdLdQpumwl3NSy4t8OCVA0r0h6XgDN2WJG1w5ocDRtyNW3J1bQmS9uMTC1T7m835f6nJqR/bETudmNKdC2oN7elz92ZET9X5g74IjnmizTcl+Uzoaxe3Mvq1QM8vHaQ5av7Wbqm8sJjL109yMrFAzy4dICVi/tZORfC0plgxIe9EO3zYHynO71uLrTa2FFtaM699025+VtTLr2txZVfaHH9V7rE/lqH2+8akvSxCSnbzEnXsOC+lhWZWhbkaJpSoGNGkZ4FRXoWFOqaU6hrTpGeBcX6lpQYWFGsb0mRnsVTz2vfrZ2BqzS1V98ErjCxo9rIjjYzJ5qtbKi3taLS3oJSK2sqTO0p03GgXN+BAiMzZm4dhOE7UHmOf0mNYOXaAYZD/GiyVcFkmbYTlXrulBu7UmTsQJGpLVV2jjQ7uCGwcqTGxJoGC3v1neG1wZN2Rw/qzGxptnGm1yOQFudAmhz9qbX2pNHBm16/EFrdPOn2DWA4JJTR3TvpD/Kjzd2Ddt8g2n1CEXqH0OoZiMDVlxoHV1q9fBk/eADR0SNMHNrP0J5QhvfspNvXg3YPVzo8vRB6BdHgFki1gz9F1t4UO/jQtusQo+GnkV66jjLtLtK0BCSpt5Gl32E+6x6rhfeZvhvHZMI1xm5dRpQYiyT1NnNpt5FmJzGblchc9l0m024xeOcK3TfOMZ5yg+n7CcxmJTKblYgk9x6y8ixmSzKZLspgrjQLWWUe8qp8pBW56klgZU0h8qp8xGW5zDeWM99YibKhQrUipq4MWW0p8roy5HVlSKqLmSrJQVSai6iigPG6ciYbKplrrUfaLkDe2Yy8sxlZRxMSYSPitgak7QLme1qQtdepE8O1PYFr5WFJW7U6OVSdjGtB3t2KrKsFaWczsi7V+0xrPbNtDYjbBci7W1H2Clno72BluIeHEwN8JpvgkXyCB5JRFsd7Ga8pI0xbj2O/+5QbnxhRa+BOh4U3Y26+SHeHoDi4F9nx/SgiDqCMPowi5iDKmAMsxHwLgfNRu1Ce2sV89G7mo/eijNqPLPwQ04d3M7YnhA4vb1pc3Sg3tybf0JL4T4w5uPUDQl/6EO/nP8bhJ9q4bLbA+O+1Md9kgOVmPdx+bsBFuwMMlRYxJShF1lnH78d6+ONoD0pBJZ3pd+jLS0XaUYtyuJWlqS5WpntYne7gc1EnX8/18o24j6/nevlqtodvxH38QTrAH2WD/Ov8KP+2MMa/L4rIu3YT+/eN+fDH72C32RGz/2aO8wsGuL6khcemT/He+gk+r2zH71UdQt8yJvg1Pfb+3JQ9b5t87xycz6Yd+GzaoUoAt+qqT715vayL5yadp/b+ra2ECfyZCf6vGuG6SRe3l/Xw2KxN4OsGHH3XjmTnA1TsiqLuYAx9Zy4xeO483VHHaQ8/QlvYYYTHjtBxIoyBmAhGzp1i/OJpRNdOI7oWrfL1UyqvvX/H45civufumHUAXNe61vXn65kAmK5hxX0N68fTtLbkatqSp2VDjq4F2TrmZGmYk7XdjMxtpn82AK5cO8DydZUXH3v52iEeXDqoBsDlsztZPB30TABMes+EG78x4cKbGlz+B02u/aMO13+lza139Ln7kbEaALN0VCWsJwFwDe7+swD4pGuM7Wk1dVQDYJWDJWXWNlSaOVCu60iZnj1FJhYspEbASCJUnOWPyeEoL+yi29eNOgtryg2sqdJ3o0rfg2J9R/L0bSgwtqbOyZU6KwdqTW2oMbFGYOVIp7MXXS7eNFk7UW9uR6udq7o83Onii8DRh1obd6osXWh19aPPP5Q2d28GgkKZ2n+IvoBAWt3caXZxpysghFbPYMqtXCizdKTK1pVWL38Gd+1lOuwo02FHGT+4j96dgfQGBdDr60WHpwdCNy8aHH0os/Yg38yFMscABEH7mDxzAcmVWKTXr7F4PwllZhKK+3eRZySqPXbrMhO3rzJ68xKD18+pIDDjDg8rclEWpTN9P4HeWxcYSrzKROpNxDlJSHLvIc5JYjLtFqKM2ygqc5grzWK6KANFdQHztUXq5zXLKvOQlOcwXZSJor70KehbEFSx2FSNrLaUmfJ8psvymCnPZ6okh7HCLOaaaxC31CITNqDoEKDsbELaVo9M2KD+TNEhYL6rmbmWSvWS6DXgm2upRN5Rp54UXtslON8tQNrZjKSjCXG7AElHkxoE12BQ0dOGslfIfF87S4NdPBjr43PJOI/kE6xIx1gRDfJwpJcbXj5EfKLNxQ90qDT2oMnUnTEPP+ZCgpDsDUUSthdl5EEWz4T9IAAunNrNfPRuFmL2MB+9F0XkPqQnDjJ5IITR3Tvp8vGlzd2DEhMLsrTNiPuNDsE//hXef/MbPH78PlY/3ob1T3XQeu5TjLfoYPcLU854HqQxPodHgz18NtrJo6F2lMJaZutK6MpIZLqmCLGgnOURIY+meng428eDmV5WxltZHW/jc1Enn4s6+Wyqg0eT7Xwx3cXXc738XtLPf1eOqAGwIT2TQANHNF74CJtNtpj82BTnF4xwfVEHj03b8d66DZ+tGvi9ok/Im0YEvarLnrdN2P2WsRoAA7Zqq3sAfTbtUKV/W3SeOvW2tg9wbSm03yuG+L9qhN8rhvhuNcBriyFeWwwJfN2AA7+24IymO0WBxxEcOU3r8TMMnL3A8LnzdEWcoP1EGM2HD9BxIozeqJOMnItm7EIM4xdPM3U1hqmrp1S+FqXy2vt3vA6A61rXuv5S2rhhwwZubjclSdOSZI1vS58ZmtZkato8vqlrR56WHfnatn8RAHxw/SArsSovPfbK9cOsXj7E6mUVBC6f3clCTOCflABe/aU2sb/WI+43utz4rS6JHxo9vmtsSbauLbl6NuRqmVGoa06xvqXaTwJeqaG1GvyeBYBrrjS1V5+FqzN1RGjuTKuNHQIHW2qdbaiyd6DWyoVKfWdKde0oNbfmm+IrMHyH/1l+hm/uHkNyOogWVzsqjEwp0bWgQteFSj13Sg2dKTC0o9DEhhoHZ9XdYRNr6s3taLN3o8fNl25XH/UgSLujB53OXrQ7etDl5kOdrQsCRw+E7n70B+yi1z+YkdC9DIfsYSAoFIGTKw0Ozqq7wP67aPUMpsLalUobFwSuvgzvOcjovoMM791Df2gI3UH+tPt50+nnQ4+HN0I3L5qdPCm1cCHP2IEMAzsEgQcYDo9BGR+P/PZNJPHXWMxOZiE7GWVmErL0O4hT4hElxjJ68xJjty4zFHuewevnmEm6gSzzLkvF95nNSmQsOY6hxKuIMm4jzUtWp4IzmXcYT7nBVHo8yqpc5kpVKeBifQmL9SWM5yarE0BpRS6S8hzEZdnMlmQzV5mPtKYERb0qCVwQVLEgqGK2ooCxgvtMFmcjrSlhpjyfsaJMpK01yNpqkQvrkAvrULTXI26uQtpag1xYx0KXgIUuAfOdjYgaS9W7AqXCGmaayhE1lqphcA0AVRdEGtTp35PwN9/XrrayV6j2Yl87y0PdPJwd4aFsnAeycR7MjfDZ1BAVp09z2cyG6Pc0KDf3Qmjvz4iHHzPBAczuCkZ8dA/zUYdYPnf8BwFwMXoPCzF7WDy9Vw2AkuMHmD26l6kDe+jx86fF1Y0sLT3uvq/J+Te34fd//RKf/+cdvP7uI8z+7lOMN2qg9eKnGL2lxU4jL9pySpF0dPNoqIt/mR7kn0UDtKbfpuLmBRqSYtV3k7+Y7OGLmX4+n+7j4WQ3y2MtPBhr5dFkO48m21kdb+PBWCsPJ4TqZPBfFMP86/wo/744SW9pCWHOQRi8sgPbl+0wf87sCQDcgfeWHfhs1cLvFUNC3jRWl313v2Ws3vu3dg1kzX6bNfF7WUu9CPrJ9G/tIkjAa8YEvGasvhfss9kIn81G7P65GZEf2XPLPIi6A1F0RZ6nN+Ycw+fOM3zmDD3h4XQeO4bg4D66I04wdCaaiUtnGb94mrELMUxeiWbySpTKVyNVXnv/jtcBcF3rWtdfShs3bNhAvIY5ydrWpGpZk6Fty30dO+5r2ZClZUuulh352vYU6DhQoGP3vRJwxifGfzYArsYe4kGcysuP/SD2CI+uHuHhlUM8uHSApTPBKE/5PxMAMz61JvF9a2J/ZcCN3xoQ/ztjbr9r9MwEMF/nh2Gv1NCaMiMbyo1tKTOyeeq7ZwFglZnD44sgLggsXemwdKXd3pFWF0cEHo40uLrR7OhNs5UfZXr21No7Q08O9MTxr8Wn+Dz+ENORvjQ4WFKsa0C+hjEF22wo03ah1tKbCks3SsztKbGwpsbCTp30dTp7IXRwV90UNlRNB7fZu6nXwQid3On286HDyxuhhye9/kGMhO6l0yuQVlcfmpy86fHdTY/vbqosXaiydafO0ZtOv930Be9jIOQA/SF76Q/ZTau3F82eHrT5eNId5E9fQCDN1u7UW7tSZe5KuaUnlU4B1HruZuZyHPKEO8wmxTGVeAlR8mVkGQlI0xKYSbrBZMI1xuOvMHLjIlN3rjN26zLj8VeYS76FPCMRcXoCfTfO03PzPCNJ11kouc9iaSbKonTkBalIcu8hyrjNUOJVRpKuM1ecjqQ8B0V1gWrtS3UBc6VZiArT1Z4pvs9caRbyqkJEpdlIqouR1ZYiqy1luiyPyeJsRvMzEJXmIq0pYbmllsWmauYbK5E1liJrLEUuKFNbXFeEpL4YaUMJyuYKFttUS6PFzT+cAK4NjKxNDKt6COvVkPdk0rcGfIqeNhQ9bci7W1VpYFcL8z1tLIz1oJzqQzk9wOLMIA9nR/iiq4OeuFvcsXMjYYcZNbZe9Dp7IAr0Y3ZXMJKwvcxHHWLp7LEfBMDl0/tYOqPyfPRe5BF7mQvbx/i+YIZDgxB6eNLo6ESOjgH3PjEk4m1NfH7yCa7PfYLV336E9o8/xGDTDsLdD1GRkM1EYxuLo10sTbSy1FHHcG4aNTcuIsy6y1hdIdLueh5MdfNgqptHk92sjnfyYFjIUl8zK6MtrIy2qMFvabiJhcFGlP31LI8082iynT/KBtUpoKSjifijJ7H6hQ4Or9hh95INzs+b4PqiPh4vaeK9WQefLYb4bTUj+HUV9K1d/FjrA/R6cdu34LdZE++XtuP1wnYcn/sU1+c18Nyk8xT0hbxlQchbFgS/YaYuAfu+aELQZgtiPvYgyTqE0qAwuk9GMn7xDBMXYhiOjmAw4gQ9YeF0hZ2g6/jxx/B3HtHVC0xeVkHgxOVTTFyOVPlKhMpr79/xOgCua13r+kvpmQCYqW1LtrYduVp2j+HPgUJde3L1LMnWMSdb0+I/nQA+jDvM6g2VVx57Ne7oUwC4eDoIRZTfMwEw7WNLEt615Nov9Yj7jT633jEi/neGz+wBXAPANeBbA70/BwDLjW1VfX/mjtRaOlNv7UqTlRutpo7qBLDOxZY6Zxca7Txotw+mXN+BBic3GCnh3zuv8c8FEXx26yDTkb40OlpRrGtA3g4jSjQdqNB1o9LUnRJTJ4rN7KiwsVcD4NoamDozWyoMzCnWNqLBwp4OJ0/qze1U5WFXL3oDfOgL9KXTxwuhhyf9gTtpc/emzc2fNjd/hG47aXEOpMbKgzpHb5rdAxnefZTRvUcZ2nUIoU8grV6+tHp70RngT19IEEJfL5pd3Gm2cKfBwoMac3cELjvpCjnOaNg5xHHxyJMSmbp3jfGkC0zdv8p0SizTd+MYvXmJ4bgLDMddUIOfKDEWcUo8s/duMn03DtG9G4wmXnuq10+ck4QsPwV5QSrSvGRmMu8wmXaL2axERPnJSMpzWKwvQV6Vr36eLclkpvg+UwVpTBWkMV2UgbgsF0W9qtQ7WZzNWMF9xgruM16YyVRJDvONlSy31LLUXKO2tK4QWX0RisYSlALVMmlxTT7imnzmqvOQ1hWiFJSy0lGHvL36B3sAv3s3WOUGNeA9WfKVdjY/VQpWf9fRjLKzBdlgO5LRTiTj3UgnelgVj/KH4QEWyyupOxbJzR2mlFu50eHggijQD/GeEKTH9qGIOMB8zJEfBMCVM/tZPrufpTP7UJ7ag+zkHlX6dzCU4dAgml1cqbW1I1tbn7vbjdj7s23Y/v37mP7Nu2j99T9h/ZYpgZo+1CQUstA7xleiaRR9dch7SpgoSqf51lUqLp9G2lrN6kg7K2MdLIu6WZ7qUj2PCFkZaGW5t5mlgUYWhwQsDTexOCRA0VeHrKcGaXc1i0MCVsfb+IN0QA2Ay8PtpMecx+7XethutsT2RcvHCaA+Hi9pq5K7zUb4bbUg+HVj/LdoqfcArgGg5wufqlfA+G3WxOvFbXg+vw2Xn+7A/UUtvF7WfaoUHPyGGTvfNFfDn88WfQI2mbHrFSti9QMp9DpK86FT9EdHMnUphonzEQxGhtF3Ioy+oxH0hEUweOoUo+fPMHHpPFNXzjNx6QzjF08zfumJZO/ySZV/APSe5XUAXNe61vWf0cYNGzZwb7s+Odom5GibkKdrRp6uGTnaJuTrmVOgb0G+njm5OqbkaJtQqG9Goa4pBdoWFGqZU6BpRpm2KZV6ZjSYmNPvase4nzNze9z+UwD46OphHl45xMq5EBUEHvdHetSf2X1+9Lm70mpjR62xJSkfmnD7XROu/0qbG7/V5dY7+tx8R4ekj41I3W5ChqY5WbqWZOtZkKNrQZ62KXlaJuRpmXyvF/DJZLDMyIZSfVPK9FSuMFAtYq43t6PW1IZaUxvqzVVQ1mjpQJOlPa22NnTaOdJp60qHtTsNJs5Um9hTbm9LtpUerQfcYCKPr+piWL0RyjfXD/DZhX20uthRpG9I9g5DinWdKNFzpdLYjRpzN+qsXGi0daXc2JZaC1dqLVwpNbSmSM+MMiMrGmyc6PL0psPdkwZbW1qcnOhw92TQP4TR4D30egdSZ+VAu6s3ne6+CF28aHF0p8nelTZn1VBIe5AXHbt8GDq0k6EDIfSF+tPm4UaXrzcTu/YxHrybfs8AOh086HD2ocDYlkJLe5p9gli4cg3ltcvMXDzLTOxZVu/fQplxDdHds0wkRjN86RRT1y4wevE0XadO0B0djiL5NgtZ91BkJDIUe57OS6eYS7vNSkkmyvxUFIVpKArTEOckMX0/gYnUm2rokxekslSWxVJZFrMlGUyX3GeqKJ3JwjSmitKZKc1EUpnLTGkm8poCVporWBKU0Z8Wj6w0m8nMJCYzk5jOS0VWloO8PBdFdQHymgIWGkpYbqlEKShFUlvEUlsd883VyBsrUAgq1c+SulKmKwsQVeQjri1hWViPrKmS+bZaFG2q8u9cWxXyrnoW+ppU5+K6HltYh6KtRr1bcKqhhGlBGeLWqu9A4rde6FUNhEgHhMwNCpkdUlk+0cPCYCdLve2IG2tI3rePi5YWlPq4MujvzmyQJ5/tD+DLo8F8ER7CwulQZGdDWYjZx0rUQR5FHGQpIpjFSH+WIvxZCPdFccwH8WFvxvd60x/sSY2zKyU2Llz/0JCIfzTEc4sJps9rYLr5Yzw/NKAi4QrjDTl8OdXI1xMCvhysZ6bgPr2J8QjT4+krTWW2pYSHIy1qrwwKeDDUxMORFlaHm1nqb0DeUYO4pRxZm+oGs7yjDkWfgIXBFhaGWlka7+DBVDdfSIf4Sj7CHxUj/GG8l/RjJzF/5T0cXzbD6sf6uL9giOeLuni/rIHvz3QJeMOYoDet2PmGEQFbtXHd+CHuP/0Yzxc+xfOFT/F4/hP8t2ip0z/PFz5VpYAvfoLXi9sIfk1129d/sy5737Yg+FVjArcY4/uSAW7PaeL5Uz1CN2tw7j0bKn3CEB6IYuTURYZPRTN2OoaR6Bh6j0fRcyya/uMXGQg//7jfTzXgMXX1lDrR+1NLvesAuK51resvqacAMFfHVA2AuTqmTwHg2mf/uwDwwflQls4EPxMAUz8yJeE9U2J/rcON3+oS/zuD/yUAFuiaU6BjRr62qXrQo9TQWt0PWGpo/ScBYJ2ZLfXmdjRY2P+HAFhkZUG2lR69J/xhJIsva6P5Q/IRvr62H3m4H02O1pSbmFGgY0apvgul+m5UGrtRbeZKjYUT9dbOVJk5UGniSJGuFfnaplSY2FBn5USrkweNdg4I7B1pd3Ojy9OTbi8fujz86PEKoNvTnzZnTzUAtrt60+rkQYujO0IXL3p8AugK8aV9pydNPi40ebvS7u/J4M4g+gODGAnexWhgKAM+QTTbuFJj4UCJlSO1rt707T7Icux1FuOuIbl6kZnYsyiTriK+dwFRwmkmEmKYuXWJmbjLjF48zfDF00zFXmIx/S7i5FtMJ8aqhkESr6PIvsd8fiqSrLvqku94yg3GkuMYT7nBbFYi0rxkFIVpLJTcZ744g7nidKaLMhAVpjNVkKYu+cqr8tXDIZLyHKQVuUzmJNOXFEf/3ThG0xKYyU9DWZmPsjJf1S9Ylcd8fTHLLZXMN5Uhqy95Cvik9WXIGytQNlUhb6xAXFvCTFUhczXFKjhsq2Wpo4GFjnokLd/uCRQ1lvJwUMjDQSELHfVMVRUwUZXPXEsl04IyphpKnugN/GEAVPZ9C4CSxxA4NyhkYaqf1fF+Ph8f4GFfJ/Vx1yk8cpCyYC+6/V2ZCPLk4f4APjsaxMPjQSxEhyA/HcJCzB5Wog7wWeRBliJ3shAVxFJUAAvh/syH+SE76Mv0Hl+GA72ptLAnT9+KWx8Yc+5dS1xe0sH/d44cNw8kcX8k0w1lPBhq4rPRepZ7KlE0FzKek85w2j3GKrKZbipivqeWR6OtrA4382CoSQ2Aq8PNrAwKWOyrVwOgXFj7PQBcHG77HgD+QT7MN6PdpIWFY/7Ke9g8b4j5j3TwfMkY7036+GzWxO91PQLeMCb4LWs1ALr95CM8nlfB3ZoDX9EhYKu2ehBElQSqfiboVV18N2ni97IOu94wxX+zPt4v6OK+UQunH2/D86d6HPm5IbEaTjSGRNATdpbx01cYPnWa0ZhohqJO0XMskp5jUQxFXGbk1MV1AFzXutb1f5Q2btiwgeQdBk8B4Fri978bAD+7dpTPrqkg8M8BwJv/pEf87wy49TvdZwJgsYGVegVMiYGVuuz73fSvzMiGMgMzyvXN1ABYZWT51F3fJwGw2crhmQCYZWRAnq0hs5cPQ18qX9Sc4n9kRfDF5T2M73Wk3tacaovH/7aBK2UG7lQYuVJp4vx4yMSeGgsnSvRtuP+JAbmaxgjs3Ghz9qbDzYcqc0tqrWzo9/Oj38+PHm9f2pw9aXXyoMPNh25Pf1qdPNQA2ObsqYbCHp8ABvcE07PLn85Ab7oC/egPDWb64CGGQ3Yz4LeTXu9AOt39qTaxpVDfjHovX7r27GHy5EmWY6+zdCuWhVuxiGPPMXPjDONx0SrfjGYy9gKTV88zd/Mq8ru3UCTFM3XjMhPxVxiOPY8oMRZlTjLLhRnIc+4xk34bWX4K4pwkhu9eYyTpOmPJcUjzkpEXpKIsSkdZlK5KCIvSmS3MYKYgnen8NGYK0pkrus9sYQZzRffVz6K8VEYz7tB+6xIDSTcQZScjL8tRwV+ZakhkrjwbeU0Byy2VLDSXo2hUAZ+0vgxxbQni2hIkdaUom6pQCCrVYDhXU8xsdRHy1mrm2+tY6KhH2VqDrKkSRUs1ExV5LHc2omytYbwyj8Hi+0xU5TMtKEPUWIqosRSp8NvU6wfd06wqF/e0Iu5Tea6vlYWxHlbH+/lmepQ/TI0yU1PB2P1UGiMP0RrsRX+gB0sHAnl4OICVo/4oowKRxexkIWYXD07t57NTB1iK3sViTCgL0cEshwewFObP/H5/pgI8GfP1odbMkawdplz/lTZnfmNM4D8aExcYSe31dKYrG/hqso+vRV3Md5czWZ/FQGESQ9lpTBblsdRVz8qggM/G2tTJ38qggOWBRvXzUn8DC711yDtqkLRWIBd+e35P0SdgcaiVpREhyxOdrIp6+FwyyJeyYX4vG+Kr4U7SwsKxePV9LJ7TxeSvNPF+2RSflw3w26qN/xv6BL5pws63bdj5hhGBr+io4c9n0w5VufeFT9WDIF4vbsP7pe2P18KofiboVV38XtbC72Uddr5mhNcLWjj/3Tbsf/Qx9j/6GK/n9TnzoS2p5n50HT7DSNRVROdjGYyMZiQ6hoGISLqOnqQ7LILx01cQnb/K+KXoHwTAP7XXb/xSBGMXT37PXdFH1gFwXeta15+tjRs2bCBFw1ANfgX6FmroKzSwpMjQikIDy28/+y8EwC9ij/H5dRUEPry4m5VzIc8EwPRPzEn8wJwbv9Xj1jv6JLxnRPy7es8EwNLH/X2lhtaUG9uqJ3mf/Gytx6/CyIJKQwsqDMypMDBXD1w8CX5rZ9harB2fCYCpOlo0B7vzP0vuQNttvq4/zfxlfxQR3ozvdaTOxowyY1NKDKwo0XOmRM+VUn0nSg3sH8OoFVVmDpTo21BmaEejrTtdHgF0uPlRZ+VAh7snHe6eNDk40OLkhNDVnV7vQDrcfBDYuVBtbovAzoUuDz+6PPzodPely8OPbk9/+nyC6PbxpdfPn8GgYAYCdtLrG4jQw4dun2Ca3fwoNXMkQ8OYMnMXBB7+zF2MRnb1LOJLMUydOYnk2nmWEmKZj7/GxIUYek4epS/yGP3R4UxePY/8zg1WM+4xF3+dgXOnEEaGMRF/hZm7cYhT4plJucV8bgorJZnIcu4xeOcK4yk3WC7PRlmUru4HnMu+iyT3HorCNFUCmJ/KbF4aM7mpTOekMJObylx+OrN5aYgLMpjOSWEk9Ta9d67TFX+Fufx05svzeFBbwiNBBdLSbKZyU1T9gkXpzJZlsSAoY76pDKWgHIWgUg17soZypPVlzFQVIq4tQd5YwUJLDcqmKsQNZUzUFCKqV5WDH7Y38qChiqXqMiaz0mi5eZWm29foyUxLUZM0AAAgAElEQVRC1lbDfHej+p7w2pDIk32D37WksxFJRxOSjiZkT1jaLkDW1cJCfwdLY70sj/exMtLFw75GBmNP0xG2i9l9/iwcDWQ1PBhlpB/yKD+U0UEsngrmYVQoytO7UJzeo1oFExbE4sFAlKF+jLi60OPkSo6uFbe3m3LP0o80z7203knh0WAf30wMs9orZK6+GKmgjP78FHryUujLT2euqZrlvg5Wh1p5NNrKZ2NtLPbVM99Ty2JfPcsDjSz1N6DsrkHRVY28swpZezXStkqUHfUs9AiY725kfqBZ1SM41sHKZBeroh4+Ew/wuWSQryUDrPY0k7D3IFY/+xDbF4yw+BtdfLeY47fFCP9XdPB/Q5+AN4wJfMOSkDeN1VO/a0ufVaVe1RDIWvnXf4vW47vAeuqBkdDXjdj5mhGBW/Vx+NsPsdjwDjZ/9QFuz2my/+eO3HcIpm7nAYajLjAWc5nx01foPBJJf3g0vcej6Ao7Rl/4CWYun0Mae5HxS1E/CIB/jkcvhH/PnacOrwPguta1rj9bGzds2ECqpqEa/goNLNXAV2RoRbGR9VMQ+F8NgF/EhvH59aM8urSHB+dDnwmAGZ9acPdDC27+kz7xjy+A3H5P/38JgCUGVpQYWKlBr8rMQZ36PbnipdLYUg2A5fpm6jLwd+Gv2caZVhunZwJgpqE+I8f3QEMmtN3mn5svIIpyZvaoC6O77am3NafcxIxifUsKtR0o1HaiWNeBEn27x4mkCgCrTJ1otPGkzdkXoYsPLY6e1FjY0eHuidDVnRpLSxpsbWlzcaPHKwChixf11o5Um9vS6uShhr5uT396vQPp9Q6kzycI0a79jAaG0uLkpu4NHPDfQ6tHANV2XuQb2ZGpbUmTRwj9+8KQ3ziLPO4cs5dPMRoTxuSFSOaunkMae5nJ86fpOXGU3vAwBiMjWE1L4uH9ZGbiLtMdHU5n1HFkSbeYTbqBNPU2s/duMnr7CpKMOywVZaDIS2H47jUm027xsDqflYoc5AWpiDJuI8q4zUzmHaR5ySiL0hHnpTCXk8psdgozWcnMZqcgzk1jpbIQaX4GnXEXab9+nt74q8xmpzCVdY/ZvDTkJdksVBUgL89VJYWlWUwWpjFdch9FfTGKxhLkDaUoBJUom6rUZd81AJyrKUbWUM5CSw0LLaq0b6apnLmWSh51NfF1dyuPaitZLCmkK/YqrbGXGUi7i7i2BKmwhsnGEuQddU8Niohbq9QrZL5rcYdqObRMqLK8TYCyTYCyvZn5njaU/e0oR7qYF/WzNN3PV9Jh5gpTGLkaw9SBQJRHAngQrur1U0T7ooj2ZT7Kl8WTfsijdyGL3oMycjfKQ4Eo9/gjDvJh1MebVmdX7hhakmDthvD6PcbyS5G3N/KNeIDPxzoQt5QzVVWAvLGCwbx0RsvyEdWXs9TfwcpoP8qeepb6G1gZFDDfU4uiq5r5nlqW+htUZd/OKqTtFUjbK5C1VyMTVjHfqbq/PN/dyMJgC8sjQh6Md/JgqptVUQ+P5vr5TDzAV+J+FC3VXPYLwnTL73DeYoHVj/Xx2WyG72ZD/LZq4/OaDr6vGeD3mhkhbxqrFz8HvapL0Ku6eL+0XX0Wbu0KyK43jdj/C3N2vWnAnrdNCH3DkF1vGLPzNSN8N2lj96P3sdzwO1z+2w6CtpoS9UEAZf77aT8cxnDUOYajzjEafYmuI9H0HIui51gkfeEnGDp1kpkrMYivn2b8UsQPAuAPpXrPAsCR8ye+546oQ+sAuK51revP1sYNGzaQpmX0FAAWGVr9/wKAX8Yd58s4FQT+OQB4+11D7rxvTML7Bs8EwJLv9PutQeBaKfjJRc9VJlZUGakgcA0Aq4wsabR0+B4Attk6PxMACyzMkF+MgLYCaL/Dv7dfZSbalckD9nT7mdJoryrhlhnZkLvDhjwNewq17SjWs338f7RWDYPYeNLi4IvAzoNGW1cEdm4I7FyotbKh0syCWisrmh0d6XD3pNnBjTorB1VC6OajSvqegL9+32D6fYMZ8AliYudehn130mqn+ptCFx9Ggg/Q5OJPgbE9hcaOVDn6MnIgirFjUcxci2Qu9hRzsTGMnzvBcMwxhk4dZ/JsNFPnTjNwMpzBk5FMxZxl4W48soQ4Bs5E0nXqBEMXYniYk4YkJR5JSjzTd+OYSLzOTMot5jISkGYnMZd9l7nsu8jyU5gvzmCpLIvp+wlMpcczmXaLmcw7j9PAFMTZqcxlpTCbmcxcVgqSnDSkuemM3YtHeOUs/fHXmEpLRFGQyVTWPcYzEhFlJyMuuo+iIg95uWpX4NoQibSmAGldIZLaInXf3xr8rYHf2lDIGhxKBRWIhdWIhdWsdjTyhVCAIjcbUdJdeq5cZjApgenCbJSCSmZaKhitLVAnfmtl3icniL/rWWEds20NSFobkLY0oGhuYL6pgcWOFpS9QuQD7UiGO5CIepHP9qGc62WprRx51l1ER3chORzA0rFAlk/5Mx/tiyLKG3mEJ8oTnsgjQ5Cd3I38xC7k+wKQhvoyEeDFQIAvzb6+lOw9SPWFy8wIe1iaGGN5ug3FSBXirlJEglymqvKYrS5msqIIaVMdC91tLI8PsDjWj6SrhoXeOpYHGpnvqUXWUYmso1Jd9pW2VyBuK0PcVoZUWIW8vZr5zgaW+ppZ6FH1/62MtrM60fU9APxyro+pqgLC7ZzQ+ckvcH/NBsu/1cNrkwnem/TxflkDr1e08Nqqi/dWY0LfMiHkdQOCX9Nj58/02fkzfbxf2q4+A7d2DST0DUMO/NKCkNf12P2WMUGv6hLyM0MCtujhtvFTbP/6Paz/7/fwf9mIQ7904qruQZoOhDMQcZKR6DMMRZ5lNPoSfcfP0nU0iu6wSIZPRTF2JgLRpQimL0cyfvnkDwLgD6V6zwLA4XPHv+f2yIPrALiuda3rz9bGDRs2kKVjqk7H/iOX6VtQqmtGqaYFpZoWlGtaUqVtTo2eOc0mFgw62zLh7chsqBuSI35IjgeyfHofD87vZ+niPhYv7GX56n5Wb+zn4c0DrMYf5EH8flZu7ufhzSM8jDvI5zcO8cX1vaxcCEYR4Yv0iDczu90Z8XKlx9GRVjMrcrZbk/iOCbd/q8+ddwy4/Vs9kj8w5t4HBqR+bEjGNhMyd5iSp2tBga4lVeaOlBvbqte8fK/v7wlXGltSrm9GiY4xxdpGlOmZqtevVBpaPNUHWGdhR7WdHU22zrRZudNm6kalgQP5BtakOpohSzkHs/XQcIH/UXGS4VB7Br0d6HKxpt3JmRZbZ6qM7cjTtCBfy4oiA3uKTRwpM3ehxtqFagsnmuw9qbNyoVjfkgYbN7o9gykzsqFIz4JyY1tanXxocfRGYKca8mhxdKfVyYNWJw/anD3pdPelzyeI4cBdTITuZyRoN51egdR6+FLj4U+jewAt7v60OvvSaOtKmYklbf6+DBzcx3jUMcbPRzB+7iSys6dQXDyN4uJpRKciGY86yVjESToOHKB5zz5WEu/xKDmNqQuXKfP1of3IARS3YpHeuo741jUW0hKRp99BmpaAKOUmUyk3mb6fgDgzEVHqLWQ595Bk3WUsOY6J9FvMZCciyklkOi+J0YxbdN+9zFjWbcaybiPKvYu8NIOH5TnMZ92j81wEbadP0HP1NJKiVBQ1OUhrc5gqT2Mi/y6y0gzERamq3yu7z4P6QuRl91FWZCEuSmU6LwlFeSarglJkVSXMVRQhr69AXl/BdE0xM43lSFqqUXQ1Iu8RIOmsR9JWzcP2er5ur2eptpi+1FvUXouhO+UGotJMpiqyEFVmI6rMZqo6h6mqPKTNlchbq1EKa1EKVdPDYkE50uZKlMJalroaWexsYL69jrn2emaEDYha65hqqWWyuYaJpmrGBVVIupqRdDUz296ItLuFlYE2HnbW8U1fFX/sK2fw5hH6o32Zi/bjmxN+/DHMi8+PePLgmCeKCG9mj7oxHx7IfNQe+vYE0hochPBYBMM3EphMzWSlW8jDyT5kIiHy0Wam6ooRVeQzUZrDWFkOIxW5jFXls9DXpJrWHREyP9KGfLiF5cFWlvtbWOgRfDvQ0tXwjFJ3NTPCMmbby5H3NjLf38KDkV5WR1Vl7UeTnXwx08FX4ha+Ejfx+9l2hjKL8fwnfYye/xiLnxrj8ZYjHj8zxvs1Xbxe08RnqzY+Lxvg+6IZ3i/o4veyHjtfM2HnayYEbjXE83lNfF7SweclHTyf18TjpxoEvWJE6FtmeP9MA983tPB7Ux/f1wzw2aKP9yZd7H70Lo5/+y6HfmHCVV1vst2OMhJ5gYnIM0zHXGAq5izjUTEMnAynNzyM/ojjjJ+PYuLyKUSxZ5iOO6sGv8krUX9y+Xfs4klGL4Qzcv7ED8LfOgCua13r+s/qLwKA1ToW1BlY0mJqybCrPVO+zsztckcWFoD0RBCL0XtYPruX5Uv7Wb60n5VrB1i9sZ9Htw6qAfDBrQPfA8AHF3eiiPBFdtSH2T0efxIAJn9oSNonRk8BYL6Oheo27xNl4GfBX5mRDRVGFt8DwFpTm2cCYJWtLQIbJ1ot3WgzdaNC3558A2tSHEyR3DsDE5X8W/Vp/lh4hNHdjgz7OtHjZkuHswutdi5Um9hTqGNNka4txYYOFJs4UmrmTJWlE00OXlSa2lNiYEWdlQtVZg4U6JhRbe5Ipak99daudLgF0ObsS5O9asCjw82HTndftbs9/enxCqDXO5BuT39Vj6CjB7Wu3tR5BNDsFUyTqy8N9h5UWzpQYWGjBsCJU8eZu3YGybWzyM6eYjbmJNOnTjAZeZLh8GP0Hz1C9+HDdB89hvhqLNLrNxg7c572w4foO3kMSewV5LfjUCTeRJF8m5m7cczeu4kkMxFJlurCx2xGAmN3rzOXkcBs+m0m7sWpE7/JrARm8u8xnZfEUPoNRjPjmc5LYiYvCUl+MvP5qUjTEui9FM1YwlUmkmKZyUtipiSV6fJ0psvTmS1NYzovCVHuXWYLkpGWpCMtSUdSnIaiPBN52X1mC5KZK0xBXJKBtLIYaWUxspoypNWlzFYXI6opRtxYgaytFkVXI7KOehRtNSw1V7FSX8pc0X2678XRmnCZkZwkpsuymK7KYaY6l7nafOYaChE3lCBpqkDaXImspQp5azXy1mo1ACraaljoqFcNlAhrmWuvZ7a9kem2+qcgcKyxkrkOAXMdAmaEDUi6mlnsa2Olu5kvBwT8fqieseRoBs7tZCrCj6+P+/LPx7z58pgnj054shDpieKwP/NHQhGH7aL/yF76I08gSklGUpyPsr6ar8Z7+XKii6nWQkaqs5ipL2KqPE8FgBW5zDSWIW6uZLG/mYWhVhaH21AMtSAbaFJ91iP43oDLswBQ3FmJpKsKZX8TCwOt/yEANt1Mxv7tbRj+9CNMnzPA+TWbZwKgz4t6+L2sR/CrxgS/akzAFgM8n9fE6wUtvF/UxvN5Tdx/soPArYaEvGmK56vb8X51Bz6v6eC9WQevl3TweEELl7//EO8XtnHqA3sSLUMoD4hkNOoik1FnEUWfZzL6DGOR0fSHn6Dv5DEGIk8wfj6KySvRiGLPqLwOgOta17r+D9JfBAAbDG1pMrWjw8qOCS8X5oI8kO/3YTEiFGWkygsxu1i9eojP48J4cP0gD28e4LP4QzxKOMzDBBUIfhYfxqMbh/ji5mG+jN3H6qUQ5qP8kYf5MrfXk2FPF7odHGg2sXgmAKZ9YvIY/szI0jAjV8ecfB0L/l/23jM2zsRK0+2fd3Z2HDonte2xPbsYr/d6x6lbiVHMpEiJIsVM5ZxIMeckijnnnFORLOacsxirWLmKxagc22lmZ+/guT9Kqmm5La994bsYA3yBg0/1oSiAAH88OOe87xG8zPwTGFnTamqnH/n+QQg00TmAWw3NaTU0p83Yki4z2zcCYJutLX02RxiydGL4kBNCQ93JvJkwH/5XXwVIO/lNSwhbed4ofd2Rn/dg2duZO+4eTDm502/jTLvZMdrNnBCaO9Fs7qiDQHN7Kn5pRLOxDR0WR/QZhp2WR+m0PMqggxtjTt6MHvOi/7ALXVaOtJnZ0Gt7lBFHV+54nWHx5HmWT1/kjtcZJo570n/4GIMOzowd96LP0Z0hl1P0O3nTbueE0MaRYTdvVv38EQXeRBzkhyTMH3lsKMrYMNaiw5CE+LHkd40l/5ushASyGhaK5vZtxJHR9F24TP/FK0z6BbKZkY4mJQHJrWikiXGoMpJYL8xirSQbbVkuG7VFaGt0930lReksZyWwmp2kuxiSnchKbhKivGQ0VflsCMq431HLdns1iroC1qrykRdlsJyVwHJWArLCdNYq8rjfXMl2Qymy8mzEFVlIqnJQNRSx01GDpr4ITX0R602lqOsKkVfl6jqMVbmsNRSz1VKBqraA5ZJMJPVlqFtr0bY3sNHZxHZvK/cHO7g30M79wQ4ejffyaLyXewPtSOpLWCzNRlxVgKyxDJWwms2eJjSd9Trw62lA09uIur8JdV8zyr4WfakHhGgG29AMtrE21K6HQ+1wh+7zaC+asX7Uo32vlaSvHflgF4qhbhRD3ahGelGODqKYGEczN8ED8QwbXZUsZYQy5efJ06CT/DbgBM/9XXjg54TW/yiy8+eQXPBF7BuEpqyQ7R4BO+Jh7qsn2FodRNZfjay9kPvCYu53ViFvq0be14JmWHfn+MHCKI+WdGHO9xZG2LkzxMZ0H9pJHdi9Mrt89SrKH4676WFncYCdxQHuLY9xf3mChytzOggUz/JUNs1z5SQv1MM8Vw3wK8UYCZ7nOfB338fq/b1YffMQh9+zwOM7FnjtMcLrs4N4f2ygM4S8Z82J90w4+YExpz7UPb3eNcDtW/tw+cYXeLx9QA+AOkg0xfvj/Zz4eD/eHx7A+739eL9zAK+393NxjxFh/92WBtfrDFyO4E5QIrKo28gjbyEJi0EUGsFycBhzgQEsR4Yiig5HejtSd+YtJQppStQuAO5qV7v6D6W/CAAOHHJg2PIIU3ZH9AC4ed2be2EXXwPAxym+PEv351GaD0+ybvAsx1cPgI9zfHia7c/TTF9eZN3ky/RrPE68wE7EKTYDTugBcPrIEYbMrN4IgBWfW76EPytq9lvpAbDJyJomQyuaDK2+tgP4+/UqB7DV0Py1KJg3AaDQxoZeawcGLY4xaOJIy0E7qg9aIk+JhrEGWG7hd8IwNnI80fh7obzoheikC/Menkw7ezBge5xOC2c6LY7TZuGsuwTyEgBr9h3Sdyxr9x2iw+IIY07eNBvb6E7RObjRY+NEu7nOONJlZc+AvRPjzh763b9Zj1NMungxfNSFAXsnRhxdmfM8y7CTF8NOJ+iwPU6LrSPdx9xZ8vFDGRGBNCyI1ZAAJCF+yMMDUUQEoQwPQhERhDjIl0U/X6SRYawn3EYeE8Okz026z15g9Lovi+FRrKUks56ejOx2LIvRYSzGhrNZnMO92hJ2aopRlecgK8nUxb0UpCLLS0WSncRqViKizASWMm+zkH6LzbpithvLuN9SxT1hNdrGEmS5KaymxrOQEIUoMwFNSTb3BBWoK3XdRFl5tr4UlblsNpVxv62GnZZK1uqKUFXns1ZXhLqmAFFRGpLSTH0GobqumJWKPOT1pWy213O3W8DDfiEP+1q529XEVns997oF3O1qYq2pkqWyHOYK09E0V7HT24y2s56N7kY0nfUou+pQdNYia69G3FaJWFiNsq8FeY8AeY8AZV+LHgDVA0LUA0JU/a2o+lt1n4e6UA/2oB7sQTPUqy9ZTzvS7jZkPe3IeztQ9HUi7etmZaAf6cQI6/Pj7Aw0IMqPYyrwLA+Dz/Hc/wwP/LzZ8vNE4e/Git9NJGFxrGVk8Xykg2d3+tEstCOfEyCZqkfUVohUkM/9pnLuCauRCKvRjHdxd36YRysTPFwc4/78CPfnR/TmjY3xHtbHut94Fu/PBcDHq3M8k8/wXDnJc9UQz5T9fCkf5YaZPQbf/CEOe4xweN8Ghw+s8PiOBd6fGeP12UFOfGKoB8BTHxzi1IcmnHjfCO/3DPF85yCu39yLyze+wPOdg/ou4In3jTjzsQlnPzXg7KdGup3BT4y58IkJFz4xxv+HZiTuPUbP2QCm/KJZCruFNDIOaXgs4pAoloPDWAoKZT44CHFMBKuxkcgTo5ElRyFJjmQ1KWIXAHe1q139h9L/kQ7gqxHw4xRfnqb58Tjdl6fZPjzL8eVp3k2e5PnwOMeHZzkBPMu6yZfZfvwq4zpPki5yN/I0W4En0Vz1YNndmSkHBwYPWb4RAKv2Wr+EP2tqD1hTZ2BF/UErBMY2egD86km4P1QtRuavwd8r8HsTALZYWdFteZh+s6MMGB9FsN+GqgMWrGXdhvFGmKjkn9vC2c4/wVqAN6pL3ohPueoBsN/G+TUAbLV0otXSCaGFAwMObrSa2lGz15R2cwcGHdzotj5Go4Gl/h7xV0F2ytWbWY9T3PE6w6SLFyOOrgzYOzFg70T/4WN6t++sxxkmXU4xfMSLdhtnuo+5M3bmIsrIaMShIYiD/REH+yMJ8UMZHoQmIpjVQF+kof5IQ/1ZDQlCFhWO5lYcM76+9J27wNiNm6xExqBOTkMefwttWhLqlASWYsKZjw5lsziH+3WlbFUVIi1KZyUvmcU8XadPWZCONDMRWVYS8rxU/e3gjepCtupL2GksY6OuWJcTmBjDSlwkC3ERyPNS0Vbmc1dQgagojdWSDJTlOagqclGX5aAqzUZbXcCjtlrut1SxVl2AqiKX9doi1muLkBSlIy5IRVtTyE5TOTstlYiqslmtyWWrvZr7PQ3c765nQ1CGuqYAaVkWa9UFaGsKWS3MYKU8m8XSbHa6mngw2IZKWI1KWI2yrQZpWxUSYSXilnKWmktZEpSj6m9F3iNA1t2Eqr+VtaF2PQAq+1qQdTch7xGg6G1G2duGsrcDVV8n6v4uNAPdaAa6kXe3sdrejKSjBXl3G7IuIaL2VhY7hUiHu9GMdXN/qBl1ZRrLt/zYDLrKXf9LbAZdRht+FXmsD6t5KahqynjYI+B3K0N8udTLxng9y50FSLpLWeutZaOzDmVdOaLqUuR9LWzcGeS+aIJHq1P6jt/O7CDbU/1svNxn3B7rQTuqczd/Ff7WJ3RBz1+vXjbmeti808vO4gj3lsb1APhEcofnilleqKb0APhCNoLHP+3H/IMf4/T3Zjh/egTHj23x/K4lJ75jgvd3DDj5qREnPzLj1Ps2nP7QjNMfmerh71XH71XX7xUYnvrQhLOfmHJhj4m+rn3PEt/vW+H/AytifmJHvqk7Y1eCmQ+MZCk0ktXwGFZDo1kODGcpKFRXYaFIb0Uji49BkRSDLDmK1aQIxInhuwC4q13t6j+U/iIA2Gtsx4DZYcatDyN2O4bylAvaKx5sBp5hM/Q8j2/58DTRl0fJPjxMusGTjJs8y/Hlee5NnuX78TRf1wl8nhvI82w/fpXjz68zb/Ak6SL3os6wHXSKtWueegAcMLV4IwDW7Lel9oDNy/p3AGw9dFgXt/LyIkijgSVNhlZ/EACbDc30o98OU+vX3MB/CAAFFhZ0mtvSa+pAn6EDTfusqdhnBgNCUI3DRCW/bQ1Fm+WuB0DRSRfuuHswecyNHktH/Qi43fI4Qitn2qyP02lzjNZDhxmwd2X4qIfe+NFpeVQPg4MObvpO4LjzCQbsnRhzcmfa7YQeAF9B35znaURnL7N8+iJzbqeZdzvH+BFvJtzOIvIJRBURy2JoCCtRYYgjdB1AcYAPS5cvsHDxHLNXzjN67gRLfte4m5LEQsBN2t3dGLl0icWQMNRJqcjjE1mJikWVmIAqKZ6NzFR2CrLZKcpBkZXMUmocoswE5CWZyEuzWMpPZjHrNtLMRCQp8aiyUnhQVczdmmK2KgsQZyWircxno7qQhcx4FjLjWY4KQxobhTolQfe92mLExem63b+afBSlWaiLs9gszeV+ZRHaslykBWkoS7JYrypAXpTBUuZt7jaUcb+pgvWqAiT5qahKs9moLWJdWI6kJoft9irut1ejqslDXpLBSnYCi2mxrJfl8KCmGG1ZLpvNuuDpzfZ6FIIK5ityENcXs1Cdz1JjMaLmMiTCShQ99Sh7mlgbatd3AdUDQv0OoKq/FVl3E+L2OlY76pF2NSJpa0LS1oysoxV5pxBFVxvK7nYUXW0sC+pZaW5A2t7CqlDASlMNEmE168NNaPpqeDraxIueap5U5yLxu4Hc7yZrt5O4W1jK45ZmlCsdyBQdqFdbWG3PQNaQzK86S/i3YQG/7WpAWVuFuLGRjakF7q2IeaRYYmt5FM1cP+qpHtame3UAN97DxmgX60Md7Ix082C877UuoHa8m41J3Xe3Zwb+QPW90QTyVDqvB8BnykGeyHt5Jhni0Mc/4NgP9+H8fXNcv3OMY5/Y4fU9K05+15QT3zXk1B5jTn1szukPbDn7sQWnPzLF852D+tHvq/Hv2U/MOPepOWc+PsTZT8y4uMeccx8ZcuFDIy59bIL/920J/Ud7on7sQL6pJ43HLjLvH8ZKSDjLIUEsB4WyFBDGgl8Ii4EhrISEI4mJRpEQhzLxFsrkWGTJUYgTwxElhO0C4K52tav/UPrGW2+9RdVB89c6Yq925FpMbL92L1cXp2JFo6EpTQdNEBga0nXIhH4rM8bsrVhwtUfs7cSmzwm2Qk+xHXmCh7fO8TjxIo9SLvMo5TKPM669DoB5N3mS68fz3EB+lRfIr3MDeJF2lSdJF9kOP8l20Ck2fE6w4nGc6SNHGLGwoeoX1hT9xIrM/2pA9j8akv/fTSn4v02oPWBHo5E99QZ2VO+zpHq/OXUHLGl8OfptMdGdVHvVCXy1F/jVajpgRctBG9qMDtN1yIEOk8MIjXRZgJ2HbOg4ZEGnmTk9llb0WFvTbWdNm9FhOg2PIdznROkX5pSamfK/RvNhIZffjd0T5ScAACAASURBVMbyvNEXSYwjj2N90Vw7z8opT5ZPejHueJRBu8MM2h6ly+wwrQa2dJo60mtxnC5TJ7pMneg1d6HL1IlWg8P0WTozfsSbxr1mdJnZMmR3jPGjrgzZOdJveRixmxdy79MsOrnSaWDOqK0jIq8LLLmfZd7jPJKzvqycvEa3zXHqzK1pP+rMyg0/ZIFByAKDEN+8iSTAB01EIJqIQOTBPsxfPcvc5TMsXb2ONCAQbWQUitAwJi5coMPFhYWbvkjCw9hMSWI9KQFlXAyTYQEsJESxXZ7PTlk+mrx05mPDuRMVwlJcBJqsFDZzM9BmpaLMTEZRnIm6IhdFaRaKgnQ2KvJ5XF+OOCkOSUo82pw0FqPDuBMaiLwog7XqArYby3RdxOwEthvLWKsuQFGWjboyj836ErYby5AUp6Esy0BTnYWiPI3V0lTWGoq421bNnfwU1E0VaASViCoLEVcVoagrZ725Gq2giu22etabq5FWFTKeHs9kZgJLxVlsCetQ1Zchry1jra0eTVsj4rpy7lQWMldVyGJdKaouXRdPM9iGZrgDSXcTS8Ia3T3gwXbW+4Rsdraw1dXK3W4hWx3NKFvqWGmsYLm5ClFbrW4c3NuCrLMRaUcD0o4G5F1NyLuaELXWsNJSjai1BlWvzlyy0tfAYkc1S21VqLsEbPV18HCwh76EeLri45E3t/B4YoIvlxb4cnGMneE2ZMIqFO01rPcJ0HQ3sNpcjqqzjgfjXTyc6ObhRDePpvt5NDvI/ZlBvUN5Y7SL9ZHOfwfAkc5/N7ZMdLAx0cHmZCeb011szXSzNavr8m3e6UU704VmphP1dAfq6S6UE11oZwe4uzzOztIo98VjPJJO8lg2wW82ZvlybYov16b45+073Jsd5fyPnDH7m59y+O39eP+9Ne6fmOC1x0R3/eP7Fnh+uB/39/dy4XtmnPnYhFMfmuD1rgGe7xzUmz+83zPk5AfGeL9nqHcFn/zAGO+PjDi7x4JL37HF9weOhPw3F2J+4k6N/Q36T4chCbuFLCwKaVgIcyEBTIcEMhUcwExoAHcighHdern3lxSpO+uWHKarpHBWE8KRJkUjTYpmNSESUXw4y3GhrCZEfq3eBHu7ALirXe3qL6U3AmCbmT0tXzmfps/QO3SYFhNrmowO0Wx4iBZj4zcC4GbISbYivL8GgE8yr/Msx5cXeX56AHya5/8XAcCKzy2pPWBDzX5rKr8wp2qfGXUHLKk/aKEH2kYDS70Z5H8HgJ2m9noA7Dxkoyszyz8KgGV7LSi3MIPZchAX86+Tt/l1SwCaJHcex/qi9TnP6lkvlk96MHHMkUE7W7rNbWkz1v0/3WaO9Fu50mN2nO5DzvSYHafD2JF24yMMWLswau9Jn+Ux3S3il3mEAzZH6Lc8zJKzG/POrkw5ODJkYc+YvRPz7mdY8DjLotdFFk9cZcbtPF3WzrQ5HGPQ4wRS/2DkQcHIAoNQhoSgDA1AHR6AIuQmkoBregDUhkfyOCWVrdg4etzcGTx5krlr11gJDGA1LBRZdCSK2GjU8XGIbkcjSo5DnZvGWn4GyuwUFuIiWIiLYPFWJLKUeJ0xJDedtfwMtGW5qCtykRdlIM1NYa0km3tVRcgzk7gTE8ZCTBgLUaFIEmJRlmTpAVBWkokoPwV5aZYe/jbqitHWFOr2AUszUJVnoqnKRFGWiqQ4BVVNHptNZUir8lmtKkBWW4y2tY51YT2bwgZ22hvYaKlBK6hCWVfKckk2ksoCRGW5SKsK2RLW6QCxvQltewPaDgGK5lpW6stZqi9jpbECRUejfsyrGe5A2iNgpb0OTb+QtYE2NvrbWG8XoG1tYLu9mXVhI6rmOsSCKsTN1awIa1D26M7Nydsb9KXsbELWVo9IUMVKUyXi5mrdubrBDuZaqpgX1rDSXo+2R8h2fycPB3sQVZQgqavk8cQAv16c5MXSJFvDQlSddYgFZSjaa9B0NyBpqUDRXoO2t4lHkz08nOjWgeBUHw9nBl6LqHkFfZtj3WyMdr3ubH4JgBtT/w6A27M9bEx3sTHdxfpUJ5qpDlQTbSjG2r4GgPdEozyUTPBEPslvNmZ5odE9/3n7DttTQ3j9vR2H/q9/wvZbe3H5xBTn9w/i/rEhXp8Y4/2pEV4fHcD744Nc+J4ZFz7Txb94v2eIx9sHcPvWPty+tQ+vdw1eM4ac/MBYFwXz91Zc+cFhbvyDA6E/difulydIP3AOgbM/Ixei9QAoCQ3WA+B0SCCzYYHMR4bsAuCudrWrvxrpAfCrIcn6UehX9uaaDK0QGFkjNLNHeMiW1kOWtJla0m5m9kYAXA/yZjPcSw+AT9Ku8iTtKk+zbvA89yZf5vvzojCA5wX+PMsP+IsAYOH/MKbyCwuq9lpS+YU5dQZWCIztqN5rqgdZgZG1Lu/P4sgfBMBmAxtaDWwRGtrRbvyyTP7dBNJtYU23hSXdFpZ0WVrSYW1Bu7E9XUZOtHzhSLWBLY1H7GGxBpYL+O1IDE/rb3A3+wwPoi9zN+gyWp+zrJx2Zcb1GGOOh+k4ZEbnIWv6rR0ZsDlGv5WTvhPYbnSUNsMj9Fm6MGznTr/VcXotHBk74sKEoxuTx9yZdvbgjosXM47OTDk6MeXoxKyzB7Nu3tzxOscdr3NMu5+l3eoYQoujjLicZu7CFSR+QayFRyMNCER804+t2FhUYYGIbl5h2ecSK76XEPtdQex3lflLV+hzc6fPzR2Rnz/iwECW/fyQR4QjCQ9j9qYPC4H+qG7F8rSsiLXMFGZCA5iPDkWcEIM4IYal+CiWb0cjTrmFNDORtcJM1ouz2aos4F5tCXdrilHkp7GafpuVlDhm48KYiQ5hJSmWrZJcNotz2KoqRFOei6I4k7WKPDTluToXcV4KqtJstmqL0VbmoyrNRl2WzXpFNprSNBSFSUgKklgtSEFalI62phhpeT7K6mIedLfyuK+dR71tKGp110Nk1UX6U3NagS5QWlyeh7SqEHF5HmuCGpTN1ay1N7HVI0TTKUAmrEMmrEMqrEPcXoesuwnlgBDFy90/RXsDqs4mtB0C1gR1KGsrUdVU6J4N1Siaa5E21yBurkbaWouspRaJoBppcw2yllqUbQ3IW+tYqS9nobqYhepixI2VrLbUsyBsZVHYzoqwDWVbK+r2FtbbBTwZbuXZRDv3xupYHyxH0VeIur8OZW8Dip56tsbauTvZxcaIkJ2JTh7M9PJorp+7k11sjraxNdrJ3SndvePtiV591+9VrY90vpZvuD7ZgXbydQDcmelha7xDV2PtbIwIWRtsRtHbhGa0k/XJPu7N6xzFD5ZGeCwa54Vsit+op3ghH+PfdpZ4oRhluqYU22/tx+Jvf47dt/dh841fYv/NX+L+sSHO7+zl6Dd/htdHBzj9mTFeH+zn/B5d/MsrAHyV++f5zkHOfmLG+T0WnP3EjAufWXL5ezac/54tl/7elms/sCX2l25km5+j8sg1Rq9EsRAYjzQ8FklIBOLgIGaDdfB3JyKUxegwVuIikSTE/EUA8A+FQ7+pdk/B7WpXu/r/Ij0AvoKfFhNbfRdQYGT92r5ck6HVy5u6NrQesqT9kBUd5uZvBEBtoBcbYZ48vHWOJ0mXeJp+jafp13iW7cOLPD9+VRCgB8DnBYF/EQAs/qmp3gRSs9+KJhM7hGZH/iwAbDWyQ2ioqzYjW9qN7eg8ZKffA+yxtKHXSgeBnRYWtFma0WHiQJeRE82fH6XO2B7hcSdYqoWlfH47EsOzBh+eFF1mJ/wc90Mvsx1wEfFZVxa8jjPjepTBwzYM2zswYu/MoK0jvZZHaDe2o9fiZffP6Cj9Vq4M2rjSa+FEp6k9k8fcmXXxZsLRjQlHV6ac3Lnj4saCpxfzHp5MOrsz63mSpTOXmfM+x7CTF3VGNjSbH2HhvA/L128iDwxFHRrJqp8/yzd80ISHI7p5jfmr51i6cRFJwDVkQTeQBFxn0N2TRhtbOp2cWY+JRR4WxsyVK0jDQpFFRuj2okKCkEZF8Lg4H21aEtMBvkyH+LMUE440+RYL8ZGsJMWiyktDXZSJoiAdRX4a68XZPKop5Wl9BdqCTJaTY5mKDmYqOpg7iVFIspN4UF/GTnURd2uK0RRnsZqViKowg43yPDTFujNz8rxUNMVZbFcVcremmLWSLDYrclAXp6AsTEJekIw4NwlRThKSggw26yvYbqxCW1fJemM12y31evh7BYDqhnK2hHVoGivQNFaw2VqLqr6MNUENkvoyFM21rHc2o+5oQt5Wj6K9AamwjhVhDZLOBuR9LXoAVLU3ohDWoxTUslZfzVp9NfLyEpSVZShqKlA01SAX1LDa/BL6mqqRNFQiaahE2liForlWP3JeqChktiSXO2X5zFWWsNjWwnyrgMUWAaqOFjZ6hdzrb+XLiQ4eDjeh6ipE3VvI+lgZ6xMtaEZaUQ4K2Jjo4N5cH4+Xhrk728uD+QHuzfWxMdGBZqSVtdF2tie6Xwuv/n34e5VjuD3RqwfA9ZcAuD2tA8B7U93cn+hia7CVzb5m1nua0HYLdD870ceDO6Pcnxvm4cIwT5bH+FIyyW+Vk7yQjPBvmwtsz7TRGBeBzTf3Yfutvdi/cwC7b33B0bf34v2ZKa7vH8DxWz/H88P9nPjEANe3f8mpD3VGj1cjYK93DTjxvhEebx/g/B4LLn7HivN7LHQA+F07Tn1qwfnvWHH9hzYkHfSkxOESAg9fZv1j9cHP4qAwVgKCmAkKYCY0iMXoCFbiIlm9HYM0MXYXAHe1q139VUhvAmk0sKTh5Zj0VWByk6EVDQctqD9gTsNB3Xd0cSoWCIzNEJpY/NEOoMbfA22IOw/izvIk6RLPMq7zPPMGz3N8+TLfn18XBvKr4iC+LArkRWHQXwQAS352SA+A1fssqTe0ptnk8J81Am4zsUdoaEergS2tBta0GdnSbW5Pq6E57SZW9Fnb0W9jS5e57vdvMTOh0/QIXUZONP3CAYH5MfpOeMGdSljK14+A/7UhGKWvK/dDz/Mw/DLSi65IL3iwes6NOfdjzHu6MeXsyrD9UfqtHRh1cKXbzJE+C1f6Ld3oNnOi69BRus0cGbV3Z/yoK/3WRxAaWdBnZc/4URcmjx9nwsWFSVdXJlw9GXfzZMLzNIPOHnQcdqbHyYuJk5dYvRmK1D+Y1ZuBSP2DUQSHIAsM4s7ly0xfOM3SjYsoQ/3Yigtj6cYFRk+5M3fhEtKAQJQhoSz5+LLs58dqUBCioEBWgoNYS4hHdSuWpeBAFgP8kYaFshoRxnxoIAthQagyktDmZbBWmKkf+cpKMpEVpqPKSkGeHI8i5TbS1Nss3o5iJjqE9bJc1svzEGclIs5PQVOZx1ZZHtqCTJTZKSizU1jLz2C7NI8HVcVsleSiyEpGmZ2CtiCTnfI87pblsFaQjLYwhY3STJQFaUiyk1AUZKIqyUddWoCipAB5SQHy8iKUdaWsN1ejaaxAWVeKqr4MSWUBK6U5rFbko6ovQ1SWy3JpHuLaEiQNlSiadd26tZ4WNgfaUXUJELXVImqrZbWrEUl3E9KOBmQNVcgaqlDUVaKuKENZVoKypBhFcRGSkkIkVaXI6ytRttShaq5D1VSDpKYMcVUJospiRJXFyOoqWCzNZ7Ygi6ncdN2zJIvZ5kIkAzWsjQnYGWlmo6+eja4axNXZzJWmIBYUoOqqRD1Qi2KoEeVIC5rxNjamu9ia7eHB0hA7d/q4O9/P+lQnypEWZINNKIda0Y51vNb12xzrZnOs+7X8wq3xHnYm+9BMdaCe1oU7b7wEwHvTPTye6uX+UBvyuhIk1YUoakvYFDawOdDO1mgPD2eGeTA9yOO5IZ4tjPJieZTfScd5sTzIr8UjDJXc5szBLzj89kHsvq2DQMf3DXD9yAjXDw/i/qEBHh8dxO29L3B/fy+nPzXi5Ae6SyCvIl++CoAXPrPk0netOb/HglMfmnD6QzO8P7Tg6g/tifi5K9UuV+m5Esp0UAzLEdGsRkfpjB9+QSz5hTAd6M9MaBCiWzFIE+Ne/v3G/0UA8E8xiLyqmSi/XQDc1a529WfrjQD4CpR+HwAbDCxpOGhGk9EhWo3NaTt06E8GwOeZN3iR5cOL3Jv8qiDg/xcALP6pKVV7dVmAFZ+bUXPAggYD6z/LBNJmYk+bkc6Q0XLQSg+ALQZmtBlbvgaAbYcO0WJmQteho3oAbLZwYvD0Sf5tvJD/ZyZDbwL5l7pApNecuB96nkcRl5BdckFx2QvZRU89AE4fd2HE4QhDh48w53qKrkNHGbByZ9Dag65Dx2g3tqfbzJEhWxd6Le3110pG7J1Y9j7LsKMjfYcPM3T0KDOeJxk57ka/sztdR5xps3dm8swVlq4FIPIJRhEUpgdATXgE6rBwps+fZ+biGcR+V9FGBXMvIYrZS6foOu7A3IVLLN/wQREcwnpMLIrwcMSBgYiCAlnw90ObeJu1hHiWggMZvXiB5QB/VLExLIeHsBAWhDozmfuVRWxVFqAqzdbBX3m2Lq4lK4U7EcHMhgWyfCuSxdtRLMRHcr+ulMetNWjKc1nMus1KXjKa4izWC3Wlzk1DlZOKJi+dRzWlPKopRZWTiig5DlFyHPerCtkpzWYtL4mNwlS2y7JRF2UgzUlmo6KQ5cwUVrJSWassZa2yFGWZbsy71lTJZmstGy01bAnrUDeUI60qRFZdhKaxAmlVIYq6ciT1ZUgbq5ALdCPajf427o32oOlp0QOguLMBcWcDq211iKtKkNVVoKqrQllWwmpBHsqSYuRFhYiL8hGXFSGvrUDVXMdaSz1qQS2SmjJElcUslxeyVFbASkWRHv4mc9KYL85ltjyb5a5iNueaebjUweZQHavNhcyXpyGuzmGlOo+7w608mtKNdWUDjajHhGzP9fJweZj7i4Pcne9ne66X7ble1ibakQ8JkA40ohzSdQG/er3k9wFwbaidrfEe7k71vxEAH413s9PbzEppDotFmayW5rLRUsdGf9vXAPDp/AjPFof5nXSc50sDPFvsR5gegsM//hD7dwyw+eYXWP7nX3DsA0NcPzLC8e3PcX3/AF6fGOL+/l7c39/L5R9YcvYTU05/ZIrXuwZ4vH1AX57vHOTCZ5Zc/I6VfkfQ+11j3N4x4fL37Yj8hRt17tfpvxHKXGg0K5ERiKPCWQoMYvFmIEt+IUwF+DETGoQ4PhZZ0i0UKbdRpt7eBcBd7WpXfxX6xltvvUXR54eo3mepG5ka29NseoRWM0daDh2l2fQIjUaHaTQ6TIORDc2m1joTiIENgoPWCA5a021qR6+ZHUNWtiy5OSI77cKmjxfrwZ76EfCrHcCn6dd4nuPLs5f1JPdV+fG8MIQvi4J5URjE06zrPE69zHqYN2sB3iiveyA66cacizMjNoep/KU1pT+1JedHxuT8yIi8H5tQ8lNzSn9uRtVenRGkwdCOJhM7BMZ2NL3s+L0ab7+Cvz8Yd/OVHMDfj3/pNrfTZwN2m9vRa2lPh6k1fWbONP7Mhpqf2pDzxX5mgi6DpBqkBfxmNJZH5Tf4dZEfG2HnkV7zRnHjJJqb55j1dGDK1Z5RBytmXY4gPuHBwvHjTDk4MH74CK0HDREamdNr4Ui/1XGGbDwZtj3B6OFTtBsfoc3oMMOHnXTdv2NujDueYOyoN1POp5nzPM/YcS8aD1kitD7MgMtxRD5XkfjdYO7ieZQhIYhv+qGNjEIaEMjk2XNoI6OYPHuOu/G32YiO4c7lK7QddaTTyYnFm1dZDb6JNNQfUYCuxIGBrAaFIA+NQhuTiMg/jJnLvizd9Gf+xg0W/W4iDg9FfisGRcptVuKj2CjK5mFjBbLCdJZyElGVZrNTUUC/7xX6fC6jyUljszAbbV4GOyV5PKgo4mFlMev5mcjTE5lLCkeUextVWQby4lQkBUmoyzNZq8xmq66Azdp85MWpiPMSUBVncLemiHtVRexUFLBZmosyNxV5djLSzEQUOSn6f6vy0tAU5aCuLkFTV4aqvgxlXSnyuhIWSrJYqchDUl+CSliNoqUSUY1uF1BWUYCqqQJlWw3ynnqkvfXI+xtRdtWhbKtBLahEXVuKqqYMSVUpq7XlqJrrULY1sFBbwkheGouVRUhqyljKy0ZRXMRmdRXrra1ohG3Ia+pZLS5DnFeEvKiEycQE5vKz6EmMpTkhjJWuarRDAr4cbeVFbwOP2quQ1eSxXJbBXEkm6i6Bzigy0sP6+CAbU8PszPRxb7rna7Uz2cXmWDvKvkaUfY2sjwjZGu9ia/zr496t8Z7XzB+v3skHmtme6ePenUFUQ83sTHbxYKabB2NCJA0FLOTFs1qYgCQ3Hm11PhudDaz1CtmaGOXe7DRb8wOsz7Vxd0nAw2UBmsEq7g+NkeLpw5FP9mH9N7/E+j/9nGPvGnDs7QMc/tuf4fh3P8f17b14f3iQsx8bcv5TY6790Ipr/+Uw579njft7Bni8b6i77fuBEaf3mHPqUzPOfGbBue9a4f6eAUe/+TkuHxpy7Uf2xBt60306hDm/OJThKajDb6EMjkTsH4LYP4TVwDAkcTpYkyXHIE+JRZ4Sqwe8P1TylFhkyTFIk6KRJEa9Afx2AXBXu9rV/xl946233qLSwIZm0yN64HtVAhMHBCYOegBsNLZFYGJFs7EVAkNbmg1saDaweSMAboR4sRnuxaP48/odwGcZ198IgM8KdPD3ojCIJ5nXeJRyiY3wE2gDT6C64YnopBuzx50YtrZ7IwBWfqEb/9YdtKXewJZ6Q2vqD1rRYGD5NZPLq47gnwqA3eZ2+pNw7Sa6WJhuczu6ze0YsnKj9QsHGj93oMjAmIXwG7BSzq+nEnjUHcy/tETw25IAtiLO82VyII9ifJg7eZR1v3PcD7vOgocjKyeOI/J2Zf74McYP29BvYc6Inb3OIWxkS7eZ48tImOMIDY4y6Xia8SPe9FraM3bkOAsep5hyPs2wvQedZkd1O5tmtkx6nWLh3CUkPjcQ+Vxl+fplZAF+yAIDkQcFs3D1GovXrrPq58+dy1dYj4pm6tx5upyP02LvwNS584hv3kQU6IMkxI/V4JusBgWiCA9DEx2NKjIadWQcK36hjJ+7yuiZy8xdu8Gynx/SsFBEYSFIIsPZyExFHB+NOCEGbUEmdysLWUmPZzIqiKnIICbDApiPDWejIIudkjzuluazU5LHRkEWmpw0VFkpqLNTWUmPZSE1iqX0GLaq89ipLWAlMw51STqa0gy2a/K5W1fITm0ByoI0llJjEaXeYjX9NoqcFLbL87lfXcxiYjTy7GSUuamo8tJ0o+mSPJTlBcjLC5CU5CIqzGK+IB1RRR6rVQVIaoqQN5WjbK5E21qjGxHXlCCtLUbaUIqyoxZ1Vz3KjloUwmqUzZUoGsqQ1xSjqCpBU1eFqqEaeX0l4rpyVpuq0HYImMnPZDIrla36WpYy0llOS0NeU42stpaV4lLmcnOYychgLiuDnrhwxFUFaDvreTTVxf3ZbtZ669nqrEZem4+4Igt5QzGa9lq2egVsDghZH+pgY7yXrcl+tqYH2JzsZnui82u1OdbO+ogQ9YAA9YCAjdG2PwqAX+0KvtoRXJ/oYmu6l63pXh7M9PJ0pp/twWbmi1KYy7nNck48y7lxrGTGsFGTx1pTOfd6Wrk/3I+6qx3loIDtmVaeiDp4stzKv0jHqPaP4vg/GGD57V9w+O/2YfO3v+Do2wc4/p4hbh8YcuYzM87sOcTJjw1x/9Yv8Hz7cy59z4zTn5ri+YERx7+9D7d3D+L5gRGeHxjh/p4B7u8Z4P2RCaf3mOP1oTGu7+zj4n+xIO6gJ2WOPkz53GI1LBFNdDLy0BgkQeGsBIQgDgpDFBrF6q1dANzVrnb11ys9ALYcOkqrmaMe+JqM7fX1VQBsMrZEYGSJwNCWlpf1xwBwK8KbR/HneZp8mWcZ1/8oAD7ND9KZQQoCeZJ5jYfJF9mMOMl60Ek9AM44H2PIyvaNAFi115raAzZ6AKw9aEntfgvqD1roAbDNzP7fr378GQD4KgbmVTj0q89txpb0HnKi8Wc21P7Mlrx9B5kLuQor5fxmOpFH3cH8timU3xT787vsEP6tIJrfpAYiveqG9uZptoMuIDnjivSsG+ITLswfP8qEvTW95iZ0mZrRY2HHkK0L/VbHaTlwmKa9dnSaODPmcIJRe08GbR2ZcnJnyesMU86nGbRzo9VIdz2kzeIwyxevovANYC0kmKVrl5i7eBZ5oD8iX1/kQcHMXLjI8g0fNqJjmD5/AVlgEL2ubrTYO9DueIzlGz4oQ0KQhPi9BoCqyAjW4+KQh0WgDI9h0SeIsbNXmLp4A1FgMMqoSJQx0SwFBzIf4IfydhzKpHik8THIU2+jzk5lKT6KiVB/5mPDUWQkoclJQ52diiorBVVWChsFWWjzMvTv1NmpSDJvsZIey0p6LJridLSlmcjzktiqzEVTnI66KI2N8my2KnOR5iSxkhLLYmI0i4nRiFJvoS3KYrs8n7XCTOTZyYjT4pFlJbFRksP92nJW8zORFGSxWpiFKD+Dxdw0pFWFSCoLdLExdSWomirYaq9nrbkKdUM5kupCJDVFaJqrWBfWommuQtVUoYO/Op2rWF5ZjLq6grXGWtT11axWlyJrqmazs4WVskLmcjNZqyhHmpODKC0dbX0titoa5nJzGE1JZDjpNlPZKYgq89nua+LJeCdPZrpQ99YgEhSyUp2HsrmctbZq1rsa0HTWo2qvZXukjc2xTjYnu9ma6mF7upeN0bY/WOsjQrTDragHBGgGm/+3APjVcfD2RK+u5vrZmNaB4PO5QZ5N9rLZVsNSfjKivGQWMmKYTQxhNjEEdXkmD4RV3G+rQ91Yy2ptFZqeOu6OC3i61MaLpXZYmyfczh3Tt3+M7Xv7OfptA46+fQDXj0xxed8I1/cNOPmJCac+MeHkx4Z4vv05Xu98wbk9xni+fxCXQmjA/gAAIABJREFUt/fj/K29egD0eN+Q49/eh8vb+/XdwNN7zDnxsTEB/8OWTMvTNHr5Mx8Qz2rYbVSRCchCIhEHhbAUFMpKSCSiiLhdANzVrnb1V61vvPXWW5TsNafB0E5f9Qa21B200XXQDGxfA8BGIwudCcTQllYjO1qN7N4IgFthJ9iOPMGThIs8T72q2//L8nkjAD7ODeBpnj9P8/x5lH6FB0kX2Ik+w2bIaTS+3ohOujHt5MiAhfWf3QEUfKX799WA6z8HAF99/ir4CY0s6DC1ZsDChZbP7Wn64gilxodYifaDlXL+dSGdp31hPKn05csCXx7cuoAm0JON4BM8ir2C9LIT4guOrF3zRHXZDclpJ1ZPOLHscYRxB2tmjzsz5eRO0z5zSn68D6GBA+MOZxiw8qTD5Cg95seYdvZk1sWLaWcPhu096LdxodviGCOOniycuoj0+k2UNwNRBQYwf/k80+dOsXDlEvNXrrB0/Qarfv5owiPYiI5h9OQpmg/b0+vqxuTZcyzf8EEWGIQ0IAB5eCDy8EAkIX4s+91EHBiALDSUO9d9mL/uhywkGklQJPLQGNRxt9Am3kYRG81iUACT168yef0q2sTbrCclIAoLYdrnOiuhwagSbiFLidePezcLs9HkpKHMTEaenogqK4W13HT9O1V2Imt5KazlpbB0O5zlhAjuluVwvyKPjcJ0JKmxrKbEvHzGoXl5Zk6cFs9KShyi1FuI0+IRp8WzXZ7PvaoiZFlJLCZGMxsXwWLybVYykpEVZKMszkNZmo+yvABFWT6SklwkZXnIKwtRN5SzLqxlrbkKZXUxiopCNBVFaCuK0VYUo64sQlFRiKyiAFFlPuLyAlbzclFUlKKpqURRU4G8toLl4ny2WxrZqK1mJu4W6wVFqHPymE9NYT4jjZmcVO4UprNSXcDOUAvbo83sjAhY76tluSEbUV0GWz217Ix2ou4TouxpQTvcwfZEN/dn+nXRKxNtbI63sDHWzMaYAGV/vX7M+9VS9TehHhCwNtTC+oiQzbF2Nsc63wiAr2p7QhcTc3eqn53lYTQz3WjHO3k80smmoJrVvDTmb0UgSozlzq0Q7iSFIi1M5G5jIVtlaYiToxkJD2UxM5W7XXXc66vlwWgt/7ykM44c+eznWL/3Bcf3WOP4tiGeeyy48F+P4vqBMce+vRfHv/s57u/u5/Snxpz7xIiT7+/H453PcXtnnx72Xo2A3d7VQaHbuwc59akZV/7BnoCfuBL4k2PkW3vQ7HWN0auhrARFIQoJRxIShigokMWgIBZCw1iOjGMlLgHRrahdANzVrnb1V6tvvPXWW5Tus9DDnsDEgWbTI7ozai8h8BUANpnY0WBo/hoACo0PvxEAt8NPshN18jUA/DLb908CwIdpl7mfeP41AFw54cq0kyP95lZvBMCyX5hTvc+KuoO2NBja6aDVUBdg/arz91WDy58DgK/evQJAoZGF3hn8+wAoivGHpVJ+NXmbh11B/LohmF8V3mQ9zJvN8BO6E3dhp1nzc0ft4866jw4AZWePozjngvzsceZdj7Do4c7YkePUf25Kzc9NEBo40H3Ihaa9dvRbuTLm4MWEoxvjR10YO3KcQTs3+qx1z8WTl5Fc8kFyzRfp9ZtIfX1Yvn6Z+cvnmTl/loWrV5m7dBlNeATayCiWb/jQ5Xyc5sP2jJw4ydyly6z4+CINCNSNi8MDUUYGIwsLYMHnBgs+N1j09WXu2g1mLt9gPTaJ9dgkNFG3WQkOYSU0GHF4KCuhwSwGBXDnpi+K6ChUsTGshgQz7+uDPCIcbeJtVGmJrOWms1mYrQdARUYS8vREZGkJyNISUGYmo8lJQ5uTrC9F2i1kKbEo0m6hzkzQv1dl3EaWogNAZU4y8uxkZFlJr9ViYrQujiY/naWkGOZuhTMTG44oPRlpdjrq4jw0L13CytJ8FCV5yEpyWS3OQVKSy2pFPtrWGtZaqtHUlaGpKkZdnIe6MBdtSYHOXVyWj6Qsj5WKPFbK8hFlZ7Gck8VqQR7q2kqUtZWsFOWhqdG5gufibiFOTEGcmMJETBSzKQkoqopQN5ez1lHD3fFWVjtKEbXko2gvQd6Sj6o5l3sDjWyOdaMc7EQx0MH6WA87M308mB/Sw592pJG14Qa0w3XIe2uR99R/rV5BoHa4lY3Rtj8JAF91/u5O9euCopeG9AB4t1uArCSXxeRbzIUHIbkVzWpKDIqCRLbr81mvyGQq7Crj/hcYDwlgOT2Ju23V3Oup4V5/Bf9zaYA7pTmYfftHOH5iypEPzDn8d/tw/ciU09+3w/UDY9w+MMTt3f2c+MiIM3tMOPXBATzf/hy3b/8Cj/cO4PrOAdzePYjXh8Z4f2SC6zsHcH/PAM8PjDj3XSt8/5sTUXtPE7fPm0aX8wxcCmTOPxJpaCTS0HDkYWEsBQawEBjIfGgEi9HxLMcnsRK/C4C72tWu/nr1jbfeeovyA1bUG+iAqdXMkTYLJ2r2W+kh8PcBsNHAnOaX8PenAODTxEu8SLvGl9m+fxQAH+Xo4O9Jrp8eAO/GnGUr9IweAKeOHf2jAPgmE0ibuQPt5g60mdnTZGhF/QFz6vab/VkA2GJg9jUAfOXC7TZxpOGn1tT+zJbCg0a6HcCFYh4NRrIjvMm/CqP4dZEfOzGn+F3WTX6X4YfG34P7EWe5F3ZOB4BXXJCfd0ZzyQPNJQ9EJ5yYdDxKj4UujHrA2oWmvTYU/8iAon88yMTRU8y7XWD4sBODtkcZsXfSA+DoES8kF3yRXbmJ5Jovq1d9EF+/xurN64h8rjJ19jRL168zc+EiW7FxaCOjGDt1miZbO7qcjzN59hxzly4zf+Uqq37+KIKDkYcHoooKQR4eyJ3r15i5cpmZK1e4c92H6UvX2UlIZychnbXoBCavXmPi2hUWgwJYjQhDFh2JKCSY1ZBgJKEhSIKDWQ0KQhMdjfZ2PJu5GSgzk1Fnp7KWm448PRFRYiyKjCRWk2+xkhCDPD0RbV4GG3mpaLISUWXcZqsgHW1OMrMR/izFhaJMj+dBWS5bBemoMm4jTYtHnBqHLCsJZW4q6vx01gozWSvMRJqZyPztSCYiA5mIDGQxMRpZVgqK7AyU+dmsFeezVpyPqiQfeXEu8uJcZCW5iIuyERdls1yYyVpLta7qy9FWlaDJz0GVnclGYT7q4jwUJXlIyvJYLs9lpSwfcWYms8lJ3ElPRVVToRsFlxYiKsxDkp/HYkIik6ERzIZFMRkTwVJGMg86mrjfJ2CrtxFFTzWzDdlMVCUi7yhiq7+C9bZCNrtrWO2oRzPWz/bsGDuzQ2xOduvcu+NCNsYEaIfrWBuqRT1QiaynBll33ddK0dugN3/o4O9PA8BX3b970wNsLA6inO5ifaKLdWEty9mp3ImPYikyFGXiLbQ5yexUZvO4uZSVrCgEpxzpOefOncgwVtOS2W6u4H53DXd7yvifSwN0JURi8J/+gePfscDqmwZY/80vcXznIJ57LHD70IQTe8w485kZ575jzpk9Jrh/6xcc/8//hOu3fo7XBwZ6A4j3Ryac+NhUP/o98bEpF79vS8BPXIk3vEiy8Rm6zvgw7hPCUkgM/y97bx1ch32ne/edfe/S3aZgO06cNIUtpts0dRLHJGaWxcx0xMyMR9IRsyXZllnMaDFZLJ0jZpkxDvXtFrb3c/9QdBo39e6bO+nO7h09M8+Mzk8z+vd89IXnuxwdz3JMNKsxMUyHBDMZEsR41GcAKBTtA+C+9rWv/9aSAmCVgh6V8rpcldnNz7t8SkNaAbwmq82V05pcPq3GdTlVrsuoUCmjSY2s1u4c4GlVWpW06NfRZ87ahCUnc+7423E/3I77UXY8EQp4muHFk1xfHuf78bg4gCdFu+D3rCDgMzDcBcAnBYE8zg/gcbYXj0Tu3I515HakM9vBjtIWcK+WLldP6XHuHR1yfypHwc8VKPmlCmVHVbl4QlOaA3hNVptKBW2qFXSo/gtxLy9ytawyNTLK1MqqUCen+lzlr1FRg0ZFDeld4BZFTZpllWlU0qXiuBolJ1Qo0VRhpygRRgr4txtx/K4ljI8u+PBhmS9Psz3YiLZgPcqST3P9uRvrwnqINYue5ohdzVn3cWbHz41Vd0dmra1oV1HhhpomXaoatCioUiejRL2MCs3KOrRoGNKmZUyLujF1yvpcl9eizcCGMSdfJN7hiL1CmPPyZ9zVjQk3AZMCN8bdHJgQODLv58tqcAQS71D6LJ1p0TejQduIm04CpgSezPv5IvH1YdbLnXk/b1aCg9iMimExJJQpbx/EQcHMBgUx5u3NdFAg81GRu/Evnu6M+PkwGx3BfEwU2ynJ3EpJYTsuHrFfANM+vgw4u7CcEMfdwlwWs1ORpCexmJLEUlLirpOTWBImspyaxHp2GusFGdwuy2chM5E5URwb+cls5iexlZ/CRm4Ka9lJLGckspKRgiQljnlhPJt5adwpyWYjJ521jBTWRELWREJWMoQspCcxn5bIZGI048nRzKQnsFKcxWpJNsuF2SyV5LN8toC5vEzm8jKln9fPlbBSWshMjojF4jwkBdkslOazcr6YnWsXuHW9gtULJSyVFyIuzmEqT8RcUTbL54pYqzjLSnkJC7l5rJ09y9rZsyzk57NcWsp6xQXmS4oZy85hUCRiLDeX2ZISbndfYafnPCt1BcxfyWD+QjrrVwu5VVPGRnU567UX2Gi6zL2BZu6PtPFweDdo+f5gC3f6Grnd28Dt3gZu9dSz1VXDWtt11tqus95eyVpXNaudVVLgW79Rw1ZvPRvdtc+1f+8Ot3JvpIP1vkY2+lvYHGhla7CN7aF2tofa2Rnu4PZoF3fHurk/0cu98R4eDbfwdLCJ+zeqGcxPois1gr70aEZFcSwWZvDo6jm2z+YxnRxLs5szHZ6eDIeGs1ycxVJFHsuNZay3XeLxaAfiy5W4vKOM2WE59P7xffT+7n1Mv3kS02+exPzbp7E/oozLdzUQ/EAbx9dVsTokh+VBWSwPymL0T0exPngUh8Pv4fi6LFavnsb80GnMDsljckAOrx/qEfiTM4T/zIAiBReu6LkzGhLAbHQEi3ExzEfs/pMyHxa2WwGMCGUyPpJpYRxzGUksfQZ9f+4XAeCLYO/zQCgRxiBOiZaGPEuEEcynRrKQthslsx8Eva997eur0lcCgPUyarSr6DCge4Y5axOWnS3+WwNgrbzqc+C3VwVsU9OlWVlLOgfYpKRJo5yaFAAvvK9K8XFlzulp8vC8CCZLoTeRD6578fuqMP6/i8HcT3NmM8aSrVgb7ic5sxpkyWqQJWI3Y1a87ZhzsmDNw4EHoX6MGBrQrqJCl6oGnSrqtCio0qaiRaeaHi0qurRpGdOqaUStgi7VCjpUKeowYu/Bol8EK4HRTLh4M+Phi9jbj0k3D4YdHBl1cmTG04OV4BDWQ6PotXCi09iWTmNr6rUMEXsHMO8bwFJgAAv+fsx6uTPjKWDO24v1iChWwiOY9PJm0seX+bAwliIjGfHyZDzAnyEfLxqsLOh1d2M1KYGl2Bg2ExK4k5rKraRkbnp4MuHry6i3F0tJ8Wxli1jLy2ArPw9JXAozEQlMh8cjiU9iSShkNT2VtaxU7pTn8PhyMWJRFNNpYaxmp7CaKWRZlMxievwXKjASYQwLaXGsZiVzuyiHByUFzMZFMREZylRcJPNpiUhSE1jNFUmXQxYLRKwUZ7FSlMNiYQ6rZwtYKMhmPj+LlZJ8Vs8WsFFezEpJPjNZaSwX57FcnIe4MJv54lxWyotYO1/C2vnddvHquWLmCrKYK8hioSRv962sBEl2DvN5eSwWFLBUWIiksIClsrNM5mTRJ0xipqSAzeuXuddQw4d91TzsqEB8LpXJonhmS5O5U3eOnfpz7LRe2Q167qvhzlgr9ybaeTDaLgXAPfDb6a5jq6uGzc5q1tsr2eio2v35Ro0UAvfm/rZ669nsqZO2f28PNnN3uJW7w+1s9DexOdD6HADuDHewPdQuBcAHk308mOzj6WALj7tr2a6voEcUzY2kMAbSYxAXidipKGa7LJ/RhAhafNzo8PZgODQccVIqW+eLWa4oYKmhnK3Oazyb6OVaeBxG338X7f/5HoYvyXDmH3Zn+sy+dQqLAzLSLV6n76hh/bK8dNnD+mV5TL/xPraHjuH4ygkcX5PH6hUZzA/JYv6yAjavqeLzEz1Cfm5A7NumXNT2odEykMnIUObjY1hOiEMSHoY4JARxSAizYaFMR4YxlRAlBcBFUQJLf8ELaXF/0V8WACXCiH0A3Ne+9vVX01cCgI1yGnSo6jKkb4jYxvS/PQDWKeyCX4OCujTypVlZi3Z1PekySJOSJvXyatSdVqZJRokGRR3OvadM4TFFLhvr82lVEQzm8mlTKA8uuvKbq0E8K/Xhk0I/HqQ6cyvBnp0YW5YDzFkOMGcjwI41XwdmHc1Z83DgdoAnPVqa9Ghp0aelS5eqBq2KanSq69KjZUiPrimduma0ahrRpGpIp54lvSb2iL0DWAkKZzkwjEk3L2Y8vJH4+DPuImDAxp5xVzckvn4s+AXSbWZHs545Q7YCRh3c6TG3Z8zZnUX/IJaDdmcGJb5ezHgKmPH0YCk4VFoBnA0IZCE8nIXwcPpcXeh3F3AzwI9mW2t6BK5sJCexFh/HYkQEy1FRu8si/n4sREexGBPNSkoiS8JEFtOSWM/IYDUlD0l0OrMRQhYS0lhNy2IzK4vVzFS2S7K4ey6f+cwYplJDmU8VIklOYy4xkZmEaMTJsSyJ4ljNimcjN4nVrOTdL1dhPNv5WdwtzGU42J+BAB/Go8NYzhSylJHCnbJCFnJSd5dCclOR5KYizk5DnC1iPjeTtZIC1s8WslZSwEZpEVvlJawW5zMtErKYn81SQQ6SgmzE+VmI87OQFGSzWJzHUkk+WxVlLBTlSn+3fLaA9dISxFk5TGdkMpOZhSQ3l/HMNEZESYyIkriZncpOTQVP2mv4qLuR9Yo8ti7lsXkxl9WKbNau5HG7uYJbLRXc6a3m3kgD98abuT3Vwr2JVu6NtnB/sIW7/U1S8NvqqmG9vZL19ko2O6vZ6qph+0atNOZlrauata5qNrpr2e5rkPrWQNNzALg50MzWYNtz8HdrpFMKgPfGe3g41c+j6QE+GW7ncVslyxUF3IgPoTcpnInsJLYuFnPn0lmmUuPoCPCkwcOJm7GRzKeks5ldyOa5EubL81hvucTDoWZ+PTtKzBlL1A78DJX/95dYHFTF5OuKmH/7tHSub6+ta/2yvHTDd69CaHXwNPaHT+P8qhwORxSxPCyL+UF5LF9RxvWHegT9wpjoo2aknbSm0SqCfo9Y5uKiWEqKZzkhbvfCTXAwc8HBiCPCmY2OYCYphpnUeGZFiSx8yUrflwHAPfD7vBfSovYBcF/72tdXpq8EAFuVdOjWNGDU0ASJrRnLzhbc9rP9bwuAL6oA7sHf3kWQPQBsPK1IvYI2Z38lT86vZGh0sIb+Wv7QmcqHdYH8tjmUjyt8eVbqw7+WBvMkQyCtAD5J8eJxsicbAXaM2eiz5G7HLX8BKwIHlpwcmbKwYNrcimF9Q26o69CqrEm7ig5dWkbS6yxDpk5MO/ogcQ9gMcCXOW8v5ry9kPj6MePhzbiLB+MuHky4eDMtCGDCxZduMweqVPUZsfegz9KZHnN7JN7BLAWEIvHZnRdcCgxgNSSQBX8f5ry9mPbyYcbXbzczMCSUMW9vuuzsGHQXMODhzmpSAotxMcyEh+7ODQaFMubpRa+LM73ubiwLE1lIjmc9I5XF5HgkCTGfVQrjWE5KZSVZxEqyiPl4IbOxSUxHJ7CYmsFkQjI3Y+JZEGUxnZLKorCMpeTzLKWcZTUjh42cTHaKhKznxnGrOIXbxRmsZKQwkxDLZEwM0zFRjIYGMhUdzlJ6MreKc9kpymEuNWH3izwnlc3yfDbK8lgvzmUhI52ZlCS2igq4W17KZmE+m4X53DpbzFZRAfOiNFZyshCnCVnOy2YxJ5M5USqz6UJm0lKYTRfuzgIW5rGUm4U4I42F7AyW83KZzchhJFHIUHwyUyIR45lCJCWZ3K4q5+PuKh61X2D1Wjaz5YlsXyrm1pVytq6XsV5Vxmb9Be7317LTe4W7g9e4P1zJg6FK7vZd5nb3FTa7rrHRUcVGR5W03bvnjY4qtm/USr3ZU8dGd6007mWrt55bA01/MRvwztDuQsfnwe/2aNdzrd+HU/08nOrnwWQfT1qr2blQxERaHCPx4cxnC9kuy2erNI+Z9ARuhPpK3zcK81nLKGAlvYDJ9HRminL58OYNWJ3hw4lhDH90FI2Db6H7T6exP2KA1YEvhjpbvyyP1SE5nL6jhtv3tTB+6Thn/vFdHI+o4HxECdcjqti/ooLFIUUsDili+7o6zj/QIuDn+sS/b0ahmhN9HvFMBCchSYhhMTGOhdhopoMCmQ4IYCZwd8RhPj4GSWoCs2kJzKQnMP+CSp9EGPMX/WUAcDE9moW0KBbSophPjUQijNi/Bbyvfe3rK9VXAoBtyrtVqZtGpszbmf+3B8AXzQB+fuljbxawQVaVhlMK1MlrUfK2HNlvn6bN1QHGWmEghz90xfJpXQC/qwzlD9cj+TDPmw+yPHiY5sbtOHseJAh4nOzJgocZix7WzLtas+bhwI6fO8vOTkyamzNjYc24sRkDuoa0q2rTrqJDs7IOV04qU6ekw7S9N1MO3ozaOCP2dUfi54HYx5MpdwGTAnfGXQRMC/yY8wxk1MGbXgsX2gxs6DF3ZMDalUEbN8acPFnwDWUzPIYFv0Dm/XxZDgpkPSyYeT9vpj3cmfP1RxIYxKSXN8NuAvpdXOiys2PC34+p4CDEURGsJSeynBDHnJcvcx4+jHt5M+rrw1hIIOLkOGaTY1kWpTCfGMtCwm5O4GxYKNPhgawKE9nKSGM5RchMTDxjYTFIkrKYTsxiJCKNqfg8xmJymYu7wHz8JZaSz7ORVcBmbhZbBYms5USzlhPNckYs4uRYpuNjmIyJYzEliYXkeBZTElhKT2YzP5Otgqzdm8Np8dIZwPXSXDbP5rOek81qVibLGSJWszLZyM1hIS2V9ZxstvLzWMvOYrsgnyVROhJRmtTi9FTm0oTMpQlZzMpgLT+X5ZwsxOmpiNNTWcjMZCo1m+GEFAbjkhDnZLFSXsSjxss8ab7Io9YLbNXksHhJyEx5DLdqznG39iq3Gq+x2XSRjdbL3B2oZbvvKrd7L3O3+xL3Os9xt6mEW42lLDecZ6npMsvNV1hpubp7iaT1mrT6t9Ndtwt/ndVs9tRJIfDzALhb8fuT9wBwe6iVneGO5wDwzs0bUvB7ND0gnQFcKctnXpTMzdhwJBnJbBRls1WSy3hyNEOxoYwnR7OYm8Z6cTbi9FSmYtMYC09hTJjK0vky/nV2BNbE3O29gc4bb6H/2vuYHFDF+mV9zF7SkMKf3atK2BxWwPKgLA6vqUg/7/3O4VVlXI6o4/aaBvavqGJxSBmLQ8rYv6GJ24/0CTtqRLq8LRWGHowFpSKOEjEXF4UkLhpxVASTAf5SAFyIjmIhIZb5tETm0ndzJSUvALrdFu4X/WUBcA8C9wFwX/va119DX4iB2fPeJZBqRf0/vctqUiunTr28Bi0K+rQqnqFd0YAbKmcY0DZmwtCUBWtTVh13l0B2ouzYjrXjQZqAJ5m7APg0z4+nhbsA+KQogMfFf/KjAl+eFPrwuMCbR1nuPMrYjYG5HenCdpAzy67OTFvZMaBjwvXThpx/V5e8n8lLbwGffVuZiuMaXDyhzqWTu6ftrspqcF1W84UAWKuoLQ2IluYEymtRL/dFS+8CqxrQpmpAnawmtSfVqD+lzsVjqpw/rkHGOzJMC8NgqZ1/GxPxm4EYHjZ6Q28aH1bF8XFFJH+4lsCHJaFsJTnzcWEYj9J92Ahz4IMUP6bs9RA7GvE02gexvQmb7q7MWtrQoaRFh7IOjbJaVB9X4fwvTzFqac+cixsbAV6s+LkxJ3BixNKZGRcfVgIjGXX1os9JwIRPIEvhMcwGhFKvZUiviS2jVi50GZtz08mVtZBwFvwCmfX0YcEvkEX/IDbDo1gJCmXOyxeJjz8rQeHM+ATRb+9Ki7El7WY2DDoKGHf3ZTk0mtXwWBaDI1kKiWIjKoFR1wgmPeNZCE1gKSqOtfhYdkRxrApDWIgPZCrSj5mYUGbjopiJjWUqKoHBoBjGo1JZzb2IWHSO0aQSxEUNDIuu0R5/gZaES1wJLqbWM59Gj2yaPdPo8I+kw9+fJncr5oRh9Pg5sZmRyVJ8FnMR2azEFrMpzOJOVga3M0VsilLZzExlOzsdcWIkK9mJrOelsJQZi1gUiSQtmrXMTLZyc9nKz2E2KZ6ppBjWC7NYyRMxlhTJ9vk8VksyWC7JZLU4n8WcbJZEGWzmFLCdmc96ahazkYlIElLZyCpgKT2bntAIehLiaMmJZrA8Dcn1XB62nuWjjnIWS2KYL0lgoVTI2vVyNmqvsVpTyUbbeW73XOCDsWoej1Rxf+DqbqWv/QJrLRWsNJ1nqf4ckuqzzFWXMt9UwULLFRZbr0qXO/ZavHuVvr0Zv/W+Rtb7mr+w2HFrpPMLvj3cyVZ/G9tDHWwPd7I91sXmVBdb0zd4ujbK46VeNoZq+XShn4djzTSFR3EjMomxtCweVl5k61w+A/EBTKWEsJoVz53sNJZjohnz9KPDwo0+h0Ak0RnMlIv4SNzC9lQdn6xPEm/jgOLfv4Xm3x9H/+vy6H1LHss31DE7LIfFqwpYvaaE9evKWL+ujMuPdHD8gSZ231XD7rtquPxIB/+jxjj+8ynsvncc+yOK2L+qhdPL+jh80wCPV83JPe3BZd0AOp3CWIiNZSY8FElkFHPhEcyG7UYXTUWEMB0ZypIwmsXUSObTIphPi0CS9sUW7Z5fBGpfxl/mb+8D4L72ta//E70LPiXdAAAgAElEQVQQAPfgb68yeF1Oh0o5rb8qAD4u9ONJoc8uBGZ78CjDjTtxTtyKcGYr0IklFycmLWzo0zLi2ikDzr+rS+5P5Z4DwPPH1Kg4riYFwOvyWlTJa78QAKvlNaUgWKeks3se7gUAWHVSlVoZDRoVdk+zVZ5QofKYEu1K+lw9qcmFE5qk/+oUo3H+MFPPs65onrQF8vuhWJ5UBnG/IhSaM3mY78udDHd+ez6GzXhHNqIdeJjsxWaIPXPOhtwKcOCDGG+WXa3Y8nBhwc6eYT1jBvVMaJTT4Nq7ClSdVGXSzgWJmzvr/t6s+LkhdndmxNKZEWsXpgV+jLp6MeTmxbh3AONe/vQ7Ceg0tmbYyplhCydG7JyY8fBmNTgMiY8/UwJPxN5+bIRFsugfJIXBlaBQVoLCGXQU0G3tSIe5LYOOAiY9/ZEEhLEaHstqeCwrYTEsBkciCQhjyDmAcY8wVqISWU+IZzMpjs3UGJYSw1iMD2dVmMSGKIPFZBGz8SIkybmMRWcwFZ/HUuZF5jLOMyU8jzinmoGkc7SGFdAUXsRVn0wq3ZKpdIrjmn0ElQ7+XLEWkKeuzVl9PUp0dLiTX8J2Zj4rKdnczSlhR5TGTlY6myIhq8JEVkXJbGansZiWyGp2KqvZqcylJjCTEsdMUgwLiQksJiWynZOx265OS2I1O5W1nDSmhDFsFGcxn5XMSoGIhfx0JFmpiNOEuxAoymVLlMtUWBwT4QkspGazkJ7PYEwyQykpDJ1LZ7H+LLfaz3O3oZg7tTkslSWyWCZk6VwGm7WX2GmsZqOxWgqAT0areThUyZ3ey2x3XmS99U8AuNxwnoXac8zXnWOh+TILLbvxLn8Of3vhzp8HwI3+Fjb6W56b7ftLAHhrZBcAtz4DwK3PAeB9cS/3Zju4M9bMJ7PdrHdcpjspnsmMTJaLihgTxjAcF8pYcigLolgWUmLoEQioNbGiUseMFlMBXQ7+iONEbNad48O5Zu5L2rk32YuXig4qf/8r9P5JjjMvKaD3LXnMX1fF8ogi1q8rY/MdFWzfUMX2DVWc/lkL+++pS9+c/lkLn18aYPe9k9i8cRzbV+SxPayB4yE9HL91Bq/XzClW9KHKOJheQTRL8fG7uZWfA8CZ8FCmI0OZiQrbB8B97Wtf/9fppa997WucP63x3CWQSnndLwBgpbwulXJa1Mlr0KCgSaviGdqUDOhQMvxKAfBpka8UAB9nCrgd68hOuBObAY4sODkwbmZFt/qZ5wAw72dyFP1CibNvK1P+rgoX3leVAmCVog41irovBMC9ObrnQPAFAFh9Sk0KgA3y2lSdVKXymBJtinpcOaHBhROapL19UgqAH/fE8XF3OP82Es+DK348q4zlX6/Fs53uwk66C5+UhDAfZspyuCV3411Z9DFjJ8ie+6GubPna8iTCh013R5YcHJg0teCmkTk1J5W58IuTdGoYM+fsgcTNk1VfL5Z9PZC4uzJs4USPsQ0D1s6Mu/sy7h3AiLsP7ZZ21BuaMWTryk1bN0atXJB4+bEcGCKt9E24ujPr6cNGWCRTAk+m3b2kIDjj4UuPjRO9ts7027sy7u7LjE8QYv9Q1iPjWYuIYykkijm/kF3wdHVn3Mt391xcSgI7wkTWkxNYT0liLUnIWkoOy0l5DPkn0SGIoT9URFdQGjeC0xmIyGM4upDR2GJm0ioYiimkOzSLzqBMagXx9ISm0+aXSKNnDM0eCVTZRyKUNSXoTTlij6lxp7iczdwsZhOjWUyJYD0jlq3MBNbS4lhMiWJRGM9qeioLaSlI0tKZT89Ckp6DJD2HxbQsVhPiWYqPZVOUyp3cLNbSU1hIjmczK52l9GQ28jKYS4ljqyQXcU4Kklwhc+nJzKQksJIqYlOUizg2mYHASG5GpzKTnMNYcjajaSJW60p51FfJh/01rF3NZv58CmuXMlm9mMnKlVxuN13lXlsdt9pq2Wy/wO2eizwcquRu7zUp/K02X2C1qeIzX2Kl8SLLTRdZ/Kz6t9x+/Tnw+/Pq31ZvPRv9TV+o/u21d/+Stwfa2R7uZGeki+3xG2xP7eb97Yy3c2+ilQ/nunk40MDkxWzGsxKR5KWxWJDOYGwgAxF+zCRFMhjkQ6+XJ+c1DMg7pUXBaX0aTD1ocwxgIk7I074aHk3W80TSzfDVcxj+9Cgaf38U428ooP+SLDrfPInpESVsXlPG9nUV7N9Qw/4NNey+o4r9G2rYvq6C1auKWB9RwvF7Gni+qYvdd2Ww+94p7I8oY/+qBs6v6OP+qhF+3zPjok4gLbaRjPrHs5IYjzg6HHFEpBQAZyPCmI0OZy4m4j8dAPc2gP/cc8lhX/BwtP8+AO5rX/v60npuBvDzrpTX/cJbjaIu9QqaNCpq7cKfihFdKsZfGQA+LQ7gg2I/Pij242muF0+y3KUAuOHvgMTBjlFjczpVdLlyQp/yo9pk/1iG3J/KUvgvihS/pUjpUSXOH1Ph4gl1rspoUa2kS52y/gsB8LqM2nMQWC2v+UIAbFLcDWRuVtKjSVGXejktGmQ0qT2hyvl3lCh7T5W0t08ymRwCC60wkwsTQp62+kNPKr9vFXG/yBNahFAVx2qcJVxP4I8XotmIsORZqgcPo53Y9rfkdpANjyPceBgiYNvLkREDPbo1d2Nn6k6pM2riwKyTN+M2bkzZuzLt7MKkgwtjNm6MWLtw09GDhaAIxr0DqDUw5br2GRqMzLnp6EG/mT1rvuGsBISwHBjCvG8As54+0hbwmLPb7hygbwATru50mpjTbmTOqKsXU14BzPmFMOUVwE03b4adPVgMjmQ1PJZ+e1duWDkwJvBhMcIfcYgn4lB/lqKjWI1NZD4inengVAYE8VzS9qZcXUCZuidn1b0p1fWmUEtAjqoTWUr2FKk7U6bjToNdGN3uccxE5jHsK6TKxIuR6HgGImMYjExmNvkSk3GXqXXIIEfDj7gTNgxGZzCVlslcVipL+YnMCSPZyk/nVmE2m/mZLGdls5yVR19oNJ3+sfQECxlLKGY86SyT8QXczcjjadE5VpMzWU3OZD0tj4nwJMSxWYyGJtPrl0CVtQ+Vjt6MpWUwk5vDYl4+06lpjETFMh4dz7Ioh07/YNr9gxiOT2SzooLNi2U8aznH/fqzrF7MZLwwCcmlHHZar7Ddcpmd1is87K3jcX8Dj3rr2Oq4xO3ua9ztrWSr4wprLbvQt9J4kbWmq6w3V7LZWs12ez1bHfWsfO6Sxx7sbfc1SCt/exu+O/2Nz231fn6274UAONzJ1mgXO2Pd7Ex0c2emh7vTPTyZ6eXX4l4+nbrBeHEagxkxzOcnMCuKZDI5BHFsJMPePlTrm5L+5ilyjqpSqmjGeTVbrhoI6PZPQJyVg7g4h99Iuvl4qZPJugt4KKqiceDnnPm7kxj9nQzq/+NttL95FNPXT2NzSB7blxWwO6yI7csKWB+Uw+aQPNYH5bA+KIftywo4HlHB7fta2BxRwO47qji+poHDEXUE39El/OcWJB6zptMllpuBycxFJ7KaHM18bOgu+IWFMxcewUJsNAsJMSwlxf2nA+CLPJsU+gUPRfntA+C+9rWvL62Xvva1r1Ehq0W1ov5z3rsMUqWgJ32rVdKjQVGLJiVt2pUNv3IA/KAkkGcl/jwr8eeDPG+eZntwL8GFO1GubAU6Me9oz00TC7pU9bhyQp+yX2mR9aPT5PxE5rNrIAp/1Qrg3hxgrYwGNafVdyuCJ9Vokdfh0vtqlB9TQ/jWcYaifWCyho974njWGcL/upnIR3XhPLwUzm8ro/n1xQAe5rvxKEfAx8W+PMpw45McX56lubPmZ8QHca6QF4bYUZtP4nx4GCJgzFiXPh1tBvRMGT5jw5ChLVN2XoyYuzBu48Kkgytjti5MOXgy4+LDlJsvs77B9Du7U6VnRIOROZ3WDgzbuTFs5cxWYDSLvruQJ/b2Y85rNy9w3jeAKYGndC7wppMr3eZW9FraSWf+Zn2DkQSEIfYPZdY3mGnvQMT+ofTYONFn54LYP5SNuEiWIgOZCw5lPjyW+dAUht0TqDrjw2VNL8pU3Lik40ubQyI3XIW0O8RQZeLLJT0BJcr2FCrYUCBvTbm6M5fPeNHuFEudZRglqk70BEbRFxrJSHQyc6mlzCSX0RdWQIOHkEwNFy45hHLNLYJqzyga/MIZiYljPjWNpfQsFjOyWcsrYauwgsHIZFr9omn3T6Q7LJ2WwCQaPaMZC01iJaWQ+aQCJiKyWUgpZTQyj/7gHKrsI7lkFU66shP+v9DkqiCMpuB4ZkTFzIoKGIyIozc4nJGoWPqjQhiIDUecJ+RpyxWeNFXw4Go2q6WJTOVGM1uawUbdee73NnG3u4E73bU8HqjnyWADD3uq2Oq4wq0b17nTU8VW+1XWWy6x2VrJWtNVNlpq2GytZau1np32RrY7G1jrqHku0mWnv5Gd/kZp1W/v862BJulW7+fbvrdHu/5dANy+eYOdsW5uTe7C34PpXj4RD/Lp1A0edlUznp3ERGYC0+lRSETxzCXFcEXXiILjSuS9rUjh2+oUvaND4ckzFCkbcc3clen0LO7XXOduy1V+u9LH73dGqEyOxeCHv0T/wFGM/1YGg//nFNr/cBS9g0cxee0EtgflsDskj90heWwOyGL1rdPYHJDF5oAstgflcDisiPMRFdy+q43pt2WxOKyE7WEVrA8p4fSKKpFvmZCj7MSgXyKTYUnMRceynBjJfGwoM6FhUgBcio9lOTmeVWHifzoA/qVK31xyGDOJIV/wYKTvPgDua1/7+tJ66Wtf+xoX5bSpUTrznPc2gPfawTVKZ6hT1qdRSZtmZR06VIzoVDXmhqrJVwaAz84G8eHZgF0IzPfhgxxPHqW48yDOg9uhbiy5OElbwJeP61H6tiZZPzpN9o9Pk/+mPIX/Iv9XXQJpVTlDi7I+DfLau9U/eW2a5XWofl+Zc0cVKX1XhdRfnmA8MQgkzbBQDIt5fNgRxO/aE2C4lGcX/HlY6MKjAheeFblzO9WaB+kO7MRaMO+jw6/TvXgW78K8qxa/TfPjUZgjt/1smbLQZ8RIl0kLO8S2Anp0LJmw8eKmpTvT9t7MOHkzae+BxM2feY9Ahu3caDezoc7QjC5bJwZdPOixd2HEXsBWcAxiVz8WfQOR+Pgj9vZD7L0bGTPq6MJGWCRdphY06RnQYWzGpJsH0+4+jLp6cdPNmwkPPxaCIlgNj2UjKoE+OxduWDkwHxjORlQCaxFxrEbFshIZx0ZMDusx+Uz7ZnBOUUCRjCOX1P2YCChgIeYcQ35Cup3CmXQLp8/Mg34LHwYdI+iwCKRK35MLml7Ev21E9FvGxBy1IlnGjcn4QpZEJWwVlbOYK2IuI4nl4hymcjJoCAinKaiIMpsMcs5kUmFVSrlJKHnq1mQqmZGnaU1fqBBJeikLuecYT8tjJqsYcX4po6nZdEcJydZypcjAh66QQi5Yx3LBJp5JUTstQZfJN0mhPaKeGt+rBLzvgcY/vYft91Wp985kKv0SozEZdPiF0OHvz8PKYj5oLuVZRyEbtQnMnvVnMd0fSWYIa6WpPOqo4k57Dc/G+3l0s4f7wx08HGrgYV8lt7sqdgGwq5I73bXsdFax3V7NvZ5mttvr2W5r+MxNbLc1sdXewHpnrbTVuwd6twebpZXAz79tD7V+Idblzs0bL54BHO1ie7ybnYkebk/1cm+ml0fTfXw43s12y2XG8lPYqShmpUBErbMLZ/WMSHpXhsx/UaH8XUOuHDPlwq8MuHrKnHojR1qd3BmJCOdBbQX3Oq7wu/lePpC082ypC9Nfvc3pfziCzj+8hdnfyGL5twrYva6ExfdOYPzqOzi/oiy1wyEF7A7IYfttWewOyOFwSAGXV1Vwe00N9zd0sD6sgcN3DHH7nj4ub2jj80M9MhXtuGTmw1RkCtNRsUyGhyCJDUQcE8h0yC4EiiMiWUmMZy01iY30lP90APxLlb7ZpFCmE4K/4IEIn30A3Ne+9vWl9YUW8N6835+3f6VtYCUDqhX0aJTVokVOnU55DUY1tRnT1mTKQIclB2PWBObc8rfhYaQDD2N2bwE/y/Lhg3z/3bu/Z4P4oCSIZ8VBfFQUxKeFQXxaGMKzghA+Lgzh08IQPs724QORBw8TXLkf6cKtAAcW7K2YMDGhT12b8nfUKHxbnYyfyCD68Smy35Sj5F1Vit9Roux9Fc6fVOeirCaX5DS4LKtBjaI2VXIaXJdRo0ZBi3plXRpV9alV1H5uCaRBRY8aORXp3d9GRQ0aFNSplVV5LhamTk6V6tNKXD+lQMWx05T9y2nKfybPhZ+rMOHuDX3N/NtYMU/64nnWHw/D2fy2MYk7JW7QngQdQnZSbfi0yJ/fFgXSbXqCD5I82Qi2o99aHYmPBb8riGbeVZMNDx3WXI2YttJmQE+XQT0jxLauDBnb0W9gy7CJI6OWzty0dWHK14+5wBA6LB1pOuNAt7kXHQau9Jl5MO7oy6qfPyu+Xsy5OyPx9mbW04dJNw8mXN2ZdPNgzsv3s4qfDT0W1nSbW3HTyZUZD18mPPyY9g5kwsOPMYEPkoAwNqISGHQUMCbwYdY3GLF/KAtBEUwHBTIbFspCVBLTQQn0OAVTpmjFDfsoep1iGfVKYNQrhj7XALqdfBnzi6PG1J0GS18u6btzTlfARUN/CjR8yFDxIlPFH+fv6RHwSxsGRWeZKChlofwSkqwLiFPPs53dgDjuOk1OmTS4FVPrUUqRuYhzTkUU2+ZyzqmQyy5FZBvEES/nTrlJNBXmMXT75DAaVMh68hVWEi4wHXaWKttkLlrEUqgbTLqSB+HHbCkyiiHyhBMO39cmxyCGOp8yYuQCMPiWFpr/oMR5xxQWzjbQEBbIaGYMi+dT+KilmI8airh9QYgkLYIZUTTD5SKmrxawVH+OjdbLrLdc4k53NXd7arjXW8ud7mp2Oq+z0XqZzc5KtrpquNVTL73qsRfnstlZzUZH1XMBz5+f8/t8BXDPd4ZaPjvt1sbWzU7Wh9pZHWjl/kQfj8f7udvTxsOBLh717/pBfyf3etu51d/J1tQgG1M93Jnp4ZG4kw8n6vl4qJIHlfncv5jF7cJUJvz9uGHvSOzJ44QdP0bsyZMUyutQdFKHcycNuCpnRaWqA402vnT4hDORks2T7hb+sDnE+vAV/ri9wMilCt7529cw+r4iOgdOYXpAGauDytgfVMT+oCx2B2QwP/A+1odP4fgdBYy/8Q5GLx3F8Ou/wvRb72Hzymlcv6+C83eVsHpFBqODJzA5JIP1y/K4HFEg5Ce6VKi5MyhIQhyaxkJkGuLIuN0zb5GhjEWFMxETyVRcNHNJsUhS4pCkxLGYHrsbzSKK+pPTY790EPRezMtcchSzSZFf2tMJ4V/wQMT+Esi+9rWvLy9pC/hFwPfnrlU2pFbpDM3yOrQpaHJDUYubWjpM6GozbajLsqMJGx6W3A6w/coBcNHBmgkTE/o1dDj/ngbFRzWlAJj1M1mKjir/hwBYKav+fwyAdXJ/Coiul1ej+rQSlacVqTh2mvO/lOPcmwqcf1N5FwAHWvn9aCEfDafw8VASf+hL5/fNKdCdxu8aonh6wYdfl/vzu/JQnqa7cT/OkcfxAiSeJqwF2fM0JYB5HzMehtvyJMyGVTcTJi206dHRolfnDKOmNgwa2dJ3xoaeMzYMmTkwYu3CqLsXPfYu1BtY0WzgSJepgF5zD4atvZl09mfZ259lH2/EHq7Mengw6ebBlMCTWU8fpt296Le2o9PEnEFbB4btnRiyc+SmkysTrp6MCXwYE/gw4eHHjE8Q096BTHkFMOTkzpRXALO+wcz5hbAYHMlkgD8zoWFMBETQ7xZMp50/N+wjuOmVwk2vVKYCUpkKSKHT3od6U2dqjJ25qGNHpZEHefIWCI8bIzxhjvC0I3En7Ek85YbL9/UJfNuetthseoTZjGWXslhwlaXs6yymVdPlnU+NfRqtvufpCL5KtdcF6oKqqAq8TpF9AWWOxZTY5uD/riPuPzMiVsaNAp0ACjR8OG8QyCWjQMr1/cnX9idLzYskWRci37PG+01D3H6kj9ebJrj/1ASHfzbA+5c2BL3vjuXrhuh9U404FQFdscX0C1NYvVDAvdoyHtQWsVORhTg3lvGkUMbSYpi+WsBiXTkbrZe51VXJdsc1bt+okkLgne5qtjuu/bsAuJfl9+cXPv4jALw92CyFwFsjnWwOtrMx0Ma98V4eTvRzq7+d7d5Wtntb2elr41Z/O7eGOrk10sXSUAubY63cn27n2VwHz4aredZ9ifWSVObSohkJ9afG0JyLavoknThF3PvHSTl+iqLTWhQd06TsuD4VcmZcVbej2zeSybRsNi9e5qPRLj6QtPPJSg+rHfXkentz8h9/gM7hE6h9/RiG35DH8oASLq+q4HpEGbfXlbA4eBzrw6dweF0e42+8I4VAs28fw/ZVGVy+p4zTG4pYvSKDySEZzA4rYPuKPB7fVSX6LUOqzvgx4pWMJDyNhUghcxGxTIQFMxERws3IMCZiIpmOj0GSEs+8MJ6F1IT/MgA4kxjxBQ9GBu4D4L72ta8vredmAGuUzlCrbECtssELAbBBzYQGVSM6VAzoVtNnQP0ME7r6TJ/RQ2xqwLqrBdveNtwLdvhKAPBRohsPoly5HejIkqMNU2ZmDGjqcumEDqXv6ZD5U1nSf3QS0Y9PkfeW/AsBsOqzBY9qec3nIl++DAB+/jJIg4I6NTLKVMkocfF9Ga4fV+fSL1Up/bE8A/bOcKOefxsr5jcTGXw6ksK/3kjhj21pfFgTyrPqYH5dF8EnFYHcy3DlUbory/5GTDtrsyAwRiIwYdrpDE8TfPltegjPYjwZt9CjW1udDi19unVNuaFvwYSdJxN2ngxaOO5W/1x9qNIxpUxOgyodU1qN7WkztmPOMxixRzBzHn5IBF7Mu3uz4OXLpKuAaXcvZj19GHcRMGjrQIexGX1Wtky4ujMl8JRWB6cEu63fUVcvRlw8uenmzaCjgB4bJ1bCYtiKSWLS059hZw/GBD6sRAuZDUmg0VxA5Rl7Gkw9mA/PZjYok+kAET2OkdQbe1MiZ0bBKSPOqVpxSdeZi9quiE6YkvSuMYnvmhP+C3O8f2SA749NcfuBCSFH3WgOLqA9qoDe+DKGEivoi6mgLaicBp8SukKvctWxkDzDFNI1YwmXCyFQMYpIbSE2b7lz5rsWRGslkG6SSZlrKRGKQbj+wg6vXznhddQBtzfN8fiJPm4/1MH1h3o4/0AXm++oY3hQCbNX1TE+oonByxqYva6HxjfkOP03b6P17VP4HTOhJTSHDxu7+W1XHwuFRQwkx9KbEMOQKIW1yxfZqt6FvXu9tTzor+d+Xx13uqu51VUp9U7ndbbar7LZduWFAPj56t/ehY+d7rr/EABvDTRJfbu/hXsDrdwZauPOeBc7k12sjbezPdfD1mw3a5MdrI23szHewa2xFn670MWzwWvcaz3HemUu/UkhdIT6cN3KhvO6xhQp6JL3ng75x3QpO6lG2XFlLpxW55KsPuUndbmoZEqVmQtNAn/mSotYqb3MVlcV98abeTzexm/mhvBVUuXkP72KwWun0Pz6MQwPKWPxsho2L6tie1gO24OnsD10EuvDp7B6+SQ2r5zG6KWjmB94H4uDx7F6+SR2R2Rx/I4C9q/JYfGyDEYHZDA+KIfTG0qEvaVDvooDgx7RTIckshCVxHxkPNOhEYwGBjMavAuAU3HRiJMTWBalsCxK/uzm9H8NAPxLAdMjMSH7ALivfe3rS0sKgHvwV69qRL2q0b8LgI1qxnSqGtKjfoYhTcO/KgA+ThLwMNqNO0FOLDvZMmVmxqCW3pcGwOuy6s8tenze/38BcO8ayN4VkFpZFapllbl8Qo7KExpcfluNsp8o0GFmBbUVMFXGJ6OpfDSYyB/60vlDi5D71/z5TXscf7yRwuMyb54V+vJRvg9igTbTjlosuhlx01ydHj1ZKBZyP1TAupcdXTrqNKup0KVnSp+hHe065ozZeTDp6M2gtSODtg4MOQg4r3CGCmU9mk3saTOx54aF/e5Gr7c/Yk9f5lw9Ebt5Me/py5SrhzT/r9fShg5jM8ZdBJ9V/NwZc3Zj1NGFaXcv5n2DmPEJYsLDj0FHATesHKRLIXvhz9PegYy6ejHu7su0fxy9ziFUnXGkwVRAt2MQN73jmfQXMumXRoOJP6UK1hTL2HBJ3ZVruu6UqtiRc8qMzJNW5Mo7UaDiyVmdCFLlvUk86UXcKT/SVaOo9sqnIaCA5pASav0KqPEppiXsCtW+ZdQHXiZTP4HQE974vO2M449tsX9LgJdMCEY/tEHnNROExpkUOZVT6FiK41tOGH/PBL+Tfni974Hdj82wfV0N6yOq2LyuifVrGpi+oobBYTUMX1FH75Aa+oc1MTyiw/tf+xeO/c0Psf6pIuWOYSyVVHP/WhM756/RF51Ib3w8w6J0Zs+d5U5HE/d727jXW8v9vjoe9NdL27174LfdcY2t9qtSvwgA9+BvDwB3uuu41VP/HwLg52/93u1t5H5/M/dH2rh1s42t8TbWJttYnW5nfaqd7Yl2tsfa2Blq5n5fHf86UsfmhXQm0sPpDPegwsKEMn0DilUNKFTUo1BGj6JT+pScMqTsPVXOv6vM5VOaXJLV55yMPpe1rWj3DmEoPpnVqgssN11g9cYlnkm6YEvMVmMdVm++h+ahn2H8mgLaXz+JyWFVLA+rY3tYDdvDclgfOonVofexeeU01odPYfuqDMbfeEdaEbR9VQb71+Swf00O21dlMD90Gr2XTqD/0m5bOO6YEef0XRjzj2E2PI6F6BgkkVFMBocxEhDCaHAY49ERzCbGsZCazEqGkGVRMkvpSfsAuK997ev/Oj0HgHUqhjSoGdOobvJCAKxTMaJexZBOVUN6NQwY0jRkXEePST0dZqdzZi8AACAASURBVI31WXU2Y8vLmrtB9l8JAD5JdudRjIC7wc6sONsxbW7OkLY+F49rc/ZdbTJ+IkP6j06S8ZPTFLyt+EIAvPbZ7N8e6H0e/L4MAO7dBW5U1KBOTpUaORWunVbk2vtqXPmVOuffVKZGW59HRekwe55PRlP5cCBBCoAMZfDHwTQ+aY7mkysh/PF6HE9yPLkfbc+yuyHTNlpMW2kzZanFh3GBLAqsGbcxoUVdlWYNLboNrOgztqdJw5QeUweGrN3ot3agw8ycZgNzKpSMqdG1ocPShS5Le4YcXZH4+iDx9mbO05s5V0/mXL2Zc/NjRuDFnJcvw/ZOdBib0WFsxrxvgLTqN+rowrD9blj0gl+wdP6v396VTgs7brp5Mx8YLt0CnvMLYcYniFnfYFrNvanUE1Bt4EaPUzATfgmMeEYz5pPATe9EqvQ9KZG1pVLHn07reFqtwjmn7kzuKUsu6wdSaxlHrVUS1dYZ5GmEkyoXSIp8OCK1WErNUymzTKbURsg552wuexVRF36dXBsRmWapRCoG4feeB54/d8TrLVf0X9bH4kfWuL3jQYxmLEUOxWRZZBOuEsGZ1w3QeUWXYIUQ/GUCcPq5DaYvK2BwQB7Dg0oYHFBE+1sK6B1Sw+aHJji+aY3at1RQ+5YKhm9oYv4LWZLN7RjLK+VRXQuTqRkMxyTSExHFVEEuS1cusNF4nZ3+Zm4NNHGvt5Z7vbXc7amRVvv24G+z7cpu67ftyr8LgOvtlay1XZcC4K2eem73NvyHALi3DbzZU8ftnmruD9TzYLSZ7fEm1sYa2JhqZmeunXviTj6cucFH4x087ajmacMV5rNjafO056qlMeV6OuQpapAjo0mhrC5FsvqUyOpTdEqTghOqFB+Vp/xdJS6d1uGishHnVE2oNndlPCUdSWEBd1qvstN9mTvD1/jtUg8sz3AjJR3rH76Hw0+UMDggi84/ymD0TSXMD6hg/YoaDq8r4PS6Ak7fkcPmldPYvHIah9flMf3We1gcPC4FP/vX5LA7IovNK6cxO3gK7X88jt7XZfD+qTYiRUuuW3oxGRzBXGQ489ERzIWHMREcyGhgKGOhEZ+1fhNZFqWykiFkKT3pv1QLeC456gsejg7eB8B97WtfX1pSANyr/jVpmNKsafZCAKxWPEONoj5tSvp0q+kzqGHwV10CeZriweNYd+6FuLDqYs+MhQXDOme+9BLI1dOq0tm/OiUd6RWQLwOAe/DXrKxFk5Im9fJq1MqrUqOgxsWjilz5lTpX3tbk7ElZbgYJYLqcP4rz+c1YGh+3xkFnBv9rJJOnrZF82h7H75viWUm2YTnKjDk3LWbsNBjSl2XCRA2xtS5DZ9RY8nBmysGBfmNLBsxs6Ta0p13Xmg5De1qNrOm3deGmwJ2W/83eeQdVmabp++zub3dnprftNmft3D0dzYrkfAiHnNPJCQ455xxEREEQMKKC5BzMWURREBUD5pw7TZ7Znb1+fyBsOzM9O1PVW7M7xV11V53v+97DOf8c6qr7eZ/n9XBjh7k1e7xD6fYKpEHky+nAEC5EhtOnlXNWo6Jfq2ZQHcI5ZThnZGEMaEM56ONPu6MLRwOknNXqOC6RczRASn9gMANBIZzV6uhVqDmlDOS4IpBDYiXH5NqxETBndBFcikmiPySKc2ExnA2O5KhMww5LCbWiEA7KkzkemEaPLoXe0FQOKqNpdFVTaamgzSOeHk0px5RF7LIPZYuVikobHb0RFRzWbaDeK4ddXvnkGUUS+6mS+EUhJCwJo8g+myS9UEI/V1AuK2F7aCVRVrHE2iQgWSAj2iiaRKNY1B9I0L7nT/Dn/pR5ZVOr3UCxWyaeM20JeMsZzWf+hC/XolukIGSJGt1iFerPxPjOscNtmiWOUyxwmGyOzRumOEwVYjfJGuMfG2I/3ZFIoxh2xW5iT1EBZ6oLGa4u48LGNbQGq+nPy6RvVTZf7WnmFyf38qyvi+t9zdw9M5KmjQLg6B7AUfi73rmTax0jZ/7e3lPzvQB4rbt2zDf21HPvUCv3D7f9twA4evbv9f2N3DlYz6PjLTw53cnN3haunWzi3tlObp1o4sHhRm5u30B/VjLbLMwpWriYCkMT1i8zoWSZBRX6IrYYebDZwJPNxm5sMnZgk7Et2ywt2WFjSZW1M/X2PnR5a9irjuZASCL9uWv5WXc39xtreNS9g1+ebuYXp+vorUglw9YGnzk/xe619/GctgL7f12Gy7+ZETDDAfFMEeJZNgTMMMRv2gp8p440gEhnG6N+2xKfKSvwnrwc5XxzFPPMkM0xIWCGAX7TVuI5eSUO/2aA60RTUld6U+kRzL6QBAaT4xlICud8ciQD8RH0xUTRF5fC2cR0LuZlc3VNPjeKCrm6Jo8LuekjA8X/lwDgeBPIuMY1rh9KEwQCAVXGwrERKO3WznQIXei2c6fNyolmc9FY80Sd0ci6bqEzR+3dOGbjwjFLO05a2nDWXsR5Nxeuij25qfDjYZSCJykqHmcoeLEmmC/Xh/NiYzTPNkbzuCKSJy9Hvzwvi+Sr0ki+Ko3mRVkcX5bF8GJDNC+KQ3leqONRlpoHKWruxCq4rJZwxtebQ3YOVC61YdMCW4o/Mh6bA7h1iZAtSyzZvsKaKn3bkVE2JnbUGdtR94ez/sxFYyD43T2BrZaOtFuMDHp+ZdyLuePYEXCjY2GaDG1oNLKmxcqOej076hbaU/mhkCo9ES2uHjBQz3+e28TzQ5n8rreQ3x4t5NYOFZxaDUOlXK2Q83R7OL/cnsRJd3POudvSYyekS2hJm8iOnhA1PWoxF4KVdDna0W4v5LRMzjFfMV0OLpwM0HJGFkaLlTtNFu7sFvlyyMWFHm9vzkokXNQGMxQUSp8yiAFtKIO6KI7LgjgmDeR8WDyHfeXsdfdnj5sfR/2V9MqDOOqv5Ix6ZO2FkBgGdSMjZY74KTjkI+OEVEW/UsdQUCiXgkK5FBhGvzKMEwE67mdtpC8klypbFbU+gbQqwulWJ7EvMJNDQauoc46n2SOFelE8bS5JHJHkcNAvlSbnGDbYhrDVK5md/hl0hWxgu08W2UYa0leqiPjYi+D3XUlYJCNpiYqIT9SEfawlwzCJndoq1ngWkWyfRYWmkgjjOCL1olB/qEA214+UFTHkCpNZ65pD6GIV/u+6k2AWSZJFNCnCeKJMwnCd70iwQRDJDkk4zbJD85478vdtsXjjXSynfIzVlOUY/Nge4x+7Y/xjT0QzLIg39+VJcyU/qy/m+aYMehODORqr43R2FmfyC7lXU8eT7i6eHdzD8yN7uXuwidv7/rjcO5r6jSZ/o+nfaAI4uufvux7uqhlLAEebQG7ubeLavhau72vjxv52bh5s59ahNm4dGtn79/BkOzcP1XNtfw03DtYyfLyb++dO8GjwGMP7qnl0rJ5f97byqyO1XCzJYKeHA9XOzpQZWlG0xJiSJSZsXmnNFn0hm/SEbDWwY4eJI5WGjmxaYU/5Uhu26jtSZerBegM/tjuHsC84nb5VmZxak8iFTUk821fMzaZVcGo3P9vdwv6EFGIWWuE/eQW+b+rj8doyvF5fgXSaKYqZFkinmaKcZYlipgXiKcZIp5kinzHSEKKcaYJihjGKWYbI5hoQMNsAzftC1O/b4fyGIe6TLBH92Az7H5niNdmGQqGCJnkYPXEpXMvOZyg1h4GYDM5EJXEqNob+jGAGcsI4vzqdi2syubQ2m8vrcri8LodLa7O5tDabi2syuVCQMfb8QkHGn/Rgftqf9EBeyl/sszlJf7GPpESPA+C4xjWuv1oTBAIBu0xtabV0pM3KiXZrZ9qtnemydaPV0pGml92zo26xcKDTypFDNs4cFTr/WQB8nKzkUbqc5wU6XhSH8bwiiqcVUT8IAO5YbseWRfZjAFjysQmbF1n9TQCwxsic2uU2NC5xpOoTezZ+Yc42cys4UclvTpfy6761/L6viBed6XB2Hb/ak8jXXTH8+4EcnlSGcS1HyuMYBbeVPvTYCTnm7kK/Vs39gmxOBcoYjtJxJyGGXqk/+93cGVAH0a8KpEvk9bJc70Sb0JtDbjJO+vhwRizmnFw+Ami6MM4FhnFWHUyfKoTzYfGcDYqi1dGLfR4jR8b1SLUc9pVz2FfO+eBozmrCOK0M5pRCxymFjtPKkfceF6s5KdfQr9SNNJNog7moCeFmdBr96mj2eIdSY6dgp42Sk9okzgSnckyRxBFVBsfUeTS6pbDRMpSdogT2qIvZoyumTpzBDq9kGpT5ZBupiPjElfCP3dC+44DfFDNU8xyQzxYhny1C+5Y72rfcifxMS6p+HJnmqaRapFDoVkhVaA0pNulkO+RS4r2eTKt0ip3WUCXfQqnHasKXaihyz6NSVY7iU3/c5zrg8ZYz7m87YzPVkjTHFPJ9V+H3gRcek0Q4TDBDNNUAl9lmCKcZYPAjPSzfMMf/Iw8OZpVxu6qWR7UVHIsPo0stp1WlpC8rg2/b2vims4PHTXXcbavmbsdObnVt5/qezVzfvWUM/kZTv5vd1WPXt3bv4kZXFdc6dowkgXtGEr4/9F8LgPePd/LkdBePT3XyoKeN+ydaeNjXxcNT3Tw83clvLhzmq+Pt7AqWUeblyGpLcwoNrSg3dWazkQeVJr5sMnBho74zG5aLKFlqx2ZDV7abebHTwosaoR+NIil7vIM5GBDBhdRVXMjJ5+raVTzYVcTz9jJ+tn8L99tLYHA/lUo1/vM/x3PS53i+sRz/SYb4TTTAe4Ievm/qjw1ylk03QzXbCsVMCwImGyGZaoJsuhnSKSZIpugjmaKPbIY+0jn6+M/SR/G2BYp3hHhMMcN7mg1ek22RznUi8hNvavyjOBgRT19SEueTk7mYlEFfbCqnYpLojY+lPyeCwVXRfwR/4wA4rnGN6+9VEwQCATVmdq/AX7u1M502rmMA2PCdDtpmcxEdlg4csHbksJXjnwXAR0mKkfEmq4N4XhTKs/IR8PshAHDnCvtXAHD9T43ZtNDybwaA9Xp2tOm5Ub/QhfLPTCk3MIYTlfCgld/1F/PNwSx+c2QNX7XH8Ks9idCbx887U7hZquTmKgV3wwIYFrtx2tGefok/lyPCuJaZxJX4cC6FabiTEMNQSCAH3D04q9RyRqGh0WLklJZmSze6RQEc81JxRixmQCbjvFLJUGAIl3RhDAaFM6AN5Yw6lD5tBCfkOlocPDnsKx+BOlkgJyQaeqRazgdHj6xThXBaGUyvPIgeqZYTEg19qhDOaIIZ1IRyMTBkLAEcDk/iRICOFicVtfZK6hyDOCmPZUCdwEl5KifkGRxT5FHtEM82+ziqPTJpVBaxQ5zHWucY1jpGkW8VSuhHLqjm2xD0rjPatx2Rz7ZDNc8JzXw3tG+5o5nvgWa+BxELtWRbpVLonE+x51p2aiop9VtPjGEUadYppFokEbE0hALHPAodc9B8KmFjQBF1wZWs916NxzxHvN5yRrdMjc8HHjjOtiPfO481AQX4/9QHh59YY/uaBaLJlrjMssF5jhUO043QLnKh1D+G21W13K3axvH0aCrcXdjm5ceZnFU8qKri2+5WnrbW8ai1ipvNm7nWVM6VllKudpZwrWvjK40eo8nfnb21Y/sBr3XsYLh9O1dat3F9d80Y5H3Xfy0A3j7cyu0jjdw8VM+Ng3XcOFjL/WMtfHmqm2/O7OVy7SYO5KdT5uPNOnsRBea2bLT0YpuVH5uNvNlhFsAWY28q9F0pXe5I8RJ7tpp6UC30p8FBSqenloOSCPqCUxmISOdybgZ3y/L5clcJX7WW8c3ujXyzdxNf7d/F1/tbCVtshtk/zsXltcUoZzsQMMlkDAIDJhshn2GOcpYl8hnmqOdYo5hpgf8kw7EU0P9NA/wnriBgkt4YAMrmm6B61wrVe7b4zLDCe5oNvtPsCXzHhZTFfnRpEjgRl8TZpETOJcZzPimd03Gp9MYl05sUT39+LINrEhgqzOLyuhyuFOVypSh3DP7GAXBc4xrX35smCAQC6ixEdAhdXgHADqHL2JiUUXBqNLWj2VxEu4WIfZYiDlk6cNTC9nsB8GGinIdpMp7mB/JsXQhPyyJ4XBbxgwBglZ6IrYtFrwDgxgUWfxMAbDCzpsnAgS5DL1qXe1H+mSklK/Th5A74ci8vDmfx6xOroX8jj+pD+P3hDBhYy5fNcTypDONhkY6rancu+TpxydeL6yFB3IyP5Wx0CA9zUxkMknNBp+F6dDgn/AM47ifhgLs3dab2tFi50S3y44Crgh5fLYMKBYMKBeeVypGELjCEc4EjENivDWe/j5xu9wAO+CrolQdxXKzmuFhNnyqEc0GRY+nfGfUIMJ5S6DjsK+eAl4QLITGcD4lkSBfJJV0YV4LDuaKLYEAVTpejPx1ugezxi6bTJ4bj/hEMKOI4o07nlDqHE6rVbLOJodI5je3uWaxzSCLFNJjQFRKi9RUkLJcR8bEXUZ/6EPWpHyEfeKF92xXNfDeC3/Ml6B1vVHPdCXrHh1TzWHJEaaxyzGBjQDE1QduIXxlKlmUCGeZxaD6VIPvIlxz7VGINw5D/1JeWyF1sEhcTsSIQxaf+6JYoSbVJwPt9dxxn27FOXEiB/2p8P/TC7icW2L5uhemPjLF4zQi3OTbEmHixPSieS1squbtjEyfS49nh70Wpqzv12lDuVVXzdUc7T9predC8g3ttlQw3lnKlfj1D9cVcbd3AtfaK/yrvviz9Xu/c+UoieK1jB1fbKrncsvUHBcAR8KvjztEm7h1v5sWxTh7vbuJa3Q4OZGfQHBFFtTiQYitXikyc2WblxzZzH0qXOVCx0oXylS6U6jlRvExE0TIhlZYe1Nj7s1ccxDFNBGcjkhhOzeN6Rh6XV8XzeFsuv2wp5VlTEd/s3syvDlXDUC+DG8vxmLEQ+598jucbxni9bknAJNOxY9xGy7+jyd93AXA0BfR7Qx+/N5cTMEkP+UwD5PMM0X5gjfYDGzQf2BMwxxavqUICZtgT+oEruSsDOBiaRF9SEgPJ8ZxLiuNcYiKnYlPoiUuhNzmBgTXxXChKHoO/q8V5YwA4VJg1DoDjGte4/u40QSAQ0GDpSKeN6xgEtlk5je3/Gx2VMgpMTWb2tJrZsdvMlgPm9n8WAB8kyLifIuHJKi1P1wbzZEM4jzaE/yAAuEvfkcqljqz/qQnrPjCg+CMjyj83+5sAYLuNAw0r7enQ96BlmSelHxtRuGgpNyqT+M3pUr49sQrObeDXhwvg9Bp+vTeJF+2R/MfBXH7ZlMzdNRqexql4pJNyNcCXIbWCobAQBuMjuBgdzM24MK6EB3MxWEuvRMp+Ny8aLIR02nty0E3GHscADnuo6ZeHc1Gt5rxSyYBMRr9czYBSy1l1MKfkI2XeDhdfdnuI6VEE0yPVclys5oREwymFjrOaMAYCI+hThXDET8EBLwkHvCT0yoM4qwnjckQCF0KjOK8NY1AdxAWNjgvqYE4GaKkzd2a3Vwh9Ibkc12ZzQpdAb3Asbd6h1LmHssslinz9QJK/kBL7qQLd+/4EfSghfkUYmSYxFFjFkbhYSfJSNZr5bkimOyCf5Yx0hhOqOZ7IZriine9H+vIYWmJr2SBbR65rOpsD1lLmlkv0QgWa9zzxmWaD0yRzHKdbEaKnJsEqihz7FMKWqAlboibJLIo0YTyR+jrknwVg+GM9LCeaUq7eQLpLGjbTjBG+/hkm//IF1hMs8Xnbg0zbSIa2VHJjZzk3K1ezJ1RFi0TOkYgMrlRs5OrOTdxv2c7d1m3cbqvgTvtGhhtKuFJfxtX6TVxp2MH1piZutDS+sudvtNT7XQ+3b/8vd1Uz3FXzJ/3XAOCdI23cO97CnaNNDHVt5+iONTREJrHOUU6agSudQXkcjiimxTeJJq9YquzU7LLxo9bek50WQqqEdmyysGeXsxcNHv60+Yk5HhpMX2w4V7LjuZaXwK01SdwvTuZBSTIPKzJ4UVXA86pCvmzZyG8ONvC8rZoCDw/83/8c0YSfIplnhmSmJfKZtognmyKZaoJipgXKWZaoZluNWTNXiHKWJX4TDcYSQr839PGfuALJFH0080wJfN8C1bsWyOabIX/bGvX7rojnOBL2kQ+FJmp2uYYykJTGYFo855LDuZgazZmEGHrikzmemEJPegoD69MZKstieP0qrpXkc60kfxwAxzWucf1da4JAIKDRyokuWzc6bVz/LACOJoItprZ0m9qw38zuLwbAJ4U6HpeG/Y8BYNGHhn9TAKxdbkPLchcaF7tR/KE+q79YxNFsKb85XQq3q3ixN41n7an8en8qTxtC+Lorhv84mMvNUiU38uT8PCOM5+Eqzjg7cNzDlV65lCtp8RyV+/IkM5FHaUn0q+Uc9/PnoIcPTVa27HPx57CHgk47Hw65qxhURTGk0TCoUNAvlXJGquSsXM1ZdTBH/WR0u/iw10vKEbGGwwHqkaYOiWYsCTwh0XAxNJYz6lD2uPnR7uBBl7M3g7oorsWkMBQWxzldOAOqYM7K1SOAKdfSJwumydqddlctJwMz6QnK5URYMod1UWy28WediTfrjCWkfBFAyDuuBL/lRfiHMhKXhFHquJqtnkWkrQxBPd8Z9XxnfCdZEzDVHu1bnkinu6Cc7YFshjvhH6ooss5hs6qMHPcMspxS2Oi3hkyTSNRvu+M50RLRjw3wmSPC+20nIo2D2SBbh+pzMZL3PMm0TmCDXyGhyzWov5Dg/a4bev+8FOEUCzZqy0mwi8fwtYWY/uRtlgvewedtL5LM42iK3syD5kYulOfTnSCh2teF3apgbuRv596uam40bOF+ZyVP9u3genMRF6tXc6mukCt1FQzX7+B6Qx03mrq42dL+SvI3CnxX2yrHPAp/1zp2/GAAeOvQCPxd6NjG7vIsSqIl5Nr6kGcqpcQ2iH0hJewLLOJIYBG7JRnUOgRSaeFKlbUj20wM2GpiRJ2rC3uVSo6FhNAXG8mNVencL8rmztok7q5L5G5RHA9KY3lQGsPDigye71jLVzWl/P5QE/9+pJ2zRatwm/sWDtPexmvmErxnrMDjjeXIZwkRTzFGMtVkDP7Uc6zHAFA7zwblLEt839R/BQADJukhnWpA4Fvm6D60QjrPGL+ZBkjmWRD4kQfyt1yJWyBhk0MEHeJYLqVlMpQez2ByKBdSol4BwOMZKQyUZnCxInsM/sYBcFzjGtffu0ZKwFaOtNu60m7rSqvQmVahM81Wjq+8brQQUW9mR5OlA00WdnSa27xMAYWcsnegz8GBATdnrsp9uBEo4V6U/I8SwD8HgF+XRPP1hji+KY3h25Jovl0XyldrdGODoB/EKBlWSTnn60uPgwvbVtqzYbmI/E+MWf2xIWs+NWbDYktKF5iwcYkZ25ZZslPPmlojW+qM7ag1tKbOSEj9d0BwdBRMraH1GAQ2mtrRaiai1cSeZiNbmgxtaDaypc1URKeFEx3mI3A4CoitprZ0WtrTYWpHi4EddXrWbF5gTPnnK9lirs/D9Skw0Mx/HF3F73qz+bYtEo7mwKEcftEQB/sK+F1DGjdXqbmbq+OMzosjYgeOy1y4mxTG/ZQoTiv8uJ+cyJ34JJosHdjrFECThQuH3OWc8FNzRh7IhaAQroZHcU4TxIA6iEFNOBe0cfQrItnjKKHTzo99zmLOyHWcFMvpVwVyMkDLaUkofdIwegN09AboOKeOoF8TxgFPfw56BXBSquasOogzMjUXxCqGNSHcDInlSnA8g+poTssiOSaOpM42gHqRjB5NMr3adLaJEikVJpGwQE7w+56o5zujmOeE5gMP0o1D2ei3mgzraHzfccRvvh0BM61QzLVBOc8W8XRLvKda4DnZDNl8FzymCXGdbE2FbyF1gduocM9hi1cuGz2yiVggQTLPAZ9Z9vjMccTxTUuk7/uy1q2AGl0V0o/ESD/xJ8EykhTLMNa4JuE0SQ/PaSZ4z7bA8jV9rCdaUqGrIdgijUyvdTjMMUP9hQsH4wu5tm4b90q3cDQ0nA65gmaZjP6CYq5squar/ce429XIna5qbnXs5HprJZcbNjFUV8GFmjIuN2xiuHkr11q2cb21kuutI5B3pXUbl1u2cqV12yvwd6V129izyy1bud62nRvtO7jdVT0Gjlc7tjPcvZOre6sZ3reL4YO13DjSwK3DTTw40smltp0Md1Xz8GQbt483cW1/DUcr1rIjOoJkUxGBH+iTvMSRzZ4xbPSMo8wjhvqgfPYnVdAevoo9kTkcj8/jWHAExwK1XIoN5WJsIFdzwrlREM39wngerU3kyZoEHhfE82RdEg8LE3hQnMS98lTuVqTxtK2Au015fLmngsubSil09kI8fwGeE5fi9cZK/N40ImCiIeJJRkim6KOea4ZmnjmBb1kS+JYl6rlmqOaYjlk52wTZDEOk0w2QTNPDd9piAmYuQzpHD+VbxqjeNkH1lhmSWcaIZxohnmGGdKY1662DafUP5qBKx/mENM4npXIuIZm++DgOh+noS47mfFYSlwvSub4+l2sleQwVZ/xJXy7JYqg4gwvr0riwLo2LRelcXJsx1jAyCoqD+Wl/FgzPrUplIC+F/tzkMYA7typ17Lo/N/nlmjQGctP/yGezUzmbnUpfZjJ9mcmczkjiYPz4UXDjGte4/nr9IAA4chawA/2uTmMAeDdS9jcBwA0LTdm01PwvBsBGU7ux7ubRppfvA8DR5K/VxJ5WE3vaTEW0m9vTaWlHp5ktbUZ21K8UsmWhCRsXGFCw8HN6o2RwaDu/P7qGXx7L5EVzOBzNhkPZ/KolEfav4df1Kfx8WzJ3coJ4lBvJ5Vgl+7xtuJ8Swa+L8+iReHE5LITrUbHUmdpywHVkEPRRLxW94kAGNaFcCgnnWmQM/Sotp6RK+mRBnJVHcNRLzV4nKbsdxBx0k9EnC6JXouCsXMNpsZazklDOSEM5EaDjuH8QJ2ThHJKE0OGlZo+//kxCyAAAIABJREFUjmOBCQzE5nI+OoshVThnpUGcDtBwXh3N5bBkrsfkcFqTRIuLmma3YE4EZnFAlU7aYjEpS9QEveuO/3Qb/KfbEPG5mDSjENY7p7PaPhHlhx7YvLYSz6nmuE7QRzHXBsVcG3wnm+I91QK/Gdb4zbTHeaI53jNF7FSWs0u9mQr3HNY7JJNpHDICfzOESN5ywW+eM3b/ZkqhSx6N4XWU+ZXg+5YH6oVyMu0SiDMMJnSJBLN//gK7CSvwmmuD8E1jLN40JcezEMnSIFb5FhCu58Z2VQK3NlZzo6Scc5mZVHs5URfgxb4oHfdqdvK4rYWfHz/Knc46bndWcaNtO8PNW7ncsIlL9Ru5WFvOlcbNYwA46kvNWxhq2szFxk0MNW3mUvOWMeAb9SgI/qUAeP1wPbcON/Cit5Pr3Tu5f6iBr87sYbirmp5tJWS4eRBtZkeWlZjYJe7EL/akzC2Wcvc4St2i2KlIpSt2Hbtjc+nNLGSoYB3DuUlcy4rkcUE4D/JDebAujgfFSTwqSuLxuiQerY7jwaoYnpWm8aw8g4dladzdlM79ymy+2l3BLw5V8avDDZR4eeE69R1sfjQP9zeW4DlBD783jRBPMkA6xQj5dEOC3rYas3a+BYpZxshnGn2PDZDMXoFs7sjeP9kcIySzjPCZoofPZH38pxnhP80E9Vu27PJNYq86mp6QKC4mZXA+KZWB+CT64uM4FhnK2dRYLuakcGVNBtfX5zK8Pvd/DQD256bSn5P2Rx4HwHGN6/++4gUCwRmBQPBzgUDwTCAQtAoEgg//YM2PBAJBqUAg+FIgEPxCIBA0CQSC6X+wZp5AIOgSCAS/evl3VgsEgv/3V3yPHwQAT9rac1okot/ViSsyb65rxX8zACxfbM7mZRZULreiaqXwvwXAsdTv5RicFguH7wXA+pVWNOhb02xkS6uJPe1mDnRYiOiysqfL3I52Y3saDWypXGLB5kUm5H/xOc0+jvxs11o4VsovjuTys+4EXjSG8rPWGDiUz6+bUvhmVzy/rcvhbkEoL4qSeJgXQ2+gN1djtPxyfR7ndQqO+/ty3E9MvZkdexz92ePozzFvNb3iQPqVOga1Oi4EhXA+MJh+VSCnpYEccJXRYevNPmcZB1wVHPFUcloayCmpktMSBX1iNeekOs5IQ+nxC+SwTyAHAsLo8NLS7B1ChzSWPdpUuoMy2K1MpFcWQY84mB5xMBcD4xmOyORW/GpOaZNpc9fR4BHJfnUeTQHJBL3nhOYdN6SzRUjmiAj8wJMcs0iKRClkGocRMMcer2lW+MwQ4jfDGo8JBmjeFqGcZ4vHBAO8ppgjnm2L20QLnCeao/rAh9rALVT4rKXUOYNVFpFELRDjOdUSz6mWSN92xX26LYGfSNib3EFdyC7ijWJQfSIlfHkgmdYJ6BbIcZ9li8VrKxBNMcVmognWk82xnyEkcGUg5lOtiDTRslMazLnCDdwqL+dUSiKdQTJq5W7sjlIwsDaNZ921PNvXzNOD7dxqr+Zm+w6Gm7dypXHzGAAO1VW8AoDDzVsZbt7KhYaNnK+vYLCunPP1FVxo2MjFxk1jQPjdZPD7APD6nhH4u7a/hqsHarh2qI6bB2t5cGQXX/Y08vXJdvp3ltKQEkeJQoHLnI9RfWFBlXoVpW5JpBtpWWcfznqnSNY5hlLmFUm9LpPdcen0Zudyee1q7qxN4G5hCM+LNTwq1PB4fSwPil/C39pEHhTEcX91LI9LU3lUns7t0iTu78zlRUsxP9+3C84d43l7HZ4z38Np4gd4TV2C2+t6eLyuj9+bRkgmGyKbZoBypiGKWYYoZ5uMpX0jSZ8+ytkmyGcajaV/shmGL7t+9UYAcK4x0llmSGaa4vb6crwnGRAw3Rj/6fqEfGRPhzaLY2FJnI1OZCg5k8HEFM7GJnA6LpaemAgG0uO5lJfG1cJMrhXncLU4538NAJ7NSRmDvT/lcQAc17j+72qPQCCQCASCTwQCwReCEYi7KxAIXvvOmjKBQHBPIBCYCQSCxQKBoFcgEPR85/k/CQSCiwKBYL9AIFggEAhsBALBc4FAkPNXfI8fBAB7bOzotbPjjLMDlySeXNMEcDtc8jcBwM3LrdmmZ80OPSHV+jbUGtmO+AdIABv0rWk0ENJibDdWEu6ycqRbaEO3pR1d5iJajB2pXmHHjuU2lKwwpMrRnttFWTDYwpe7V/OiMx7OrYNz63m4K4zf782DI0XcL4vkSVk8d/IjebY+lV9tWU1fcAC3kyP45bo89rg4sXX5So56yzjsoeCs/OVpHqpwhnSRnA8MZkAdyKWQcC6HRtIr1rDL0J4mC1cOuik54avjlDiYkwFqzig0HPcRc8JHwWn/EQA87h/EIS8Vez1VtLlKOaKMoleXyAldEs2eaqodpGww8WWDkSdbTL045BXMgDaeq5HZ9AWl0+EbRdaKANJXKgj73I+YFWpCFojRfe5PnJ6GVJNQElZokMwRoXrHFfXbroin2+A1wRTfiWZE/NSTwHcdEc+wwOlHy3B70xjf6VYo33EndrmWYpcctoiLSTQIJ+RjX4I+cEc2T4TzG8a4TTJD9YEXVaoKGoN3kGIWR7xRDGtc8sm0TmazdyE+sxzQFyxlseBzMkTZJFinovcTIxb94yKkC/yJMdMSb6mlNbyA56UlPFhXSKdSQl2AF+06BZcqCrlRVcatpq3c21vD46PN3Nlfx7XWSoabt3KxtpwLNWVcqt84BoLfTf+uNm3hSuNmBuvKOVdbxkDNBs7VljFYV07/rlIGajYwWFfOpeYtXG2r5FrHju8FwJv7ari2v2YMAK8eqOH6vhoeHWzgdMVadugC0Xy8nPBF5qSbeKF8x5LgzxzZrlzFds1qSgLSKHIJZrNPNFv8Y9ngFUy1JoGDKbkcS8vgwupcbq1J4k5BBM+LQni8JogHhdHcWx3L/YI4HqyJ53FxMo9LU/l652qeVOdzd3s2vztVAwNNPGxuoMJfjdfsT/CesQKn15fh8ONleE4wx/sNMwImmSCdqo98hh7KWSuQzzRAMcsY7XyLV9JA3TvWKGYZI566Et+Jy/CbtBy/SUvxm74E8Ux9ZHNMUc4VoZzriN8UK+Sz7VDMtSboA3NyzLzpDkngbGIGFxLTGYxPpS86jlORMfTFx9GfksBQbirDBVlcW5fNteIcrhRl/68BwDPZyZzJSvkjjwPguMb196epgpEfsNHL6zcEAsHvBAKB23fWfPRyzYqX1zYCgeD3gldTQY1AIPhWIBD8y1/4uT8IAJ4Q2r4CgMNqf26Fif8mALhlhZDKlUJ2rrT5iwDwr9kDOFoCbjMV0WHuSJel8xgA7rayp9vCgTZTZ2pWiqjSE1Gub0m5mSmHwlTQ18y3e0v41aHsEQA8VcCLplg4uhb2F3C1UMvDDbE8Xp/Is9I0vqnI4WpSMJciNTxKj2efmws79I044iXltCSE05IQegN09CvDuBIaw6WQ8Jfpn5Y+uZrDnhLahJ4ccJVxyF3FKXEYfdJQevxVnFFoOOzlx2FPGSd8AzktGUkAj3gqOegu4ZC3lMGgcK5ExDEclcBQaCT9wfFUu0VTbOhD3udCthu5sNdDwxlVHD2aZNr9Yold4EXEggBUn/qhWyQjeImUKD01sXoaopcpCfnYF9/pQrTvuhP2kQ+yGXaIJ1mhnm1PwkIx0llWuL2uNwaA3lMtCPtMQqZ5NBs88smyikf7sRjpXAeUbzkin++A51RLxHNFpJtGslNZzgbPAnQLVGRYp7JTU0meTRr51kk4vGaC8McmOM9wZG3ABpRLQ1n4zytZ9P8Wk+mSyhb1Kprjyrla1sTt9FQGIiNoCfBlt1bN6axUnrTU8ri9njttNdzaXcuzni5u7KlluGXbCNhVlzJYXToGgH9Y/h2FwtH0bxT+ztdXcKZqPWerSxio2TAGgNc7d34vAN7aX/tHAHhtby2X6reT5+aB8tOlhH5iQZ65hE2ucUR+5kLIx47UhRfSmljG5qB0it2CqBRHU6VMoNwnlJ2qOA4k5XMiPZ8L+YXcWJXJrdxkvixK4llhPE/XjyR/DwsTeLQ2kaclqTwtS+fnDcV83VzMk6a1/O5sPV8e28au0Chk7+lhIJiO/G1r7H60BOt/WIrPRCF+k6wRTzZFOlUf2fQVyGcsQzXHEPVcs7E9gJp55qjnmqGdb4F0ugH+k1fgN2k5AVP0kEzTw3/GUiSzDJDNNkcxZ6RbXDzNDsUcB5TzhMQssqPURUFXSAz9SSMA2B+TRG9ENCfDo+iLj2MwPZnLq9K5tiab60U5/+sAsC8raQzyvutxABzXuP7+9J5g5Af86ctrs5fXb/7BursCgSD85esMgUAw+AfP3375voXf8zn/Khj5JzHq2YIfCABP2trS5yRiSOzxNwXArXo2VK4UUqVvyy4DW2oMbf4sANYZCakxsBq7V29s870A2GYqGin7mjuOpH+WznRZiegW2rDH2u4lADpSq+9EtZ4TW03tyVu0mApbczhSze+ObYPBMr7eE8fjxjA4VcR/Hsjny4ZELq1WcW99FD/flsvzDencWx3Hk4JkBnRSzgXK2OPiRI2JOd0OnvQrIjjiqeSwh4KTAVouh0QzFBzGoFZHT4CUgx4+7Hb04pC7gtOSUA65qzgtCeesPJwefxVnlVoOefqy313GEe9AeqX/BYCHPfy5GhzJjbAwhoODuaRRck7sT69YQ6s8l1a/ZJrcwthq6ETJQnPWfWJIq6uGnSIN6ndtUXzgjuynfvi844z6c1/iDIMIX6Yg6FNfgj70IujDkfl+4qlClDPsifnIj8TPxCQukuA9yQj7f174CgBGfCEjyyKGtY6ZBH8hw3uWI5I5ItTvOKN93w3xXBG6j33Y4r+WFJNIYpbrSDaNZYPvenYF7STfLoOgD/xweM0UxfsBJJgksMa/DKOJ9nwgWMiK11dSHVPJ7vTt9K5r4u6WdnqVKvZ6+9AeEMCxmDiG16/nFwf38fWBPdztbObm7kae9uxlqHXHyH69xs2cqyrhXFUJl+o3jqV93y3/jpaGLzRsfAUALzRs5PSOIs5Urad/V+lfDIDXD9SOAeCV/bu4treeprRkbCfNRU/wb8QvcmK9TQibHOJIWyFBPNuELco09uduoSNrAwUuUrYGhFKljKPEU8sWSQTdMTkcTy3gfN56hrNyuZGVxovCHJ4VpPFteQ7PS9J4UpQ84g1pPK3I4OdN6/mmtYSnrcX84lQ1l5vzUX6+BPfpCxBN+Ay/mRa4vWmK6+vm+E22w3+SLZIpZmMAKJu+FNUcw1caPiTT9BFPXYlytgkBU/TwnbiMgCl6yGaMlIsls1cgnW2MfI4VspkOSGc4IZ4mGoHBOUJSVjpT6R9Cd2g0ZxPTOZ+QxpmoBHrCIukJi6QvPo7zGSlcyc/gemEON4pzxwFwXOMa199E/ygQCDoFAsGJ79zzEQgEv/0Ta/sEAsGql683CgSCvX/w/CeCkX8ENt/zWWkvn7/iOitHOuzcXnGr0JkWa6cxN1s50mLpSKuZiDYzO7osbOm2tGOPpZDd5uYctLWm11nEBV9Xrkq9eRAm5XG8jMcpUr5arePrdWG8WB/Os5JwnmwI52npyOsX68P5ujicr4sj/yQAPslU8zhZzYMYJdc1cgb9/OhxcGGnniMbFzux+j1jVr2rz5oPjSlfJKRsoRUbl1qzebkNW/Vs2GEoosrInloj21cgr85ISK2h9dgJJ6PjYJrM7Gk2tabF5I/dZGRJs7EVraZC2s1Hun87rW3pEAnpsLWm09KOLlMHug1c6dB3o9bAjrLl+qxZ9gVXKxLgdCU/7yvh3wcr+P1AOb/pyuO3zTn8fHsid3PU3MvV8JudWXxbnc29ijjubUhhMDKELpEb1YYWNJjbcjk0ktMyFQPqIHolco76+HNOE8SgVscpiZouByktVp502vlxRhbJaUk4J32DOOkbRI9PIMc9VRx1V3DIXUWHi5JD4kgOemnY7yKh10/FZXUIV9XB3A6L5W5kErejUjinjeGUMp78pR6EzzUmbI4JhUZKCoyUZC6TkLhYStJyBbFLlUQtVBD6hZwE/UBSTUJJNwsnZrmKoE99kb3rguRtJ3zn2OE+zZLAT3woECWRaxmN3yxbXCYY4/qGCS4TjBHPtif0Ez9WWcYQ/lkA6+yTkcwR4T3VCu+Jpri/ZoD/VEsCpgmJ/UJKtmkUoZ9K0f1UTJZ5IgWiHDLMk1C874PTdAs0i6WUKTfQnNyJ96dKlvyrEYYTLFjjm05PYTPHs0s4nrWGxsAQaiVy2nUhnN9QzO3anTzqrufB/jruHajjzoFd3Nq7jVvdW7jVMTK25WprFUONlVxs2MZQYyWXmrYzWLuZC/Vbx+5dqN/KxbotnN9ZwkBlEee2FzNUV8HFugqGmjZzrraMvpoSLrRsZrh7J9f27uJmRw23O+q5s6eZW/saubGnnqudVVzp3M5w62au1Jdxeec66sLEFIisiF9qRtzn1oS9b458uj7JC93Z5BhNpUc8a4UaEle6sMFdS3tkFjXaNDb6xrExIIG6kELK/ZOpC8zmUPJ6TqWvpT8lnstZMTwviePp2mge5sfx9cYcnlak8WhLEs8a0nhYmwTHtvGfh3Zwe2M+aQuXETL3A/zfXIDn64tw+8kXeL+xBN+Jy8YsmaaPZp75GOxp51sgn2mEcrbJWNl3NAGUzzRCNccU+Uwj/CYtx3/yCsRTl6GYtRDFvJXI5xjhM9UUn5kWBMyyQTZLSOA7QjZYK2jxj6I3MoNTEan0x2ZwKjqZIyFRHA4O51x6KhfzMrhcmMFwUTbDJVkMl2YwXJLF5e/xpfWZXCxKH4O/S+szubg2g6HCrD/yXzse5kJBBudXp78CiIP5GQyuyuRcXgYDuemvNICcyUrhVHoip9ITOZ2RxJHkuHEAHNe4/o+qTCAQ3BEIBHO+c+9/CgD/ZALYIHSmS+Txijvt3emwc6Pd1vV7AbDLwpbdFtZjAHjSyZ7zPi5ckXjxIEzKozjpGAB+tTaUF+vDebo+jKdlETzbEMHz0gi+LIngm/URfLM+6q8CwB0rHMYAMP89g/8WAGsM/yv5azCxHYPAUegbvd9gYvu9ANhsbEWLiTVtZjZ0WNjRZSWiSyiiw96aDhubkWYQM0e6jFzoMHSlWk9I2RI91ixZwN4IP541FPD7C9vgSiW/Hyjnt/sL4HApv2/J43qukpu5Kr7elsI3VVk83prMw7I0hpOi2e3kRoOFkN1ObgxHxNArUdCvCuSsUktPgIx+VSB9cjVHvSV0O3jT7eDNftcATkt1nJbq6BWPjHzp8ddwxEfJYW8FBz0VHPYJ5LhfKAddpRx1l3FOqmM4MJLz8hAuamMZ1CbQp05kn38E7V4RrFnhTfhcY5QTlxL2ljWR79sT+YETaStUJCyVEbVIRsxiFbHLg8gwjyDTIpL4lVpCvghA8b4b/vNEeM6wxn2aJa5TzEk2CmaDZw6hn/lj92M9XN8wwWuKJa5vmCCd60DUAinFDqko33ahSJSCeLY9jq8ZEDDNCt+JZijnjqQ+MZ9LiFogR/O+D5K5riSujCDHOo0E/SjcZjoinGlJkmsqu9ccpGPVfgzesGLJP+sjnGZDW+w2Llfso1YeR4MignpZMF3hYfStyuVB0y4edzXycG8jd/bXcWd/Hbf31XBz9w5udlZys30b1zqqGG6r5lLTdi41bedy8w4uN+/gQv3WMRi81LR9DAD7t63jzJZC+retY6iugqH6kSaQwbpyztSWcrF1C8PdOxneU/1y3l891/c2cX1/I9f2NXB9dw3D7du5Xl/BlW3rOL8hh2qpG6uMDUhaYEiunjOrDbyJ/siemE8dSV/ux1aPRHb4J5G8wo0cM2+qJNHsjlvDTmUKGwNiqQ1ezVZ5Jpv8YjmQWMSp9CLOpSVxOSuO5yXxPF4Xza3cSL6pXMXTzWk82JTIz1rX8MuuYn67t5KrpVls83bGVvATnP9pMn4TF+E1YTHury3A582l+E9egf/kFUim6Y/BnnymEYpZxmPAp51vQfC7QoLfFaKeazaWBCpmGSOdboDPm0tfJoHLkc1YjGy2HtJZBiMAOMMK+Vv2aN9xIOJjJ7Y6BdIpi6M3MoNjofGcjEzmeFgcB3URHA6NYDAjjaHVWVxam8nV4hyulmZxtTSDq6UjoPd9HgfAcY1rXD+kSgQCwX3BSOn2u/qfKgH/ocb2AP5hArjb0YsukcdYGths5Ujzyw7ZNjM72k2taTe1psPEnC5TU/YLLelxtGPQ25nLYk/uhYh5GCvhYZKYF6sC+bIwhGdFoTwpDh0r/b7YMFL+/bYkkm+/pwT8fQBYucyeikWOFH5oRsEHRhR+ZELpF5bfC4DV+iMl4O9C4OjZxs3mojEorDe2+V4AbDUV0moqpMPCjk5Le3YLHdktdKDbxp5uoR3d1g7sthxpDum0cKHG0I5dRtZUmQgpXLSYNm9PuFDHz46v4Zujq2FoJ/9+qIhvWrN4viuVR1vjuFcezYvt6fyibhVfbc3mUmwQu51FnAjwo0+u4KIulJ4AGT0BMgZUofSKAznmreaAq5QOOw/2Obtz3EfMKbGCXrGKk7JAjit0HJeHckQewgFJKPsCgtnnp+OAdzAHXDSc8g9nSBPHlaBE+iWRHPXS0iZSUytUsMNaxU7HSHa5xLBFqGWLTRCbhToKjZTkrZSSvUJG6IfuqN9xJPQzfxKWB5JmEoXmp17I33PFc4Y1blMtcJ9micd0KxzfNEb6jjNRSxWUe+dR7JqB+2RzHP7NALc3TXF70xTRj1cim+dI0gotJU7p+EyzZq1dEpI5IlwmGBP0rivK2SPnvEpm2KKe74zdv67EY7IQ5wkWrBKmUeJeSMzyMFb+00o+/8kKCoIraM7fQ4ZvPvazbcl0SGK9Vxa7FHk0KHPJNfWlVKRkb3QG16rLeNpVw9NDzdzdV8ftfbVc27uL63uquda9i+ttO7nZsoPrTZVcadrOUGMlg7WbOVezicHazZyv2/IK/I0+P1+ziVMVRfSWr+PM5hIu1VVyuWEHFxu2M1i7lf66LVxqq+ZqZy2XO2u52l3Pla46LrRXc751OxeaK7nYuIVbrdt50VnNV807+KZ+K3fW5TIYF0ujvQ9pb+uxZoEd2xxCKLRQkqrnT9wyH7JMFRTZB1FooSTP2I/u2DwaQ1PZKo9mqyKJSlUqOdYymnQZHIpdRX9yGhdS43myNpnHRQk82pLMVzWr+La+kH/v2Ai7a/lFww4KLISIZ76H04/moJhvhP8sQ3wmLcf7jSV4vr6IgCl6Yx28ilnGKGYZv1LW1b1jjWqO6dieP9UcUwKm6I0lfqMdwT5vLsVv0nLEU1einWuKer4FyrmWSGeLULzjguY9V8I/diN1hQ91fmHs1cRyWBfFvqBw9gVG0q0NZbcujMPRMQyuymZoXS6XS3K4uiGPy2XZDJVlMFSa+b0l4HEAHNe4xvVD6R8EI/D3UCAQvP8nno82gbh+596Hgj/dBDLtO2tUgpEmkH/9C7/H9wLgf5cAtplYjdjIlE4TE/ZZW3DCwZZzXk5cCvDgbnAAD2LEPEgM4HmelhdrgnlWFMrjohCeV0TxojyKL8ui+HpDFD8rjeJnpTF/FQBuW2pH+UIH1n5kTuFHJqz9qSkln1t8LwBWrbQaA8DRxO+7Zd+/JAFsNRW+kv7tFjqyx8ZpZP+ftYhuawe6rR3osnahy9qFRhMRjebONJg5UfTJCnYa2/GbA2V8fSSf35/ZAOe38fXuPB7UJ/GLrgK+bsji3uY4vqrO4tfNa7hfHMsJtRedjtYMhQRyViWjT67gpFjOaZmKIV0sZ2RhHPfRcsRTwz5HMYfd/OjxVXIqQMNJSTAn5CEcloZzSBzJfkkEXf6RdPpF0e4TSZdHFB1OoZyWJXNBl8U5dQq9/pH0+kdxwCuC3Z6RdHvHsVeWzQFFPtVO4VTah7DRKnCsBLzGJBDt246o33EkfrmaDOMI0kyiUH3ogfgtRxzfNEY0wRD71w2w+YkezpNMUX3oQbZVNFsC1pBtFY3bJDPcJ5uPAaDz60Yo3nImcbmGIlEK8vlO5FvF4jHJHOfXjVDPdyRgiiXSmTb4TrZENc8Jh58Y4vqmJS5vWFLiuppy72IiFusw/BdDDKbZUBa5k81Ru0iwTyTDNp7W6O00h29klY2OVUINBQ5qNvpF0rumgvudlTzau+v/s/eWwXEeaNqu69S3OxQ7tmVmSmKHDTKImakltVotarWYmS2WZVvMzMzMkplZkmV2GOyYQzM7sLPX+dFWTzLJ7Dn5are2dld31V3V6vft37rqgfvhk/EWPhxt4t5YM3dGmrk33CyryvU0c7+zkXsdDdzsqOF6ezXXmsu52lTGteZyJlsqmOmokft6e7XsWUM5lyqKuFheyJWqEm61NXC7s4mZjgam2+q41lbLrb5W7gy0c3OgjQ/6Wrnf08zNdlkFcbqtipttlXIAfNpdx7O2Sj4tTOd2Qjwn7DwpfV+ftDc0SNpuRqGRL82uB4lXkxK+U0S6jhe5er7k6LjT4hlJV3Ac7UEJVEgjqfWIJ8PUgya3WMZDDnItLoUbSXE8yU/mSXESX9TG8efxEjjRACc7+Kggi+Oh4bivfhtHhbexefU9hItVsVqiLsvkW6iI7YKdSJYqycFvdsljtqrnulKNwNeMcFuljvtqDXnlz1Fhr7xyOBsBM7sEIl2ugu96Pbw2GOCx1kgWLv6aLb5brYl4T8RBdQm9rqEc8YtkwjeAEZ8gBr2D6Pf0YyQwhJPRMcxkp3EzP41bJYe5XZrGrbKDXC9NZqZYBnk/5zkAnNOc5vQfpeJ58+Z9PW/ePPV58+at+IF/84N3SubJKn6a82QxMOdeelazMTBj82RRMvrzZFmAvzgG5udawP9fM4B9Gnr0quvSq6ohB8DTpoZcE5lzw1H9u/A3AAAgAElEQVTIp/5OfB7uJAfAJ5l+PMoN4GFeAE/Lw3lWFs7z0nC+Lgnnu+JwviuO/EUAWL3LiNLtZuRu05EDYME72v8QABv26cpn/mahr0vL5BfNAPZpGcpn/4b1zRg1tGDCUMConhmjemaM6ZszbGjOoKGAQUMrunUs6dIW0KZmQdUOPRp2m3IhzYOnRw/B/WZ+fzqX747n8GwsjW9HsvimP40nTUl8353Jn3tyuBotoddKi15jTT6LjeSKh5TjtmLOSVy54OzJjG8EF50DOSny5YSND0ctPTgrcuOs2Itz9r6cdw7njDScM+5xnHRL4JhbIiMuSQxLkxmQpNBrl0CH1X5OuBzknOchTkliueAczQXHSC66xHHRJYHTzrEMWIfQbRFCjZEvpToe5Ku5cGCXPQnbbYl9T0zgG0JC3rEjTT+STMNYkjTD8dpmi2SDORaLNDBfqI7Zq2ro/3oPwmW6uGy2JNM0llppLtFK3lgt0sR6sRaWC9SxXaKLwwpDvLYIidzpRpJqAF5bhCQo+2H6GyVECjoEbxPjtsoY19XGOCzRw2eTNTaLdREu1sdGwZBiYRYF1ln4vu2O0UIjbLY5UxveTo5zISnmiQxGNnAkvoWBkHLC94qJVnOg1G0/dUGpzDT18OlIDfeGKrg3WsO98Qbujjdxa6SB28Mt3Bls5m53C/c6mrjX1sitl7N/ky0V8grgbBVw1pMtFVyqL+ZSTTFXq8q4UlnKtepybrc3cbuzmZn2RqZb65lsr+dWXxt3Bjq40d/G/fYGPmqp525LLXfbarjfWc8n/U180t/A05EWHvXU8bCtnPsl6dw+kMikeyid6jaUvG/M/q16HFJ1olQYRa5lJIf0/cjR9ydXx5cSwyCKbTzoCY1jLCGDSpco6r0SKbMPo14azXjIQWaS07ibmsJ3Zdl8W5vBo9Zk/nqykj+OlPGgPot6GxtSdqohWfgO0qX7sF+siuFvlDF+VQs7BVnFTvzqLqTLVeQZf97rdeSXPmZbwP6bDeQAODsb6LxMGUeFvTgt2SfPAZyFP7dV6vis1cdznSFuqw1xXWuO12u2BL0jJlbRkSw9D0b9ojkZHMOErx8jPkH0ewbQ6+XHSHAoZ+LjuV2Yzc2iDG6VpnGrNI0b5QeZLktmuiRFvuTx954DwDnNaU7/UfrJIsZLO//gndkg6Ofz5s37/bx587rnySDxh1o/b9684XmyIOgn8+bNy5z3fxEE3akvYNRUxKipSH4TeNDQigEDS/lt4F5dc3p1zenUNqJLy4hODVO61E3oUjehW0WPQS0jjhmbcUVsyYzUhk9DJHwR48YX8e48Sg/gSW4oT0qjeFwezcPSSL4qjeRxSSRPiiN5XvTSZTG8KIvieWkkzwuDeZYbwOPDvjxM8uHzGE/u+rgyKXHkjMBaPgOY+ZqGfAawZLs+he9qU7pTl4rdBlTvM6RGyYjafUY0KRvSrmZKh7oZnRrmdKib0a5mSqeG+U/crWEsj3z5oQe0zf8W/6IrYETfijE9K8b1BBwzFHDcyJJjxmaMGxkyZmjAsIExPbqGtKvr07jXgLrdBtRqaXEhzBsmWng2ls/nA6l8fSyDP42k8l17HH/tzoKxSr7tLKBZYkyftRbXvey46ePCaTsRE5ZihoxFnHb04rTEl2N2HozYSDjm5MJ5V1/O2Ptw2tGXC9IQrnjs55Q0jGPSCE667ueoayydNoF02gRz1DOdAcdM+hzz6BJnUW+eSolODJWGcQy7FdLjlEaHfTKN1tGkKdmR+K4NB95ypVg9gqzd/sS+LeXgXj/S1EM4qBNGik4oWdZJHDaPJWivO7YrjLBfZoJ4iRG2CobYLNLHaoEOlvO18d/qRJ1DPvmmKbitF2L+G1VMf70Hs3/ehed6UxL2uOO+1hiPdSa4rDLAZZUBrqsN8Vxvis8mC5J3e5K6x5eD+/w5rBbKYbVQUtXDcd1gg/drThRYZxGnFUuQYiBWqwTEG8aRKcog3iCWCpcS+iLbaQusoyeijjB1Ryo8EjmRW8nJ4ipuNDfzcLCOR+PNfDhQxa3eMm4PVPDhRD0fjNZyb7CKe12l3Gsv5oO2Uu63VXOvtYbbTZXcaqzgTnMVd1uq+ay3hTvNVVyvLWGquoiZulJuNJYz1VzOtcZSJpvKuNlRw73eRu72NHCnu14Gk21Vcn/W28aX3W087O3gYW8bX/W182igjeejnTwbbeXxUBNf9lZztzGfDyrzuR4fz5iFhA41K+p2WVGyU0jGLhuafQ4ynlJLtlUg1Y77qbAMJF3LjhxDKUNhmXQGHKIvPJsatygavKPoCY7ncloGdwqy+aalkr90VkFXEReD/ak2sCL6dS2cFNSQLNNGtGQPtkt3I162B8clmjgt0Ue8QBGHxTuRLt+L93oNfDZo4r1eg6DX9fHfrIPbKmVcVuzDbZUy3uu1cF+t9qMt4Nm2r+2CnfK27+x3TsuUka7VQrJaC+c1uvhusSDwDXMi3zEjW0dCk10Ao/7BTAQH0O0uod/Tj24XP4Z9AzkZE8HVQwlMZ8dxoziBmRKZp0uSmC5JYab4wD9sAf+c/xEs/pxncpKZzIhnJiuFG9kHmMlKkUPfv+e/3xqevSl8OXU/lw7EcOlAzNwt4DnNaU7/V/pPB8DP49z+xwPghL7ljwBwwtiIcSNDOQB2aBjQtM+Q+j2GlCkrM+Yi5kVzAX85X8v3Z4r5/bl8vhtM4tuOOOjPg7FyXrTl0OpsxBlPIR+EuHHTx41zDg4cEzowYirmhJ0nR0TuDFk40W1qw7DQgeP27pxz9OOsUyAXXUK55B7JMccgJpyCGRIF0iXwokPgS58omDHneI64HOaYazbHPHIZckqjyyaJTnEqraJEagTRlBqFkKHpQfR7lkS8KSD1XXey9wVxaIc3STs9OaQUQKpqIFmGMaQZRXPIJIZ47WA83rVHsl6A6zprXNdZ47xagMNyU6xf1UW4UI+AbRLKhRlk6sfhsVGE1XxNrBao4rBEi6CtNsTscEayXBfJcl2cV+jhvEIP6Up93Nca47XBjARFDw7s9SZVOYDD6mEcUgslWSWE8B1eRCn6km+VToxqBCGKAXi954HrO1IKHPOI0opgv1YkZdJ8WgKrKXfNotw9hTO5LVyubOZSVT0f9HTyRV81XwzVcbenjJmuYm72lXF/rJb7IzXcHajkTkcxd9uKuN9awu2mcm43Vcp9q7GCW40V3G2p5mZDOTN1pczUlcqet1Rxrb6Ea/UlTDaUcqu9hnvdDdxsq+ZGaxU326q53VHLnc467nU38EVPGw962nnY28FXfe1yAHwx1sXXEx08H2vj8VADH7eX8nlDCbdSkzlm606fjoj6nVaU7rQie6cN+5VsyRNHUOEcS9QeIVHbzYndbUHkdmNyzbwZisylKzid7tBDNPnG0BUYy/nUNG7mZPFFeR6PyrO4leRHjb4uCdt247V0J+IF+xAtUEaksBfbpbuxXbobxyWaOCrovGzXKiJdvhfPtWp4r9fAe70Gfpu08V6vgdsqZdxWKeO5Vg3/zXp4rtWQ3/+dDX52etlGlmX/Kb+8AqKKZLkqzmu0cVqljWS1Dj6bTQnaaka8ohWFRq60OYXIAbDL1ZkBL3/63AMZDwzlbHwMU+nJ3CpIngPAOc1pTv/r9YsBsFvXhG5tYzrUTehUM6ZD1YhOJR0GNA05YmjCJZEF152FfBLsxGdRLnwW68pXaf48yg7mUXEEX5VG/o8DwCMGVhw3suSEsRXHTcw5YmLMhLERo0amDBia0qtrSquKCY37jCl4dzflKipc3B8IN/rgdif/OlPDs+FEvh9KhuEcGMjjm+ZDTCb5cH+/L3cD3Dhja8NJkT3HhVLGzSUctfGk31RCt6E9/RaOTNi5c8rZn3PSYC64hnLRLYyTDgEMW7kzZOlGv7mUfnNXTjqHcsEzhgvukZxzDOCiUwBHRJ5MiL047R7OueADdDqGUGkVRKq6lIC3LfHaZkP4dhdi35YStMmGoE02pO71I0HRi/C3nEjXiSDXJI5EzSDCd7vj+7Y9rhuscFlrJa8CihYbIFpsgHSNJeHve5CoHEzou26EvuuGxwZrvLdYEfqWrJ3svtYY4XxlnJbp4LBEC3sFTewVNHFapoPzCj1sFqkiXqKB00o9JKuNcFihj9WrGhj/SgmRgh6JqiH4vOGI20YR7lsciFYKJkEnFt8d3iQZJ9AYWk9zRC3FnmlMZNZyobSR4QOpnC/M5fO+Vu63lHOjsZir9flcaSpkqqOMWwO13Oytlp1tayrmRkMRt+pLuFKew2RVoRwAp2uKuVZZwNWKfK7XlnCzQQaId5qruNNcxXRdCdN1JVyvL+V6fSnTdSXcbKrgdksV9zvq+Ky/lS+HOng40sWDvo6X8NfJo/4OHg908mSog2cjHXxzpJNvj3bxzZF2ngw38qKvnicVudwOCuWsyIXO3RbU7jCn9H0BQZt1sV2uSK4ggA6fw1RYh3FYU0KKih1+2wwYiylhKLqI3rAsesIO0xuczOnENKYzsjgTHca4jytHPRwo2KdF5Po9uL26G7v5mjgs1sVm8T5sFHYjWrIH+8WqOCzWfglysiqf60olPNao4rNBU14J9Fyrhtc6dXw2aBKwRR/v9X9bAHFZoSqfH5xdApndHHZfrYHLKg0cluvgsFwbp5W6+L1uTOT7lpSYe9IqCWXYL5qxgFDGAoPokLrQ4+ZLv0cQJyNiuJgcz0xWKh+UHZ4DwDnNaU7/6/WLAbBHz/RHANiuYkjHPm36NQyYMDDmksiCaYk1Hwc58lmUC5/ud+HhYT85AD4sifgfB4BHDa05YWzFSRNrTphacNTUhCMmxowZmzFkbM6AgQXtamY0KZlQ/r4KFXtVORcRyL9d7eT3V2r5w/VqvjlxmH+ZOASD6fxrXzrftx/iq9IE7kR4M+Uu4aRQyGlbJ1mWn60fw+YudOk70Klnz6jQk5MSP865hXLWOYTzLmGck8ry/UatXOk1tGPcyo3z0kAmvSO56hnOtFck5x38OG/vS6uWOR36Ao46enE+OJYxjwga7cLJ0PEg7B0R/m9KiNrpTejrdrgtN8ZzlRlR70oJ3maPzyZr0rTDyTOOI1HFn4gdrgS8aY/nZhukayzlbV+bRfpI11jitVlM9C4fgt92wWOjiPh9gUS870b4+xJC3rTFeYUe9gqa2CxQwW2NEfYKmtgt1sBusQYOS7RwWqaD3XIN7Fdp4bRWF6e1+tit1MF6oTrGv9qL5QJ1Yvf6ErDViZC3XUhSCSV8uw+BO3yx22hLiGowBR555Linke99iK6UPAYPZTNyIJGLRel80FzOncYypmoLuVJbwNXmEibby5npqeF6VxVTbeVM1RcxVV3A9eoCLpXmcLUin1uNFXIAnKwqZLqmmBv1ZdxsKOdWYwUzdaVyILxRX8b12hImqwq5VlnAhx31fNzVyGe9LTwc6pT7Qd8s/HXxeKBTDoCPBlp4PtbG1xMdfD3RJgPA/lpe1Ofz6f5IJp096N9rTutOM2p3WpGywwqP9aoE7xDQ5HaARmky6dquFJkFEPq+gHrXZMbjKmn0SmYgMpehiAzOJWcxnZ7N8bBgBlycGHayo0TFmOgNajj+aheW/6SKeIEewkVK2CjsxkZhN/YKytgvlmX7ea5Vw321Cq4rlXBfrYLXOnUCtujiv1lHDoIya+G9XguvddoywHsJgKL5O/4BAGphv1Qfp5UGSFbpEbDVhPi91tTb+9PnHclESBwjfsGM+AXTLnGjSyoDwFOR+7mQFMdUejL3Sg7OAeCc5jSn//X6xQDYq29Gj44JHeomdKga0aZsQMc+bfrU9ZkwMOaijTlTTlZ8FOjAp5FSPomR8uCQL19lBfFVUfj/SAA8ZiTkpIk1p0yFnDQTcMzMlKOmJoybmDNiKmDY2IpODQualU2pU9SlcrcmF0KD+NfLHTw6U8rXk+X8y6U8/nwynb8OHORf+9L4c+dhXlQkMR3owiUne87bOXLZ2YuLTkFccY6k19CJNm0xnXoOTNj6ccLJn1OSYE44BnPSKYhj9v6MC905KnJn0FjMKbEnM97hzHiFcEXqyzWXYC47h3HeMUx2PUXNmGGxKye8Qxh0DqRO4Ee2misx74gJes2JiLc88N5ohdMyA1xWmeC5XoDbGjPc1piRqRNBrkEMCXu8CXvbCd/NQoLeluDzmr18BtBhuSlem8UEbJMQu8cf9w02OCw3JVM/jsNaEaSo+RO8TYRwvjKiV1URvaqK+1pjeQXQbrEG9gqaOC7VxnG9Hg4bdLBfr414tRailRoIl6gjWqKB9UJ1Qt+REPSGA0l7/amyTMfvNSlxqtFItjjhtsOdA/YpZHoeJsMzia7UbMYyc5iqzONuTR53qnO5XV/OVG0xU41lskWOjmqmOquZbKvkalMZV6sLuVqRz2R5PpfLcrlWWcCN+jJuNVbI4W728yz4TVUXMVVdxJ2GCm7UlDBdWch0ZSEz1cV80dPCg742Hg918XSkhyfD3Xw18EP46+bJYBdPBrt4OtzJw74mno7IIPD5WAuPhxp43lfN84ZsvkiO5LanB+PKFvQpCmjbLSLlbTPC3zTEfpUSXm/oc0DblQNqzuQY+BC23ZpUXS96Q4uoc09iIDKPkcgcLhzIYyothxNhYYx6etAntqVgjwlR67SQ/k4F29/q4LDICOtXlREuVkS4WBG7xUrYLZJt+85W+txXq7w89aZG4Gt6BL6mh98mbXw3ar18RwOPNery9u9s5p/tgp3YL9qNZKmSPELGdaUa0hXaOCwzwXmVCS5rjQh5x4RUdTFtLkEMB8RwNCyOIZ9ghnyCaXfyokvqy6BXCGdj4rmQFMe1w4ncKTowB4BzmtOc/tfrFwNgn4E5vbqmdKib0K5iSKuSPu17tehV02Nc34gLQjMmHS35MMCeTyKc+SRGypcHfXiYGcjDwjAeFIf/jwTAU6ZCTpvZcMrcUg6AE6YWjFtYM2ZmQ4+2FS0qZrTvNqXkLWVOePrCR6f4drKFJ1fL+NN0IX86nwljaTCSwR/bkpmKduK4nRlHBeZckbhx0cmLCQs3TtkEcMI2mHGrAI6JQjjrEslJpxAmbP0YFfkwKvRmUODOuJUb55z9+SQikfv+Ucy4y6583PUK4KKdD0fFcRxxTKNUyYFyNRHdlp7U69tSrmVJ3m4hWdvtyHhHQvImF6LXS3DbIMB9oyVeW4RY/FYF6wUauK41J/wdCVHvStn/rgtRb0kI3GRD5HZ3IrZ7EvimM16bxTivFiBcqEf4+x4kqYRgq2CI5XxtauxyqbPPodQqmZgdzogXqeO4VBvrV5QQzldGslwXx6XaOCzRwmGJFo5LtZG+ZojdZm2s16piorAb80W7sVFQwfyVPYgWqlBlnUyzXQYdklwyVSPI1Ign6F1fvN7xpMyznMHcQarjyhkp6eRKaztnKkr4qLmELztK+KQhjzsNVdxoqOR+TzP3+lu52dPIldZKLjeVc7GuhIvl+VwqzeNKSR7TNcVyz9SVcrelmvtttdxqrGCquoirFflcrcjnRn0ZdxsruV6Wz7WibK4WZvFhYxVf9bTyoKuZx33tvBju4fdHhvh+YpBvRvt41N/Fo/4ungz2yOBvqJtnI108GWrjxXj7jyqAzwaqeFCTwlcHwvjA153TauYcUbJmVNWB7PcEhL2mi81SRRzXquOzzZgGxyT277QlYoeIgHetSNX3ozs4nzb/NAbDsjmfks+FpDTORsdxISKGESc3wpbvwON3u/FRMMDuFSP05+3BaoES1ot2IVy8E/GiPdgtUnu57aspBz3PtWq4rlSSzwP6b9YhYIsuga/pEbBFH+lyJfmM3+ztX/tFu39+CWSpBpIVlrivt8JjoxlROy3IMZLQ5RnMaHA0R8Ki6PcMoN8jiHYnH4Z9IjgeGsfkgcNcO5TCVHoyd4tT5wBwTnOa0/96LZg3bx5dRiJGzBwYNrVn0FjMgJEtXTqWDBjZMmRiR5+BDZ3aAto0zGjVMqVVy5RmVRMa9xlSt1uPNmUDutSNGNQ15oKtNVNSW+74Sbgf5coHsR58kRrIo4wQnuRF8DQ/kqdFkbIcwLJwnpaH87wygueVkTwtieJZSQTPSyP5piSMZ7kBfHXQmweJ3nwe48l9P3emnJ04I7CmWcWSsh3mHNqgzKGN+8h8XY2Cd7SpUDSiep8xtcqm1KmYyKxkTJv63+CvS9OCbi3BP/Y/AMAedWN6NUzo1zJjUMeCYT1LGQQaCThqJuSYuQ3HLUQcM7fhqJmQCRMrRg0tGDEwZ0DHmC41XZpUjMh7X5kLIcFwrZu/Xqvlr3cr+NOdPP5yI4d/O54Jfen8S1kCJy0N6dfTY8xEwBWJO9dcvTnr4MoJG2fGrSUcsXXjtMSX09IAxkRu9Js60qVtR4+uA+MWnhwXenNJGsSMbwTXfcKZ9g5h0suPSS8/pjz9GDOzZczIjuodRlRuN6VB2YlqdV9St9kSscmKxO1SsjWCiFN0JfANIY6rdHFYqYN4mSbCxWrYLdNFstoI6VoLQt6VErXTG9/XHQh6y4XgHVL2q3iTrB2Ez1t2WC3Rxm2LDUHvu7FfKQjTV3RwWC3kkF4iZY4FVHkVEmsUhP0WE0wX7MNxlTYem4yRrNDAcaUajivVsF2hhOXyPbKW8EJtxIu0sV6shcUiDUzm70W8WgevLcY0CWMYcz3IoDiWuPXaJG2zot4xk0OmcZT5FDOa205NeAqT1XV80VnD5x2VTNeXc62pjqnWZm531XG/p5GPe5v5qKeJDzrrudNcxUxdKdfK8riQl86lgkxmykqYqahksrSKqZp6rre1cK2jiQsttUx1N3G2qoiThdmcyc/gVkURH9WUc6s4i3sV+XxSV8rTrkaeD7bx9Ugn34x28fV4Ny8munk+3sXT0Q6e9rfwrK+F5/2tvBho4+vBdr4Z6uC7kS6+He7km6EOvh5s58VAG9/2t/K4pYQHaUl8HhnGjEDMSS1jBvbpkf2+FlGvq+Cweh92q1SxXaVNrlEApYJQktSkxClLyDD0ZzC0gIHQbBokUVxOyuVKbCpXo+I4FxjFmFs0EZs1cVuqiMPCXVi9shvhQhVsFNQRLVHHfokakiXKL+/47ka6fO/LLV8NuT3Xqskh0GeDJr4btfDfrIfrSlm8y2wOoMMPgqQdFfbiulJNHh3jvFQN+8UaOC3VwGOdDpmaEqqF3hwNjudYSDxHg2IYdAumTxrAgEcAQ75+TIQFcfWgLFblekYqt/PSuJ2Xyu38FG7lJXMrL4mbuYkyF6RwuyhV7psF/044dH7yy9//vG/kJHIjJ5HrWfFcz0x86f//8TDTGUk/ioiZvR185WCsHP4upkRzNCZ4DgDnNKc5/WLJcgD1hXLw6zOwoc/ARg6Ag8ZievWFdGoLaNc0lwNgi5opTUpG1O/R/y8BwEYlC8p2mJO2SVVeAcx7S5PyXYY/AcB6ZZP/VAA8aibkhMCWk5ZiTlqKOW4h4riF6EcAOKhrQre6Hi1qJhTsUOWMny9cbOMvV6r5690q/ng7nz9NZcOpfP7adZjH6SEcMzdgQFePUWMLLjm6ctnZg9N2Uo4LJRyzdeW4vSdnnP045ezPqI0rfSYOdGnbMWjkzGlxIBecQrjmHsakh8xTXsFccfPlgrMnp+yknHX04riNOwXv6ZP+hjZZ71qQ/p49UZsE+K0zI17RlXStIALfFuH9ugCHlTpyALRRUJcDoMs6AaHvuRC/L5Cgt6T4b5UQpujGfhVvEjT88X5TjNUSbVw3Cwl414X9SkEY/Eody0XGpGjFUuZYQJ1vJdl2hwnc44H5QnWEizSwVXhZ9VuphdMqbUTLVbBYshfn1UY4LNZF8Ioyxr9VxHTBPqwVlAl6X0i8shNdjokMOifRbhFK4iY9yrS9GA2toVSSSU1QOSM57TTvz+RGQwuftlXyWXsFN5urmWppYKq1mXu9jXzY18wnfS182N3I/Y46bjaUM11TzNXSXM7npnExP4PpkiKulZZypaicyeo6ZlqamWxv5HJzLZcaKzhVnMXx7EOcykrlekke9yqKuV+Rz0c1xXzeWMHznmZeDLX/CAC/PtLD8/Euno118nSglWcDrTwfbJO9N9zB18MdfDfWzbejXXwz0snXwx28GGrn28E2nrSV8SAzhS+iwpkRiDmhaUTfHh05ANqt3IPtCmXEK7SIU7QjW8eTJGUJ0XvsSdF0Zzi8iJHIfFpcY7mclMuluFSuxSZyLiiaTpEfwetUcFuqiPOSvYgXy86wiZZo/AQAXVcqybd8fTdqySuBXuvU8V6vIf/Of7OOfAt4dgHEeZkyTkv24bRkH+JXdyFZqiSfAXRZoYqTggoOCppIlmnitUGPXD0pDXb+HAtJ4HhoAseCoxl0C6RP6segZyBjgUEciwzl6sFkJg/LIPBG9sGfAOCsZ69+zN7/vZGfLM//+0k24BwAzmlOc/pvrAXz5s2jRUcgB78+Axt69YV061rRqy+kz8CGbl0rOQC268jcqm5Gs7IxDXsN/ksAsG6PqfwSSO6bWuS9pU32VjVKd+hTtdeIWmVT6lVNaVAzo1HV7BcBYK+WKX2a/9iDOhYM6QoYNbBm1MCaEwJbTlnZyf33FcBRQwuG9c3o0zKkVcWYWiVdjkid4VIHzDTz1xuV/PF6Hn+8lAPHy3hSFMspBwtGtQ0Z0DVgyMCUE1ZiTgjtOWptz4TAXnbT195TlgModKHfwpFeYzHjAmdOiDy4JA1i0iOcyy7BXHMP5apbCJekgZy28+KkrQdjIjdGnYNoF/kSuGY39q+8hePCHbiu0sVpuTbSDcakaPmTpOOP5Qo1nDYZYLdcC4eVOtiv0MZ2qSb2y/VwWmWI40oT/Lc5kKYTQ5JKCIFvSgl4z4kwRReStYMI3eWKw1oTbJYZ4PG6HcmakRj+WgPt/0cFrzekxN2gqZ8AACAASURBVKhGcViQTmdkDxXSCny2ueK12QGvjfY4LTXFdrEBwld1ESzQxGyhJjr/tAPT3+1DsFAJ8/nbES1RZL+iOeNhmUwEH6ZO4EOemi25Kjb0iMO4nVrJRxXjdEeUUe6Xy2BmC6dLO/mkZ4h7dcV80FjCJ/1N3OltZaarkU9HOvhsuIOPe5u5217LzaYKrpTncak0hwsFGZzNPsS5nMNcLszhfHE+F0qLuVFfx93WRu621HKnoYrLxdlczj3MZG4a1wvS+aSqiC9ry3jQXMWDlmq+aqvlWXcTT/tbeD7UzovhDlm8y5Gev1UBh9t5NtLB89FOXox1yZ6Pd/P9sX6+O9rHt0d6+Waih6/Hu/l2vItnvdU8LkjjYeJ+rgvtOaZpSJeiJvnbdYjdqo6dwk6Er+7C9lUVbH79HjFvmnNQyZmo920I3GZGX1Aup5Kr6A9O40pqAZcPpHP94GFOBUeRuc8UzyU78Fi+B681GjivlG3h2i7VRLxME4el6kiXqb4MflaRV/p8N2r9yP6bdQh+w4DgNwwIel0fv026eKz524k4R4W98pbvD6+IzD5zXLwP6QptPNfrEvq2GdXWvvT7RHEqIpGTEXEcD41kyMOPQXdfxv1DObs/hvOJsVw9mMzlA/FcSonj6qEEbmQnczM3iZu5MvC7nZ/M7R/A3+2i1B9B4HROwk88k5soh7wfeg4A5zSnOf13kOwUnK4VA0a2cg8ai+nWtaJHz5oePWu6dCzlJ806dC1o1zGnTcOcFhVZG/i/AgDr95pRtsOc3G065L2lTf7bOmRvVaNkux6VewypUTKRXQFRN6dJzfw/BAD7tczo1zJjSFfAsJ4lY4ZCxgyFHDG1llf9jluIOGom++6HADhqaMGAjjHNe3VpUzdkwtERrvXBvW7+baqSP08V8q+XivhLby53EwMYMjFgTNOYIT0Thg3NOGIu5IhAFgQ9IbDniI2UCZErY0Ip/RaO9Jk7MGDmwGl7D07beXHG3psLEn9OiT2Z9orkimsI5xz9OCHy4JTYi7MuYQy5RNBmH4r/RnVsX3kf8fxdSFfoIVmlj/9bYlK1g4lR9cBs6V4cNuhhu1TjB1VALTkA2i7Rx32jNQfUw0nViCByhzeeW0X4v2vPAd0QYpR9cN1ihcVCLVw22XBQdz+ChQbo/7MG4hWWSDY5EqYawWDCCJ0hnRzQjiNNJ448owNEv++F1yZbxAqGmP5WFZMF6mj+n/cxfGU35ov2YrZgG24b9tHjEc3U4WLORh0mV9OaQ4rGlOg4cSO5jC+L6rlf3k1baBa5rsl0pzZwtW6UT3vGuVtbwt26Qj7uq+defyu3+1r5dKSDT4fa+aCrgVstsuiWiyXZXCjO4nx+uhwALxVky8661ZRzr62R+231fFBXwYfVZUxmH2Ym+xC3ctL4oCCTB1XFPKgt/REAPu6o56vuBp4NtvF8qJ3no518faRHDoHPxjp5NtbJ8/EuXkzIqoPfHO3l9ycH+f7EAN+fGOC74/18e6yPb4/28Gywjqfl2Tw6mMhNOwmndE3p3atD8U59kt7WxmHRDoS/3Y74FSVE//QOUa+bkLbPmbgdYny2GNLsnsqZAzWMRGRzNa2Ya2nZTKelM+YXwqFdBngobJcDoOMyDcRLNBAv00K8TBPHZRpIl6m+XNhQ/hEEeq1Tl1cD/TfrELLVkJCthgS9ro/PBm2clux5WTmUXf2YnQGULFWSL4fYL9otmwdcooz7Wm0CXjcmbrcNLU4hjAbFcjJiPyfCozkWEsawpx8jXv6cDI/mYkI8lw8kcvVgMheTYzmfGMOlA7FMZyRwPSuemewEbuQkcDM3UQaCRancKT7I3ZJD3Ck+KAfBnz0RNweAc5rTnP4ba8G8efNo0jKXV/tmIfAn4PfSnXoCOvUEtGta0KoqawP/VwBgq5o1lYqWZL6m8bL9q03Re7oUvadDxW4DOQA2aVjQoiH4RQDYr2MuX/j4e8+2fkcNrBk3smHCWMSIgbkcAk9aijltbc8pKzvGjS0ZMxIwZiRg3NiSYX0zOvbqMqBrRruBPhyrh5td/OViKf82WQEzTVxP8mPQxowRA3OOaYs4amzFmImAMRNLRk2tOGJlxzFrJwbNxIxaOzNiJWHYWspxRx8uuAVx0cWDC86enHV044KzL6MW9pwQeXDcxpNjQg8mBJ6MmbvTZ+pJo3kADVYRxL0txH2ZNpKFGkgW6RL6mph8vUgSd7nivsYQu8V7sVNQxkZBDfsV2jiu0sV+hQ4OK/RxWmWI/XIj7Jcb4brOmrD33IndE4D/u454bhUSstOZ0F2ustNw6wW4bhaRZhCP1WIjBAuNcFgtRLDUGN1XNWgJraPepwyXzZa4rDPF5zVrot53wvs1MxxWaGI6fwfGr+7EZKkqugt2o7/gPVK0bOjyCON+Zh4nQ0PpdXalwcqBcb8Ybh4u51FNLx8X5nGrtIqhpGwqg9KoDM3jeEEnd5uHuFdbya2qfG40F3O3v45PJjq439fE/Z5GbrdWM1VXwpXKfM4XZXK+KJOLhZlcKnjpoiyu1JUy3VbDB+113Kkpls2ZHUjkVmoSn2Qc5MvcDB4WZvKoLJuH5bk8bq/jcUc9TzobeN7TzNP+Fp70t/BssI1nIx1yyPvmaC/Pjvbw7GgPz4/18uJ4H1+f6OfrE/384dwovz87wu/PjvD9mWG+Oz3Ed6cGeDbexNeNxXxTmMknnn5cthRzRMeCamVzsneZIl20C/Gvt+P4O2XcXtlN0AoNItYbcnCvMyFvmJFj4s+xhHJGonOZyqtkuqCYS2mHaHKUkrxdB+mCt5Eu3oHbChXEi1UQLVbDbrk29iu0cVquiesK2abu7Nbv7Oyf1zp1PNao4rVOHd+NWoRsNST4DQP8NmnjulIFR4Xd8srfbAj0bMVvdvbPdsFOnJbsw321Bv6vG5Cw15YCU2+G/OI4GhHPkZBQjoQEMx7ox5ivL8eCgphMSeVqSuLL6l8i5xNjOBsfxeXUOM4nhXPxQDiXD0Zy9XAUk+kxTGXsZzonQX7u7XpuItM5CUxlx/9sC3g6O14Gd3/nOQCc05zm9N9BC+bNm0e9ugldOpY/avv26FnL4a9d01wGf9oCOQB2aAloU5O1gf8rALBdw4bqPdZkbFEn83U18t7SpmS7/k8AsFlT8J8OgKOGFhw1E3LSUswZoQPnbSWct5XIAXDc2JIJEytGDMxlV1P0zKlVU+ZP/cUw2cKfL5TAVCXcbuNsiDMdRjpMmAg5rmPLcVMRE2ZWcgA8am3PcaGEAVNbxoRSxoRSJsQenHMLZto/mvPOrlx28+Kyqw/XPAIZEzgwZGLHqLkzR6zcZPCn70TVPiHpO63IVnEhcosFHgqauCzQwOVVXWLekFBpksD+tx1wXKCK08K9iF/ZjXCxquyf/Wq9HwGg8xpz7JcbYbNIH9/XHYhR9CNM0Q2vbTZ4bhXi+7Y9nltF+LzpgPtrYg7rx2E2XxfLRca4b3FCtFqA6QodhlLa6IqoRrRCG7Pf7cJywR6EC3ZjuWAnFq9sx2LhDswUdqLxyg6Uf/UOxkt20RecxExGMSeDQ+h3ldBkbcWwpz93M0p50TTMJ6WNfJCXyd2KSk5mldEWV0ixfwYDh2q51TDI/boablbmMVmXx53+Gj4/1s2d7nrudtVzs7mSydpiLpXnygHwUlEWlwuzuFKUzeXibC7VFzPVXsW91hpulOVxKSGGyzGRfJx+iMd5GbwozuVFRR7Pqwt4Ul3I084G2fJHTzPfDsjm+p70t8jm/UY65PA3C4B/D3/fnBzgX86P8Ydzo3IQ/P7MMN+fHuTpkWa+aS3j29IcvvAPZkrkxAkDaxpULSnYY4HrIkXsfrUdye9UZNu8r+7FV0GVw0ouhL8pIF3fiyNxpTIAzK9ipqiUC4cPUi2yJ/E9LZx+tw2nV9/DZZkS9kvUEC/RkAOgZIUWritk7dofLnn4btSS5/7NBkLPtn99N2rhvGwf0uUy8LNbqIjdQkV5NdB+0e4fAaBkqRJe67QJ3GrEAVV7yq0DGA2K52hEPONBwYwHBTIW4MuYrzcnQ4OZOXRIDoCXUhI4lxDNuYRorhyM52xCKOeTQ7l4IJxLqeFcS4vmWlo0VzP2cy0zlsmsOK5lxnI1Yz9X0mOYyo7/iecAcE5zmtN/Z8lawHrmDJoIGTQR0mdoSa+BgH4jK/nnHn0LuvXM6dYzp03bTGYNc3kFsEPViC51IwZ0jDhnY8mks4j7/s58Fu3BZ/u9eHAwiAfpwXyZH8bn+WE8LI3kUVkYT8vDeVYWzrflEXxbJouEeVIUxtPicL4pCeNFfpA8BuaL/V7c93PnuoszF4S2NKpZUbLHkkNbNUjfqk7OOzoUbtej8F1tynfqUbvbiMZ9xrSomNGiYkabqgkd6mZ0aVrQp2tNv56QAX2bn28Ba1rSp/HSmoKXlsW/dKoYMGEiW/zo0zKQtWctrTlr78gxaxsGjUw4YWXDVYkLpwRCTlsIOWVuzXEjC47omzK4T8iAii2taibcyYiGK53wUQ/cqISZOkb9LBm2M+eIlYjTpo4cNbdlwsKGcXMhY2bWcg8ZWdChocewsYCbPkFc9/TnipMnl+x9OSP25qSdL8fdImiycCVtnyUZe23IU3Uif48zqa9bkrTRnLC1RsS8YUX8WyKC1pngrqCJdLEmSYpu5OhG4L3eAvEibSx/o4bjUn3sFTRxXW2I8wo9XFcb4rbGCOlKfaQr9XFZZYDDEi1cVxsSvE1EgqIHwW/Y4rfFGt/NQtzXmhO1yxPfrY6k6cWiOm8XlgomiFdZ4bjJAcv1Iqq9qxiO78Hw1+9jvWAn0pVqSJcr4bh8H4b/9CZG8/dgvFAF9f/zPhYLFQnZoc3dzAN8npdKt6WIJj07BqxDuJ9Zz+d1TXzcVMJ0SQifZ8fwQWYRFw5V0B5dRmVsE925gxyrHGE8r4QjBXlc6ahkerCR2yOtTDeVc7u1mms1RVyqyONyZT4Xy3I4X5LFmcJ0Thekca44k8sVOXzcV8ft1mLOHorhTHwY95Lj+Tw1ha/SD/M4L4tHxbk8qizkQXM5D1or+Kqrhid9DTztb+TpYJPsnNtIM49Hmnk02sKj8VYeT7Tx5Eg7Tyc6eXakmxfHevnmRD/fnhzg+9NDfH96iN+fGeYPZ0f4w9kR/nh+jD+fG+O74/1819PINw0lfBwRxDVHMaeNTejbp0vVu5r4L9mB4/wdWM9XxHrhHhyXqSFdpUXk+3akqHggXa1BtW0MZxOruHy4jLsldRxPSGTAP5ywbRpIFu9CulQZp2UqCBcrI16middmc3xeN8V9rTZ+a9QJWK+O9zpZBXC2Ejh79WN29m82C1B2Fk4V+6X7sFuyD/ule3BYvgvpmr24rN2H12YN3NdrI1mhgehVdewWa+G0TI/o7SIKjNxpsvfhfHQkV+JjOBEYwbhXBAPuoYwHR3E6IZ5rOYlczY7jWtZ+Lh6O4HxqOOdTw7lwMIYLB2M4fyCWcyn7OZcSx5mk/ZxN3M+V1ASuHkzk2qEkptJl8DWdkcR0ZhzTmbHM5Mh8IzeO6dx4pnPjmcqJYyonjsnsWCazY5nOjed6XgI3CpK4UZAkeycrjpmcZG5kH/iJfzb+JUPm2b+vpyUyk5bIzMF4Zg7Gcz0llpmUWK4n7+dsdOgcAM5pTnP6xVowb948GrWM6NG3oEffgi5dMzp1TOXw12sgkMNfl67ZzwJgq5I+HaoG9Gsbcs7GkmkXMR8FufJplDufxnjy4GAQDzNCeFAQzhcF4f8hANimbUuFsg1pb2qRvlWdrLe0yHtXW1YB3KVP3R5jmpRMaFU1p1XVXA5/3VoCOQD26wnp07X+if8RAA7qWDCgbU6Phj5tSpqctXHgw6Bw/jW/kDN2DoyYmjMhsOKElQ0TphacEgg5I7DhtIWQE8YCjhmac1RLxBEtMV2aZpwIduZZexbMtMONBrhSTbdUnwGhMSetRZw2EnNB7MxZO2dO2jgwYWFDt7Yh7eq6dGjocdHJjeue/lx18eKSxJ2LTh5ckwRy3NqNTm1rypTMKNhjQtJbeoRvUCd8gya5SlLSdzoSslqPhLdtOajoTPRbQtxX6GA3fx/uK/XJ0QsjWckHx6W62CzUwmq+JqJF2nhtMCP8HXuCt4nw3miOzyYLvDaYYbdYA/EidSTLdXFZZYDLKgO81pnjscYUvy3WeG2wxHmFEe4brUnRCCffPBXP150IUwzAeaMdgqXGaL2qRKi6O/0xdTht0MVysSLWCxWx/J0iZr/dieV8JYx+pYL2P+3F+3VDii28OJ+QxcWYCPol9nRY2nDMI4Tr+zN5VNfJR9WVTJelM1Mex4fZCdzJKeZCVg1dCRXUJ9YxXNDH+bphzpSWcba8gOvdtcwMt3J7pJ27PQ3c6azjWk0RlyvzuVKZz5XyPCbL87leUcjt6hJuV5dwp7KQ6awDzKQlciNpP/eS43mYmcaznCweZKXxeWEWn1bk8WldER93VvBJVyWPumtl8NffyJOBRp6NtvJktIUnoy08Hvsb/D050s6zI108P9rD18f7+PbkAN+dGuT3Z4Z/FgD/eH5M9nyojX/pqOZxSiwf+HoyLbZjRN2Yxp36RK9RxmepCk4KKlj+bifCBbsRLdyL10ZjIt4TE7jNjKA3TejwSOHSoVKuZhQxU1DISHA06eo2eK5SwWedDv6vGWO3XAPhYlWkawxw26CPdKU6vqvVCFivjs96Nfnc3w83f2cBMGCLrjwf0GWF8j8EQLf1Krit00KyQgPhfFVsFqghXqTJAVUJNSJ/ej1DOB8dztmoEI4HhDHhHc6wVzgnomK5cCCJydwkJl8C2uX0KC4einzp/Vw8tJ8LqXEvITCOs8mxnEuK5WJyPBeT47mUksDlA/FcOSjztcPxXDscy1RGrBwGf1QN/MFyyGRWHFPZ8fJZwemcBKazErmencRMVspP/HMAeC09gWvpCUymyTx9OIHrhxO4nhon80v4m06K4UxUyBwAzmlOc/rFks0Aahv/CPa6dM3klb9ZKJwFw58DwJZ9erSr6NOnZcB5kRXTLmI+Dnbj4whXPon24MvUQB5mhPCwMIIvCyP+QwCwU8+eKlVb0t/SJmObBllvaZH7jhZF7+lQqWhA/V4TmpVNaVU1p03NQg5/PdqWPwLAn/M/AsA+TVNZFIymAcP6ZnwYEMY3B9L4cn8cwyZm9OjqM2pmwSmhLUfNLeUAeEZgwylTK04YCzijZ89JPXsGdc0YcLbkVnY4/3amBmZa4FI93Q56DFsbclpozRkjIedETpwRSzglcuSopS29usZ0auozaGjOJYk7U+6+XHb24IKjK+fsXbnnu59pjwiO23jSa+pCr8CTUjU70ndakfKuOQd32RH1uhlO83fjvlwTv3UGuC3XRPhbRSx/tQOv9SaUCRKI2+uJrYIWtkt0ES3RR7xUj8A3hIS/Y4/vZgHSlfq4rzXGbY0RTst0cFwqA0SvDWZIV+ojWaqH+2oT/F8T4rlegPMKIySrzUhUDeGQTgwHtPeTZXYI/3c9Ea40xXK1FtK3TGkLLsT7HQEWS5TQ+/V7GP56J4b/vAPBfDW05u3E+J9VKDH35GhwPB/kljPu40+DwIpxdx/upWfxWUEpX9bVcq+6mJmKbG5UHOZ+TjK3i8q4lFdL74EqmlPqmCjq5krDAJcrSrhSVcTNvgZujrZza7SLDwda5AB45SUATlcWcquqmNvVJdytLOFWWSG3cjKYjo/hdmw0HyXG8/mBZJ5kZfAkN4sH2el8WpLNJ9X5fNhQxIfdlXzcXcXjnjqe9jfybKCJJwONPB1p4elYK0/HWnky/rLyd7SDp0c7eH60m+dHe35U/fv3APDFyX6+HWnjD501PDucyCdBftyWODOqYULzDn0S1qkTuFwdqYIqFr/ZjsVvtiP47Q6cV2rj/7oFUTtEOK1QolIUxpW0cs4dyOZeeQUD/uFUCrxwX6GEyzIVPNbpIFysjNnvduO0UheXdbpIlqv+CABnZ/9mq39+m7Tls38BW3Tx2aCJxxpVnJft+4cA6LJWCZc1GjguU0M4X1VeBUzXdqXZKYSRgEguxUVyLjqYo/4BTPgEM+obztm4RK6kpfD/sveeUVHYa9tvnud597OTmMTee4/RJBqNioC0oQ9lht577yJtZui9g4AiKBYQFUQROyAgvQliL9HYorGbmLL2edc5v/NhZHbc6n5Xzrv3eb9wrXUtZ8YP+vG3rvu+/ve5/DiGNsUxlBdDf2YUfelR9KZF0pceTW+ajJ6UmNcQGENnYjRd8bF0x8XTHR/72tH0JMjoSZC9BkEZA2lyD2ZIGciKYSArhsHsWM7lxHEuJ46h3HjOZkYzmB3L+bwEzuclMJQbz1B2HEPZb49/3zcCPpsew9n0YfCM4VxqDEOpMQwlyeR+DX/n4qJoixwZAY9oRCP683prBDw8+h0e+w6DX7WWkGot4XtHwAfVDTmqbfjGCPjmRhduRbgrAPDHoggebo78lwFg2XobMpcJ5PD3lTYFy7XZskKHsjUGlCsZyS9vqImoUhO9M+l7n98HgEe0TKhVF3JYU59WM1sGnT1ptbDluFA+Bm4Um9MgMqNJZM4ZM0sFAHaIregwtaTN2JyzJnZ06VvQZCim0lhAtaOQ83nhMFQHQ0do9bOmxdaYLksxfaZmNBmZccrYnEaRFU1mNpyxtKfVyoEBNx+azGxoMrOhx9FdkQBe9AjjkmcEPbYBnDB045iBO3s0XShRcSR3rS3Bi/RxmKyM8yxNPGfr4jpNE8vPVmP+6RpsxqngOlOfVJ0QAr6yw2DUWoxGr0c0XoD5RAGRyx0JWGiG8xQdPGcJ8ZwlVFzqcJ6ig8dMQ1ym6mIzVg3HCdr4zzPDd548/XOeYoD7HDPCvvHCZ5E9xVa55IkySNGNI2JtAJ6LLTEer0aOWTxZ5okEr/XBYJwWmn9difaH36D3169xmqxCqroz11ISuBQdSmdgALU2PjR6R/KwdDu/HKzgh4o8LpQm8N2efG5X7eTS9jKuFOdzZdcu+rfv5VjWNqoSi2gu2Mm57bs5V5LHxZ0F3Di2j2sNh7neWMeNI3sZ3FtKV2ke/ds2ca60gEslhVwpLuBqYT5DGWkMJiYyEBnFLVk0D2QxPElK5klqKg+z0nmQk8G9gizubs3jblkB98q38EP1dh7W7ODp4XKeH63k2ZE9PDq8m8fH9vCsfj/PG6p42lDFs6YDPGs6wPPmGl40/T39G4a+3ztPvhMAf+86xeO2Op43VPHq8C6eZydxLzyEGx4e1KsasudrbVLnCYiaJsBrjCqmHy7H6L+/wuTD5ViOVsJhkjqJqq54zNYgQdWWq0WVtCdkcW1rCdUeAey08MdzqjJO45Vwn6GJ72JTgpZZvTMB9J+rrtj7G4a/P7Z/A+YL8J6lhtvUddiP+/afJoAOk5WxHquE7ThN3GcI8V8gpsQ8mDo/KU3hEvrjQumSBtDg702jfxBNIREMpqVwMT+N84WxXNwsH8MO5sgYyBp2nBwCU2PpTY2lJyWO7uRYuhPi6IlPpic+me64JLpiE+iMiaUzJpauOHmDuCdRSm+SjF7F+FhKT0oMvamx9KXFcTYjQfH5XHYyQzkpDOWkcD47hXNZ8X8fKf/B7wLA/rRo+tOiOZsq92BKNOdSojmXKGUwQcJgXBSDsZEMxkbSGhE8AoAjGtGI/rRevwNoRJ2BGXUGZm/s/A0nf8PwV6Vp+E4APKhuRK2mEcd0hHRYiDjraMFVXwe+C3V+AwAfbY7kxy1R/xIArBLYsE3FisxlAnKWabFpuS6bV+opALBinbF89Ksuplpd/EbC90fYO6QlfsvvA8A6TWOO64g5qi3ktLEFHZb2nDCQj32bLawUbjGzfAsAO0VyCDwnsqdbz4IzQjH7jLUpM1GnPtwJzh2Fq6c5F+FBl5M5XeZGDJpZ0GQk4qSRGSeNzGgwtaTL3pU+Z0/6XbzodnCj3caJDltn+l28uOAdzJDHRgadQ2g18+Skngt1Os5sXiEiaaEuYbPU8ZqjifNsDbyXGuG9SIjjZDWM//o1ZqPXYj1BFfHodcSp+RK80gnjsaqYjtPAbIoedjMMFcmfw0QtghZb4DlLqDjXNpwGOk3Wxm68Bs6TdAlaaInrNAOsRmtgP0EHn4XWpGhF4rPInizDRMLXBJOiG0eqTgwRq/3xXGxPsf0mqkL2kSpOw2SaMRofr0Lzw6/Q+ehz0gU2HPaWcik6iL5gR0452tDoFsY5aR4v9u7jzo5crpclcKMime+ri7hbXcHVHZVc3b6Fq5V7GNi1j2O526hOyKMpr4SB4mKGtmRyuSyXm8equXa6juunj3G1bg+9uzfTsTVHkf4NFeZyPj+bocx0BhISGIyN44JExp3YOB7GxvEoNYXHmek8zs/mx4Ic7hVkcW9rHg+3F/J4VzHP95XxvOrdAPi8oYrnDVU8a6xWwN/z5hpeNst3/4ZHv8Ow9y4A/K37FM97TvCy+SC/Ht/Dy01pPIjayPc+PpxWN2b/N3rkLjYgbrYB/uM1MPtwBUb//RWij7/BcrQS1mOVSVZzJ/gLIWHLjbhVeoCe1HyubS3hoHcwJSaeBM7Vwmu6Bh4ztfCYZ4jf52Z4zBHiNd8At+kaih1A/7nqivLHMAAGLtAmdIkBGz7Xx3+eFt6z1HCdooTd2FXvBUDPueuxm6iExWercZiojf8CeSt8r4uU+tB4WiKldMsCaYvwot7Pk9MBgbRsjORCVhpXitK5UBTDpS0JXCpMYCgvhsHs6NeOpz8jhr60uDcAsCcxnr6EdPoSU+lNSHkNgXF0xcbRESOjM1ZKV5yE7ngp3fFSzsRE0hobRUeCjK6kGLqTY+lNjVf8OZiVwlBOGkM5aZzPTmEw8/2Fj390X6qMvtS/lz4GkmUMJsvk8PcHAByIieBMkslrzwAAIABJREFUeNAIAI5oRCP603prBDyc+P1j+lelafheADysZUqdwIQTesZ0WIjodzDnsrcd34U6czPc7Q0AfFQs+ZcA4D5NK0qVLclcJiD3SwEFK/Qo/taA4m903wmAR3QtOaJr+RYE/pkSyMH1BtQbWHJS35R6QzHdNk60mFnTbGHFSWNT6k3FNFtY0WZpQ6u5lQIAO82sFQB4QeRAj64ZrcYi9pvosEVPiQPeZnDuGNxs41pcIL2uVvSYG3He3IoWE3kCeNxQxCljc3oc3eUn4WyduegTxICbD2cs7Tnr6s2N4Ei67f1oNXPnmI4Nx7QcOKzlSM4iXTaOX43jX5fgOmM97gt08PzSGP8vTHGaoo7xxyuwm6yO22w9zMerEqvuR5SKN9bTdbGYpofdHFM8FllgO04d80/WYTNWjdClNrhN18fgP5fjMdOQgIVmeM02UhRCXCbrEbzICvsJAkw/XIfNWC38FtuyxTydoGWuxKtH4jzXlkRBNLnGacSpRLHxm2C2OZVyMPwIyeIM1D/TQu3jVaj/9XMMRi2ixnMj/YlZdAXZ0OpmxAlbC7oCk7iRXMaL/dX0ZUkY2hrJvUMZ3DtczO3qcq7vPMDVXWVc27+fgfIqjueVUh2fTVNuEf2FBQxtTuFKWTa3jldxvekIN5qOc7m2nM6dBbRtyaKvNJ+hbYUM5mUymJnGQGoyA3FxDMXGcz0+kbtx8TyIjeNhWgqPszJ4VpTP060F3C/M5mFxPo9LC3m+o5hf9pTxav9OntVVvAGAj45WvBMAX7Qc/NMA+PPZBn5tP8Lf6vfzqiiTx9GR3PX354yWiIOrDCn8wpjkecaETBRg9uEKOfh/sgqrMeuwHK1EiroH4cvF+C8WcKfsEGczixQj4C1CN8I+NyBgri5u0zUwG6OE1QS1d5ZAAuZpKABw+OrHPwKgfP9PCdsxK/9pCcR2wlrMPlmF02RdNnxhS9xaTw77JdIcmUKrJJr2SF+aNrgqAPBMWASXctK4ujmNC0UxXC5O5HJRoryIkRPzej8v4Q0AHIa2nsR4ziZl0p+YQV9C+uskMJGu2ATaZdF0xEheQ6A8DWyWhdMsC6ctTkJ7vLxM0p0cS1dSDD0pcQxmpXAuO/XfAoADr9O/EQAc0YhG9P9V8lNw2iYcMzB/wzWaQg5qGb1pgTHlqnpUrNenUlXInnUGlK/Vo3KtNlUquooSyICTJdf8HLkT4sG9MG8eJYTyOD2cx4VSHm+W8bBYwo9bJTwqkfK4JIrnpXI/2y7jxTaJ/HNxKE8Lg3mY4ceDJD/uxPhwNdiLQTdn2iwsOaBtS9kaczZ/bcCWFfoUfqVD6beG7FAyZreqCeXrTalQM5FfA1ExolrD5I09wFqBmcI1GqaKVvBhbXPqtMw5ovnaWmavLeKYtoijAlOOags5ZSCiz96V8y5enDE154yxGa0m5rSLLOmxtKPXyl4++v0Hd9m40mruQKfYjjYjI04I1DhmrMajEhl0lHNneyT1gcbUu+vT5STmmK4eJ7SN6LJw4LybLxc9/Bl09uKskze9Tj6cdfVnwDWILgc/2qzc6TJ3oVZgxk4lIclLdYmYp4XrZHX85ouwHKtOslYoUiUfIla6Yz1BG/FnapiMUkH8mRpmo9WxGKuJ9wILMnUjiVzlgec8MzzminGcZojrXCEbVtgTvsIR9ym6OIxWw+Gz9XhPM8BnphCbCfLTYPYz9Yhc7kzAfEvcphthM1YLs1GqOE0XkmsUTYpgIyHfuCBR8WPDKjccZhliNHot2qNWYTPXmGppNTJRLMJZQnTHfovHIg0Khc5cjE6kLySEk/ZenLD3o8EjmO9z83i4bQuXCpK5ti2dy9vT+W5vEXcOlnK/dje39u/i+6pK7tfU0l9UyqmkDPaFx3IyJZeu4jK6yrZxbu8u7jQe4PbpKm6d2svQ7hJ6i/M5m5fJpdxsrudm8V1KMjeTk/guMZbr8VK5E2XczU7jXk46P+Rl8qAgm4db8vixOJ/7RTk82JrPo22FPNlVzIvK7TzfV8aLo5U8f+1nxyp5crzyvQngq6Zafm08zC9NdfzSckT+AHTbMX7vOsXvPfX83lPPb30N/NbfyO8Djfw6WM/zzgO8aKvkyf5c7udK+D7KjwEjMY1K+uz80oDcxXpsmK6M+bi1mI5WQjRGGesx67H5VIXQBSLSld3YsMiAs+k7ubZ1Lxe37aA+OolCQ0cSVpriOPprHMd+i+tEDVwnauExwwDvuUZ4zzXEZaYmrrM18ZwjwHOOAI/ZWnjOEeA1Vxuf+boELTHCf5GB4u/dZmpgPW4VztPX4jDlWxwmK+M6QwOPWXq4z9THY5YB1mOVsBm/FqdpSkStElFs6klzcChdkVJ6pTE0h4ZSHxxAw8ZAWqJC6UqO4nxBEpc2p3KxKOW9d3yHyxrDT730pkXSmyahJyXune5OjqU7OVZRGOlIkNES/7bPJETTHCelJV5Ga2IMbUmxdKYm0JWSQE/S62JJciwDaXEMpMUwmB7L2VQp/amR9KVE0JO0kZ7kDfSnSelNkSqeehlIlnEhPU6xA3guXjKyAziiEY3of0ufffDBB+zTElKnK3rDb8GflhE1WkZUrNdnj5rBGwBYsVqLfeu0qdXQpdNSzDkXa24EOP9bAbBKy5rSVSIKlulS+JUO+Uu12LpSnx1Kxq/hT8QedVPFJZB/BoAHNUXU6VhwVM/qnwLg8CWQo9pC6g3FCgBsN7NSlD06zazptbKn38aRLnObt9wmsuOMkTVdRtb0mYhoN9ClxVRAf5gtP+1O4l5BJGd8RDTb69NrZcpRLW3q9U046+jBRc8gLvqEct4zlLNuIXS5BNHjFkK/RzhdrhtodwikSexKjZYVRSv0CZi0Ftcxq3CdrovLDENEo9UoFCVRYJqI10ILbCbqYPyxsrzoMV6A0UfrsJmog9N0IRk6EaRqbSR4mQMWYzWxmaiD1yIR0nUexCl74zlNH6exGjiP1cBnuiH+c0ywGKOK+VhVnOYYErvGC8cJuvgvsMR6jCa24wSIPl2PVMmH8FXuOM0xIfRbdwK+dkTrL6sxGa2B0gcr0P5Ejaqw/ewI3I7HNw7YzVlPlpErDWFxDMmiaPJw4JidO2d8wrgQncK9gk3cLshmKDuO77dn892ObG7uK+buoTLuHi7netVO7h85xN2DtXTmb+FIXDK7giKpjUmlq7iMoT0VXD+0n9unqrhxtJwrNdsZ2FpAd34W/ZmpXMxI52pGGlfi47ieEM93ibHcSpb7u+QY7uWkcz83gwf5WTwszOHhljwebsnjh825PCzZxOPtRTzeuYXne7bxbO/2dwLg+3YAfz596A0A/KVF3gT+rfMkv3WfegMAf+tv5Le+el521vKqo4bnB4u4XxjNregAzplZ0awmpHKFkMKlBkjnqGE7SRXxWGXEY1WwHrMe60+UCZhlSMpaZyKWmtAiK+BSUTk3yivpysin0NCR6K8MsftkGY5jv8Vlgjruk7Vxm6aH1xwh3nMNcZstwH2uHPg8ZmvhNlMDt5kaeMzWwnueDgGLDfGZr4v7LE08ZmvhPksT+0lrcZy6GrtJK7GftA6X6eq4TtfGeao29hM15E3lsavxmqdBnLI128x9aQ0NpztKRneUjNMhIZwK8qclKpT26Ah602Rc2pzKleJ0Lm1OffcFj/z4t970k4+GYxV7gf/onpQYelJi6EqSKZ6PaY6LojlO+pZbE2PecFtSLO2JsXTGy+iOj6Y7PprexGjFLuHZ1Gj6UyT0p0joTQ6nNzmM3pQoepLl8NebJGEgWcb5tNgRABzRiEb0L9NnH3zwAZUaBtRqm7zhQwJjDgmM5eCnKaRGU8gBTSGV6oZUqhuyd72RAgB3r9Kgcq0Wh9R1FC3gm0Gu/1YA3KdhydZvTMj/QptNywTkLtFgywpdBQDuURdTqSGSW830vQA4vAd4RNeSo3pW8hHxewDwqMBUfgdYx4h6QzGdVg7027nQbmZFm6n8zb92kSXdFrb0WNrRZ+3wlrvN7Ok0tqbH0JIhU3POmYk4a2lMo70O1xN8uZkcQoeLiGZTXfrFIpqEQtosrLnkGcQF7w0MeIQz4C6h1z2KdrcIOj2i6PGNodNHSrtnJAd07NmubE7iIi18JqviNUMLj7mmWE/UQ+e/1xKtGkS2USxuc8ywHKeFySgVvOab4zbbFOOPlbGdpIvdZD2ilXzJ1pcQs84P8Wdq2E7SxXuxmKi1bkhXu+EyUYDzOE08J+viO0NI4DwR4k/XYTZGBfeFpiQq+2E7RgvZKk9sxwlwmKiL0UfrcJ1jiucCcywn6xC43ImArx1R+WAFpmP10PyrBlofalLqWsThqEqkWr5I1ok56C9hMDWT1mAPjjoIafDy4qwkgXv5RdzZlMOVtHguZ8Vyd3sOt8vyuL2vlDu1u7l9eC9Xqiq4e6yWu3V1dG8p5URKBtt8Q6ncGE331h1cq67m7rFavj9SyaXqUs7tLqA/P5uujFTOpiRxITWVKynJXIqWcS02lptJcdzJSORORiLfpcbxQ16m/NrHpuw3APDBlrw3APBZRSlPK7fx/Mgenh3ZI4fA43sVLeBn9ft5Ur9f0QB+1nSAnxoP8ktDLa9OH5a/8dcsbwP/2nGCX7vkEPhrbz2/9jXIQbC7gVedR/i1q5aXdaU8KEnkduJGztva0yowoepbE0qXC0lcoInjNDUsJqxHNEYZq9GqWI1ah9cUbZLXOBH/rQ2HA5I4l1fGzT37GMgvZpO+PZKlejiNWY77ZGUcx6riPF4D16m6eM42xGuOAe5ztPGcr4PPfF285mrjPksT91maeM3Vxm+hPr4L9PCcI8BluhpuMzXkT7xMVcZx6mocpnyL01RV3GZq4jpdG6cpAqzGqGA5eg22E5QIW25Ctp4HFfYbaA+LpDtKRmeEhIagIE4G+nFGspHO2Cj60qO5WJQih7/C5Hde8DifF8dgdrTi2ZbzeXGvk8EkzmbEv9N9abH0psbQkxJNd7KM7mQZLfESBfQ1xUpoipVwOiaK9uQ42pJiaU2M+XsiGCulLTqajhjZa8uvkgw/TN2XLH3tKPpSIuhOiqA7KUoBgGeTpJxLiR4BwBGNaET/Mr0XAOt0RQoQPKBhSLW6AfvV9BU7gPvU5FdA/k8lgHvVLd4CwM3LdShZpU+ZkiG7VIzl6Z+66T8FwCO6ltQKzDimb81xAxs5BL4HABsMrRQ7gCf1TWkQimkyMqNVZMEZYzNajMS0GIlpNTGnzdSCJkPTt9wgFNNgYEq9tiGXbOx44OvLnUAvDptoctxaSJenE+3WljTpGjFoZEWXhTmdtlYMuvtz3kfCOb90+v1y6PDIpN4theMuCVRaBrFF6EK+lg1p31gQNF0N6w+/JmSJFaHL3TAep4PgIzXMp5oQsMKDbONErCcaYPyJCi4zjQlb4YrXfHNsJ+liO0kOaqafqOK9wIKNy13wXmCB/+c2pOqEIFP2xH+xORYfrcX643U4jlbDd4YQr+kGiD5RwnayFiHfOOA+Q4jlJ2rErPbGdZoQ23ECTEapYPKpKiafquI0x4QoZV9Cv3XHfJIuqv+5FvEkA3Q/WofzbH1SdbzJM/SmPyGfCyl5dIXL2G8u4qiTLddy0rlVmM+dzXlcSpZxMT6Ke/kp3ClI52ZhJjd3l3CrppKbdQcYOljFxZp93D11gotVB+gr20X5RhnlG2Wc27GH72sOcvtQNRd3b2Fgey4DxVkMpqYxkJTMleRUbqZmcCs5le/i4rmdkMjt5ATuZSVzNzuFOzkpPCrMVfjHolwebJb7x62beLStUAGAT3Zv5XFFCU9fPwL97MgeXpzYx/NT+9/7DuDLhhp+PnWQnxrk5+F+bjrMTy118ssfnSf4pfMEr7pP8qrnFL/3NPJ/d7fz25lT/Np+nFcNFTzdV8CjzUlcdnej3UjEQWUh5asNyV+qhecsLSwmrMf407UKAHQeux7plxbka/tQJPKmI7mAqzvLGSosZaupG9Jl+vhOV2bDQn2sR63B5pN170wAfRfo4bdQH/9FBgQsNiTwcyGBnwvxXaCHx2wtHCYr4zRVFdcZ6jhPU8F15jpcZii9Tgp1cZuhg+NkLSxHK+M6Xf5bkWkQVR4JHPVPoCM8io7wKM5sCKM+MJDGDUG0R0fQFSehLz2aoU2JnMtPoD/7zff5/vGtvj+efbtUkMilgsT3AuMfr4L0pcuflOlIiaY9Oe4N0GuKlSjgryVeRnOclNMxUTRFS2mVxdAqkftMlIyWyChaIqNe7xbKr5R0J0joTpDQHhdGR3w43QmR9CVLOZskpT8hagQARzSiEf3LJG8BaxpyWMf0Df8jAFap6bNfTZ8qgQlVApM3APD/xA7gfk0rSlaasmmpDgVfapP3hSbF3+ixebm24hTcLhUh5euNqVA1/qcAeFjbnGP61pwwtP2nAHhSz1xufVNOGYgUANhhbq24+DG8B9ghtuK0gclb3rtek2pNHQ5ra3PFxYVHoSF8H+xFmfoqitev5IS1mBZrGxp1TWnVMua8iwO9TjZ0O3pzzlPCgG8eXZ75NDhnccI1k6Pu6ZTbbCRf6EKaujXRX5rjNFYJ0X+vIHpdAKGrfNAbrYPyfyhjPl3MhrV+bHPYhN0UI0w+VSVgiS3eCyywGi/AdpIujtMMFTuBdpP18JxnhnSNN0nqISRpBRL6jQNuswyx/FgJyw/XYvXhWnymG+IyUYDZZ8o4z9QnfI0rFp+qYv6xKqFLHQj70gm/+fJ/w2W2CYYfKeE6X0yKXgQhK10xn6qL8n+sQOfTtaj/1zIsx68ifLmQnZZBdESk0hwk47CjNwdtnOkK2cjd0iK+25LH1dwUrqXKuJkSzd3MBG5lxXMjJ4XrO7Zy40Al1w/XMHSohvOH9nP75HEuHqhhcM9eahMzqEvM5MLufdzYX8W1ynIGSnIZ3JrNxZJcLqSmcyEplVtpmdxPz+F+Wib3U1K5l5zCnRR5+ncnK5l7eWk82pzH4yK5H23OUwDgo5KCtwDwUflWntTufgMAX9RX8fhEJU9O7uXRyb08btivgMAX9QfeAMCfTtfysvmw/PZvx/E3APC3rtPQ08WvLfW8OnOcXxv38fJgMS93ZHHRy5UOYzGH1hmwZ7U+BUs18Zipidk4FQw//har0apYf6KM0xhVAufokSfwJkPHgfakTVzbVcHFLWXsc9qAZKkeXlPWEjRPB9tPlXAer/HOHcDhka//IgOCvzAm8HOhAgg95wiwn7QOxykqOE9bj9NUZZynr8V5+trXaaEOzlO1sB2vhuVoZTxm6eC30IAym0gO+6dzIiiZ9rBI2jZG0BwcSn1gIE0bQ+iOl9KXFMNgdrw8+StI4mxO7DtPuL3rAedh0Luw6d0evvJxNktCf2YU/ZlRdKfH0ZWWSEdKPG1JsW/s/w3D3zAUNsfIaJPF0SaNpVUSQ0ukHACbIyI5I4mkVRpBmyxSkQq2xW58AwD7EyX0xkWMAOCIRjSif5nk7wAKjDiqb8ZRfTMO65hSq23yzh3Ag1qG7F8v4ICGLgfUjdinYkj5Gl32KOmwT1WXGk0Dmi0s6HG251KQGzcivPlO6sv95FAeZYTzJD+Kp5skPC6I5HFRJE82R/F4SwRPt772dhnPtssB8MWWUJ4VBPMkzY9Hcb7cj/LihrcbFxwc6DYxZ6+ymB1rLdi0VIfcJRrkL9Wi+Bs9tq7UY9saeQq4U9mQCjUTKtVMqdV5/cafwOzNJ1/+sAs47EPaIg5pi6gVyCG4TmDCEYERp3RNqNcz5bSBCS1CE1qNRXQYi+kVm9NnZkG/uSX9Flb0WVnTZ2XNgOVriywYFFnQb2jKeUsXzlm702vpxI2NEZywsCTj62XsMjag1smerohIusMjORMUxi5tc7qcIum0iaTdVUqHr4wmPylNATJOeoRxwi6YRusNdJmF02EYzEn9jZh8ooHLXAtc51my07UI/+VuaI9S5ZsPvsB4ki4hyv7s9C3FY6kD/kvscZlihP14PZwnC3GaZIjHDBGSFZ44TxbiOVNM/NoAsgVRRHztgv8CMa7T9LAarYroozVYjVZVnH9znCTA8L9WELrUhmztUHT/xxrsZ5jiNt+KfFEyiVoRuC+wJuBLFzT/czVFFumk6kqxn2GK4C/r0RtljO4oNcwmqhC2XJOd1u70xmRSauRArpYpxUJLLuelcXtHJkOpEi6lRnM9I547+Rl8n5PB+dQEzqUnczYrhSu7S7hVt587pw5x7UgVtw5Uc33ffi7v28fF/eX079tGb8VWrh4pZ2j3Joa25XCxMI0LuQlcSovjhiyBm/EpPMjK4WF2Lncz0rmTJfft7GRu5SQq/HhbHo9Kc3lQnMWD4ix+LMnhx5IcnpZt4lFpLj+W5PCoNJeXuzfz055inlWV8Ky6lKeHtvP4+C5+PLmbh/XlPDi1mwcnd/Ho+C6eHd/Ni5MVvKjfx8uGan5qquGnlkP8fKaWV+11PD9zkOdttbxoP8zLriO87D3Gb92noPsMf+uo55fO4/zYvIsf6op4UJnNxRA/Oq1tOKoqovpbE0qW6OI9cSUO41Zi/cly7Ear4jhOC7vx2jhP1yNayRX/ZTqUe4bTl7eJO+X7aJOmE7NcD++pq/GYshbfWdp4TtUiaJGIjV9aEPi5ET6LdPFZrIXXXC185uvit1CfoCVGBH9hTNASI7zmauM5R/Aa/FRxnKKC05S12E9YhuuUr/Gao47zTHWsJ2tiM1GAyah1OE9RJ+pLEXVOUbQExNO5IYHW0Eiag0M55RvAcT9vWiJCGMqM5Xy2/OrHUIGM84XRXCiSn2R7V6I3DH/D34fLIVeKkrlSlMzVzSlc25LK9eI0rhencakgkaHcWPozJIp7wV3pErrSJbSnRNCaFEFLQgRNseGcSZAqxsNNMTJOR0s5HS2lQfpu10sk1Eskiu+NMhlnpFG0ySR0Rcvoi4+hPz6Gs7FSLiTFciEplotJUi4nRXE5KYpe2cglkBGNaER/XooSyBE9MUf0xP9LAKxS0/6XAuCT4sj/3wDwLdD7FwFgt8iMHrE5vWYW9JpZ0G9hRb+FFb1mFgxYWjNoZcN5K1vOW9hw1tKWPmsHWkUWPEqM5ztJBMftzalzsKTZ1427mUm82LyJRzmZHDA0p94skEbzCJocJTQ6R3DaJ4q2oBjq7PxosA+mzTmMVvMQjqg7UfqNLZbj9XCbb4XzHHN2u2/Be5kTBmM0WfPB1xiM0yJ4nR+7/LYRquSH10ILHCbqYj1GE7vx2tiM1cJxkh6+88wJ/8qZmNXeZGtHkKMTSfS3XoQsscJrthEOE7Ww/EwFu/EaOE3Wxn2GAc5TdBB/vJawL+1IVvXD9FN1rKcIcZwlJl+UTJYwDvsZpojH6WA6RkCBWSqei2yxmKiP9VRTxBMsMPhEFZPRqyiz8uJkkITGYBmbBGLytUTsd/DiVkk+35dlcCU7jhs5SXyfn8r9ohzubMrmYmYyQ1mpDOakcWV3CTcOVXLzWDUXD1Vyab88Dbx0YB99lWX0Vmzl3L4yLuwv5Vr5Fq6XbmIoLZ6B+CgGpBF8F53M7fhUHmRk8yAjm7tpadzPzeJ+bhb38jK4uyn9tVN5sj2fx9vyFOD3qDSXx9vyFAA4/P3FriJeVmzh6f6tPKsu5cnBbTw6tpPHJ3bzY305D0/t5uGJXfx4bCdPj+3i+YlyXtTLE8KfT9fwc/NBfjlTy6vWw28B4M89x/i9+yT/T0cTv7cd51XnEZ407+bHus082pvLtfBgeu2dqFMRU7lCSMEibbwnfKsAQNvPVHAYKy/quMzQJ+pbR3yWaLHDdQODhZu5vXsvrZI0ElYJCZ67nqB5mvjP0cVtkjqhX1gQ/rUVgZ8b4bVAG88F6njO0cR7ng5+C/UV49+AxYa4zlDHZboaTlNVcZqqivO09bjPVMVx0le4T1uB52wNnKarYzlRHavxmliO08Bvvj6Ja2045iahJSCW9uBYzmyIoCloA6d8AzgZ4MuZyA2cz4rjfPbr27ybpAoI/F8B4B/HwBc3JXC5MInLhUlcKUrm2pZUhYebw2czpQoA7MmU0Z0hpSM1krbkSFqTomiJj+RMgvQ1BMpojo2mKUZGU4zsvQD4RzfKZDTKZJyOiKA5IpJWaRSdsteWhjMQL2UwTn4FZCg+kvMJUXRLRh6CHtGIRvTn9acBsFpdhwMaulSrCdmnYkjFWr0/DYBPCqPk8PcHAHxWEvlvBcBD2m+D3vv8ZwCwzURMp4mILtPXICgyo8/Mgj4zC3rF5py1tGbAyoY+c0v6rW3osLagy86aU2IjnmUk8aoom4sRQTR72NLt78KL3ESo2AK7ijgpMue4KIhTlgk02MdwwjaMZq8IOgKkHDR35LRTAL1eUTSIvClZrkvk5LW4zbHAa7EdTrPN2OlahOM8C0wm6qL2lzXojlYnRNmf3f7biRFsxHGGEKvRalh+th7rMeqYf6KCzVgN3KYbkq0dRoGhlHz9KBKV/Yhc7kzQYgs8ZhriMFELm7Fq2I3XwGGilvzdv6m6OE4SELvGg2RVPyzGaSMep4PLXAtyTRIpts5CNFYbrf9ag+MsMcnaUVhM1MdhpgivRY7YTDaXN1InrqYvMYezCenstXUlZ70h203s6ZQm8GD3Fq6VpnBjcyq3i7O4X5LL/ZJ8bhflciknjaGsVM7lpnNldwnXaiq4dngvQwfK6aveyfVTtVw8UkV35TbO7inlxoEKvq+p4NrmPAaT4ukMDKAnMICB4BBuSJL5PiaV+8mZ3E/O5E5yGj9kZ/FDthwC7+dn8sOmLB4UZPJke/57PZwOPt6Wx7MdBTzfXcSTSjkEPjlQypOjO3l8fBePTpXz48ndPDq+i0fHdvL0yE6eH9vNy5N7eXlyPz81HuDn0zX80ixPAZ831/Ci9RAv22p52VHHz11H+a3rBP+z9QS/njnCL+2HIHvoAAAgAElEQVS1PG8u5+mRzTzfm89tSThnHd2pVjKl9Es9Muaq4znx7wBo86ky9mM0sBmrhetMAzYut8FjoRrFdn5cLt3OrZ17aJdlkLzGhIjPtYlcakjQfANcJqwnbJkV4V9bEbBYiOd8Ae7z1isSQP9FBgQtMVKMgB0mK+MwWVme/L3eAfSao4nLlJV4zliD52wNHKdpYDFeA8txWjhO1yVqhRX5Ol7Ue8fQEhBNa6CUlpBwTgeGcNLHn/ogf9okGzmfFceFnNi3AHAo7917gMP3ev8IgH/cBRyGwKubU7i6OeWdANibFU1vVjRd6RI606R0pMpoS5LSlhRNa6L8SZiWuBiaY6Npjo3mdPS7PQx9f/SpsHAawiI4HRFBS1QEzZHhnAkPpVMaTrcknD5ZBGejwxmIiaA9cgQARzSiEf15KUogw7t/w83f9wFgjaYeNZp6VKsJ2a8qZK+y4Z8GwKdFEp5ukfCsWMqzEoliB/DfCYA1Wn/f/fvjLeB/BQCeEZnSJhLRaSKi21RMv4kZA6bysXCflTU9NtYcFQnpcHfkUZaUn4sSuZcWzkVpKCec7Ej66ksSlnxJ6rIVZC37ku1KazhmZECjtTMnXBM54p5PnV00ja5Sej1COW3lSoOZLadt3Ki39aZIRUzUHBWcPl1BkkY4G1d5s+EbT2LUQ9H7RA29z9QxmaiLcII2KabxlLgX4bLYCtPR6xB9vBrnqdq4zdDDeao2vvNNCF1mzcYvbfCdb4LXHCFec4Q4TRFg/sk6TD9cjfjjtdiN18BuvIb87NskAfYTNHGYqEX0t27ErHZH93+swehTDVJ1pcRrhLHZMgO9D1WwmKhP5Fp/vBbb4bnIFs9Ftph9JsDoL2uQrTDlkGs4Z6Nl1DjaskljPYedPbmamc/fDtZxdXMaZ/OjuL4rm+8rCrm3r5jrJTlcyEtlIDORMwlSujIT5QnggQpu1u3nen0NF5r2c65+D5dP7eVW/QG+21PGtZIiOqQSNimpkbV0FYe1xTSY2HNa5EybfQB97mEM+kYy5C/h0sZo+Vg4JolbCcn8kJnJ47w8nm4p5NFWOeQ931nIi11FPNtRwLMdBTzelveGh8fBT3Zs4unuIp7uLeZZbRlPj+zk2akKnpzYzZOjO3lUu51ntWU8qy3j+ZFyXhyt5Kfj+/j5ZBWvTlXzS2MNPzUe4MUfxsK/dBzh9/Yj/M+2o/x65gCvzuzj5YkSnlXl8nx7Gt+FBtNj5ULxMh2SZquxYaoS7pPXKADQapQStp+pYfGpGq4zDfBdZILLXGWi1U25t6+K78rKGUgpJEPFnNAFGgTO1SBwnj7e07UJXiwmcLEJXnN18F9igN8SbQI/NyBkqQlhX5sRvtyckKUm+C8yUIx+/wiCLlPX4zFdBZ+ZGrjPEGA3SQvzcZpYjRdgN1mHFDUXdlltoCUohvZQCR2hUZwODOWkjz8nvP1ojdhIT5yES7mJXMyN43x+LOc2STm3ScpgvoRzudHv3P0byJIpLoP84zj4j4ngMBBeyI9XJIfDhZC+7Bj6smPozYqmJzOGnsw4utPj6EyNoyMlVt4GToynNSGO1oQ4WuLe7+bYWJpiYmiUyZPCU1ESTkXKaJTE0BQl43SklIawMBrDQmkMC6UlPJTWiA20RmygPth/BABHNKIR/WnJL4Go6yvav8PPvrwPAA9q6VOjqUfVekP2qwrZpyL80wD4bLOUZ8VSnm+V8bxUyottEl5sk/xbAbBaw0RRABl+9PmontX/NgC2mohpEYtoF8sTwD5TMwZFFgyZyhPAHisrup3saXKx5VqyFGq2QmU+97KktPj7krdegONn03EYNRe30Yux/c9puH40k5QlKpz2kHLQK5mjIZs45imjyTOcbmcvThiJaDSx4JiJPXt1bIn53JCAOQI8p+uQriMlfLUvSYJI3BZaoztqPVofKWM5wxjxNEMKHXMpdi3AeIIAw49XYfrRStxn6uI5Wx/X6doELDLFb4ExdhPWIx71LdZjlfGZJ8R9pj7mn6xD/LG8Neo+wwCXqbrYT9DEeYoOzlN0sPxMhZAlVgR/bonBX9chHqdDkUU6oSu9yBclY/SpBqZjBPL/23wrLCcZYPDxeow+Wof4LyvZJfJlQJZBrbMN2/Q1KNXT5FxcIi93VfDbgRouFCZyfrOMa3ty+b6qmLs1pVwqyaIvO4HutFhOx0fRmZnI9T3buXmwkttHq7nXfJhrbQcYOr6LqycquHt8P+fys2iXRJGrqkHCvC/J+fxb6nStqNOxpErVlBNCZ06bedFg7kGjhSdtjv4MBIQzFBzFpXAZd5LT+DErl+ebi/ihKIuHW7PfAMAn2/MVyd9wEvhwazY/bMmU/7ZjE08rNvPs4Hae1e3kxckKnp8o5+mRnTw5uI2nNdt4fmAbLw/v5mVtBT8f3ctPx/fx6jUE/lxfzc+na3jVJB8L/9JWx+/tR/hb60FeNlbw4tR2HlZlc7cknrvZUZx396DJ0JqM+euJmKqM32Ql3KaswXH8Kqw/WY7lx2ux/kQVs1GquMzQx2ehMa7zVAhYrs6D6hq+KytnKH0LBdoORHyujc8MFfxm6+A/W5+gRSL8FgjxmC0gcKmQgKW6BC0xZMMyU8KXmxO+3JzgL4zxma+rAED7Seuwn7ROfpN6iioe09XxnqGF61QdbCcKsByvg81EHRym6ZApcGeP3UZagqW0b4ygKyyKxoANHPfy5biXL53SSPoTo7mcl8SlvHgubIpTwN9AXpS8vKE4Afd3D6d4wyA4DIF/HA0Pp4IXNyUooHA4PezPkNCTKfuD5QDYkxFPV5rcnakJdCQn0p6UQFtiPGfi3+9hCFQAoDSGelk8p2UJNMniaJTE0BAeRWN4uNxhoTRtDKFpYwhHAnxHAHBEIxrRn9ZbAFijKeSAhuF7AbBWWw6BwwBYtd74TwPg8y0ynm+V8aIkmuelUl5ul/vfCYBV6sbUaJi+8ebfMX3rfwkAtlqa02lpQZ+5JYPmVlwSW3NJbM1ZCyu6ra1od7TlhJc997Zm8XNZCiecDJHMm0TMV0o4j1uGwX8uRvSJNpZjTRGNNsFltj1pOon0ZJzifNkxfmnp50HZbs4EBHBQU53KVauoXq3CXmUxWZ8bYPuxGk5TzAla6k2c6gaCl7tT5rgJtf9YheU0IzT+qoTr57ZYzTalMngX272KEY5XR+cvX2P031/hPFUD+4mqiEetxGbcOmzHK+MzzwD3mdq4zRC8/iyHPesx67GfoInHTEPsJ2gi/ngtDhO12LjMlrAv7cjQDCZNPRD/JfY4zzEnX5SM7TRj8kyTsJ4ixH6GKVFKAWj+52rE43TQ/osS1uM1iVpiyp2sHXQEhlOmq8ohGwOOO1nwe2U5P5WXcyE9jft7C3lSt4UbNUXcPbKDByfKGdqWRVd2PB3psXRkJHCuKJvb1eV8f3Avtw/v54fTh7l0rIw7DZXcOrSdwaJ0ykyF5CuvZ5+RmBYnX5ptfanStaHawI6jJi5Ur7fgoIY1pcsFbFmmztZvtNiprE+FmhFV+uY0O3vT6xfKhSgpd3JSuFuYxtOyTYrkb3gf8Mn2fJ6WbeLJ9nzub87gXkEaPxZnyyFwVyHPD2zjRe0OXp6o4OWxcp7V7eTJgVKeV8v98uBOfjpUzk+H9/DqyF5+OSqHwJ9PVvGq4QC/NMrHwr+dOczfztTyU/0e7tUWcHNfOgPZQXRJnOn0s6HR0ITqNQIkk1fhO341rlOUcZ2ipABAi4/WYDVKBdFHyjhO1cFnoTGei9Sxnr6UhwcOcmvnHs4mF3DIJYpcdQdCFgjwmKqO/2x9wr+0xn+hEe6ztPD7XB/vRZp4zxMoGsBBS4zwnqeD01RVLMeswmrst9hOWIvDZGVcpqvhPUcH18nr8ZgiwHmSLrYTdLCdbIDTdCHBX9qwVRxMjZuE04Ebad0QQmfYRur9gjnq4c1xL196Y2WcS43nSn4yl/MTuFgQr4C/s7mRDGT/HfT+6D+WOQayZO9MBt9qCL9OAQezo+lLj6IzTW55GURGV3oM3elx9GQk0pORSHd6El2pyXSmJNGRnEhb4vvdmpBAS1ycAgBPSGI5KU2QWxLL8chojm+MpEkWQ7MkmsbwSBpCN3IqZAMHvL1GAHBEIxrRn9ZnH3zwARWaBtRoG1OtJWS/hgH7NQzeeQu4WlOfWi19agT67NM0olLdiD3qxuxQElChok2Vhh6tIjMGbG254e3CrUhfvpP6ci9pAw/TNsrTvwIpz7fI5OPfYilPt0YpSiDPy6L5eYfcL0rCeFYUwr0UL+7Fe3NL6snlQA8GXJ1oNbdgj5oR21YLyVsiIP8LbYq+MmTLcmNKV4koW2vMTmUjdqsaUqlpwD5NI/arGXJQU8RhbXPFXeDhNwCHfxuGwjqBiOM65pzSt6JO05hDaobUahhwXNeYYzpGHNM14IS+AS1i+RMwZ4RiesV29Irt6BRZ0WNlxVk7O/rtbem0s6DFwoTLfm78LT+NJykxXNjgzw41DTZM+wavsauw/egbLD5UweQva9mw1IxsHW922UVwNi4NqjZDTT6/b06mx92evRpC0ucrkbJIk6Sv7NiwwBqPhS54LPXG4wt3YlR82eaQwS6XAjT/ax0Gn+qg96kuXsvcidWRkm6eQK10L8KJahiMVkbvo7XYTNPH8BNlROM0sJthSOgqN4JXOOMwywiHWUZ4LLIgXi0I5yk62I5TVySAjpMEmI1SwnmKDq7T9AhYaEaBYRRbTKLxXWSF6afqJGiGYz3ZiLBVvuh/rIH5FCEBKzxQ/uAblD74EosZugQsE3LcLYCLEgmHbazZoqNNU2AA13OzuFmSz7WSTK5sy+JGRS43q3K52lDKzaZd/HBiJ9/lJHE1VsqN5CTOJkRzvXQz1w9Vcr6mgktH9nO3qY5H7YcZ2pVNY3wIBzztOelgT5e7F+e8ArkaHMWg7wbOboiizX8Dx+w8OCbyoc7Yk91q5uR9qUnC7JUkzvmGtIVryFmmzLZ1uuzXNafDI5Tz4Ylcj8viSWEJT4s387g0h8elWTzdkcmjsnR+3J7G/dI07pSkcW9LOs8Ks3i5NY+fdhTyqno7P9fu5EltGU9qy3h8aDtPDm7jyYFSHleX8FP1Dn6uKuNlVRk/HSzj17rd/F8N+/n99F5end7Dq9N7eHl6N88bd/HbyXL+tqeEH9OTuZMQR6ubF6fs3Wlw9GGnljW5K4WETVMiapYaUbM08B73Ne6jv8Jp1JfYfroG69EqmH2qhsMMXTznG+M5Vx2bict4XHGIH7bt5Xp+CXWeoeRomBEwTwm3KUr4z9EhaLERUSutCf7ChMClxoR8ZYTfQnkD+B/tNlMD1xnqOE5ReWMM7L1QB68F2jhMU8Vm/FocJynjMX09UcuNqbAJ4KhvFI0hYTSHhXMmIpKj3v4c9falITiAC+kxXM2J51peNNfyYrmaG8OV7DguZyVyKTOBcxkxnMuUveWBdMk73ZsWSV961FuAOJwSDp+P68+Q0JsmoTdN9pb7M2LoS4+mO0VCd4r8bcL+jBjakiV0psbQlRZLZ2oc7cnyKyGtCXGKFPB0dAyNsmjqJZE0SKPkhZDoGBqkMk5FymiKTuRUZAyHgyM5EiLl6AYZ+3zCRgBwRCMa0Z+WfAdQIOSQrikHdUw4IDDigMBIAYDDYFitJaRaU5/DAgNqBPrs1RBSqW5EhZrRvxUA76d6/9sB8K29QE0TjgrEnNC1oE7TmFp1IXVaQjn8/QEAm0Vi2s2saDEU0SW2pdtMDoCdlhb02FjTY29Dv4sdPY7WnPd14UmihCcpMdyLj+GEtSMJX2gRPkcbt3GqiP7HOkR/VcFzpgFxax2psJVyI7uEy9Fh9Ac50uXpxFFTY7Yr6xEzcwUpS3RIX+1M6GJL7Gea477UlcCVPmQbRlFgHk+0ahAGozQxm2SCeLKIkNWBJBrEEmsQSXX4bvTHqaD98WrU/2M5pmPV0fnrakTjNHBbYIb3Emtc5omwnynEZZ4Im2n6hK9yx3WaHtZj1mM3XgOXqbrYjFVT7ANaj1mP8xQdYtd4kCXYgOcCMeLxmiRqRWA5yYCAZa4YjNLEaY4FnovtEXy0Bp1Ra7Cfp0eGnjvdYbG0+/qy18SYOhdHrmem8lPlLq4XZ3FlawZXtmXx3Z48bh0o4PvTu/j+9G7u1m3jcnos52OjuJaZypXCLK6Xb+Pcwd0MHqrg4vFqvju+n/vH9tCVFkX9Bk9Oejhx1sePy34h3AiO5E5EPNdCJFySxDMYGUN3YARdHhtpdQ7ikNCRMmUj8r9SJ2nuSoXTFiqRu0yd7SomHDbz4LRLMDeTMrifk82TrTk8K83mUUk6D0tSeLA1lftbU7i9JY27han/L3t3FR2FvfZ7vPts6W7xkAR3d4gno5lkkpmJTdzd3ZPJTCbuENwhQhIsHtwdirRQHNpSpEhpgcq297xyvuciZXa7d3vRs/a7znuR31rPypoIF1x91vP//5+HN+vq+XbTSr5tXMN3u7fwbXfjzwLw684tfLenlW96t/G6u4E3PY1829fMXw5s55veRv5yoI2/HtzO9/uaeNS6nIebl3KzRMuxiGj2BYSyRaxgg50jDRI3Ntq6sXqJnMppQmpm2FMxRUyy0UJihy8iauhiAwB9hkoJHisnZorrTwD4vGEX91Zs5FBKAeuVwWTNEhMzxo7UKc6kTFdRYB5A1nxPMhd6km/hTfqc/uHPKTNVho0gb9fC/RwA46fLiZ8uJ3y8hGATO8JMBcSMFaFd4sHOkAwOphZyPCuP49k5nMzNY39iKgeSUjielc6tumIDAO+tKOLeiiLuLCv+HwnACzX6HzqEpVysLTMcE/ffEyz7RQD2f9ZxME87AMCBDGQg/7L8BIA/rl6FpwGFbzuBXY4u9Dmq6HRQsF2iolWkYptQ9d8KwGc1iTwtS+SRPsEwCPqcn/+vBmCHvRs9Dl4G6PXJfzoXsMteTafUgw6JO7vsnOkWu7JHpjbs/z3grGaf3JV9clcOKFw4pHLhqJs7J9w8OaJ046xXAOe8Aznr5ccZPx/OB/pzKzmez3LT+Cw3jauJ4XycHMnVzCSeL1vKxfRc0sdakz5BTtRIGe7v2BE02IngISKKlgSzJ6qafWH5fFKwjE65H01CNa0yP9Zae5E/UUiNhS9lduEkz3Infq4POvsk6jx0lEnTiJvlg8sgEb6mbigHy9HLCqnzqKbYSUfQDG82RC0n0SwED2Mpzn+0JmicCr9RTsTN8kNjm0CuVSwBYxSkLQqjWJpOxBQ1lQ7ZpM/yJcRYRsx4Ff7DRLj93hzP96xR/9EK19+Z4fGuJZ7vWZM4xYOlbjlUqTIodczA/jfmuA2WUe1QSPhYNQHGzjj8ZhbBo23Z4JfErfoGXqxtpMM3gA5/f15uXct3uxt4uWM9tzZUcGtLNfe2LeNR12Ye72nk5Ykunuxr427LWs4Va/igRMudhtVcbVvLh12buHF8F59f3MsXF/ZxcXUVZ5PiOO3tw3kvXz4OjuRFWj5fZeh4nlHIs/wy7qVpuJyayz19Bc/r6nlRUcxDXQEfRMdyJjSa4wERdMr92C72ZquFC2vnKVk5y4nysbboTZdQM9WG3c4+HAmO5NMSPc+XVfBiRSUvVlXwYmUVz1ZV8Wx1Hc9X1fF67TLebFjOm62reL19A6/aN/N6TzOv+pr6q6eB190NvOraysv9TbzY38iL3q286N7Cy87NvNm1ldetm3myYim39TrOJiawQ6Fgq1TOGok7NZZKVtl6sEHoTpODF50uIRxWR3LYI5QDTl4cdvKmV6gkx3QxqaOtSR5lS8gwW/yHCvAbLsNnpJiQMY4kzXAkyHQBz5raedncwUcV9ZzOLWN7QBIllq7EjhWQOMGB+Ely8pf4kbfYl9S5buSZe5GzUE3WfDVps12JnmBP2GghQcY2BgD+eAxM1HgpMVNk/S+Ipzj27wIeKyF+gpRKYRB9cVpO5lZwPCuPQ2npHEhJ5VBKBieycrig03Crrpi79SXcXa7j7nI9d+oLub20iFt1pdysLfkfBcCLdcVcWVbOh/UVXFlWaTgm7r8nWMHZ8nJOlZRysrjkB/xpfzgSLuRwgZb9ORqO6Uo5lK9nX7aO/dl69mfr2R4/MAdwIAMZyK/P0HfeeYcWqcLQ7XtbbwHY46z++/d/BMA2sZIWoZImO8V/KwCf1ybxrDzJsAnk45hIzvsH/GoAdsrcDZ2+t/D78TzAHwNwh42cTqGKPnsPAwAPKjzZ6+jCPrkrB5WuHFK5cNjFlcMu7hxRunFS7ccpT39OevlyPiSQy5FhPNRk80Sfy0NtFtdSo7iaFsXZ5HAe15VyJi2NqOEziR9tQ/IEOYnj1USbqvD67WJKFvtzJK6GTq9kLseVsFPox0YLNettvNjkGE2lhS8FCz1InKEibJwjuVaRVKryWO6pJ88iCk8jCW5DJPiYuOJp7Ea91zKqXMpJs0zCxdSROt9Sajx1uI4Q4fh7C/xHO+M1Ukb4ZA/iZ/uTPD8Y+R8sCRijIGleEH6jnCiVpFNoEUXCZHfiJ7nhM9juJwD0et8G3yECXH67hFATB0qd4ljqlcUyjwJcBolQ/kFIhUSD+7sSgowcEb0zmtgJ5hzN1fPp6k1cK6yiKziS0+mZ/Lm9iRctq7m1ppibm0q501zF/Z0rebynmacHdvDyaDePulu5vmUVp0u0XKgu4c6OjXzUvoGbB1t4dL6Xp+d6+HxvC/sSozno4c4N/xDuBEdwNziaxwmZvEjV8DAxl4eZhVyLTeeofyRX0/N5Ub2UN9VlPNNr+TAmlo/jU7gWl0qHVM0ukSdtNh40mbuxeYErK6c5sGyKiBXTxWw1c2KnvTvXUtN4oNPyoq68H4L1lbxYXsPLlcv4alU9X6+u49W6ZbzavIJXbev5evcmXu9pNiDwdW9j/+OQ7ga+6NnEk95NPO3ayLP2jbzYtYlXLZt4sqqeC0nJ7PX2Z4e9kmYrGY3WCjZJfVgn9adVGUWHezR7PGM4EZjMR1FZXAyK57CzJ8ecvNgvVaIZa0bWBCEZ48WEDrfDb4gdAUaOeI0QEmhqT8osJ4JMF/BwUxtfNrVzubSO45lFbA9IotLOk5gxdkSZCokZLyN3kQ95i32JmeJI6lwl2Qs8yJznQdpsV+ImOxrQFzVe+sP6NzERY8VEjpMQM1FG1KR+BEZPdiBqvD0Jk+Wkz1CwXB7NgeRizmiqOZqRw4GUVPYnp3AkLYuz+QV8WFrErbpi7iwr5u5yHXfqC7lTX8itOv3/SABeqNFzqa6Uy0vLuFRXbugA9t8TrOJ8ZSVnyso5XVrGiaLCH8bHFBs6gAdyCziqLeFgXiH7cwo5kFPEgZwi2uIGNoEMZCAD+fUZ+s4777BN4kyHg2t/l+8H7PUpvehVeNKr8KTbyaO/5K4GALaKFGwTKGi0df5vBeCPV8Hdz0zgemzU/xMAuxw8ftL9+8dB0D0OXnTLPOmWef4EgH32bvRKXdnv5MEeBxV7HV0MADyoVPV3A13cOeruzTEPH455+fBhTCS3UhJ5VqzlaVkBD/U53MpJ4EZOAmczQ/hidTFXS3LIn2NF/nwHqgRBrFPlolsYhP+7c6k0U3M0togTkTncSKnghHc6m6y8KZ8jZ7kkHM18NTETHQgYJcPXVI5eksUy91KWu5eRtTgM92FC/EcpCR7vTbpZMit9V5Brl0XgZF8ch4nQOKSzObqe4MmueAyXEDROha+pnMipnsTN8iNqmhey35qhfN8W/9HO+Jg4ohcks9Qhk4Il4cRPcsPrfRs837PG630bvAfZEmQkJchIivsfLPAbKiRihgNZdr4s99QSM9MX7+FOhI/2wukdC4KGSnD7zQRKrRVc0uu5WlJCT0gcR5My+WxZPd+3b+VhQyXXVudxZ1sZ93fU8qB7Lc8O7uTZ4U4e72nn/q5tXN2wmnO15Xy4ail3Oxr55GAbX5zp4cnhndxrXsXFigJ2ONpzVOHCndAo7oXHcDMkilvh8Xwal86tqBTuJuZwITiW7SIFx/2jeKQp5XV5OY/zCzgXFMa1mCSux6WwS6iky96TPU5+dEl92SVQs8vOm1ZLL1osPGkyU9Jmq+R8WBS3UjN4WlLE84pSXlSW8aKmiq+WLePr+npeLK/i5epavtpYz6u29bxq38ybvdt4s3cbr/c086aviTc9jbzpaeRZxzqedazj+c51PGtdw9PG1Txdt4pL2Vn0evrTKnGh0dKBTokXfc6hHAlIp88ricP+GRz2TuSYXzIXQjK4HJbGcc8I2u2c6BA4s9vaHu14C/KmSMmd4kDYCAG+g20JMnbC20hEgImU9LlKgkwXcH9NI88bdvFRRT0HkzW0+iWwVOpP3DghoSOsiRorJWehN3mLfQkbJyZxppzMeW6kz3EjdZaL4Qg4cpzEMAj6Lf6ixkuJneRA5EQJUZP6t4BEjbcnY7YbBYu82KRO40h6OWc01RxOy2J/cgr7k1M4lpHDxcIirleVc6uumNtLi7hTr+X2Mh23l+m4WVvIzdoSbtQU/48D4M8dAV+qreZiTQ0Xqqo4W17BmbJyw+iYM2VlnCwu4VihnoN5Wg5rijiYV8iBXD2H8ko4kFNEa+zAHMCBDGQgvz6GRyA9zmr6lF7sdfFhr4sPe1TeBgS+PQrucXIzALBF6EyTrRNbreX/7QB8UZnCk+IkPslK5EZcNBcCAn81ALsd1QYA9jp60y3zpMte/bOPQHbZOdMlcqHP3oMeiQvdYhV9Mhf6ZEr2OrpwSOXGIZUL+5yc2StXcETtxQFXNftdPDjs6cX97HRelOp5WJTPozINj8o03NdncFeXxoV8P163FvEf+9ZztaaEA2lZHMst51plI0fTa9kblcvh2Bz2h8XT7eXP+ZBkzgdmUDzZiuhB09GZqXF/fxE+phLSzOLIME+jznkZWwKa2AJ0PzkAACAASURBVB7RSvgEFzKWhKEXpVMoymGt/0pK5MV4GLsi/K0NipH2BE5Xszq4kjxBPGGT3PEYLsFlsICoaV4U2CWiHiHF11SO8x+tcR0iJHCsklzzaJoDqljrqiVmvAqv920IMZbhM9iOEGMZYaaO+A0V4jdUiM9gO4Kn2CEfNpOgiTLy7eLQ2aTi8I4FPu9KUP9mCZucw7hXs4rucDWt3io6gqJ5uamF/+zdw40VhVxbkcNn20p50FHD496VPDvYwJfHevjy+D5ubG/mWuNmPtywhhsb13K3eQufdG/jiyO7+Pp4F8fykmh0FLJtyWIuO7txxt2DHUIh2wUC2mUO9Cpd6XJS0ePkxmH3ADpECvLfNWHtlMUcUwZwL7GAC/7xbF0oYLdAQZdERYfIiWPu/lwJi+GImxd9jkpOqUM45BTBMacETihjOO4awcWgWK5GxnM/I4dPc3L5PF/LQ52ep8WVPC2t4FF1MU/rK3ixro43OzbyTVcD3+xr4Zt9LbzZu41v9jTzTW8/Av/W3cDfOjfxumk1z9bX8lltKR9r8tkXGMaxkAROBKdyMiiFQ+p4DrnHcNwtmq0LpGyYLWDjHCGtVkr2yANosXFli4Uza+ZL2LDYgdULJOimCCic5YRulpJwIyG+g20JMVXgaywh0NSe7IVuBJrM5+O6dTze2MqDtQ30xWbR4hvPRrcYMmY4ETzMkhBjO7Lme6KzDCJ6sgOZC93ImNu//SNpuoKIsWJCTO0IMLIyAPAt/mIm9m8MiZggJny8iKBRdoSPEVNoEUidNJpd4XpOZFdzKq+SA8np7E9O4WBqGiey8rhaVsGdpTXcXlrCrTo9t5cVcHuZjltLtdysLeRGTTHXq4v+RwHwSn0ZV1dUcW1lNVdX1PBhfRVXllVzua6GS7W1XKyp4XxlFecqKn9AYRUXa2o4V1HJqZJSjmqLOJSv50CujoN5RRzOL+VgbjEtMekDABzIQAbyq9MPQHt3uuXe9Dj5sFcVwH7XIHqdfelx8qHHyYcuRy+6HL3odPBkl0zNLnsvdoo82W7nTou1C02L7Wm1cKRd4MhpTzUfhQbyaUokjzOj+SI3hpdl6XxVl8VX6zR8taGAl5sL+GprHl835PNqaz7fNmr4trGAbzbreLMxn282afh+Yy7frsnkVV0qX1em8WVxCo+zkrkbH8uVgGA6pf40W3qzcYGSdXMdWTlDwlYzJVvNFDRZKmm1dWOHyJ1OBx+6HbzplvZ38nqlroZj3b0O/R2+f6weqZpeqZo+ezf22TtyQCbjkEzMUZWMvY4iuuQy9rir6XL3YYfCj251AocC0zkfk8vdvGI+SorlUVE2Tyqz+bJey9N6LR+XZvBhcSr3KyN5Vh/LNxvS+cvWIr7boOfNmhK+X1fP5yUlnIhMpsczkgaxF2ut3Flh68NSGz/8Bi8h0FRCxMwAJH8QoDJRkmQRR74kg83BNWyLqifPIorICQHkWWdQLNORapFIlVcZufbpKI1lSAdZY/fOPEInupBjFkGtqoCEOQG4DxMTOFZJ7ExfapQagsap8DFxxGWwANUgO0ImuBIx1ZNl3oUs89KiEcTg+p4Z3iOsiZ7khN9wS/xHWBIxVkiwiTUBJhb4DJpN+Gg7XEyUKEZ74TU9CtUwOerBlvj8bgpno9N4tXwFzU5OdIcH0ZUWyneH2njUupJPty7lYfMqbqyt5vPdW/hi73aeneji8/N93D7bxb09DXzYUMvZ9aXc6ljH3a4NvDraDh8c4lp9KRtEQtqkMnqkTuwTOtEj7H8AtFOgYstiKStmWrNyph31M21ZOVdK9RRr8ozmUjTenKpZAjaK3Cmba0ey0WzyxltSOl3C8nnOHPZK5XpsMR2WLhwQqLnjG89t/yguunhzTR3ILa8QrqkDuRsUxYPIRB6kZ/E4v4AnRUU8rCjlYUUpz6pKeLmskldrlvJt2wa+6dzKq74m3uxv4bsjO/j2YFv/PMDeRr7tbOXfenbz9ca1PF++jOc1NVyNTeReajZXIpO5kZjPiaA4li4QsN7ahdIZYjTjbMgZZUHBeFuKp0oon+lA2QwZlbPlVM6WUz7TgZJpUurNPCmboyRrnJiwITYEDxXiN1jSv+LPWIre3IeI0Yu5WbueL5vaebC+kfaYdFqCk1nvHkPSZHuix4iJMBGSOdONMuswYsdJyZ6jImu2C+kzVCRNlhM5SkiEqYAIUwHRY8REjhISZmxLuIkdkaOExI93JtxERaSpB8FGUsJGCqkRB9LglciR1GLO5pZxJreYQwnZ7I/NYF9sEmcLUrhakc/tpUWGulnbf/Tbf/9Pz83aQj6uKvgBgzquVWq4VqkxfO/OsmJu1Oj4uKrgJz/7sFrDRzUFXK3Vcq1O97N4fFuXa/P/XjWaH+oHCFYXcbm6mMvVpYa6VFf5s3W+qrR/aHRFMWfKizhdpud0aTGnS4t/mA9YwomiYo4XlnC8sIxjulKOFJRyKK+Eg7nFdKRoBgA4kIEM5Fenfw6gzIM+hR97lP50y73pcvQyfO1y9KJDpqZDpqbd3oOd9v1z9bYLPGi1caXZUknDQgnbzGTsspVx0sOdK8H+fJIc8S8D4FcVqbwoSuZRZhJ34mK47B9Eh8SPJgsvNsxXsHaOAyumi9myRMGmRXK2mjnRZKmkxVbFDpE7u8Xu9Mo8DOjb56hmv9yT/XJPAwr/sfZIXOmTKNkrdmKv2Ik9Ymc67Rw5oPClVehGo8iTs4llXMqp5URaPnera7iYk8VNbR5381J5oEnjkTaFp0UZPCvO5PPCdD4vyuJJYRpfl+fxZUUuRwK96PX04GRkFPdL67mmrUc7y4HA9+cS9P4iQkfYoHxnHu6/Nydygpq0eRHkWGeQaZWB3qmENIt0tkZsZYW6ljzrFDyHK4ifFkaZQyHVqnLyxdksC6ghzS4BpbEMpbEU58E2RE1TkzDTh0JRCvk28XiNlOE+TEzkVE9WqIvxNZXjPkyM21ARbkNFeBrZ423sQK5NDFvCatiesJrUhYEEjpbiOdwGHyMbAoxtCRxpje8QM4JH2hAwdBE+g5cg+YMt4kGOOBq5IfudOT7vL2CNfQCfFJVzPT+fVi8PDqbE85e9rdzbUsPtjZU8al3Fg5bV3G9axZO+Fp4e3s3zk918drqbO8d3c233Wp4ebOHJ3m086Gzgb2f2cbm2nBUqORVWVlTPNWPdEhGbFolYN1uAxnQBhRNt0U2wIW+MBVmjLcgebU2aiSVJIy1JNLIgfoQFCcZWJJpYkzDSjDgjc8Len0/McDPiRpiRNGwhBeOsqJ5uyx4nX+5EZ3AvIpF7kfHcDIrkbnA0d4OiuOUfziehsXwalcjDlEweZ+fxuEDLo9JiHpeV8LSymC+XVvBqzVK+276Rb7sa+HZ/K98caOXNwdb+mYAH2/juQBuvdq3jbx1beL5+KXdKC7mYlka7yo8GO1dKJlqTN3IxacMWkDLCjHRja1JGLiFx+EIShy8k1diMzNFWZI+1IWecLTnjbNFMEqGbKqVohgNls5womCwlxcSGsCE2BA0R4P2eEP9hIoKNpRSaeRNmupBrlat5umUHTxu2syclnx3h6WzxTkSz0IOMmS4EDbMic6YbNaIYEiY6kDLVgYyZSlKnKUiY6GDAX4SpgNhxUmLGSogeIyZmrITYcVISJyqJHKUi3Ni1vws5woYV8jB2BKdzPLOIs3lFnM4p5EhSNocTsziSnMEH+gw+riowYO/20iJu1OgMCPwx+m7U6Lherf0J8m7U6LhVp+d6tdYAwI+rCrherf1FAF6r0/1T/RIAL1XruFSl51JVEZeqSgx1sbbiZ+st/s5WFPfjr0xvWB93oqjI8DL4qLaIY7pSjmpLOKzpx9+BnCLak/MHADiQgQzkV8cAwD1Kf/Yo/emQqdklcTN0/N7Cb7fUnd1Sd7ZL3Ngu9qDV1o1tVioazZ3ZukBM02IpO23sOeHuxqVAX+4lhv1LAPh1bQovy1N4UZTMw4xEbsdG/wSA6+c5s2a2jOXTRGxe7MzGhY5sWSKnwdyZJitnWu1c2G6nos9BzV4HD/Y6eBjwd8DJix6Jyz9Vn8SZPokze8RK9ghV9Alc6LZzY6eVgh6ZP412PmyTh3Bdv47b1Ru4t2opz7bWcy43gQ9y4vhEm8Jn+cm80GfwUp/Jl4UZPC1I54k2nZd6Ha9LynmmL6LXxZsGgYJGmSftfmkcjKtCs8CHgBECAo3tUf7BFvUwOa6DHEiaF0O+XTa5trlohBpSl6RS7lzO9sTt1LnVoJfqiJgcQsb8eKqcSyiTF1Ek17IuchXpgkRUJg6oTOxRDLEleronCTN9iJ7uTaZZJEHjVHgMlxA51ZPV3mX4mspxGSzAY7gE9QgpqkF2uA4REjPVizoXLa0xa6hXF5JhFU7ENDdcB5njPtScyDESIowFhI+0I9LEFr+h5igGS3Aa4YzjEEecfjufxAkCjsRq+DhPw/6IUPYlxXNjaSUc7+H66hLubarmk6Z67m9bycP2zTw7uJPnxzp5dqqbByc6uX1kJ5/ub+FBbwM329by/aEu/uPIPurtHShdZE7pXHNqZ9tSO9uWmqnW6McsId3YnPSxAjLGCUkbKyRpdH/FjxISPsKGCCM7YkZLiDaVEmUsJHWCjNRJTkQY9z90iBhpTdj784gZNIekoTNotlNwMSSRezGp3I1J5G5UAp9EJnAnNIa7QVF8GhbHZ9FJfJ6YzqP0bB7m5vNYr+dxcRFfVBTx5dIKvl5dx3fbN/JddyN/OtTf+Xt9oIXvD+/gz0d38efDO3m1fQXf7VjF58srOZ+TQbtvECWzROSMtSDNyJqU4bakG4vIHONA8kgBiUaWJIwwJ2GEOSkm1mSMEZA1TkT2eDGZY4VkjRORN8ke7TQ52ikSssfakTTSivChtgQNEeD5rp0BgLolXoQYz+dK6XIebWjhWeMO9qZqaAlOZqM6Dr25D1mz3Qgebk36dBcqbCMMAEyb7kzyFCfiJ8iIMBUQbmJnAODbihtvT/wEGYkTnYka7ULoSAXe71sSOtKGdS5RdEZlcyqnhLN5hZzKLuBoShbHUrM5mZHN5ZJsrldrf9L5u1GjMyDwZm0h16u1XK3INyDvakU+VyvyuVap4Xq11vA7b2F4vVrLjRrdLwLwZ4+LfwGAF6u0XKws5GKlnouVxYb6oKb8Z+tt5+9MeRGnSgs5VVrIiaJCjut1HNfrOarrfwl8pEDPUW0JR7UlHMov5mBuMfuz9QMAHMhABvL/FMMRcK+zL73OvuyWurND5GKAX7u9B7skbuySuLFT7EqryIVWoRstb7t/Zk5sniekcZGE7VYSjrm6cDHAhzvxIf8SAH5Vk8yXZck81yfxMCORWzFRXPILpF3sS6O5508AuGmRExsXOrJ5sSNbzZxotHSixVZFq43C0AHcI3Nnn6Pa0AX8RQCKFOwRKui1U9Fj40q7jQfbbdxotfVguyKYfeFZfFLfwGdrN/C/9zTysqmME2m+nErx4b4mgQe5CTwrSOelNpOvC7N5XZTLS30mTwr0PNFWcj+3mE6XEFZZKCmeIabczJv1igwSp3vjOUSK93AnBO/Y4vCeI46DlRTLS1gbuIZyp2IKJRr8xqppiNhEY+Rm9DItdR615FhnobXKpNKpmHy7bKrdy9mW2kCmKBmViQPORmIc37MkcqoHyXP8cXrXitCJbkRMUeNt7EDYJHfW+lYQNE6FapAdXiNlf78L+L4d/iPkpMwOpkahpSV+HSsCyiiUp+M3Xo7i/SUEDhcQPlxExLB+OHkPMUNtIsfN2BnZH+3wen8R9WIfbhUt5XB4GM1qJR8ureZV1w6+7Wzi1ppSHjYv51ZDLbdbVvBk7zaeHWvn6ckunp/u4cGxDu4e2sFnB9u407GRTzq28G3Pbq5X15AzdjpVs62omyOkcooA3XgLNKPNSRtpRuoYO5LHSEgZKyV5nIzYURKiTUTEjLInaISQYCMR0WOdiRrnTORYR4ptgiiyCSFmogPhY8QEGdkQNNSMsCELiRg8k+LJFrRJPPkoMo3rUQncj0vm05gkbofFcD80lk/D4ngYnczDhDQepmTyMDOHJ1odXxTqeVKu50VdOV+vruP7HZv4vqeJvx7dzXeHtvPmYCt/Obabv53o4C9HdvG37i18tWUZBxNiaHD3psLCnoRR1iSY2hEzQkDcSAmpoxzJneRK/lRXMsdJSTaxIcHIksSRVqSY2pI2WkDeZAeyJ0jJHCcma7yE3EkyssfakW5qRcIICyKHCwgdLsbrj4L+TS8m9mgXexJkNJeLRUv5bE2jAYBbfWNZrYpAb+5DxkwXwo0FpExRUGwRTPwEGWnT5aRMlZM4yZHYcVLCTewMx70xYyXEjJUQP0FG/AQZCRMdSJjgRNRoJSFGcnwGWxA9xo4GnwT2Jmo4m1/K2XwdJ7PzOZaawanMPM7l5fFReR43awsNnb+33by3CHx7tPtReZ6hw/dRef/fXa3IN3QBf3z8+xaP/z8A+BZ/p8v0nCot5GSJ7ocRMFqO6nQc0fbvBj6Ur+NIQTFHCoo5mNf/AnhfViG7k/IGADiQgQzkV2foO++8Q7NIxW6pO7skbuwQubBD5PIT9G0Xqgy1TaCk2VZF01v8LXJgw2xbtswX0moh4ohKyXlfT27FBv1LAPiyOokXpUk81SXwIC2em9GRfODjzy6hN1uXeLB2jpxVM6UsmyJg40I5W80U/d0/SyXN1goDADtEKrpESrrFqv7NHj8c9XaJlP9UfaL+rl+vnYouKxXtFiraLBU0WclZYybg2foV/PvebTxsq+J/H14DJ5dzQ6viRKQNN9I9uJsWzMPseB5lJvE4L41n+hweFWVyIzeak2nJnMzI41ByJvVSNQXz7EmfJkK72JfsWb4EDnXC810Znu864TlcTZxtDuUh66iPXEu+Uy5h013xMhZQJo+nSBZH0uIAvMcpyHNIo8A+iwqpjhJ7LamLE2lLbmZPUTcR84MQv2eN/WAbwxFw/Axv/Ec7EzBGgcY2gdSFoURN8+KgZidpi8JwGyoicKyS0IluuAwW4DPcAb8/2KN+V0KgqSvlbkUsD61jZWQ9Wnkm6RYRRI9yIvhdW0J/b034CAEu/2sBXsOlKN4X4PCbRTSqk7iSX8UnpZVscLClLzGUpz27+aJzJ59vXMbDDTU8aqrn/o5V3G1fx+2ezXxxqpMnp7t5erqbx8c6eXhoN3f3NfPsRBcvDuyiwdObqrmWbJojo36sLSvHS8gZZE7S4CWkmAqINrUj0cS6/yjXyIIEUzuiR9oQOsSMoMHmRBgLiDQWkzHDnTLrKOqdkzlVvZHTdQ2sDsqlQBpBzGwVXiNsCTQSE2okIui3C4l/35pWcQRHfMK5FhvPzag4PgoK5154HPdCYngck8KDmGQexKXweWI6X+RqeJqv5XFZIc9ry/h6dR1/2rmZP/U28+8nu/jr8Xb+fHw3fLCP/zzby7f7W7ldUU67dwjxxrOJHmVO5Cg7wsYoSJzlT5CpnOz5AWTP86TE0ofeyFK6w0pZLoyiYJYbEUMtCBtsRthgMwN+08bLSB1nT+o4e5KNzEgasYSEERYkjJIRbeqI7yAxgSMkhJjYo1nogd/QmZzRVHKnfiNft3VyMLOQ9R7h1Ej90C3xImmynJgxUjJmuFJhG0HadCWZsxQkTpIRN77/juCP7/uFGdsaOoFx4+2JHSclapSUyNFyQkbaE2YqIHuuM+2RWRzN0nNRX8bZ/HyOZ2ZyIiONCxoNHxX3d/ve3v172837uKrAcIz7trP3YVku1yo1XK3I58OyXD4sy+Wj8jzDke+Pj4XfHiX/EgA/rNb8U/0SAC9UaLhQruVCuY4L5XpDna8q/dl6C79TpYWcKNZyoljL4YL8H6qAg/kaDuTlcyC3gMOatw9B9OzLKmRvpo6dCTkDABzIQAbyqzP0nXfeoUmoNEBvh8iFnWJXA/52iFzYLlTRJlDSJlDSbKeg2VZFo4WCrUvkbFooY8NsWzbPE9BiLuSwUsE5HzU3YwL/JQD8sirxVwGwwVzZjz8rFdtslLTaudBmq6RdqKRTqKBTqKBbrDJA8GcBKHSlz86NXltXOi1d2G3uQquFnM0WEtZYWsHBNrjSzcPdOri8AQ4UcinRivMRFnye78PdJD8eZcXyTJvFU10uT4vzuZ4bx7EYNUcykzmaV8CBzBxKBU5kzxdTaKEidpyYwKG2BA91JGSoCr93FXgMcUPvVcfmgm5yVRpcxjsRMs2R6JnONEYVETDODr+xQlyMBSTbhqORplMh1VEsLSBtSRLdue3sK+nFb6oa6/+1GPvBNriOEBE705vISW4EjVPhNlREyoIQIqd6oh4hZW9OKzmWMXgMlxA83oWIKWrchooIMHYm8D0nfAY54DPCmRSrBArdCqgNqiJXmkKtWkepZQzxI+WE/c6GGBMZ7r9fjOcwCcr3bVG9a86FvBXcK6vnllbLekcbzhVm8KSvnY+3rONp42oebazlk03VfN69kfs9m7javpbHpzt5fKqLL0518eRoJ48Ot/P8bA/PT3Zzfm0VxYvMWGshZcNkIesnSNkwSU7uYEtShliSNkZGmJEN8SMtiBmyiIQR5qSOsiPJ1I6Y4RaEDF5C/BgpSeMd0C8JYIMqh12R5Tzq2M+X+05xoGwj6yIK0dhHohpkhfdQEUHD7Qn6rRVRv7dj1SI/9nuE8mFUDNciY7gSEMq98Lj+WYM/APCz2GQeJKTxJCefp/laHpXqfgLAP/dt4z9OdfO3Ex389WQHXD7If53r483ebezwCaJyrpC4EQtJn+pEyhRX3AdJCRznTtQ0Navc81mjzma1KoqLhRu5VtbCdl8tNTahxBjbEj7MgrCh5kQZWRNnKiBlvD0p4+1JHiclYcQSEocvJtHIkqQxjsSOdsJvsMQAwPwF7vgNncnp/ApuLV3PN7t6OZJTbABgoZk3SZPlRI+WkD3bgzpJHNlz3MmY6UzCRHvixtsTNVr0EwCGjrQh3MTOcAwcM1ZChImQiFGOhIyUEjVORMFiN7rjcjieo+dSURlnNbkcz0rnZGY6HxTkc61Uz606PXeW9Y9/edvN+/E9vre4u1KaYwDgldIcrpTmGFD4cwC8s6z4/ysAT5boOFGs5XhRAYcL8jmkyeOQ5gf85eWzP0czAMCBDGQg/7L0zwEUuxju/LUJlGyzcaJNoDR0A9sESlpsnWm2dqLJQsFWSxXrzRWsW6JktbmSpXNFrF4gYoullMOuHlwKDODThGgepIbzJCear8ozeFmbydfrC3izRf+zAHzTWMBXzTpeNRfxulHfPyJmnZav6nJ4UZbGY20in6SEcyPKj0v+rnSK3Gmx8GDVNCGrZwhZP0fK5gUymszktFo7s8NOxW6RK+1iFzrFSrqlSnqkzv9UvfYKusRyOoQOdInl9Nor6HVQ0ilyot3akT5zF/YscaNznjPbZglpWSTkv7Zv4j/3rOPN4Wr+sr+W7zdo+TDchauRbtxL9ONBWihPcmJ5rEvnU20mz2pKORIXwzonGUfD/LmTm8bHWRksF8hZKnKj0MwF9VAL1MPsCJ/si/swR+z/ly11ylK2x61jc3ANUdPUuA4Rkrkkmnq3YhrDVuM1whnnP4jxHK4ifWECedYZVHmVU+NVTpmrnobY9awLqcV3rBNqE3vcRwjwHSUleIIT0ZNd8PyjFcFGUvyNpfgaS3AdYsOutA3UemhQDLIkboYanxEiIkbJiTB2INRYQrCxmIARAoKNxYSPlxMzRYWfiYiIqUp0kljy7CKInuWG6+8luL8jxec31vj8ZgFJxrbcr1zH9aIqOoNCOJQWzbOG5TxqWsrV+nweNJTxqKWez5vXcHfbNu7tbOd+Zx/PT57i0ckDPDjezf0Tzdw7vZH/OHuAqzU1rFWoqDcX0SxRs2G+gtrJEkrHi4kbZkbw0MUEGlkQOVlM/AQLCuY5EDRoNqFDF1C4yJuQoZb4/XERwcOXkD3bGc1CJeW2ajpT9Lw4dpZvzl3helM7VzduZ5+2hqxF9oSPmkfIiNnUWqmpWuzCsrkOHHMN4IpXINcDwrniFchHPsHcDIrks+gkHsal8jghnafJWXyZnsfzrFyelOXwvE7HyzVlvNm5hu/3NfGnIzvgw0P9df4gXDjCZ1tXUin1JX2WK35Drfr/v0fJCTJxJGyCguQFPmRa+HFIv4Wo2VLO1jZxZtlm+hL1NLnEUmBiS+rgRcS/t5BwIysix0mIHudA3GgZSaPkhBnZEj1GTNw4GYFDbfF+1xL/QXaEjpAQPFxA2nRngo0WczJ/BVerN/FgQxNHc/U0B8VSLfVii1c6iZOkJE12oNDMlzKbYFKnOZIzT0HiNDnRE+wJMbUj2MSWsNFCwseIiJ5gb1gL93YgdJCpgAATKQEmUjLmuFAnCeVQkpZzWUWcz9FyNjuL4+mpHMlI5Yxew0dVJT956fv2kcfbu39vP/8YeD9Xb4+E/7E+LMs13BV82zl8C8l/rI8r8vi4Io/rlfl/R2WVnssVWi5XFHKhXMe5cj1nSnWcKdVxqlTbP/evrpJzFWU/DHnuX/XW/8K35IcHHkXs1xSzL7+IPbmFdGcW0J1ZQE+Wlj05xfRlF9GT+ffamaIdAOBABjKQX51/AuAOkQutdgq2C1XsFLuyU+xKm0BJq52CbTbONFsqfwLAVWYK6uYIWTVfyGYLCYdc3LkY4M8n8VG/CMCvtmj5uiGfrxvyed2g4dtGDd80afl6WyGvtxXzpqmIN5sKeb1e94sA7BJ70GLhwerpItbMFLFhrj1bFjrQZCanzUbBToEL7WI3OiSudElU9P4wx+8fq9deQZ9MyR4HleFzr5OKbntn2gWOdNu402frQ6elNy1mKlbMtOZBXRXft2/h4e5K/v3kNl5urudeUR53NBncyornXloEj3MTeKFJ5fPsRB7mMNQiTwAAIABJREFUpHE6MIg97moel1ZyX1/GwdB4UicuIWe2jPTZCvxN+/fxxswMRC/MolymYbl7GSkLQgiZoMJ9mJCIKWpKpFmUO+QSNdUP5R/FuA+REzEpkIxFiejF+dQH1qF1zCXdNonGuA2sD60jfLqawIkqfEfL8DGV4DtKit9IMZ5/tCLUWIa/sRQ/EymqQVYs9dTSl99M4Hgnoqe6ETrWiYBhItS/MydwuICgkSJCTaWEj5YRMqa/vEbY4jnSjtApzoROccZ3jAT1e/bkz48nytiRzGku9IaX8GFBLU3uvqyRy/lz9w44vY/ra8t42b6RRy31PGvfyNPOJh507+KzvT08PLifJycP8/jkfh4f7+HhkWY+P7yVtgh/trq6sFIgZpOtI5st5ZSYLEJrtIACo8UkDzcnZvgSYoytyZwpZ4XUl/WOQeRNE5ExWcRycST6BT4EDjEnxMiaQjNfdBZehI22IGKGLTePHubRhfM8Pn6S785d4usDJzhVUE2zVxTFswW0O4VxKUxD0zwZB6SunHf15mP/MD5w9+Ujn2DuhcdxJzSG+xHxBgg+Tc7iSVomT8vyeb6slJfra3jduZk/Hd7Of10+yP+5dJD/c+kwf97Xzq3lVewOCyBrshXp40RkT3FGO8eLglm+BL7f/2Ajf74vmgU+tAaXkDLDgdP69Txo7uHjqg2cSCxh5TwX9GMEZBlZEz3Siqhxgv77d6YSUkxkxI+REj1GTNQoMbFj5cSMdiJ0hJQIYxmJE5WkTnMiaow1R7OXcmfFNh5tbuGUtoy2sEQqxWq2BeRSaOZN+gwFRRb+lNkEkzxFRvZcZ+Im9w9+DjG1I3SUwLD27e3+37cVYmpHoIkd4ePlRE1SUCYIZqtXMmdyyriiLeeyVs8HmhzO5GRwpiCLi+WFfFxX9qsA+Pbxxz/WvxKAH1fk/f3frdBxqbyAS+U6LpTrOFtWyJlSHadLtJyt0BsefJwqKfphxEsxR7Q6jmqLOKotMgx67svR0ZutoydLS09WAX05OvblF9GTVUB3poaOtFw60nLpTM+jLWlgE8hABjKQX5/+VXASV8OL3587Ct4uVNFqp6DFVsE2KxUNVi6sN1ewdrGClUucDQDcZC7moMqND/z9uB8X+YsA/HqrjleNGl790Pn7rqmAb5t1vGrR83pbMd80F/PNZj1vNhT+IgC7JWpaLdWsmSFm7SwxG+fJ2LrIkWZzJ7bbKtkldKVd7Ean1I1uqQt9Dq7scVD9U/XJlP37fZ3d2Sd3pU+mpF0qY5dYym6BI11CNR223mxZ6ELVJDtyTefzUVEp33a0cbg8mWvry/mmfTuvGrfydFU990rzuZEZyb2saJ5qU3mmyeRpfg6XQqI47hXCPW0NF9KKaFAEEzR0NpGjbAgZLcJjuAjlICEFgjTW+tSw2qsKrXUS7sPEuA8TEjfLhzzrOFLmhxE2UU3K/Ah8jVV4jVASPjGA5LkxlDvqKXHVk2IVT4JZNDvTm9kcuZywaR4GAPqOkuI32h5fIxFe71kTbuqI30iJAYAacTy70zcSPVNN+EQlQaMcCBwuJnCIEP+htgQaCQkbZU/kWEeCRknxGynEc7gNHiNs8BsrxXeMBHcjG7yHyUibEULWLC9WyZM5l7uWvVGZNHr40h0VA8f28++HOvlgWRH3G5dzZ1M1n+9Yx8OOBj7du5vPjvTy8MR+Pj+xl0cn9vDl2b18eXg7t7YtY42jhAYHB7Y5K9nlrGabQEnNRAuKRy1Gb2pOypBFxA6eT4KRJSWL3Wh2i2S7OprS+Q6kj7dhsyqVFq8CUiY7kTVXTbkgEo2ZD0mzHSlwDODOB2d49NElHp46wbcXLvLN8VN8tmYrp5LyWWXuwE4bF64HZ9Jl5sQeGwdOOrlxxSuQsypPLnsGcDskmhuBEdwOiTYg8EliBo9TM3hWoePL5ZV8tXEZr3sb+f54B3x8gn/74AD/dfEIr3dt42RmKuvlMpZaKSmdp6BgqiOVi3xYahFG1GBbooaLqbCKIG+2mkrbcNKnO3BWu45Ptu7mZtV6zqeUsWGhG6Xj7cgZaUG0kTmRo62INLYhdrgtSSNExI+REmEqINTIlvjxziSMVxEyXEKYkZSMGWoSJtoTPdaGfSkV3F/dxuMtrZwrqmJ3dBoVIg+2BeRSJQwle44rpdZBlNkEkzTZnszZcmImSg0DoMNGCw3bP8LHiAgbLfwpAkeLCBsvI2aqgqWOUbQFZXIur5zLBSVcKtByPi+TM7mpnC/M5mKFjqs1Rb8KgL8EvX8FAK9X5nO9Mp+PK/7+91fKCrhYpuFimZbzZVoD/k4VF3Cusujv9/yKCjlZ3D/n73CBliMFeo4U6H/Y8qGjN1tLT5aW7swCOtPz6EzPoztTw+6UTHanZNKRnkl3VhZ9ubl0ZmcPAHAgAxnIr44BgD+e9bdb6s5Osath9MtbFLYJVLTauNJo7cp6cwVrFjmzfJGcmll2rJhrx0YzEQeUrlzw8+VebMQvAvBVQyGvmwp406zl22Ydf9qm47tthbxpK+ab1lK+aynlu63FfLNR/4sA7JF6st3ai3WzpKybLWHTfAcaFstpsXzb/XOnU+pBl707Pfau7HPyYL+T28/WAWd3Dio8OODszn4nNw55uLDfVUmPQkmbxINN1u4UT5cT/v4c4kdZ0BycxoOGDnJFUtJsbMhzkPHRxpW82beL/zjRwVcttXy2UsPzNZXcLtFzPC6NusWupJvYkDnJgbSJDkQY2+H6rgU+RjL8TBV4miiJnxfJGu9qlrroyTOLxnuYGB8jKaETXUhfHErqwlBiZ/gTNzOAzCWxhI73QvlHKWET/EmdH0drTAPLAmrRO2soUek4XLqHxtjVeI92xNNUhpeJhMBxjgRPcCJolIzA4WLiJrjgNUyAn4kUj+ECImepWRNYRpk8neipboSMkeM/VEjqFDU+g6zwGWJNsLGY6PFOBJpK8BxqjdcIW7xNhPiMFuNpIsBthDVuQ22RvDOH1a4Z9CZW0+SbQpVIQXtUHLeWreCjZTUcLyrgyuqlnKgu4dLKSm7t2MCdnkZuH9nOndOd3D/Xw/0THTw6upsvD7Vzo76KnphwupRKDnt4ciYgiCOeAexR+NAh86ZN5EWTtRq9qQUp780mfdAC1i5xZ6WFAydjstkTmMoqW0+yJ9mTP8uVwsX+FNtEkTzbk7jZbqz0yePKpj08u/EhX938iK8+OM1fLp7n386e5FVzMw+r6jgRFsF2M2uOOai4FxzJMamCYw4qzqo8ueDmw0UPPy56+HHVN4QbgRHcCY3h06jEfgCmZPFlVTlfr17Gq8a1vD60i+8/OMCfPzrGXy8f578+OM7t6mo6vf1pESs4GJnGDt8Y8meLKLNwZ4trMitliVTZRbJGkU7hkgAyZrvREqzn03V93FrXzK2KVVxOLaHF0ouVM+ypnCgkdvgCIo0WETp4AZHvLSJhsDnhwywIHGZB4FBLwkaKCR9pT+AQIQGD7ShcEkKIkSVRY6xpCcris3U7+XxjM1drVrI/XUu50J2NHinUO8SgW+JDpSCMctsQ4ieISZshI2JsP/KCTWz7j54n2BM5TkLiNGfiJjsSPkZE6ChB/9HweAn+pjZET5WxwTORvgQdZ/MKOZeTy/m8TE5mxnIqJ56LJVlcrMzlUkXurwLg28cf/1j/SgBeK+//ncsl2XxQlMsHpflcKNFwtkTDqeICThZpOFmk4USxxnDH7+0L36M6neGBx8E8LfuyC9iTmU9PZiFd6YV0pGrYmZTZX8mpdGVm0JOTwSF9LicrtXxQX8b55eUDABzIQAbyq/MTALbbexgguEviZhgD82MAttm60WTjxjozZ1YvdKJ+oSPVM21ZPseWDUuE7Fe4cN7Xh7sx4b8IwNeNet40a38CwO9b9LxpK+bbtjIDAL/dVPSLAOy19zIAsP/+nyONS5x+AsAuezXdMg96ZW4cUHhyUOHxs/UWfm8heC7Yn0OeruySSalfIKBytojcyfZ4/246kabWaKw8ubqijU3hyawJj2ZLWiI3d23g+aFt/Pn0Dv56dAtfdSzjRdtaTmjyWK3yI3KMBNXvLfB73+b/sveeUVEneKK2Z/fu3JnuNqKAmLXDTLfdRnLOmSKHIuccKlBVUFVQ5FAkERRRUcxgziISxJwDEhRz1rbD9O7M7sy+c5/7gZYzvTtz3tvvmbnzfuA553fqX/9T8Pk5v0joZEuCJ1vg8UtzfKY4EaQvIOnLeOQWUjR22YiWxRK/wJdwAyci57gT+7EPaV8KSflCSNKvhaR8Hkb0ggDiPxYSpOtF+uIEJMvT2Je5i+qQSvJdcylwV9FRcIjNiQ1jAuina4NwtiOhc5wI0bUlfLodyfO9EHxkQsB0a3x1rIj42JM8h3RkprEEzrAZE8CUuZ74f2iE74eGBE81J3a2E0I9G3wnm+A3zQzvaaZ4TjXGa5oJPjPMCdC3JVDflvbESg6mldPgEUOzbzgXNKUM1TVwtriQ7oI8bq9fw7WmegY2NfLw0HYenmxn4HQbd862M3h+Dw/O7OHRyV3c2drIvtgodvr40iHw4Zx/IJfDIjkTHEG3XzinfKI57BHJAZdIaj91IHfqUqQfLqbqEzs2mrtxIiyZrhgpe/1TUH7mgmiBE4mz7Ehc5EHyr31pjiimt3QP33UN8+LSed5cvsC7Mz3825ke/qOrg1fr1nKvpJCr6akcd3PmhIMDI7FxXBT40+fqzVl3X64HhHHVT8hZd9+xXsChiHjux6aMloDTJbwtLeXr1bW827SWb0/u4beXO/j+Sid/vH6aP13spU+cTbu7H3vsfTgWn8axzGwq7bxRrnCmwjaEVW5pFFvFkGMoRLo0gDzLSPqKtnB/wzGGmloZKKrlYoqKzcs9qVloQfEsU1KmLyNBdxnRE78i4aOlpE8yIuyjZYRONSJCx4zQKeaETDRHOMkS4SQLik3jEE5ZQcIcc1oCM3i8bjcjjRvpr26kM1tDkYUXq1ziqbSJJm9lEKUWkRSZhpEw25L0j22J0Dcb6/97f/ItepY1qZ+4krTQiXA9c4TTTQjRMUaoZ0aQrhFxi2xpCcngeEY+ZxUqzkjEXFCI6BXH0ydL4lqJjCvlci6X/DwBfD/88V/jbyGAt0tHJfB64aj8XcoXc14t5bxG9t8EsFst56RSSnd+7tial46cHI7JZByRZnNUquCoVMFhsYKDWTJ2pyvYnZ5Le5r8x+yfjIPZUk7mKzlVoORMRR4XazTcaCzjSuO4AI4zzjg/n0kTJkxgq43nTwRwj73PTwTw/XqY7Rbuf1MB/K5VyfeblfzbFhU/bFHz3XbNmAD+sFHz/yqAO0z8/psAbjUaLf/uthb8Hwlgh5vPWPn3mLMXHW4+XIoK45jAjY3Ghsj0P0Ws+wVps8yJNzAn89duRM61oCu/iX2SEvYqNAzv3cHDYxu5f6CR16fWwYNjMNLByz0ttGdlIDZxwkvHGrtfWREw2Z7IGS5E6Lrg/ksr3D9yxFvHA7WdCo2jmrSvogmfIyDCwJW03wQQPd+duE98kayMRrIylugFfggNPBAaeCFelkjKb6JRmkmRG2VxQNROoVc+MhsROfZSjqr3sSV5DQEGTvjpO+CvZ4twtiPC2Y4E6lgRpedI6kJvPD8wImC6Nf4zbAhf5EH8F/5ELfLE4Z+/IlTfgZApViTOciPgI2O8f7WCgEkmPxFAfx1zPCYZ4virJbhNWomfniW+M6xI/sKXA5m1tEYpKLUNZFdUKq9bdzKyZh2Xqyu5Vl/DYOtGHuzaxtO923nTc5AXZw8zdH4Pd863ced8G08u7ONx5y7OrSqm3s6W7W4CTvv5cyVIyM3IaK5HJ3AlPIELYWl0+MZy0i+JjSt9KTEwQfHRV5QYmHDYJ4I9AiEdYRl0RctYax9HpVkkok88SFzkgcI4mguVhxnefIHvu0d4drqHl2d6eN15jG87jvLtwX08rKvitlrBtaxUzoYGcNzFljsRYdwShnHBK4ALXgEMhMVyKzhyTAb7hdEMRybwIC6VF2kSnmdm87a0lHcNdXyzuYlvu/bz26sn+eZSJ3/qv8CfLvZxLC6FHY6jd6uPJaZxoaSMjSFxyFY4IF3qSLFtFKVOSaQt8UFhHs7aMBXP2y7wctdphtdt4bamir44KU2f21M2yxD19OVk6a0geeZy4qYuIXnycrKmGRP64VIippsSq2+NcLIZgR+YED7VhrApVlRapxA6dSXJ861oCczg+cb93F29noHatXQriiiy8KLKPooyywg0RiGUWUZRZBpG/CwL0hbZEK5nSuiM0Xg/+PFeABMXOCKcbkLglJUETF5BoI4RQbpGJHxiz5ZwMackxZzPzeOsVMKlXAl90kTO5aRyq1LBdW0u18oV/78VwIt5Is6pJGMC2Jcvpzc/h261nG61nBM5Yrrzc+ktUHFKlctxuZwjUulPBPCQSM7BLBltqQraUkcF8IAkl6MKNZ35eZyrLOW8tojLdYVcbyzm9rpSrq0tHhfAccYZ52fzkx7APfY+Y+ffdlp5jH3fZe3JVjMXNhs7sd3Mi1YzAeuM3Glc5krtUicqfm1O7edmrFlqzmEnV876+3E34a/fAn7fA/jNphy+bcnhhx8zge+2qPl6k5pvN+Xxry0FfNek5l2VjDfFWTxTpXI/I5qB+BCuCgUcdPZjh7UvjV/Z0rTEho3LHdhi5MROExf2WrpzwMaLI7ZeHLX35Ki9J8ddfTnh6k2ni4BuZ3e6XVzocXbhuL0D5wL82bDSkFYzS8o+/gz1fGsydCxImmJChWEQDTYxFK30o8oulC3BIs4XNHCveRe36zdzMEvGrepCXrU1wIWD8PYO/+vWKe60rSNm5Uo85nxGwjJHMpcJCTFwJsRAgNc0F5w/tMVtkgOBBt6IjdJYI6yj1q8CqUkG6csSSVocQ/BsX7ymueA60Z4KzyLCFgShsJYisxQjs5GS65iD2kVF3PJ48gUFtOXspiGuCcEcX8Q22RzTHGFHxiYSvghFaOBB2udCwvWdiTRwJWiyJSmLBETq2xE0xYyASSb4fLCSSH07Ymc7ETbDmuCp5kQbOJD2iYComfYIdcwJmmJC2AxLkha4EjPLkdDpNgRPsSFkqi0e/2yC3wd2hE5zo2CFJwejRBxLkrHa2Ye1Hn48b2nhDyeOMNBQw5W6Qh5sW8397XWM7G7k/vFtPDi9h+FTO3lx9iDPT+/j4ZFtnClTszsugh2+3vSGhHNBGMVlYTAXQ3y5GOxPf0Isd1PTGMmQ0p+URX+ilC7/WNodfGk182SXlT87TL057BhBpyCRS5EyrqQV0hWn4Iy4hM68anqrmri17ygDJ7oYOnmK5z3HedVznO9OHuG7Q/t5vqmZwYI8rqSncjkxhjtxMZwRCLgaGMi96AQGwmK55B3EBa8ArvoJuREYzq3gSAbCYsfiUUI6TzIkPC0u5u2aBn67awu/O9fBH+6c5Q8Dl/jP/kt823mc/TFJbHHxZZOlG1s8BLSFhNGdruJESiF7ozRs9M+nLaaGk7mbOF+6i4H1R3jUdpx767cyUlXG5axMjoVGoV1qR+58U0S6hmTqm5NlYE2qnimpeqZkzDIlae7olG7wjxPC4XrmRBlYEaFvQa1r+tikbrVzKpfKtjDQtJnba9ezX6Kk3j+W7BVerPJKp8Y5mWLLSLK/8CJjkQNRM1Yg1DEkTNeMyJmWhOmaIZxuQugMUxIXOJIw34HQGaYETzMiaKohfh8tJmneCjRGzhxPV9ErL6Q7W0V3tooTWRK6ZFL6lHJulBdyp6aUu3VlY7v+/jz+stApuFQk51JRzo+TuaNxpUTJYF0pt7QFXCsbndq9Wqoae75SouRKiZJrZWqulam5Xp439m50wON9n5+Mi4UyLhcruFSUw4WCHM6q5VzQqDifr6RPmUNfrpIzShV9qjx61Pk/DnqoOCFXckKupkORx2GxgkOiHA6JcjiQKedAppzDCinHlNl0ahSc0+ZzqbaAq6vz6V9fzJ0NRQxtLmBkexGP2koY3l4wLoDjjDPOz2bsEsh78Xsvgm02XmPPO608xgRwm6knm029aDJ0o3GZKzVLHP9mAvjN1jzebc7ju835PxHAtyUinqvTfrYAHrUTcMzBi2MOXnS5B9Dt7ku3uy897l50e3jQ5eFFd4CQa8kSchcuJ/9zS+Knf0bk5JWEfmBI5CRj6u0SaQ9V0hYu52RmKRdUdVwvXs391S38655DvGpt5Ua1Gs7sg/4euNHJPpUIjcAdT4Pf4DNnJWkrg1BaZhExLxiBjisuH9nhPtmRtKUJ5Nvn0BRWzxphHesjG8lYnkTIHD8CZgpwnWiPwy+tcJ/sSJV3Kb56nsitJBS7a5BaiRFbipBaS0g2TqEkoIz23D3URTfiou9BklEqvZXdtEm2obITk7I4nKxlUUTOciPpYz8Cp1qRMM8doY4lfh+Nlna9f7WCaAMHog0cCJthTcg0C6INHEhe6EHUTHuiDKwJ17Ui2sCO5IUexM1xJULPHt8PTPD70JyAiZb4fWhOqI4jbUEZnBcXsNUnnDp7Vw7Ep/Cn48f5un0b/Q3V9K+r5v7ORu63NfDg8EZGTrdz99xehnvaeNG7j+cdbTzZvYn2SCHbBV7s9RRwLTSW/tB4bkaEcy08hKthQgaTErmfIeJBlowHYgUjWbncSJByNiKNzoBYDjgJ2WMXzBYjL465xXA1Ss7NZBVXk5U8Ll7FnRIt/dpaHrS28rBtO4/at/Ht0T38cHw/b9q38nZnK8+b1/KgooybCjlXMzK5nphKb0Ao10JjGYoZPQF3xTeEi4LAsVUwf0kAn6ZLeFpYxJvV9Xy/fTO/O3OC/+g/w59GbvDHO5f4+uRRjqeJ2BMYyU5nP1psXdnm6ktPnIxLojKuZ6/iXGY956SN3C7dzFDNFh43b2d4TRNXiooZLMijOy6BNq8Aij41QWKwlHSdL8mebUH2XBsyDczJNDBHMteaxDk2Y2XahPkOY0Ma8fPsqXPLIG6uHfHz7KlySuFy+Vb617QwtGEzR3MKWBeagsLIh2q3ZFa5paEyDCJ5nh0ZixyI1TciZNrKsfUvITrGBE8zQjjdhIT5DiTMdyBM1wz/Scvx/WgpsbPNkHxuRaWNgE5RHqcVRfTI1PTIlZzIEtEtl3BWLedGRQF3aooZri39WQJ4oWC0J+9SUQ5XSpRjotdfXcTd1RXcqSnmaqmKy8W5XC/P+4kkvv/ttTI1V0qUXC7O/TP5e/+/s38UQcVo2Vcl44xKwRmVgrPqUfnrVeTQrcjlhExBh0JFh0LFcVkuR6UKjkhG+/+OSOQcEmWPfe8tUXOmQs2F6nxuri2mv7mMwZYyRraWM7K1nIc7y3ncXsrzfZXcbysZF8BxxhnnZzNpwoQJ7LD3Zr+TP/sc/camgd/LYLutgO0WbmwxdabVxJktxu5sMvFk7UpXVi9xpupL+7+ZAH67LZ9vWvP5vlXD7zYX8dvmfL6tUfCuTMKLvHQeZsUylBjK9TCfvyqAbWZu7Lf25JCdN8fsvTnh5M0JBx/6PISc9QjkrKcfvd4Cun28OOkr4Jo4h8HCWtz/x8cI9Wzw1rEmYaEzksVe5BsGsjdGw2XNei7nN9CXXcGNwnr6S+u4pilnqLyaoeoaBpuqGdncxJ6sTKQmZoTMWkrsx7b4TLPG+UMrvHU8qPJZRZmgjjKPUrSCEprC6tmVtoWG4Bry7BTkWkkpcFTir++F7b+Y4/yhLd7T3fCc6kzEwmCaIxrwnOaCxCyTav8K0o1TSVgWT4phMjIHOWVBFaxNbqYpYzPx5unkehVwtuE8VaGVtCSvJXSBDwGzXcmzTR/tJ/zMjzA9ewImmeA/0ZiASSb4fmhItIEDcXOcidCzJVLf7sfMnyUh08wI1zMdXe2ha0XYdAdCptoSMNEaz38xxPtXhrj806e4/o9FZH3hQr+mknNpWTTY2NCRlMhvt7byza5WhtZW07+2ipFda3mwZz2PD7fwrKeNB9cOM3x2D68uHuHpjg305UjY4+/HfjsXTrn5csUvnKHQBAaCYhmISeRWVBw3I2MZTExnJE3MvXQJdzNkDKZKGM6Sc1eq4nZ6NkcFYVyJy6bLL5Fzwen0eEdzyjWY/ogMjth50Bcg5FpcEsMyCbcl6VzNTOFBQSH3C4u5kpvDs9X1fLd1K683tPCqaT1vm1p4W7OOR/la7mWo6Y9MYiAslusBYVzzD+V6QNhfzQA+T5fwUl3Am+oavt3YzL/2HOEPN07zH4OX+d2Ns7zuPMr9tc08Xb2OZxWrua8oZiBTxe20XO5llzAiK+V8tITraUru5hQzoirkQUExV7LSOSEMZZ+XkPUmbtR8YUnuzMVIdX+NZPrn1C5zp+xLJ2SzzBDrmSDWNyfOwBLhdBPCdM1I+dhlrEybtNCJMtt4hNNNCNczR20cSo+6ifMVq7jfup3O/DK2xkuRrRSQaxxInWsqOcv9SZxjQ+bHjkTNWEHYDOOxKd+gqYYETR3NCCYvciZpoRNJC53GpoHr3ZMpt/ZmnXconWIlp6QKTmSJ6BBn0SHOoE8l5mKhgltVam5XqxmozvtZAnguf7Qk+14Ar5WpuVGRz7UyNffXVDFcX87VUhUXCxXcqMjnYqFiLMv3Put3tVQ19u5CgfzHIQ8ZZ9QizuaJOZcv4WyelDPqbHpzJHTLJfQopJxR5dKXq+SUNJsOSTYHM7I5Ks39cZFzDoclUg6KxBwSZ3FIksZRWSZnipVcqSqif72GgZZ8hlsLebirlMft5TxuL+f5vkqe7a3g6Z5Snu0r5cWBcu63j5eAxxlnnJ/PTwTwvQTuc/TjgHPAWCbw/SLo9wL4fgq4/iunv6kAfrddw7dbNPx2SwG/21zED+s1fFebw7syCS/zM3gkimM4KYwb4b5/VQDbzUezf4ftfTju4MMJJ286HH3pdQ/Ar+YpAAAgAElEQVTntHsIpz386RW40+XjzElfV25Ls7lbqMV9whwCJ63EZ5IZ8sVurLIPZZcwi9vFzTxfs4c+uZZT4iL6FBV0S4s4kaHkcmE1d1Y187xtN83RSUgMHYhZZELGZwJSF/nhO8kZwSQXgmcFURvUQFNMC3UB1ZS5F6BxyEVinE78byKJXBRCiWs+MrMsPKc64/BLKxx/ZY1AxxV/fS9iPwunJaYJP30vxKYZlHkVIbEUEb04ipgvo1E45VASUEZ1ZB2r01tQeBdSHlFHZ3U3clc5VcGlhH/iT7phDFpvFcmLgwmb5UTIdBsCJpkg1LFEqGNJwCQTwnVtfhQ+C6Jm2hMzy5FwXRuiZ9kQPduU6FmWRBlYjwrgFEeCJjki+J+jvYHO/zSPkBmLqXAK5qo8lyMhwWz39mSoOI//tX8Xww0VDK6pZGhDDffamniwbwNPO7bztGc3j68e5n7vbl6d2sPl/Fz2+vmx2diCPhc/rvuGMxgcR39oPLfC4hlOyGAgNpXbUUkMJWUykibhbpqYkSwZdzOkjEgV3JcruStVcC4qievxEq7HSrgSlk6XZzh9npEMRIjYa+JCjyCUqxHJ3EzK5Gx0Ap1BkZyNTKc3Ko3jMckMFFfypHEdD+rX8KRxHW/WbuTrmjU811QynCTlZujoypebQRHcDIrgdkgU/cLovyqAr5Ua3lZW8c26tfxw6hB/uNbLH4au8Pvb53nbc4J7zet53NjM06pGXhRX8zCngIHMXIbFagazlPSEJtIVEk9fRAo9oYn0hCbS5uhD41Ibqj42p3S+EcVzV1I4bxlFC1dQvGgla008qF3ujNzAGJGOIVkzjIj7MTsXomNM4gJHYmbbEDvHFtEXAiodkgjXMyd6ljVq41BO5zfTW6Tl4daddBdW0paai2ylAPESL+pcU1EbBZMy357U+baET1tKpP5o+TdypiXB04wI0TEmQt+C9M/cSZjvQOICR8L1zAmeZkS1Uxz1bsFsCYnhlCSXTomMY5npHM9K46QknbN5Yi4XK7hVpeJ2jZJ+repvkgG8VqZmoLaEW9qCsazfjYp8LhTIxzJ8f54NfP9utL9Pxrn8bPpUWWMSeEYt4bRSQrdcNCaAPQoZPXIFnRIpHWIZh7PkHJWqOJY9KoDHZDKOZks4rhBxUiWip0DG9boiBpsquLu1gJEdeTzYpeHp3pKxeHmwghcHynm+v4zn+8t4caCce7sKxwVwnHHG+dlMmjBhAtvtBBxwDuCAcwAHXQLH4r0Aju4AHBXA93sA3w+BaBfb/c0E8PsdBXy3tYAfthby+9biMQH8plzKK03mzxbAE46+dDj70OEUQI9rJL1uQnrd/en1dKLb255T3vbcSEvgfl4+0RM/JknPmDhdK9a7hHE0Mo1zojyGyhp4vnoLnRl5dElLOJ6Rz7ZIEZujRJwvWce99fs4V7URmYU/UQtsSPzEncxPQwmf5kmkXiCRBiFEL4hAbCmhMlhLbaCWfPscUr6Kw2eGO0GzfMhckUxTWD1ZK1PwnOqMQMcV14n2+Op64K/vRcTCYDZErSFkrj8Ss0w0zio0bnmEfRZKwHx/su1llASUoQ2voTSmHo1Qiza2kf1FR0i1SUcjUJHnKmd9Qj1S8wRC5rrhN92aYB1rAiebEm3gQNRMe4KnmhMyzYLgqeYETzUnZpYjMbMcEepYEj3Lhti5ZsTOsSbawA7hNAeCJjkSONERn1+Z4vU/l+E/5TfkGruyPTad7oQ4drrY0ZsYybu1dfyxvZWblXncXV/D3U2rGG5by739G3ja1c7j3t08OX+Qp53tjGxfxw4PD1pNLNlvZs8NDyGDgbEMCxO4GZHAzfhURtKyuZckZig+k3upUh5kyBnJkPJArOC+SM6IVM49mYJ7MgWDmRJuJYsZTJFzJTSZM97RXA9K5WZIOiccQjjjl8yVKCmXE5X0Roo5EZRKd2AmnSFZHI8VM1BSz6C2nttlWu5W1vJAW83z/CKeyFQMx6ZyLTCM6wFhY/I3GB7HUET8XxfAnHy+Ltfybk0jP3Qc4D+u9vCHoSv8YeAS786e4nZDIwPVqxgqreZeXgHDilxuZkm5mSXlSoqIzqBYDngEc9Ajgj1OYexxCGXdMg9K51hQZGBK2VwLtIssqP/SmtXLbGhYbk2zqRt1yxxRGBgi1lmBZIYp8TMtCZpqSMDkFWNXOeLm2iFfFoDWMZkIfQti59iiMhJyOr+ZnsJKnu3aw9nyOg6IC8gx9iXjCzdWe2SgMQ0leZ4dcTPNCJu6hNjZVsTMtiF6lvVY/9/7IZDImZbEzbUbvQIy3QStYzQbA2LZHZNMj3w0W3Y8K40TolROStM4pxFxtUzB7Rolt6oV3Nbm/E16AN/39b0v6V4tVY0J4HsJ/PO/Gy35ysfk71x+NqeVmZxWZtKnyqJPJaY3V0yXLIvenGx6FFI6pWI6JdLRkCo4JsnliETJEYmS43IFHTk5nFTKOFui4mKlmmu1GobXl/Ngs5ZH7YU83qPm6b58Xhwo5sWBYp7vL+Lt0QreHCnn5cGysRhpG+8BHGeccX4+o0MgDu7sdhaw29mHdidf2p18aXPwZYetD9usBWw296TF1J0WYzdaVjiOXgJZ7sXqr7yoXuxJxaeOVH9qy+rFtuy1caLbU8CdmGAeZUbzRBLDm8JMvtZK+HpNDu/WKfl6g3JsD+BvW1X8bqua32/L43c78vnddg3/ti2f77fk8W2Lkrer5bzRinhRmMoTcTQjicHcCfPihKMbey1d2bDYgo2LrWhd6sD2FW7sNHJjt7kre62cOWjnwlFnJzpcnen28uC0QECfwJduQSCnvII44SWkMzKDvlQlLUGJrA1KZGNUFn2qJo6nadkVrqQtSkpHVhG3KpvokpVyMEVFnok/8qW+FJjEoloRRaFVIgVWiaR/7kfUPFci5rkRqGeH9zRbXCdZ4D7FBocPzAhd4Edr0XG2afuokrQTYi5CLaynWdKOxqecHKd8pMZZxH8aTuAMT1IXR+M42QbP2a6U+RWQuCKW+CXRiC2yWC2sJW15Gj56Pqht1WgFWjROBbSmbWFjeiulgZW0iLdSGV3NTtVO9hXsQe2lwH2aJc4fGCFZHk7ETMexYY+wGdZEzbQn2sCBcF0bwmZYE6lv9+OghxVBkw2JNTAk0sCUcF0rfCc64PkrJzx+4YDHP5vh+U9fUmXpzZXcIu4UFbJT4EWLgwOPKyv4oWUDD2u13F+3isHmOgZaG7i2o5H7XW28unWS4Y7t/NB3hAt5CtbZ29FmbE2XrQfdZi7cdhdyxz+agdAErsencDUtg0GZgiGpnGGJnLtiGfdEMh5kyXiVq+GFRMm9hEzuxqUzkpDJ03QZLyRKHmbKuJcqZjg5i8HEDAYTM7gcGsPV8DiuRcRzMzqJWzHJ3IpN40q8hFuZKu4oiritLGYgv5yRylX0a8q5otAwpC7jfn4ld7JUXAlP4FpoLDdC47gdnsC9mDRGYtMZjkhmKDSBQWE8QyHxjIQmcS88leeqEt5U1vFubTM/HD/Iv1/s5j+HLvHHwYv89lIXw1vXM7i+kVt1VTzKL+BxtpL+pAxuxqdyLSaJ8yGR3IhJ4npkAjejk7gZncQZ/1A6PQNp+sqMHVaurF1ixi57V3Y6u9NsasMma3cajZ1RzTUhW3cl2bomxExcScivliL8YBmxMyyImmZK6jxHZF/5IV/iT+gMU3wnLyfHKITTmib6iit4u3cPw82bOCbNY7VnPAlzzGkNUJL9mYC0uU5ETzUh+xM3QicbEjbVhPBppgRPWkG4jgnJ8+xInmdDlK4xMTONiJlpRMIcM9Z4RnM0RURnpohusZSTGRkcTUnkaEoip2Ui+is0DNeUMKDV0F+Rx53KfK6X53GtTM3VUtVYb97PjfcZvZ9GLpeL1H8xLhYouaDJ5Xx+DufyFJxVyzlXmMPZAgWn82T0qKR05UrplEs5KcvmhFTCkSwRR7MkdMpy6FZoOJyhYX+6kgOZcno0cs5Xq7jaoObOZiWD29Xca9Pw+GAJTw6V8uZYGW+PlfHmaCmvj5Tw6nAxLw8V8fpIyX+LkXb1uACOM844P5vRU3D2bux2FtDu5E2bow9tjj7ssvcZE8BNZh4/EcD1K11pXOZJ/ZeeVH3hQekiO7QfW7Pqc2v22jjR4+XNYJxwTABfF2TwtlLM12ty+Lop9x8jgG7unPHwHu0B9Aigy92PDvdATobEcTlTwfmcAjqluZzMyeekqIReaQ0XVKu4WdbErfJ13KxYx5bQdGqdw1EZBiH63JeMT4MpME2l3D4TjWUSKZ/5EmrgQJC+PT7TrAmZ5YaPrhOe0+xwnWyLv4EHqtA61muOs6u6j7KE9awV72Jzzj5qIxqpFdZT51eFylJKzIIQwuf64TTJGocpVuQ6SUlZGU/8kmjivoqhwruEUo9SwhaGUepRxqqAVcgtFawKq6cpaQPrUzexSbKNZtFGtuVsY13aWjJtUnCbaoHnFAuCdG0J13dAqGNJ0BSz0Vuz+nZE6tuNCeD7ix9hM6wJmmpE5ExDQvWNCZlhgc9H9nj+ygH3f7HF/Z8N8fynL9jqG0+/ppJbajXbPT04EBzE67UNvGlew0BlCY82reHJro2M7GxmcH8Ld09s59HZ/bw+d4gXB7exMySANVaWtBtZ02ntxiVHPwa8whkKimM4IpmbiWncyhAxJM/hriyHe9k5o+VeiYJHYsWoAMrUPEyT8iBZzMMUCU8z5DyV5PIgS8a9dAnDqSKGUrIYSsmiPyGNgaQMBpMzufvnfYSifEZySrmv0XK3UMtISQ0jlasYKKzkhqqYkQItDwuq6M9UciU8gethcdwKT6A/IvH/SABfV9T+RAD/OHiRPw5e5IfL3YzsaOFuSxODjat4VlLKc6WGoQwJg6ki+pMyuBwZz+34VK5HJozFhYBwerxD2GRoS7udJxsNbdjj7MleNwGtlo5ssfFknYkr+fPMUOgZIdc3I2biSoQfLBsTwGgdM9LmOyH5wpvsL30J0zXDb8oKZCsC6VI1cLZUy5s9uxla18JRiZoGrwSS5lnS5CFG/LEHybPsidUxQ7LIhUgdU6JmWBA1w4JwHRNi9C1JW+hI0lxronSNiZixnCi9lSTMMWOddxzHUsU/EcBjqUkcS02iTy6mv0LDUHUxdyrz/6ECeEGTywVNLufyFGMCeEYjpy9fRq86mx6VlG5lNl05Mk4p5HTKZZyQZnNcnM3JbAWd2WoOZ6o4LFJyXJbLhYo8rq7WcGudhqGtKu7uyufBngKeHi7j2ZHycQEcZ5xx/u6MCWC7kxdtjgJ2OXiz017ATjtvttt4s8VyNPu3wdiVjUautKxwpHmFCw1LPVi12APt5+4UzLWkbL45NZ9ZsNfGiV6BD8MJYTzMiPqJAL5tVPxDBPCkiwvdzu6cc/HmvKsPZ1286XX24pSzJwec3DgbE8ujyjJuaJRcVMu5VVrNcNU6Hje00l+xhj5FGbsiJWgdw5F+6Y5yZRSZn4cQPzeYctscqpxlqEzjiF/oib+OFYIplnhOsiTxN0JC5/niMcUefwNPvHVd8fpNOJqYJtq0PWzMPUBr7kG2yPewNnE9a2OaqA+sQmktIW5RCMF6nrhNscHml8aIzZIRmaaQuCyWwPn+KOxkbEpqJcM4ixKvckoFFcR8EU+acTqFvqWsT93Eqvg1tCq2sTZtLUWBBYjs0ghd6Eni54H461gRqmtHyDQLAiebjt34DZ1u9ZPPqJn2hOvaEKJjglB/JSH6ZgRNt0TwkS0ev7LG/ReWuP/zMoI+XEJvupq7xVrOZWbQ6uXGBYmIH7Zt5kFDDdcrCnm0vZnnB7Yysnsjj4/t4GHHTh52tfP9uaOcr9RQvnI5jcYm7DOzp8vWg37vCIb8orkbmsjd6FT6kzLoz5IwolByXz4ajxQqHilUPJareJGr4XlOPs9kKp5JlTyV5PJEnMMjaS4jYjl3s7IZzpQynCnlblY2QxkS7mZlj2YQpTk8zM7loUzNQ3U5j4uqeVxay8OyWh5oVzFSUcvdYi1DhRU8Ka3lSUEVd9LkXI1I5GZEwugwSFQy92LSuBeT9lcF8GluEa/Ka3jb2MT3R/fz+wtdYwL4r1d6eNS+hUfbWniwoYmXVVW8LCplRJbLiFTBsCibW0npDKaKuBaVwNXwOK6HxXE5OIpzgZG0W7lz2DWAnZauHHb35bCXP20OHuyy92GDuQfFCyxRG5iSO9OCuMlGhH64nLCPVhCvZ0XMdHPSFziT8ak74s8FROhbEDDNEPESX47LarhQUcOr9jYG1m7gqETNWp9kUhZYU2OXhOQTTxJn2pKga0nmPAdi9SyJ1bcmVt+aaD0LEmbbkvGxM4lzrIicYUTIlC8J01lK0jwLNvon/TcBPJ6WTEdGKmdzpGMC2F+R939FAC8Vqv5i/Nfs31m1nF61lF61lB7V+5DRnSunK0dBV46CkzI5HVI5x0RSjolkHM7KoTM3j75CDf2NpQy2lHBvawkP2gp4uLeQJweLeHGsnJfHteMCOM444/zdmTRhwgQ22bqw096d7bbubLFyY4uVG9usPWm18GCTmRvrjVxYt9KJdcsd2bDMnnXLnalb7ELVZ86UfuJErp4RBQaGVCw0pt3Snh4vb+4mhvMgPZJHoihe5qfxujyLNw1y3qxR/GME0NGDs47enHPy4byDF2cc3Dnt4MYpR2dOurkwKE1lQJ7OvQIJbxpXc1tTSkdSJgdjJRyMVdLsJUb0GwGizwOJmCkg9fMoqr3KKLLLJdcomaSPAwjTd8Vnki0+Ux0J1vdAaSEi5tMwnD6wQWSUQcqSZNIsJeT7V6CNakTtU0xpYCXlwZWU+BRS4KIk4uNAfPWc8dKxJ0DPCa8ptrhPtCJzWQzJX0aRvDQW35leBC8MpDygmqb4jRT6VCB1VCGyUaBxL6BSWEOeVyEa/xKaRRtxnu1M+NJQigPy8TNwJGyeO5FzXQmZbjPW7xc63YrQ6VZjgyAh0ywQ6lgSoWdL1Ex7wvRtCdCzwl/fCj9dG7ymWuIx0QSPDw2J0jOkwTWKocIKOqNj2eHqwMG4CG5Xl/J0azO3N9QxuH0tt3euZWDfRp6cbOPFyXb+dK2Hu9ub2BwVhPKzT9hqZcdOCzvOeAVx1TuU8y7+3PaPYig0gaHIZG7Hp3I7OYMnuXk8yc3jqTKf5+oCXuQV8jK/iOf5RbwsKOHr0krellTwqrCUx2oNjzWFPFDnc1+Vx31VHg/zNDzM04xmEnOU3MtV8UCdP/o+v4gXVXW8qK3ngbaa+5VVPKypZaRCy+PKal5U1fGuvI6XeWUMJkm4GZ3EnZgU7sZncC8+g3sxadyNTv2rAvhIruF5iZZX9Y18c2gPP5zp4I+DF/nPoUv8/nofLw+28WbfLl7v3Mqz+loeV1ZwNz+f4bw87ipVDGRJeSDL5XpsMtci4rkRHk9/RCK3wpM45xvNmYAYTnmF0uUrpMs/lA5BCAddgthh7Yv2Y1uKZllQaGBN0jRTIiYZEjnZiCQDW+L1rMj62I2MT92RLvYhfp49ofrmZH3pzSFRBZe0dTzfuYM7a9bTIS9gfUA6KQusqbSKo9QkisSZtqTNtidWx4QYXQsip5sToWNGtJ4F8bNsSJprS5SuMVG6xgRO/JwwnaVIPndmV6SEE+lSTmWJOZUlpiM9nVOiDHqkIi7l5dBfoWFAW8itMhW3y9V/dwG8WKD8i/E+8ze65kVGnzKbrlzRjyGmWymhW5lNj1LBCamE4xIxR7JEHM4QcSg9i0MZmfTmK7mxqpi7Gyp5vbeW14eqeHOkktdHS3l9ooy3Jyt4e0rL287qcQEcZ5xx/u5MmjBhAi02zuywc2ObjRubLVzYZO7MFkt3Npu702LqyrqVTjStcKRpmQMbltnTtMyJms+dqPzEkaKF9uToGqKZuZKy+Ya0WdjR5eHFUHwo99MieJgVyYu8VF6VZfJ6tYzXjfJ/QAnYhVMu7vS5enPO1YdzLt6ccfLitKMnPW6+nHAVcDYqhlsiMY8KCriUqaAjOpPd/vEcDJezN0yN1iqJaH0nUj4OJFjfjYylsdQFliI1SiT983AiZ3kRpu9OwDRnAqa7ET0/kDxrGfG/jkYwzZ18hzzy7fMp8imlUlhDaWAlycYpJKxMJGF5LCUCDcUeauK+CCZ4jjt++k64fGCKx0QLBB9Zk/J5GLGfBJOxMpGQ+QH4zBKQaJROfXQTDYkt1MY105y+jQ2JG6kKqyPFLAOFh5rCkBKCvwwmx0NObVQlThNNcP3IhCBdW4QzbBHqWI5l+8J1bfCfaEyEni1BU8wImWYxOgFs4EDETEf8Ztrh+2MIZljiNc0E7ykryF3qypHEHC5lSWlzd2errRVncyTcrq9gcHMD/dvXMHKwleu7m7jfuYs35w/zTc8B/v3MMQ5JUpD+5mMUBrM44e7DETs3LnuHcs0vgtOO3twOjGYwLJGBqGRux6ZwOzGdJwo1TxRqnubkjQngC00xLwpLeFVcxpsKLa8rtbwsr+BRUTEvtFqelJXxqKSEh8XFPCop+cnzk7IynldW8kKr5YVWy9uG1bxas5on9TU8XlXN88ZV3NeW87RKy+uaGt6WVPAsN5/BxAzuxKQwGJfG/SQRD5JEo9m/qJS/KoAPZfk8Larg5aoG3h3czW/7TvDHwYv8P8OX+f31Pl4dauft/jbe7NrGo4ZaHlZXMlSgYVAzKoED2XLuy5XcSkjjZnQSt6NGM4/94clcDUnifGAcfb5R9PoI6fIVcsonlMMuwbRZ+1G1yJbiWRYU6luRrGNG1BRjoqYYkzzLjsSZNog/9RgTwNg5tgTPMCHjCy8OZJZxoaKG5zt3MLSuhR51GesD0kmca0GZeTRVVgnEzrAkY64jEZNWEDXdjLCpJggnGxGla06cgTVxBpaETVtBlK4xIVO+JEpvJcrlAvbEyunIyP6JAHZLsuiTS7miUdJfoeFOZQE3S5X/VwTwfan3v8b7rF+fMps+ZTanc6V0K8VjAtiVK+ZUjoRTimyOiUUcycrkQFo6h9KzOCGR0SmXca26gOH1pTzZruXdoWreHdfyTUcl706W8fWpct51VfB1l5Y3nZXjAjjOOOP83Zk0YcIENlo7sc3GhS1WLmw0dWSDiQOtFm60mLqywdiZphWOrFlmz5oldqxfaseaJQ5U/dqB8kX2aObZoNQ3HhPAHabWdLi4cTsqkJHUcB5kRowJ4Kv67H+IAB53c6bD24MuHwE9Pr70egXS6xFEj5uQ6xFS+hPUHPJKojdKSVdkLlscItknSOd4iJKNjploDePIWxrHKmcV9R4adqU2simxiiQjPyI+dSV2gYBQXQ+iZ/sSbuBNkK4X8R9HUGCrRrQyi4xl6dT517MqYDUN4Q2sjW6k0r8cbz03/Gd5ITZLpjawiCI3OfYfGGI64Tc4TzImUM+BmLkCIma4kflFBDKjFBpDqlFYS4lZHIWzrideC4PYqjzA/vIudqoOoXEvwHdhIIJ5fsjdVWQ4iuiq7+LMmtMU+KpwnWKOcI4rgTNsCNd3GNv3934SOGCSCRF6tgRONiVoihlhM6yJne1E1BxXfGd74jfXDb+5LvgaWOMz04gAvaXsjZdwU6Nlu6sbG81NOCpw40XrGoY3NTDQ3szAgRZuHWrhTudoz9/g8a386VoPV+vLiJ2tS62pCbttnNi5xJQeZx/OugVw3i2A/qAYBsMSxwY67iaO9uo9kubyOFvJY7mKZyoNL/IKeV5QzIuycl6UlfOsooKnlRU801byRFvJd+uaRqVuVR3Pa6p5WqXlaZWWZ9VVPK+p5mVdLW9W1/O2YTVvGlfzqE7Lg7pKBrUlDFWV8nCVlofVFbyo1vK6uooXKg2PxHLuJqQzEJvKcEIGj1KlPE6Vci8mjaHI5L8qgPelah4XlPG8tp63+9v4rvcY/zl0iT/dvcK/3zjDq0PtvNm3i1c7tvCkuYGHjbUMV5YyXFHCvdJiRtR5jCiUDKSMDrMMJ2QwGJ3CQHgyt8LSuOgXywXfGLo9AjnlGUi3l5BjzsG0WflStcCaIj1TCmdYkDrDguipJsRMMyV1jgPJs+yQfOZJykJn0j9xI3DKStx/+QXxCx1pS9LQV1zBi107ebBpGxdKalkfkE7MTGMUi30pM43G/xdfkTnPifCJy4nRtRgTwNiZViTMtiV2pgWBH31JjL4p0fqGpCywotw6jAOJSk5myugSSejMFNGRnk5vtpjzSgXXi/Lor9BwuzyfGyW53CpT/d0F8Hx+zl+Ms2r5WObvdK6U3hwJp/Oy6VVL6coV06nIokOWxXFJFh3ZUo6KsjiQls7RLAlXyyq5U1fN4y3VPNtVzsvdFbw7XMq7E6V8c7KEb7uK+Ka7lG+6y3l7qpLXJ8d7AMcZZ5y/P5MmTJhA40pXWky8aDX3YYuFL5vNvNls5s26Fa40LXdh3QpX1ix1on7xqPzVf+VE+WdOFC5yRDXXDs0Ce4rmW1K2yJwtJnYcc/XidmwYD9KjeSSK4pUmnTcVIt40yHm7Noc3zTljAvj9ZiW/3ZTDt5sUfLdDzffb8/jtVjU/tKj4vjmHb2uyeVeexevCNJ5IYribEsKNCC+OuXqw28aF5iXGNC8xZuNyMzYbWtJu7Uy7tTO7bVzYZ+/OUTdfjnn6c1jgw3HfQDr8hZzyjeCkdxgnvSI45RZLr1cSN4IV9DincNwyhqPBJXSkNHMicyNa3xLKgrTUZ21lg/IALepDtMr2sDquicQvoxDOFCD6LIzQSQ4kzBQQa+BD9Gw/ZMtTKXctRGwsQmIiZl3MBtZENbMhYiNV7lrybPIJnC8k0yKbVTFNrI5tJNEwCdcPrPGeaIfgF5aETXUjeKY3QbP9ERllUOJRRGNEI6vDVqOwzyHqq1iSjdMI/zKaZLMMCv0qKAuuJd5Civ+SeGQhtazJO8CJjVhobV8AACAASURBVJeRBxbgNt+J2E+diTYwI3W2ObEzzYidbUXSQicS5jsSPcsGv6nG+OuY4zfDCn9dawL07Qic6UiwvhvC6X54T3fDQ88Rt9kmeM9bSdi8ZQwU1DGUU8GhgEj2+Ag5EpPE1xvWcr++gqf71vHo5EZuHmtkoK+Vgd5Wvr1xkjMl5dRaCaicbcum37jTttSaTjtXTrsIuCgIHDupdjskijuhMQyGx3E/NoWH8Wk8E8t4KpXzTJbDc5Wal3n5vCws5HVFGW+0Fbyu1fK6ropXtVqe1lbwtF7Lq6ZVvFxbx5N6LQ9ry3lUV8GDmrKx5yf1Wp6uruL56lqe1dbyrH4VTxvqedpQz5PVq3i6qo7HlVoeFpbwJEfD42w1w8lZ3EnJYDAtg5H0LO6mZjAQk8hgZDyD4XEMh8ZyLziGe8ExjAREMRwYxcNUMc+VGt5qV/Hd3v380HOK/xy+zb8P3uCHm+d50bmfR/tbubt9La9aGnnTvJqntRU8KC/iXoGa4Rw5w1IpwxlZDKekM5yYyr34VO7Fp9MfmsiNoFhuBsdxKziaq/7hnPMO4aizP232PpR9bo1irjGZM1eSPtuRsIkWhE40RvKJBylzrElfYE3afCtKTIIJnbiSiCkmZMzzYH9MKf3VTTxq3sjTjVvor25ka1gKGZ+ZojH2Jd/Ij8gZo7KX9YkHIdPMCJxmSuA0c6INnIid7ULMTCcip1sinGRInL4R+ctcWecRxbGkbM7LcjgrEdOVlkp3ZiqX1XKuFygZ0Gq4VaXmplbFjcpcrlXmcK0yd+w82/XyvLErHv9f4s+very/33u+MJ9zBXmc1ag5k6+iL09JX56SrhwZXTmjPX49SgU9SgUd0kxOSsV0yXM4pcihU5bDsewc2tPT2JOZxgFZCkfVadxaX8T9nWU821fI6yOFvD1WzDcdZWPx7clyvuko492JUr4+XsLbY8V8d7iA7w9o+P6Ahnf78vl6j4ZXezS8OVDCmwMlvD5YzuvDWt4cqeLB7vFLIOOMM87PZ9KECROoX+7EBiMPNpkKaDHxYr2hO5tMBTQtd/mLArjqS0fKPnWkcJEj6nn25M+3o3CexT9AAN1oXmJK8xJTNi63YLOhNTstnGizcmG3jRt77Tw46OTNUScPjtuZc9LRgk4XR7oFgXT5RXIqIIl292R2+0g5ICxjm3chmwSF9Eg3crP8AIOrT3Ekfzd78vawp/wEJ5suc7jmNKtjG8lzU5L4WQjxC/zJ/ERIwmwfMj8RkjQvkNi5AeQYZlDuWkiWYSZiYxHr41pYF7uRKq9qiu2LKHIuIstUTLGgjLWJ61G75xH6qRDnD0cF0OMXFoRPd8d7sjNeU92I+SwSmbmEpugmNidvplhQQqalmGx7BXErk8iykVIeXMWqmCZq45pZndbKluITbKs8SUXKGlKdRIR+6Uu2UQDSL1yRfeZA4hwromaOLuQN0zUfXfBsYEPAdItR+dOzwV/PlsCZjgTpuRIw1Qvv6S54z3L+3+zdZ3DUZ5rv/f95ZmfGYxs85JxNBksiCKGcc87qVs45dbdyzjlHUCCZaDBJBImcjcFEE4QIQhLKAnvSnj17nu950aAxM3jP8dbOVk2VflVXIenfaukNqk9d933dN0Yz1uP8uSqSdUY8SC3lWnAcW/Qs+NrBnZtJGbysLedJdT6vjjTReaqZeyfreHp9L8+ufEXvlRaqnVyRLlhL2UIj6hbqs1dJm1N6plwwsf5PAbAnPZ2+/Fz6CvLeA2BXWQGd5QX01VfQV19BT00p3dUlvKot40V5AZ0VhaP466oqpruylJ7ycnqqKumuqaKrulIOwQ8A8HFwFA9CI3kYFkFHeBRPwiJ56BvEQ0//UQA+cZEjsMPRaxSAXQmp9BeUMfLVAX48e4p/e3iHvzy4xR/uXOXVqYO8OLiN9p11vGqsoq++YhSATzJSeJwQx2OZ7D0APvYN5rFvKPddA0cBeNfFexSApyzFfG3iRJGCPsmL1JHNUx0FoOt4lVEARizSIWyB1nsADJ1jyn7PLO4U1tDZ0ExX03buFVezwy2E8KUbSVAyJ0HJEvGENXhNUyd8kSkuk1RwnLgBp0mqeM8ywGe2MV7TDXCfpI5o/DoCZ6uSpWxJk40fraHxowA8ExbK2chQrifHcisj6b8NgO/O97uSFsfl9JQPAvBMQuzfVZtMQptMwqmYONpi42iVya92+yoinK+jIziREsmZXAkPtuTwYl8+PQezGDiWxdCJHEZa896rnwPg60NpDH2dxuCBdPr2pzNwKIeBQzn0H86n/2gRAy3FdIwBcCxjGct/IuMFQWDTRkt26Tixz0DMNnVbGjdY0KBsTo2iITWKhqMArFytR+UqHUpX6pGzWJ/0hfokz9MjcbYmaXNUyV2kxpdqBpwws/6HA7DF2JK9mhbUrVKjbpUamxU0aV6rS/NaXb7caMxudTP2alqwT0v+uhYje9psPDjrHMQ533jOBKZzMiSba7m7uFr4NSfyDnK8oIXzNec5VbSTy+W7aSvcTrFnKukOcUTpBeO91o0gZS9CV4vwW2hB2HxTJEvsCZxrhUzBhxhFXwIWOhOp4EeRRRaJ2nEErw0lRiuOUtdqchyKidWOJ0k3iVLnUirdyql0K6fAJgvrqcaYjtfBbpIB1hO0Mf1IBefJBrjNscF1lg02vzfE6vcGhK7xI1kvhlzLdHJtMtnsV0u1VwV59tlkWacTaxxDoWcJzdJtVATWEWuRiMFUbeINQtkRVkyjSzTVZt5kK5tTZRZEwloH7MYp4TJJBe/ZOrjN0sFxigYO07RHAWg/TQ/HqcZYf6KP6Wda2M7QxWKaEpkGIq6mlXHcLYCDdm58aW3HzdRURvbuor25lO59dTw72sT9g3XcO9pM99XjdJ49wr60BBzHzyZw0jLqV5nTvMKI/RsMOGtowWVzO67bOHPTXjx6uPLfAvBllIxOSQyd0li6EpPoSU6hOy2NV7nZ9ObnjgKwv7yYnooiXlYU0r+pkoHNVfTWldNXX8HA5ioGNlfRv6mSvvoKXtWW0VNTyquaUgbrqhior6ZvczW9m6roqaugs6yIF4V5PM/KpCspla74ZDrCJLRHRtMRLaVTEsPzKClPAsPo8AvhkYc/7W5+dIh8eeLiw1MneSewIyiSF7FJdGcXMrhnH29Ot/Kv39/iz99/xx/vXmPg3FG6jnxJx+5NdG0qp6emlM6SPJ7lZ/E0K42O5ESexMbyOCKKxyHhPAoI4ZFPEI98QuTLwC5+3HHx457Ih5sO7ly1FXPaypUDxo7krdQmYf5GJHNUCJ6hi9t4DTwmqCFZbE7QbE2kywyJWKQzCkDPiaoEzjBku2MC32aX8WrrDl42buNOYSUHAmTEKuoSuVSX8MW6OI9XwHOqGqELjHGZtB6nyetxmboRnzm6+MzWx2OaFq4TN+A2cS2xKw2oNnblgFcUl2JTuSyL42J0FGfDwzgXFcbNtATuZqf+QwH4Dn4/Pdz5UkrMKPwupiZxPjmB88kJnEuKH+36yad833YD4+I4HRvLSYn8uJdjUVKOSKL4OjqME0nRfFedzv3mNF58lU33oRyGTuTxui2fH04X8uOZIn44XcgPpws/CMDBI2kMHZbXwOF0Bg5n0nc4i/6jeQy05DNwvIj+E6X0nyil4+u8MQCOZSxj+cUZLwgC9SoW7NJxYq++iG3qtjQom7NpnSnVCgZUKxi8B8DyFVoUL9d5D4BxM9RInb2RnIWq7FQ35KS5zT8cgEcNrdijYUHtSjVqV6qxWUGLpjW6NK/VY4eKMbvUzNinZcUBXVt26Ymp1Qtgr0cerRF1fJe1h9s5u7iTt5MbmU3cyNrEufhCLiaV8G1WFdfKd9Ca30xjWDaeCla4LDXHepYBYeu9id7gR7SiO0GfW+M/S5/A2ab4z7UkbLkrocvEeC90JE49knKHQiI3RhKmEkmyaQbZ9kXEGqdSICqh0KWIxsAGip3yybNMJ0E7GuuJelhP1MNlphH2U3QxH6eK7SRtTD7eiNWnWm+ni/UIXuVGnGoI0RsCCFnrTZZ5IvtidrBXtp2d0Vuo9C0hyyEdqUEUouWOWM41xnKqBgWW0ZxOamC/TwJfOodSoedMhYk/iesccZ6ojPt0DXzn6uE0RQ3naVp/B0D7KfrYjTfA5BNVLCap4f65OpvFoXTW7uQrKxf2WjhwyMuT78sKGTy4m/ZdFXQfbaT9UCOPWrbSffEwvZdP0VpRRqy+Ca4TF5G6WJPyz/XZtcaCrzcaccHEmquWDnxr68J3Dq7ccfb4IAA7I6W8iJbxQhLDy4REupOS6UpNpScni1d5OfSVFtJfXkx/eTGvKovprioexV5PTelot2+osYbBhupRGPbWldNbW8bwpgqGGirpb6igd1MZPXUldJbn8bwgk+dZqXSnJNGdkMCzyCieREl4KpHxUhrLi2gZHUHhPPUPHQXgU7Ecgc+c5Z3AJ4ERPJMl0JmRR9/O3bw+dZI/37vJn+7f5I93rzF04Rg9Lbt4umczL2pL6KoqHgXgs+x0nqel0BEXR3tk9CgAH3oH8sAriAfuwdxx8eOuyJ/7Yl++c/Tgmp0rZ6zdOGDsSO4KLeLnqRA9ewOB07RxG6+B1ySNUQDGrTIlarHeKAC9JqnhN1WPRmspV9OL6N32Jc/qm7iZW8qJqFQy1CyIWKJDyEItRL9XwmuaOiHzjXCeuA6nyWsRTVPBd64uPnN0cZuihnjCOtwnrSF1nRmN1t4cDZRxOS6Fy7KYUQBekERwKyOJ+7np/y0A/Cv+pFxKiRnF34WUxFH8vaufAvBUnIzTsbGcionjeKSUlkgJLZESjsoiORoXzplMGQ+aMnmyK4POA+l0H8pgpDVvFH/vAPjmVMEHAdh/NI3BI/IaaMlk4Gg2/S05DBwvYOB4AX0ni+ltLaOvrZyOQ/ljABzLWMbyizNeEARKvtCjfq3JKPxqlYyoVTKiYpUuVV/oU7fGeBSAJUvVKVyqRfbneqMAlE1VIWmGMjkLVdmtaUybpd0/HICH9a3YrWZNzXJNapZrUr9KhwYFfXZutGTHBnN2qVqxX9uBs7YBXHKO4G5wOjcC07jmm8Qp11iOu0g46iTlfGAOrX5ZHPXJ5Lh/Lvtck0hc70KUggPe84zxnmtF3NogsrUSSVWLI2p1ME7TrRDNtcVvpRj/lWJCV7njMc8G/yXOSDYEk6grQ6IaQYRGNMnmmZR715HpWEyOuJwm6TYao5vZIdtO6BpvfBY74v+5PZ6zTPGcZfoWXdrYz9TFeqom7nOMcZtuhHiqAeJphthN0MJqnBrxqgEkaocSsc4T76V2hK/3JF43mHAtL6zm66P+0RcYf7IO0Qwd4pUcqTQO4mufVM5LMjkeFEODpStxCqaELTFGPGUj4imquE1Tx2WaBi7TtXGcrjMKQNspOthN1sNxkiE2EzWwm6bGZlEkZ2NyuZtSzCmxN0fsnfkmLZ72pkoe7NvEgyPVvDjdzMPj2xi43sa/fn+LhogYbOatxHrSYgKnKJAwR4XaVcbsVrbiqKbpaPfvp8u/HwLgiwgJzyIlPI+W8SIunpcJibxMSaErK4PunCx6SwroLy9moKKEvupSeqpLGGyoZrChmt46eVftHfjeLQ2/6xAObq5geHMpgw2l9G4upruugM7qXF6UZ/G8MI3n2Um8SkvkVXI8nZJoHkdE8CRKwotoGc8iJbQHhPLEN5h2r0A6PAJ45urPU7Efz1186RD58tg/jPaoGDqSM+nZ/iXDrcf5451v+eO9G/zp3je8udJK34m9PN/XyNOqQl6UF/CiOJfnBdm8yM3kZWY6zxISeBIl4XFIOA/9g/ne05/vPQN56BHCPXEA910D+d7Vj1tOnnxj78YFey++NnEiZ7kmcXM3IJmjgt9kDdzGa+A3TQfJYnMCZ2mQrGSFdJkhORtdEI9bh88UDTwnaFJpGMyFpFy6mrZyt7iCi8nZ3MypotExkJCFGvjOUsHlM0XEE5TxnqaJ8yRFnKcq4TpTGf8F2vjM0UI8WRnxREW8pq0hX9OWnaIATobFck4awyWpjIvRUZyLCOeiNJK72ak8LMj6hwLwp1e6XUqRcjFZwoUk6Sj8zicnvNf1u5CSyLmk+FH8tcZIOBEt5ViEhMMhERwJj+K4REpbkozrpencrcui+0AePYez6TueysDJdEbacnhzqoAfThfyui1/FH4fAmDv0VT6WtLoa0mj/3gWAydy6T+ZT9+pYnmdLqPvbCX956roaCkcA+BYxvJPlCBBEO4KgvDj27oqCILJT55/JAhCtSAIw4Ig/FEQhP2CIEz7m/eYKwhCiyAIfxYEYUAQhEJBEP7lF/4e4wVBoExRn03rTGncYEGTiuXo8m/FKl0qV+uNArDqC32Kl6hRsETzPQBKp2wYBeAeLZP/JgDasEvVhprl2tQs16Z+lR4NCobsUbfjSxUrdqnacEDHmSsukdxzD6fdwZF75iZ8a2LGRQsXLtj5ctYpkmPuWexzy2WnTx27g7ZR6VRJiXEChbqRJK/zRrbCh9S1UUQtDyJHKx3pmmjcF7rjs8ILl6XO2M62JHKND14L7Ahd5U6afixxWtF4LHdDqhtLhl0+tYFN5LlVUhO+nbKgGiqDa6gPrcVlgTW2kw1wnW6E72xTvGYYYTtBDbtpGjjO1cNmhjZOk7VxHK+J8yRdPGaZ4jHHDNF0Qyw/U6fQMoEMgyisJmvjOMsI7+W2hGq44bzEBLMpGzEfvx6HCSqU6PpTaxzIbpGUK7IsjgdEU65nTbqKHbGKtnjM0MBlkgrOEzcgmq6JaIYOTjN0cZyug91UbWyn6GA7SRenKQY4TtNFPEeXQ2FZXE4s4nxwAhc9Ajjj6cXT2mJe7K7n220lPGqt4/n5Zr4/tpW+a20MXruEh5I6qr+egsf89fhP+ILQz1awS92ZfRttadEy44qFPd/aunDTXvwfAvB5ePQvAmD3227fcFMtgw3VDDXWMNJcJ1/yrS2jt658dEl4qKGSoU0lDGwuoae+kK7afF5U5fwdAHtTEngplfAoPJz2yGieR0l5GhHNY/8Q2n2C3gPgM1f/9wD4OFLGk6QMurftYOjkMf5w+zp/vHeDP9+/zg9X2+g/uY8XXzXRUVnA87L8UQB25mXRlZXxQQDe9wjgkWfoewC87ezFN/ZunLZyZa++LakLNxA9XYmwaWvwnaT+dwBMXWuDbLnRewD0+L0G5fqBnE/MobOhme/ySzgbn869ok186R5J0Hw1vKavx/HT1TiNWyO//m2SwlsArpcDcK4GoklrEU9UwHv6Wgp1bNntGsjJcBlnoqXvAfCSLIp7OWk8Ksz+bwGgvPMn5UJS9HsA/GnH7x0AzycncDo+5u11bxKORUZzNCyKQ8HhHA6L5LhEypnUOO7V5dG+pUA+pHEsl6G2dPmkb2s2r9vyR7t+78D3HwGwtyWNvpPZ9J/Mo7+tgL5TxfSfLqH/TDn956roP1fF02NFYwAcy1j+iWIhCIKpIAiLBUFYIghCtiAI/yYIwsq3z2sFQXgpCIKuIAhrBTkQL//k+38lCMI9QRDaBEFQFOR4HBQEIecX/h7jBUGgWFGPmrVGVK8xpErJgEpFfSoU9KhU1KdSUZ8qJQP519cYkLdKh+yV+qQuNiZxgRFxc/WJmalF4mx1suars32DIceNbbjr7cmDEC8eRXnTkxpJf56MN1XJ/FiTyuu6ZN40pvK6KY3hrakMbUlisDmR4e0pvN6ezg/b0vlDUzo/bk5jqCiGwZxoXqWG81IaQHuwO7fd7Thmbs5ePSNqvthIzWo1NinpskXZlNrVOmxXNWG3lgVf6VtxwsaB044iWswcOGHpTKu1iDYHT045e9Mq8uesfwL7nMKpNg2i3iaGassYKi2zqbUpJt84jXi1UPJM45Fs9CZeKxCfZfb4L3PBf4kI58lW+C/0wGWuPdEbwylxKKDGswo/RV/s5tqSaZNFoVsJRe6lHMo8yu6k/cRoR+O30h3/Ve5EKwdhP90MqwnaeMy3QDTLGKepOrhM1UE0TReHiRqIZuhjM1ED6wnquMw0wGWmATYTNRDNMiRCUUyyZhAxG7wRzzYifLUDoauMsJ24GstxK7Ee9wV24xQoMvChUNeDRrtgLifmcTAgkipTF+qMw8hXDcJ9ijY249Zh9dk67Gaq4ThXB5PP1mM5QRXnmXo4T9bD5hMdzP5FE7uP15OkaM7jvGxuxEdxQGRNo4U5uzy8+eF4C492NnP7y2q6Tzdwd18Bby4dZ+TcOU7lVWM5XhHLjxVwm6BC1NSNJM1QYctaYw6omXNaz5Kb1s7cthNz207MXQc37jt5cMtWxF0HNx6KvHnuHUyXfzjPw8J4ERlBpySanvhYuhPjeJkUx4vUeDozkugvzWW4qojXNSUM1ZUwvLmMweYKBrdWMbCtiu5tFXRuK6dnZzU92yroaSylt76Yvk0l9NeX0LdJXq9qCnlVkUdPSTbdBRm8yk2nKyuFzpR4XiTE8DxGQneMjFcxMnokEroiInkeGMxT/0Ce+QfS7uHNQ1cPHorceeLmRYebL888Q+gMiKYrKp6+ulqGD+/ldfs39Hd8Q3/Ht/zhxmV+OHmCoR27eVFezPOyfJ4VZvM0L3N0Cbg9JoanEnnH8WlopHwPoGcQTzyCeOjsxUMXNx67ivhe5MAdJ3vOW9pwzNiG9DnrkU5aQ9xMdcS/U8J3qibhCwzwnbYB7ynriVtlSqGmO9kqIlw+WY/rOHV8JxuRvcGLE1GZdDft5FZ+OYfDormRU8LR8DjsPpmH/1x5d89l/AYcP1YhfIk5ntM1EE1UwXeGNm4TNuD6+3W4jl9GyNw1NFg5cdjXl7NRYVxPlnFREs25yCjOyMK5nCrhRkk8N8riuF0Vx+2yWG4VxnArM4ab6VJupMo+eAzMzx7s/B8c7vzudo93x7xcSo7lfIqMi2lxXEqP52JaAudT4t5iMIEzCYm0xcTTKovjpDSWIyExHAuPpyUigqNRQbTFB3G3Np5HWxJ5siOZnoNZ9LXk0X8sn/7jOQydTGOoNfltpco/P5nGcGs2Qyez3gIwl8Hj8iNgfrrXb+BkGQOtFfSfqqb/VDUDZ+oZONvA4LlGnp2oGQPgWMbyT54RQRB8BEH4TJBj0P4nz5YJ8v/gKm8/NxEE4X8L73cFAwVB+EEQhN/8gp85XhAE8hV0KV9jSJmSAaWK+pQo6FG0WueDlbtSm6wVeqR8bkTiAiNi5+ghm6FJwiw1MuepsU3ZgGNG1tzx8uBhqDePo31GAfi6Mok3VcmM1CbxuiGFkcZUhrakMNicyEBTAkPbkhnZlsabrWn82JjGD5tSfxaALWYW7NExpXqVKtWr1NikqE/zenO2qVixV9uer/Rs2adrzSETa45Z2HPC2J4zpk6cM3fhkpUHF+18uGgfwClnKfstw8lV9iBzgx+Ja32QrQtFsi6MBLVoCs2SSdeNQrrekzSdUGJV/JCu8ydguStuc52IWBNGmkEiNW4VVLuWk2gQj8N8e8RLRKRapPFl7G4OZhwhxjgeiVEcbktdcJhliddSFzIM4wla7Yl4jjmO0/Sxn6Irv6N3pgGec4xxm2mA22wjHKbq4DBVB/FsI0SzDHGYqoPLTAOi1rjhucCcgGV2OE3Xw3uBCdI1lvgv0EQ0ZR2GwgIsfrWEHDURxbqe7BRHc1aSxkHfcC7EZHIsMIPYFeZ4zlDDf5EhVp+twWG2FrYztTAer4zZ+A1yfI7biMWv12P/0QZiVpqy1y2Cq9JIWrxFHHCxpzUknEdlVfQd+ZqnB3bwpGUL7S11PG3ZTF9bC/uSMhAvUcFmgjIuU9TxmqyJdIY66XPV2LbemMNalj8LwO+dPXng4sVjV1+eegby3DuYZwFBPAsO4UV4OC+lErpkUp7HSnmZFEdXWiJ9+Zn0l+YyVFHAUGUhg7XFDL5FYH9zBT3bKujeWs6r7ZX0bCmnt7GMvrpi+muLGKgpoq+umIG6YvqqCugrzaWnKIvu3DReZafSk5HMy4RYnsdKeS6JolMSTZckmq6oKF6GR/AsIIgOvwA6fP157O7FA7H7KACfuvvxzC+crhAZ3bIkBurreH1wDz98f5XBR1cZfPItf7x1lR9PtdK3czedlaV0VhS+twTcmZHGk9hYnknlQyfPwqLkU8BewTz2CuGByJfvRR48FIu55+LId44OnDKzYZeGCekL1ImfpYFshibu49fjN02LsPn6+E1XwW+6CvGrzSjQcCNrgwvOH6/DdZw6XhP0SVUSczwyg5cNO7hTWElLpIwHZXVcyyhCNHEJXjOUEE9UxG+mHu4TtYn5wp6QRcb4zNLBf5Yu3lPV8ZysgseElUiWqLLXzY+2sDDOSyK4FBvB+ahIzkVGcSlRyvWsOG6VJ3GzPJ7vKmK4VRrDrcIYbmfF8l2GjO/SY38RAK+mx//s4c7v8Dd6t29SDOdTZFxIjeViWhwXUuNHAXgmIZ7T8Qmj+DshieFYRCyHgqM5GBxIa1wo13JlPGpM5vnudF7uy2DgWC5DrfkMnSxg8OR/DMDh1uy3x8LkM3wyn4HWAgZaixg4WcLgqQqGTlcycLqK4fObGD6/icFLjQxd2sLw5a08b6sbA+BYxvJPml8JguAsCML/FARhhSDv+iEIwu//5nWdgiBEvf04QxCE23/zfMHb71P6BT97vCAI5CroUaJkSLGiAUUK+hQp6FOwWpeC1brkr9Ihb6X2aOWs0CJzuS4pnxuRMN+QmNm6yGZoEj9TlYy5qmxdr0+LoRW3Pd15HO5Lu8R3FIAjFYm8rkxiuCaRkc3JjDSmMticzEBTAgNNCQxuTWJ4ayqvt6TyQ0Mqb+pTfhaAR00t2a1tRvUqNapXaVCvYEDTWgu2rLdit6Y9e7Rt2KNtxQFDK46a2MkBaGzPBVNHrll4cM3Km6tWgZx3kLHHKIzkM7rPtwAAIABJREFUL8SkbwgkU1tG5NpQpBujKLDMos65gGS1EBJVfGlwyabMPBHJWj+8FjkSsMqXVP0UKlxKKLbPJ80oCT8FH6xnWeG2zJUM60y2SnZwMOMIoZoRRBnEEKUWht9KdwK/8CTdII7gL7wQzTbDdpI2NhO1cJ6mi+ccY3zmm+E5xxj3OcY4z9DHabreKACdpuvhMtOASCVX7CZr4b3IEoepOvL9futsCF9qgHjyOoyE+Th+/AV5amIqDH3ZI5ZwyCeK3WI/OssbOBOVTb6GE6LJijhPWYfZJ6uxnqqJ5VQNjMYpY/KpMhafqWD+u3WY/YsinhM3Uq7nxiVJBq1+3uxztOKg2JnrKRm83n2AF/v38PTQDp61fcmDQ7W8Or2H85WVJJg5YDRhGS7TtfGcbYD3FB1iZmmSvVCL7comtOja/CwAH4l9eOzqK5+o9QjgqWcgT/0CeBYQxPOQUF5GR9ElieaZLJquxDi6UxLozUmjtyCTgeIcBsvzGagsYLC+hIGGMgaayunZUk53c5kcf83l9DeWMVBXTH91IQOVBQzUFTNQU0R/RT59JTn0FGbSlZVCT0YyPamJdMbJeCGN5llkBM+jIumMiqQzIoLOsHCe+gfS4RdAu7cvD109+F7kxgMXN3kH0MOPZ/4RvAyP5VVsCkM1tYzs38WPdy8z9PAKw+3f8qfb13hzto2+3XvorJQPrHSW5PGiMGd0D2BHXBzPZfKhk+fh0Tz2DeahdzBPfCK4L/LjnsiLB2I3bjs78a2DA8eNrWhW1id9kSbxc3WImqGFx/gN+EzRIHCWFt5T1uM7bQOxK00o0HAjY70TTr9bi+s4ddzH65CwypE2aQ7dTTv5vrSW49GxPCir42ZuOW5TluM6eRXOn63Gf5Y+bhO0iF5hTfBCI7xnauM5RR2PSRtx/f06fKcqkrBahyP+4ZyLjua8JILz0lBOh4VyOiycy0kybuQkcLM0geslMdwsl/FdiYxbhTHcyY7jVmYMtzLifhEAr6TF/ezhzu+ud/vpIc/nkqWcT4nhQmqsHH/JsW+Xgv8KwBOSGPnUb4SMrwPDORjiz7mUSO6UJfF0Wxrd+7PoPZTJSGser08XMNwmv+1jqDX1gwAcOpk1CsCR1gJetxUydKqIwVMlDJ0uZ/BMFUNnqxk6X8vwlUZ5Xd3C4LVtDF7bxrPT9WMAHMtY/smyWpDv7/t3QRDeCPIlYUEQBJEgx+Df5rogCPlvP94kCMLJv3n+sSD/I2Ai/Hx+K8j/SLyrWYIgkLVajyJFIwoVDCn4woD81fqj/+at0iNnhQ7Zy7XfliaZy3VJXmRI/DwDZLN0kE7XIH6mKulzNrJlnR5HDSy55eFGe4QfT6R+vEqLoj9PxnB5AiMViQxVJzC8KYnhhpRRAPY3xjO4NYmhLSm83pLKm80pvK5L/lkAHjG2ZLeWBVUrNKlaoU3daiMa11iyWdGcHao27FS3ZZeGDfv1bTlsbM9xYxtOGdtx3sSBb8zduWbhzTWLIC67JLNNJxjpCjEpmtEU2ORRIa6i2rWSJp96Co0TiVzhSrF+NAcDqtlsl0nYCjd8FjuTZpRClVsNNW4VRG4IxWeFBw7z7LCZbY3rUjEyvRiKPcrYk/gVCebJSI3jybJMI1I5CN8VrkStD8R3mRjnmSajABTPNMB7nil+Cy3kXcDZRrjMNMB5hj6iWYa4zDTAaboeolmGhK52xmaiBv5LbbGfoo3jJHUSlKyQrDDGbdI6LP7HYnymqlKq7Um9cSB7XKLZbutFo4UzQw1fcjEmja+8IxBPXYnRr+dj8vFyTD7bgOkEVQw/2YDxJxsw/XQ9Zr9TwOLXK4lZosc+URi3k7M5KLZnj60ZR9zFPCqs5C9H22jft50nR7fz7NwOnrd9yZsrrRS5+WCzQAHTyV/gPE2HgIVWeE/RI3aWNrmfa7NN2ZBjerac1rf4IADb3fxod/Pjibu/HH+egXT4+vPMP5AXQSG8jIykKyqKF9FRdCfG0Z0UL4daThq9eRkMFOfQX5pLf3XhKAJfNcmrp7GUvqZyBhvLGaqWg6+/LI+BmiL552V59Bdl8yo/g56MZHpTk+hJTuBljJQX0VE8jwjnWXgYz8LDeB4WxvOQUJ76B/LE159Hnt48ELtz38WV751deeLmxRNPP9qDIuiMiKUnLoWhympGdm3nx+8uMHzvEiOPrvOne9d5c+4UPXv28Lzqwx3AdwDslMTwIkJCu18Ij3xCaPeN5r5rIPfEvtwVu3HD2ZmrDg4cMbCkbo02KQs0iZ2jQ/h0OQA9J6riM1UVj4lr8J6yHukyQwo03Ehf54jjR2twG6+B66daSJdYcyY2n75te2mvauCkNJ47hZXczC3Ha8ZqRBNX4DhuJV5TtXD+VJWo5VaELTbFb44eHpPV8JqihsekDYTM2UCmsimtYTIuymScl0RwNjqYM+FhnI+K5kZmEvdLMrhblcp3FQncKJO+B8DbWbHczoz/LwXgT/F3IVHG2SQJ55JlnE+JkeMvKebt5G8cp+LiOSmNHT3ypSU8moPBoRyXBHMtJ4bH9Wl07ZEf1zJwNJs3p/N4cyaf4bYchtoy/68AHGnN482pIn44Xczw2RKGzpUzeK6S4Qu1DF+oZfBSPSPfNDPyTTND32xl8JvtDFzbxtMxAI5lLP90+Y0gCJ8L8j1+uYJ8D98K4R8LwLS3r3mvUlfpk/OFEdmrDclaZUDWKgMK15qTr2RKroIxWasMyFypT+ZyXbKWaZC+VJvEBfrEzdVHOlMbyTR1YqerkDZbhea1uhzRt+A7d1c6ogLokPnzKi2Kvlwpg6VxDJXFM1gVz1B9IkObk+lvTKSvIY6+hjj6mxMYbE5muCmZ15vkS8U/B8DDRlbs1LCkYpkWlct0qV1lSoOiNV9udGGftiv7tEXs1XZiv74DB4wd+MrcmiPm1hw3t+e8uTsXLfw4bxlCk6YvJWoB1PvWsS/zBHuKLtEc+xXVfvUkGSYQutyVLNUwtlmn02yRQo5yEFIlX4qsMyn1qCTJLINwlVAcZtsgXuiE5wp3RItdEC12wXK2FV5rfSnxLKcpcivxFinUelUSpxmF0xwr3BbY47NUhNciW1xmGuEy0wjPeab4LjDHe54pTpO1EM3QH+0AOkzVwX6KNg5TdXCfZ4rHfDOCVzqSohWM4zRd7CeoEjJXE8kSQ/xnqOE2bg0BU9QoUXVls2EAB0RSNhs5kb9el6uyRNpLC3hYVkSDsw+Stfq4zlHFfIIGuh+pYPjJRkw+VcFsnDLWnynh+Nlqdtl5cyMhhYthoeyzNeW4u4gzfgEMNO3lx0MneXp4D53nv6Lrxl5GrrVxtrICs1nLUf94EYbjlXCdaUr4cmc8Jmojm6FJ7ufaNCrp0KJr9bMA/Gn377l3MJ2+oXT6BtLlH0xPcBi9kdH0RUnokUjojY+jJz6WlwmxdKbIITiQnylfEi7LY7CqUL6021BKX0MpPfVFDDSUMdJQzkhVEf2lufQVZjFYUcBQRQGDJbkMFmTRl5tOT3ICvYnx8vePjuJFeDjPgkN4HBRIe3AQHcHBPA0Klnf/fPz43s2D+y6u3HMWc99JTIe7Nx1e/twJCOFJuJQXskT68ovp31zPH66e4fWtC/zw8Dp//v4Gry+d4cX+vTwuK6CjOIcneRm0Z6fxJCOFpylJPEtIoDM2npfSWDojpXQEhPHYN4z2gDjuuoVx2zWA78SefOMs4oK9E/v1rKhZa4B0lhqhUzXwn6SB3zQt/KZp4TNVFZ+pygTNVid2pQn56q6kKNlh/xtF3MZr4PRbVULmGHE4JJnerXvoavySc4lp3Mgp4WZuOdErNPGfq4zb5DXY/24N1v+yhshllkSvsCJkkQk+07UIW2BEyDw9ElcbUWko4oIsmYsyGWciQ7kgC+NcZASXZTE8Ks3jxaYS2htyuV+XxvWSaG4WS/muQMbdnHh5ZSf+IgBeSokZ3d/3t3UxKebvrnc7kxjN2SQp55Jlcvwlyt4OfsTQGvMT/EVKOBgczInoSG4XpfKoNpOX23IYPprP4LEshk9k8eZ0Fq/PZNF/IoXeY0k/wd+HAfi6LZ8fz5Twh7OljFyqYORKNUNXahm+tpnha5sZut7I4PVmBq8303etmZ5rW+i+2syDtuoxAI5lLP/kOSUIQr3wj10C/mAHMGWFPtmrjMlaaUTmCkMyVxhStNaKAiUL8hTM/vr15XrvATB2jh7SmdpET1X7WQA+jQn4OwAOVMYxVJ/I4KakUQD2bo79hQC0Yae6NRXLtKhYqkPNShMaFG05oOvLYSM/Dhp48JWuC1/p2bPfyJ7d5lYcsLSmxcKeM5bunLP044x1CEecUtjlksmBjBa+Lr9KXWYbkWbphGtG477cjeSNoewQFVNvFEedYSzpSr6ka0TS7FNDum0OLss8EC12QbzQiUAFX0KVg3FdKka8RIT1XBucV4hJtEhhm/RLMp3y2Bm5jRzzVLyWuuC9xIXAVR74LXXEba4ZrnNM8Zpvhu8Cc7zmmmD3ezWcp+niPEMfx2m62E3WwnaSJnaTtfCYb4Z4thEyZS9yjSVyIE5Uw3faBmRLDAmfq4PXZ+vxGLeW/LWO1On5clAkY4uJiFwlTQ55+NDXWMvD8nxOxWdQ4xhA4HJDbKfpof0bZYw+Vcf0UzXMxiljN3Ed4okKHPMM4n5qBm0+Xuy1MeGMnxfnA4N5s+MQQ/uP0Xnya3quHKL3zle8PHOQmuAQDKYsxmDSF2h/tJrQFSIiV4pwn6CFZLoaOYu02KygyVFd858F4COxzygAX/iE8NIvjJd+QXQHhNAbHE5/lIT+aCmvpFJ64+N4FRfLy/gYXibF0ZOaSH+efHijrzRXvhRcW0z/5lL6N5fSU1vI4OYyXm/+KwB7CzIZqihgpLyAwaIcOSCz0+hOiudVQhw9sTG8jIzkRXg4T4OCeRQYwOOgQDqCg+kIDOKJrz/tPn7cd3XnnrOYu06iUQC2e/lz2z+YR2ESnknieZVbyKu6Gv54+TSvb57nxwfX+cuDmwy/BeDDkjzaC7Noz03nUWYKj9OSeJKU8GEA+oXTHhDHHfcIbrkG8Z3Ym2tOYi7YubBP15paZRMiZ6gRMFEN3wkaBM82JGiWHv4zNAiYqUrYfG0SFSzIV3clWdEWu18r4P6ZJo6/2UjQLAP2+sjobtpJT/MuLqZkcjO3lFv5lcQrGRC2WAPvGRuw/a0iVr9SInihMWGLTQmYZ4DHZDWC5+oTNEeHtDXm1Jl5cEGWzAWplNMRIVyKjeBkUCBnwiO4m5/Bk+p87tekc7M8/r8FgO86f+fiJZyLl3A6Ieo9AJ5OkHIqTvZBAB4IDKRNJuFRVS5PG/Lo2p7Lm+NFDB3PHgXgyOkM+o4n86ol8f8JgH84W8ofz5Xx+nIlw1drGL5ax8g3DYx808Dwt00MXm9m4Jsmeq410X21ma4rTdxvrRoD4FjG8k+eM4IgbBH+OgRi95NnS4UPD4FM/clr/AX5EMhvf8HPHC8IAlkKhhStMaNQyYy8L0zJXWVGzkpTcldZkbfamuzllmQuNSdjqSlpSw1IXmJMzAJjJHONiZipT9gUDSTT1Uies5FmZX0OG1lxw8OVh2GePJH60ZURxcucKLrLYnhVnUBvXQJ9tfEM1MYzWBPLSLWMkepY+jclMtQQz5vGRN7USRmpimC4IJihrAB6k314GeXDE3837ohsOaZrxl5VUyqXqVOyTJuSlUYUKVjSrOPDlYBcTrnEscfAi92aDuzRcOKwvhf7DX05bBPJ1dgqbmQ0ciN3B1fy93IkYRMhaxzwW2mD92L5frqAxXak60awJ2QTp1MPIN0YhP8qd5L1Ytga2EiaSRq64/QwnmCK/UwHMoyzqRbXEawYhkwrEeeF7tjNF1MsrmFz0A4OZ5yiUFxNfdBm9sh2kmqWiNsCe3w/d8Z1ugneM02JWOqE23QDwlY5ErrSAZvfq+I8SQvnzzSwH6+NwyQ9RLMtEM+xxGaiFjbjNxC0yJhEBQtkyw2QLtcmbPFGAueo4TlZDb8pxsQtcaJS15uvnCNoDYzhujSdr52DSFiwgSodExotLHnVWEPPlnqOREfiNHUVNhPWYf5bTRw/NcL+U03EE9YRuVCFu4lSLgcH8LW5FUcd3DjuHcSdghIGrrTy8tpxOr79mv4Hx+i5uY8sC0/EM7Sw+mwdTpM1MP9IiegV1qStdUI6X5f4GevI/XwjW9focWCjCaf1bLlkaM9VEye+s3bljp07d+09eODiwSOxB+1uXjzz9uW5jx/dQaF/rbAIeqKi6YuLpStWxquEOHpTk3iZmsDL1AT6ctPpLchksCSX4bJ8hisLGakuZqRavs9vsL6EwXr5xG93VT7dFbkMlOePYrAnJ42erBR6UhPpSYqnOy6GZ+FhtAcH8dDHl8d+/jz29uWxty9P/QJo95Av/T4Se3DfUcRde2fu2znT7uTGM2cvXrqH8Mw3giehEp7m59PVVM+bsyf487cX+F/3vuXf7nzLX25c4VVbC48Lc3mZn01XXjZd2fL9f11JyXTIYngaKaEjPIqOkAge+4fwxDeQDi8fHonEPHRx5YHYk9tO7lyz92CrqgUFK/UIna6OzxQNXCdp4jdPD5/ZmvjPUSNivgYRs1XJWG1KmZqIvLX22PyPJYjHbcD2d8q4TVGlzsKL+3kVPCio4rvsIs4nZHAxMYdqax+iVuvjOUsFm3HrcJygQcACA7xna+M9Qx/3iXqIPlHDa7IKlYbWfOUq5htZMN/IgrkhjeRCaAhnJf5cSQ7lUWkKj8tSeViSzMOSZB4UJ3GvIJ47ebHcyYvlbn4cd/Pj+C4/npt5cdzIjeXbnFiuZ/1k6jc9kWvpyaN1KT3+g3UhNZazSVLOJEo4kyh5u+8vfvSYl1NxMs4nJ8ivfHt77EtrjIRDYcF8HRLI4fAQTiZGcjE7hifNuXTuzOHVV7m8Pp7DD61Z/NCaweuTybw+mczwMXm9OZHIyLFEhlsSGGpJYvB4CkMnUhluzWTkVC5vzuTzh0tl/PFKBcPXmhj6Zjsj337J6xs7Gfn2SwavbWPg6lb6r2yh91ITvZea6LvczNNTY0MgYxnLP1NyBUHQFARhviDfC5grCML/LwiCwdvntYK846cjyJeIr7ytd3l3DMxJQRAUBEEwEuRnAf6njoHJWK1PvoIxeV8Yk69gRoGCJVnLjcleYUHOSjn+0hebkrbYmJTFeiR+boh0niGRswwIm65L+FT5VGfKXFW2qhhy1MSG77zceRDqQbvEl5fpkf/lAGzRMWePiikVSzQoXapJyQp9ileZsV3fm0s+GRxzkLJDx40t6o7s0HZlu5Enh11juRRVzMOSfdwp2s213C85mdTEFp9sTD9di9k4ZVxnGWI/UZs0zVBqnbM5nXqAcxmHkG4MIlFHwmavKjJMUvBY5oHlDCt0P9HH8DMT6j0aKHeqwmdlIPF6qVjNcCBMLYZdsYfYGXOQ/WknqQrYQqZdNntkO6n2Ksd5thUe8+xwn2mG3xwLopa7IJ6qR+BSGwKWWGM7QQ2bTzdi/8lGrD9RxXq8Jk7TjRDNMsVxijbiKaqELTIkTdGMDAUTsteaIF2phe90Zdx/r0L8EhF56/yo0vHgiLeMm0nZ3EvL43xYApGzvkC24AtylTW4l59H5+Z6LmVkIZqhhOnHqzH7jTqiCcbYfqyKz0wVirVtuREbTZunG19ZWnHUxZOrsQkM7d3HyDfneHrlKC9uHOVPTy7xqHUL9jMVsfhECZsJyliPU8bst4pELbciU1lEzEJ9ZFMUyZy/nmZFHQ5sNOGUrg0XDey4auLELRs37ti5c8/Bk0diLx67etLu5kWHpzcdnt50BYaM1k8B2B0XQ29iPH1pyXSlJdKdnjTaAewvyGKwKIfhsnxeVxfzpqZEPvBRI5/87a0uoKcyj57yXPrL8ugryZHv/ct5O/37/wDAd5O/34vceChy/zsAPnH2pMMtkKc+4aMA7G6s501bC3+5do5/v3Odf793k3+99Q0DZ0/ypDifroIcuvNz6M6RnwHYnZzyQQA+9gukw8uXh2I3Hohcuevizg17Ny5au9G80ZLc5XoETFHDc5IGoklaBC0yImC+LiELtYlepE3kHDXSV5lQri6mYL0jdr9ahut4Few/UcFzugYlek7cz6vgcXEtN7MKORuXxtXUAppcQkncYIn3HFUsP1bCZbI2QYuM8J2ri/cMfdwm6OI6ToOg2drUmzty0NODb2TBXJMG8a0kgguhIVyICeJaavgoAB8UJ43WOwDezo0ZReA/GoCtMRJOxcneTv/+FYAnZdF8HRLIgeAADoeHcD5TyvXiBF7syOPVV7kMHMzjx9ZcfmjN4IfWdDkAT6QyfCyF4WMpvDkhh+Ao/k6mjeJv5Gwhb84X84fLlfx4tepnAdh/ZQt9l5vpudBAz4UGXl1spKOtdgyAYxnLP1EaBUF4Icj3+g0I8uVfg588f3cQ9IggCH8SBOGAIAjT/+Y95gmCcEyQHwQ9KAhCkfCfPAg6Y7U+uasNyVllSIGiOUVK1mSvMCFnpSW5q6zIWmZBxhIz0peYfBCA7zqAKXNV2bbRiBZTW277ePJ9iDuPo31GAdhTHktvTeJ/CQCPaFuwW9mCyiUalC/WoGKpDhUrjWlUdeRqUBanPRLYpu9BvZoj20z82Ocm40paHXeLdnI+qZ6vQwvZ7pnJLr9Cyq1kWH2sjM2nG/GYaULoCmdqHTL50r+S85mH2RlYS4FVKg3eVVSJinGYbYPDXAe8VnljNNEU8ylWNPhvI8M8D3/FUDKsCzGf6UCmXTGHs8+wTXaAZulXNEn24bPWjzrfaraENuA40wL3ubYEfu5AwDwrJCvFiKbo4rvIAp+F5thMUsduvBoO49Sw+ngjph+pYDFeA7sJWrjOMiB6mRkZ6x0oUbWhcK0JuYp6xK/UI3DGRoJn6JO3LpDctb5sMvXhZEg8T0sqeVpSzsO8YhKWbiB0xkoSl6lywCeYS8nptMWl4jRFEZOPFDH+1UYcx+li/mslopfrc9BHwqWIYI66OHPQ1o5jnl7czcnhL60tvDh3hPun99N/6xwvL7SwLzMew48/x/LTNViOX4vpbxUx/0iJgHkG5Kq6E/e5IZJJX5A2Zw1NCtrsVzGmTcf6PQDetffgvqMXj129eezqKUegu7xeBgSPVldoON2RUfTGxtATH0tfUgL96Sl0pyfRnZ7EQH4mr7JT6ctNZyA/k8GiHN5UFvFjdQkDZXnyZeGqQnor83lVkUdvWS69JTn0Fme/B8DulAS6E+PoipXxNCyUx0GBPPD24ZGvH4+8fHjk5cMTH7/3AHjPwYU7dk7cs3XisaMrT5w9eSz255FPKI9Do3mWl8+rzXWMHD3Iny6e4t9uXuV/P7jF/7p/k8ErZ3hYlEtnXhYvc7PoypYPgLxMTPowAH2DeezlwwOxOw/Entxy8uSKjYhT5iI2bTAnc4kOPpNUcZuogfMkXfwXGuE/T4fQRTrELNVHtlCbLAVzytXFFCo74fiblbiOV8Hh0414z9QiR82K+3kVPKto4HZuCWfj0riZXcYOj2gyNB3wmr0R439ZiWiKzmgH0HOaLi7jNHEdp0HEQkO22LnR4ufLN7JgrkQHcD06nIthoVxJCOPbjCgelabwqDRlFH/fFyVyNz+O27kxo3UnL/YfCsB3t3y0xUo5mxg3CsLWGAnHJZEcCA7g65BAjkaG8U1RPHdrkni1L5+Bg3kMH83lj6ez+aE1nR/aUv8OgMMnUxk8nvIWfxkMtWaP4m/4QikjF8v48Uo1P16r+VkA9l1upvdS03sAfNI6dg7gWMYyll+en+0A5n9hQYGCLQUKtuStsiFnhRXZKyw+uAQc+HsVwicpkzBTmWZlfY4YW3PL24N7Qa48ivIeBWBvZTwD9Sn/JQA8rGnHrnV2VC1Up3KBKjWfa1C9TIPNSkZ8G5rB9/EVnAvOZo8olpagXL7L3sb5mGoOemayzSKGw245XArbxF77bLLX+uI1yYiw+fakrA/mSEQTu/wqafIoosw2ncAVLuwJbyJGPZxgRR9iNKIJVArEfJoF3qv9kOknEW+UQYRGHNkOpWQ5leG0woeakO3UR+4mz6OWLLcq9uedwV8liALHXA4k7CVotSce8+wIXeaC+1RDIpc54zpNH5+F5njOM8F2kiaG/58S5r9RweoTdcx+txGXqbr4zDXFZcIGstfbstXMl7NeUew3d6JijSbRszfgP34dIRO1qdOSsd0igTMRGZyJiqenoYbupgq6Gisp0jZF/NESvD5ZQ42xJwf84tnqGvV/2LvP76jvbM/33NOn2+QsMgYTBRIIlHPOOZRKKlWVQilnqVRRpVLOASEQCETOYGOiyWBjoiRyzhlMDsbdM7Nm5q73fVC22p62zzmecZ+5D/RZa69aq/6C19rf394b/09mEtTfGs9eFnj3mk3gX2ayMiqVy9Xz2Rkdw05RNIcSZZwp1vB80wpe7v+cG0e2cfvEPq5s306jNBnBGGMEwywI7m+O919MCOg9F+FQB/JnhNDokoh+RgDa0ZZUfmbN8lnObLH05IBLMMc8wznlK+RieCxXhQlcj07kuiiO6yIDqG5J47gdG8+jlPS/V0YWj3NyeaZU8Fil4JlWzXfFOh4Va3lUrOVFVSmvq8p4Xqbnu9Iivqso5k1DFe+aanheW87Lxipez6sxPPnOq+b5vGqeNlTwtL6cpzWl3QB8XKThSaGaR8oC7mZlciM1havxCVyXJXI9LoHrcQndq1+uRIu5Fi3hUkQUF8OFXA4TckMQw01hLJelyVxPyuJGlpx7ZZU8nT+fV1s28XH/V/z308fh9mW4f43vr3RyqbacuxUl3Csv4V6Jnrt6HfdU6t8E4LV4wwTwFXESpyNiOegvZLtHBI2mPijHOSIaaEPUUBdEI/zNZ5lIAAAgAElEQVQQj3QkdqQdaROcKDTxRWfsTYN1BE22Ud0AFPWzIqKvDUnj3Ciz9udcWQPPlq7j/qLlnNBXcbWxjS9StNR4xCAdZYXvv5ogGu6K2MiOmOG2iIc6IezrgHSgM1rTULYlZHI0L5dOZQbHc5M4nZvJiZxszpcruVSr7sbf1YbC7u7fxRoVF6qVnK9ScKFaycUa1T8VgAdVBexX5HNAKe/u/u1X5LNfkc9eeS67cjLZV5DH0SIt19uLub++mHd7avmwv4YPByr469flfH9Iz/eHDPgzALCU13vLeb2/guf7y3lxoII3R+p4fbSJN9/O48Opxbw/vZgPp5fyoWsZH7pW8Lpj9a8C8Kdn4BcnV/Hi5CpenlrdswamJz3pyf9WfvMbwBrTAGpnhVI7K5TqmYYuYIVxwK92AJMHWJE52AL1SAtWWLqz0zuY8wmxXE4TcyMvgcdleTypkfOitfAPA+B2JyEbLQQsmujA4on2LJlkz5Lpdqy28GZHSCLHM0rpUMxjV3oNezIaOFHQyhcRWtb55LArrJhjcfM4m7ac7cGVzLfOImtsBOqZ8cz3KWa/aiNr4ppYJKxAYZ1MgVUSzYJKsi2SUTnm0hBeQ5ZVFtGTRRR66akIryfLUYXap4xFaWvI9SwiyjSJxdkbaEhaRm3CEqoT2ti7sJN8DwXF/jrW560m1yKF6FGBJIwPJnqwK9lTI4kd7U3ylGASJvoTPswZnz9bENzXgfBB7gT3d0Q6xpuMyUEkjnZGZ+zJArsQjifksCc0miWWrqjHOaAe50XJZAGrvQvZFl3FdpmcNcIYLjVU8N26BTxaOY+F/mEkDbZE/CcL6h3ELAvLotI5Gv+/mOD7iTk+f7LEq5cJUUMs2J6morO4ii2hAnbHSDicmMy9BY38j6O7eH14K0+7DvHk3FHaCzTEmzgQ0HcS0Ua2BPadQ9AAc4L7WRLc1wLNHCFNrkmUmgZT/KkdddMcWD7LmU3m7ux3DuJbjzBO+Qq5FBHHtSgZN0RJXBFKuBol5rpIyu3YeO7Gy3iYnNZdPwfgg4J8nqiVPNFpuK9T8aBIzbNyPe+qK3hRqueZvpCnxYW8rC7jdW0Fz6tLu5+GX8+r4cWPnb/HdWU8qSvjaU0pT6tKugH4WKvikbKAO5kZvwrAWwmJ3JDEcTkqphuAF8IiuRQayQ1BDNejYrkUn8K1lGxuZhdwr7icJ/WNvFy3ju+/2sl/O/kt3L0Kj2/yw81zXK6r4F5lKfcrSnlQVmKYAFZrfhWAN5OzuBqXyiVJMpckyZwMj2OvbyRfuIZTbexOzkgbhANsiRrmTsyYYMQjnbsBqJ3pg2aqB9Vzg6m3ElBnGUnkn2ci7G1OWG8rEse6UmzhwwlNOY8Xr+bx0tUcL6rkUl0r2zP01HtLiRtjQ2h/CyQjPYgeao1omA2xRq7EDHRBNsyD4rmRfJWazwlFAR2KdI7lJHIqJ4OTuTlcqtJwtaHwNwF4vkrBucqCbgT+swG4ryCPA0p59/eA+xX57CvIY688lz35ORzWKOmoLOP2Kj2PNut5v6+aDwcq+HCglI+Hi/n+kO5XAfhqfxUvDhjqzdeNvDnazLtjLXzoaON9Z7uhulbw4cyq3wTg2671vOlcx6vTa3h1eg2vO9by4Ov2HgD2pCc9+d0xAHB2EPMsBDSZR1BjGkTVzAAqjP2oMPajcoY/lTP8qZoZYPh/pi+6Kd7kjHYlc4QrGUYupAy0Jn3gXORDZ7Pcws3QAYyTcjU5hrs5CTwvzed5dQEvFmh5tbjIAMClhbxs1/GqXcu7ZVreLdPxermedyt1fFyl52O7ig+L8/l+Xg7vazJ4XZbKE3kSd1NjuSyO4LC7mC/MI1lm7EXbDHcWGDvTZu7OAnNnVjsHsMUjjG0+0RyNTOe4RM2GEAU7Zc3sSJjHpugqtiU0sT+zjSN5K2kL0JI5IQjJYGdSx/qzRFTLEmkTdcHFyK3TqfTVkW+VSbG7hjJPPZGjIhCOjqTCu5wSrxJUAVqKwstZnr2OupgWSgPrSZqVQ3PcCkojGsnx1rGgYBUry79A468lwzqViPHB5NqkETDMk4gxPoQMd8VvoD0hQx2RTvAlcWowwmGORA+xQzzMAcEQR0IG2iEY4YVkXDACI0+SJgRS45xOhUUMNVZiWj1T0c4JoD04jS7VPL6KSGGTaxhL5zjTPMOaNntP7jYt5GbzElaI0ogfMpf4ATZIB7mQOMIf2aggPHuZE9TbCq9eY/HuNZiCmXPpLFFxJC2RrwIj2RQWzp78NF6d+JIPF/fx/uxeuHyO66s2EDBoBoGDLfEfYk/YQDuiBtsT3NeMqCFWhPQ2pspBSLt/Ik22IVRPtqVpsh1rZrmz3TaQbbbeHPUVcDJIRFeomIuCWK5EJXBTnMBtSTx3pAk8jEvkcVwS9xNTuJecyoPUdB5nZnd/B/hcqTSUWsUztYrvNGrDqTiN4Xn4u0INT3UanukLeaYvNHQIa8p401DFizrDwMfjCj3f1ZXzvLac76pK+K60iCd6LfcUhl2Dj/LzuJuWznVZIhejY7qfe29LE7gbl8gDWQoPE1O5HCniijCGK8IYLkeKOB8WydmQSK6JkriVkM3dDAWP9FU8bWjm6eo1vNj6BR+/PQKP7vA/H9zg7bUzvFm3gqs6NQ+ryrlXoue2Tss9lZqH2kIeFvz9Esjt1CxuJ2dyJS6eq/GJXJTKOBQk5EuPMNY6hZBrZIakz3SkRg5EDXVGMMyZ6OF2pH3mQcFMX1TTPSk28UM3zYNSE39KZgYgG2pD5CdziexvR9QgS8qs/TlZWMKDRYu5vbCFEyWFnKup4qC6mMURScjG2xH4iSViIx/CBngjHOZH2ABncqd4oJ7hQpODD6fkeXQq8ulSyjkpz+F4bi4nlQquNpZyuamYiw1FXGwo4nxdIefrCjlbozEAr0pFZ6WSjgoFHeWqX73te7mxnEsNZZyvLaazQsupUhXHihScKNP8JgIN1z7UHCtRc1Sv5KheyWFtHgfVORzSyPm6UNe9+29PvpxdOdkcVOfSUV3IjUU1vNpZyZs9JXw4UPHj4EclHw5U8H5/Oe/2lfH6q2Jef1XMu31lvN1fyYuD1bz+Zh7vjrXw/ek2vu9cwvcd7Xw8u4oPZ1bxvmslbzoNU74vTy/l5emlvOpYxusOw/9vuwwAfNu1nredG3jbuYm3nZt4cGRVDwB70pOe/O50A7BxbjgNc8KonRXcjcCfV7VJINUmgZRO90I7yZPsUS7dAEweYEXagDnkD5nFMnNXdvmEcD5W8k8F4EE3AZvnBLBkmguLjJ1ome7AYgsvGk0cWW4XxHrnCDY6R7LNXcKX3kkcSqxjt6yBPUlNfJ29hCM5yzic3c7ulAU0ueWSOzmc5NG+5EwKoylYT11wMSWeCjSOuVT66ij1LKQlsgG5VQ6J0xIocS+m3KuMfJt8kuxSqYtrZnn2OkpCa1C5lyKdlkpt9GLU/hWkOBewSLWWNVXb0IcUk2aZTMT4YCoD9YSM9CXYyJ1QIzfCR3ogGOmGYIQLkSNdkY7x6AZgtJErUSPciBrtS8xYf6JG+VDhnMlCfyWVliKKZgZTYhZInWMwO+JyuKxr4EBUEvvCYllh50HlFDMUYyZT7eRNlVsgcgtvJEYWiAdZIxrsTOxoX+JGB+DzJ0tC+loTP9KcpDEm1Dt5cUqVy16piMPRMnZIJHytK+Dt6V28PLWD+wc28mjbF2zMVuH+p4n497cgcJjjbwJwRVAK8+xCqZ5sy7wp9qyZ5c6X1v58aePFNz4RnAiMpjMkhgsRUi4L438VgHcTkriTmMzdpBTDMujMbB7n5BpWwSh/vM37HwDg4xLD1ZDX9ZW/CsCfpn8fF2m4r5TzqEDOY3k+99IzuC5L5EKUqLvbd0sS/wsAXos2dC5/AuCFcCHnw6K4GZPCXVk29zMKeFRUzrP6Zh4vX853Wzbz/dcH4cEN/uf9q7y/eoYPm9ZwXa/lfkUpt4sKualVc0+l5oFGy8MCVfct4J+egG/Ey7gkjeeCJIHDYWI+9wxnhX0wWcPMiOkzA4mRE1HDXRAauRI1zJbUie7IZ/igmu5Jiak/emMvykwDKJ7hj2yoDcLe5kT2tyN6sDW6OZ4cVRZxZ34rN+e3cLxYS1dlOYe1pawQp5Nl7EZYf1uih7kT2t+rG4Dy6d4UmXnQ4hLAqYJcupR5dCnzOCnP4kReDqc1fwwAL9SVdK+H6azQcrpMbVgB87sBmM9BdS4HVQWG279qw+WPr/IMz79HdLmcrS/iTnstr3dV8XZv6W8C8M2eEt7sKfkHAL4/vuAXAPz+zMoeAPakJz35T8/AXr16UTHL/2ff/QVTbxbc/Qz8v1bRZDdUE9x+AcDEfhak9JtN7iATls5xZodXEGclMf9cAHoFs8XSkyUz7Fk00575Mxxps/anxdwwCLLWOYaNLlL2+GWyN1TJt8n1rA9RsUWg49vcNg6mL2BHXD3rI8spMY9HOSMahXEU6lmxlLnnU2CbRp5VMjUBxdQGllAfXEldUAVJ0+PROqpZFN2Kyk5J5txMwqdHsix/DW1pK8l2VpJuVUDM5CSqIheS41aIxDKdpYUb2VC3i6qoalLME4kYH8zajGWIPgvHb7ATIcNdEX3qj2icN4EDbfDrZ0n6tDASx3mSMNqNmJHuxIz2RDDCi/Bh7giMXFkQrKbKKZEm51iqLAVUmPmwMSyaDrmSc3I1K53dWWbrhP7TKWgnGKM3taLCLYScuW4EGJkSOcqGsCHWRBg5IxrnTfRYH3z+MpfAvnPQWwRSbxfIutBojqUn82VICPujEzmYlcWVBY38cO4gDw5uomPNfPaWlqJ18MX7k2n497fCe4At4YPsiRpsT0i/OUQPtSa0zwyqHaNYG55Js30YVZNsaJnuxJpZ7mwx92artSdHvMI4HhBFR7CIc2GGLuCNmHhuieO4LYnnQayMR7GJ3I6TcSshkduyJO6npvMwPZOHWdk8KzAshP4JgM9+HAz59wD4stYAvqdVJYaTb7VlfFdT9psAvJOaxtX4BM5FRnE+QsglQXQ3AB8mpvIwMZXb0gSui6TdALwkiOaKQMxdaRoPk3J4kCHnsa6EZ3WNPGpfwncb1/Pu0D64f53/98E1Pl4/w9+2bjTs/ivVc12j4ppKwT2VmvtqDQ/kSu7lyrmbmcvN5AxuJqVyS5bE2WgxZ0XxfC2QsdEjkoWWgaQMmUNUX1PEwx2JMXJDNModwRBLkj91Jd/YG7WxF6WzAiiZ6UOZaQBF031JHGZLVB8LBP1siRlqS4GxEwey1dxobOH6vGaO6TV0VpTxTVEFG5PkaK0CEQ51IGqoCyH93Ykc6kNofwdUJn5U2QayxCeUDmU+Z1S5dClzOFWQyUl5Dl069e8GYGeF9h/qp52AZ6p0dFZo6SjXcLpM+38EwCNajWH3X4GC3blZfJWfzvGyfC636Hm4qo63e6p5t6+M7w9W8vFQ1b8LwFeHa3lztJn3xxfwsWPJLwD4vstQrztW9gCwJz3pyX9Kur8BrDPzpc7Ml0bzAOZZBtEw15/6OX7Umfn+OCHsRbWpN5oJTig/de1+Ak4f7oysrznJfWeRPWAGbbMd2e4ZyBmx6J8KwCNBgWxxcKZluhUN06ypmmxP85xwGmeHs9Erh12hWvZF6jgq1nNMWsKe8Hw2+6XzRWAOu0V6domL2SYqpcY6gdxJwahnSyi3TafOrQCdUw5xUwQkz4xhm3wDS6XzybVIRzQ+ApWdHK2jmmTjJBKnyYifFk+ibQobdF+g9S8lcLwA8fRkcm21LE5Zj8KnFIFpAku0G9hQt4tl2ctJtUgickIoOzRbKPHRIBjrS+AQJ0KN3Iga44lorCexE/1QmkvJnhZKynhfgvtZE9DXipChjkQYOZM1O5Iaz0RiR1myRpBGe0AsuumWHJXJuKPXc0ev55pOx8msHNr9I1gWImF5VDqlXgnITAIIG++B52BLPAZZIJjoScg4JzwGzMJviCl6FyE709XsSc5jd0Iq2yMErPb0YXtcGt8U6jnT0sTXrdVsr1CxQZnJxuRstHM8SZ7gid8nVlj3mk3EYEdEQx0JG2COaJgNYX1nUuMUzebofFpdhNRMsaNluhOrTFzZaObBVmtPvvYO7wbg+XAJlyLjuBYdyw2RlFviOO5LE3golXU/Ad9PSet+An6al8+j3Fwe5+XxVFHAE6XC0AUs1PwmAJ+U6nhaoedZZTFPq0q6AfjT8MeTcsPz78NCFXfkudzLzeFuViaXY+PojBRy1NefrpBwLoQLuRMr6+7+PUxM5XFyOvcTkrkTK+Om+MdBFpGUh9JEHiakcT85g0dqLc+qqnmxYglvtqzhb4d3w/3L8OgK/+POef7bl5u4VVrETX0hlxVyLhfkc1ep4o5Cyd1cObezcrmVlsU1WSo34pO4lyjjdISQk0IpO0OTaLELRz3ZE9EQOwQDrBAOcUI6ypOE8d4IBpqTOM6ZvOleqI29KJsdSJmpH+WzAlF95k7KCIfuPYDxo1xJG2fLjkQlV2sXcXdhO12VlZyrqaGrtpEduWoqXMOQjLYnZoQD/r1tiRjiQlBfC8psglkRFstWSRxntDmc0+bQpcrktDKdTlUOlyuKuNpY/LsA+GtLn0+VqjhVquJ0mZqOcs2PMNT9bgAeKVRwQCnngFLOQZWSvfL8H/GXxkFNGpdaVDxYXcbrrXV82F/D9wcr+eFwNT8crubjoSre7y/vhuC7fWW821dmQOHBat4dbTR0/0628rFjCR862vhweinvO5fzrnMFbzuW8+r0Cl6cXt4DwJ70pCf/9Azs1asX1ebeNFr40WDuS6OFH02W/tTP9aFujje1Zl5UmbpTaeJGxQx3Cj9zQfOZB3lj3cka6UbaMKf/Kx3Avb4BrLF2pm6SFdWT7KmY5Mb8uWLaHJL4Jr6W8zmtnM1uYldIJlu84tjmG8/ukHR2h2azI0LOTqGWnaISimcJUU6LQD4jiiLLFOo9Veiccsgwi0Npn8E2+QYWiRpJmRlPnmUGxW6FpM5MJmVGMhmz0gkxCkEfXsqizGWk2uYQMC6CyM/i0LiVszpvG0UhtYTPjGNBwSrWVm9nk3YzWbbpCCeG0SppYkl8C8mmIoKHuRAy3BXJBD+Sp4eSbiIgY3o4sSM9kA53I6ivNX69LRCOdid+kh8pxkE0B6VR7ijgbGkTJ9WVtHtHsMzFn22CWA4lZHKpuJqTCj1VDv7oLHwomOVDwgQPIoY6Em7khmc/S7wHWhE5wQ3foeY4/GUSqeaebFdXcqZ+PieLyzmUL2dXrITNEULaI8SsiJOxPjeT/Y1lnFjUwIX2VrYm5aE18UA8zAHPfzHH6U/WCIY4ETPMibAB5sQMtyW8nwm1ziI2ReWxxCOGBmMnmqc6sGKGM1vMvX/zG8CfAHgzJpZ7kngeSBJ4kGTA34PUdJ5k5fAsJ49n+XIeZGfzMCeHJwXy/zAAn5QXGaqy2IC/qhKeVBsw+LjM0P17oFX+AoAXJVJORwg44uXD2TABlyNFPJCl8Dg5nUdJaTyQpfAkJYMnKRk8SkrjfkIyN2JiuRYl5r4olnuSBO4mJPFQoeB5VSVvVi3l3edr+NuhHXDnPDy4wH+/1cEPm9dyXa/lVrGOqyoFVxRy7iiU3JIXcDs7j5sZ2dxIyeBKfDLXYmXciZNyRiDkRGQs67ziKDcLIm2cO5FDnYkY6kTEYIcfAeiJcPCvdwArZgehmOBK2ignpIPsCO9jjWyMOzIjKz6X5nO5ahH3F63kXE0NF+rq6KqtZ7e8kBqvCOLG2yEZ7YjvJ+aED3EksO8capzD2SxJY09yCud0uZzXZdOlTue0MpUuTTbXavS/G4Cny9T/UD8B8CcEGiBY+L8NQMPkbwF78nPYmZPGXkUK3xRncGOJmqcby3i/07Dz74fD1fz1SM0vAPhTN/D9/vK/g/BQDe+/bTLg79SiXwDwXccy3nYs583pZbw8tZznp5b1ALAnPenJPz0De/XqRY2FF/NtAmi29qfRwof6uV7UzfGk1syD6lluVMx0pszYkTJj5+4pYPl4T7JHuZM2zOn/yjeAe31CWWPtzbzp7jSbBDF/jpC1XnL2SWrpyGrhTE4Tx1JK2BIgYqNnBFvcI9kdIGNvSAa7wvLYFirnizAlOuNwis0kZE2KoMBESq2nGo19JjrXPJrCy1mR0Eq1v558q0zKvHSo7OSkzEgi1zyHlBnJhI8KpyWllVJhNWJTGeGTYwgaHYXatYy18h2UhDcQMl1CfWYbqyq2sr1sB3LnXKInRZBrk8ZWxQbUzpkIRnsh+tSfdFMhmbOEpBiHIRrhhnCQA3EjPIgZ6UHIQDsiRrgQO9EHwUg7yt1E1HtFc1xdRmdROesiYskda4Vqij1VFn6sEaSwQpBK5mQ7Yo3MEQ4yQzbaG/EQd0I/cSSojy3BA2yIGGmHyydTsPvTWNoS8zjVspQrS9o5N7+Z09WVfFuo4rBCyeq4VFbIUtikyOf8unZubV7Dgw3raA+SkjbKgqj+NgT2dsCzjwuRQ52JGeZE+EALxEZ2RPQ3pc4lhvWCbJZ5S2k2daNxki3LpjvypbU/Ox38OOYvpCNUwrmIWC4L47kmSuRqlJTr0RJuiKTcFcdxXxzPPZnh+797yak8ysjiSVYOT3LzuJ+VxYPsbB7L83msKPgPAfBx2Y9Voe8G4OMqAwZ/DsCHagWPCuQ8zMvlSlw8nZFCvvb25WJkNNdFUh4np/MsLasbfI+T03mekcPzjByepmYaACgQcTsiittREm5KYnmQn8fzijLerFjM200r+GHfVrh2Cm6e5r9cPsbbtcu5UqjidkkRN7RqrqkU3C5QcDNfzq2sXG6kZ3E9OZ3LcUlclcZxQyzifJSYY4I4FthHoJjqhdTIiYjhHkQYeRI6yB7JKDcSx3kiGmb1q98AVswOQj7emfTRzsQNcSCstxVJY72JGWDGushMzpct5F7rCs7V1HGupoZTldXsURTSHCQmaZITMSNt8f6zGeFDHAjoM4sG90h2JudyOCuT80U5XCjKokudSoc6hbOFOdysL/7dAPw59v5X9P0Sg5rfCUA1R7QqDigV7FcUsK9Azlf5mezITuaAOpXjFRncXanl+ZZSPuw2wO+vR2r429e1/PVIzb8LwO+PN/Px1CJ+OL34HwD45rShXpxc1gPAnvSkJ/8pGdirVy8arQJosQqkaa4vLVaBLLYPo3GOD01zfWmc40PdLE+qZ7pRNcOd4s+cKZzgjHaiK6pxLuSPtCepjzHZg2ZSNMqcddZ+7PUWckaSyJWsVK7kp/CgJJ/vqlW8nq/n7YIS3rQW82axnrdtxbxZUsS7ZXretRfzdnkZ368s5YfV5fywoogf2jV8WKjgbUMez8ozuVOQwo2sJC4mStgfKGGrm5h1LmK2BaSyVyhnR0Qeu4X5bAlMYKNXNOvcQtniFsgXbiF8FRTL3ohUjojyORJXyH5pMe0eKdRZyyi3kJE6PpzcabGUOxQwP6qSJmEpC8RVtAqrqPIoQGeTQa5pAgXmafgN9CTZNBHZnGQqw2vYqtxGtkU2iTMSCRkVRuTEaCInRrNFtY0KQT2Jlhmk2GSzLHc9+1qOUiqpxX9qKGHGApbnLOfo/INIp4USauRG+rRwYsd6EzvSg5B/Neu+2ZoxyR/vfzFM2QYNtyFstDPJJmEkGQcTbeSMZLQniRMDiRzlSegwRwL7WbAiqogd6Q20+GSgs4gmYawLgf0sCBpoR0AfOxJGBJMwNICQ3pZ4/Xk6tr1GcKJlCadaF3Jx2UKutLdwdVEj11vqubaojnvbWnmycwnPtrVzZ1kLx0uK+Dwxlfxp9iSPtSai31wE/WyJHOxCZH87JEMcEfYzRzzEGkGfmSz0TKDdO56VnlLqPrOlZsxcNsz2ZOtcL/ZYu9DpG8TFEAFXI6K5HhnDzSgJ1wQirkfGcEMo5rYoljsxcdyLS+R+fJLhqTU1gydpmTxMyzB0An/sBj6Vyw3fBCoVPFereKFR81Kr4blWw4uiQl4U/bjYWa/laXFh9+WQJ+VF3C8r5F6xhkelhTzRa3mgVXI7P4eH8nyeFMi5IJZwIjSME77+3I8S8yw6lieSRO7FxHNflsGjtHxuxCdxNymZ+0kJ3EuScDs2nOuSME4JIjgeEMilCCEvM3N4pVHzsr2JN18u483XG3nd+SXvzu7gdcdWblcV80Cn46ZCwR2FkjsFCm5k5/KwQMW9XDl3svO4nZ7NtaQ0riYkcVEioUMcz1fBYnTT3Ugaa4fIyPHHASMvQoc5IR7jScIELxJH2KKY7EnuBEcqLYOosAhEMdWBKqtgCiY7kzbSlpTh9kj6WJEwyAlhHxsW+mVxSr+EK43t3GlbzMWmGg5r1GzPyGV5ZDKyUQ5E9bci5C8OhPzFgaiBjrS4SdgVl8sZlZ6regWXtNl0yZPoVKVwsSifOw2lXK7/R/j9VP/RJ+Cf6icAnixRcqJYxekyLR1lOroq9HRV6OksL+J0aeFv3AJWckSj47C6iEMqHXvyCtiVk8uOrHS+0WdzYZ6GpxvLeLW1gve7Kvh4sIyPB0v4/lCJYfnzwTLeHSrn9UHDkuc3R+p4+00T7781rHt5f3Ih70628e5kG29OLeX1qXZen2rn5anlvOhYxcvO1bzqWsfLs+t52bmOlx0b/qHent3C27NbeN21idddm3jVuZG7R5b1ALAnPenJ787AXr160WDp/wsALrIL/U0Alkxy6Qag+lNn5KPtSOlvTO4QU/Sj57Le1pf9vkLOShO5mp3GVXkqD0vl3QB801L8hwDwYLCUHZ4S1thHst5VwkZvGWu9ZKz3TWCVq5BVjqGscQzkc/cgvvQIYae/mD3hKRwR5XNUpudQfBkrfTKos5ZRaBJD+gQBGrNUalw11IfoqQnWMi+ylHZJA43+hagtUsgxiexF32MAACAASURBVCdzZjze/dyImhhFVWQda/M2sCZjHZlzM0mYnoB4ipSAEcEIPxOxseALakXN5LqqyHZW0J6zjlOrL7BYvpJYuyQiZgppz2rndNu3RE30x3+QA0mfBSEa4YZ4uCsxg+xJGOZEyihXCkzC8PvzTPwGzCXYyJbgEQ6kmArINRcjm+CPYIgjAb0tCRvuimSCL3lmUSwJVzPfLxP1rFBSPvVAMNCcwH4WBA+yJ6C/A4J+7kiG+BHQey5evafjN3Q61zds4UTrfC6tWsyNNW3cWbOYJ+vaebZpOZfXNnB9fRPPvlzOPlUeraFhVDl7EztsJpF9jQn68yzCelsROdiFqIEOxA5zJqq/BeIh1kT0nkGLexwr/BJZ7R1Hw2R76sZZsGmON9ssfPjKypkOn0DOB4VzOUzI1YhobgjFfygAX2jUPNdqDOfi/gMAfFym42lx4S8A+FiezyVpLKfCIzjpH8iDGDEPY8Q8TUzlSUoWZwVSvvGP4KB3CB0RIi7FxHItNp5bcRJuxkrpEgjoDArhapiQB5IEHqal86i+lCcr5/F0Rzuvv93M+5NbefX1Bm6V67ir0XBToeCuUsV9lZo7+QXcyyvgzs+egC8nJHM5TsY5sZhvhRK+8BaQN96O2OFWRA2zJ2yEezcAJWM9SJjgRdJIOxSTPcmb6ESlZRDl5gEopzl2AzB1hA0pw+2R9rXuBmCzVxrHtK1cql/SDcAjWg178pSsk2T9AoBhnxiujqwMSOZQqoozKh1X9QVcLsyhS5FMpyaVC/p8bjf+cwF4skTNqRLtj/sBdZwuLeRksebfAWAhB5WaHwGYzc7sDL4tyeVis5Znm8p59WXZvwnAN4cqeHOwirdf1/P2myY+HJv/bwLw1ekVPQDsSU968p+egb169aLJwp9WqyDmz/Vj/lw/FloGMs/Mh+Y5vswz86HB1JPaGW7UGLtSOsWJokmO6Ke4opvkjGq8HblGs1GPnkvVJGs+dw7gSHAUlxJTuJGXzg1lBo/KCnheo/5DAXgoKIa93hKWm/vRPN2V2inONJr6sNgmiGW2gax1CGSLazB7AyI4EBzNDh8hO4Nl7BdkcUCsYk+MjjbXROqsZZTMiUNuLKXSoYBGLz0lrrk0BBeyRtbMxqRW5vnrKLROR2mVjnBkIO79XfEZGcDexq/ZoN1KvqOC+GnxyIxllAdU4vAXZ+JNElmWtppG6UJKQqtR+ehZnLGKU6svsL/1KGWSGpyN3Mhzz2N/7S5ip4fhP8iBxImBiEa4ET/ai2qHJJTGgWRNcEExK4SQ/rPw7T+boOE2+A+1wX+wHWHDXUmbEkmeaRyKOYlIJgRQH6TiWuthVkQVIRvrhKDvLML7mhHefw4xo90QjfEicIgLnn1sCB7mhl2vzwgcMZuyQAk3N2/m8rpl3N26kvvbV3Fv6zIebFvB452rub2lnUsr5nOstpLsGZZED5mMeMhMovuZIehtRugn5kT0tUIw2A7pcBcSR3kgGmiFZKgN4Z8YM89FwvrQDDYFpbBgphvzJ9uzzSaIPfbB7LF24aSnH52+QZwLDOvuBP4RAHymVPCdyrAf8DuN4Sn4p+fgXwPgw4oiHpQW8qS8iGclOh4Wqn6xB/BGYhIXxBI6QkO4HRfN7bgo7qYkcSk2gXmTZ1HQexRZ/zKC6jHmLDZ2Y51FAJstA9hk7kVXQDjXg6N5FBHHHf8o7gpieVVexusFjbxZv4S/7dvM3/Zu4vHqBdwtK+Z+YSG3lErD+he1hrtyBXdy8rmZkc31tEyuJaVxMS6Rs9JEuqQyvvAT0mjmjrDfTMIHWiAY4UL4KF/CR3ohGOFC/KeeyD71IG2sE8opXsgnuVBtHUKRqReFJm5UWgahnOpK4lALUo0cSBriRNwAB6L72VFiFc3ujCq6Klq4t3QJFxqrOaBU8G1RGbuziogfYUdE77nIjNyQDXcmb6IHe2QKLmjLuVyk44o+h0u6DLq0aXTpsjhfruRaU9mvPv3+UQA8Wijn20IFJ/TqbvQd1Rb8JgAPa9QcVCl//P4vjz3yLPbIM+ioKeBGWxEvPi/jzfZSPnxVyseDJb8KwHdHqnh/pJb3Rxv5cGw+H08YBj++P73IcO3jZ9/9ve1Ybpj87VrDq641vDm7gVfnNvD6zIZu5P28egDYk5705I/KwF69etFs4c9iyyAWzPGjxcyXhXP9mT/bhxYzX+bP9qHJxJN6458A6IB+ij3F01zQT3VG+5k9irFzKZpgSf10O7Z5BPFtuIirKanckmdyS53F43IFL2o1fywAfSP5yiOK9tleNE91oGGyPQtme7PUOoCVdgGsd/Dnc9dA9voEs98vnF1+0ewMlrEnLJ2dETl8HpJHg2UUjXbJzHPJQWkST4W9nHoPHSVO2SyKKGNXzgrWSZupdM6jxCGHrBmxeH/iiL+RH7FmiWyrPUCjrBXpTBmSSRKyzLOYL1qAaz8Pkuek0Za0nLqY+RQFVVDgWcjC1OXsbjrMkaUnmZfeiuMwF6RmUrZo15FiJsJ/kAOxY32IHOqExMiNepc0qmyjSRtnS9pnLoQPNsW7nwkefWfh2X8uvgPs8Oljj2RkEAqzFGrcNaSbRrNYVM6tJUdpC1ORMMYR0SBzogdbITayQzrOk+jRnvgOsMOzny1uvS2w7TWB2CmOrE5VcaFtCddXLeHh1pU83r6ShzvaefzVCp7tXcvLfVu50N5Kq0hMWP/PCO8zjYhPTIjpZ0t0PzuEA2yJHmRP9HAHYo1cSRrtScwga6TDbInoPYNmVymbIrL5PDSdRbM8WTjNiZ32oex3CmOfrRsnPf3o8AnkbEDoPwWA3ethfvY94L8FwKcVhvNxj3RqHqgKeFQg51F+HndS07iWIONMRDgXI4O5IRFwKzGBrqgYls2xZ95kC6rHzWGZmQ8bbcPY5izkC5tgNlt4c9DRhy6PMG4FSrjjL+a+MImHqkKe1tXyenkbf9u5mb9u28jTpQt5VlPF09JS7qgN+//uKVXcyM7lXl4Bt3/+DWBCMufjUjgdl8ZylzCKpzkTOXAOgmEOCMf6EDHWn9CRnkSPdCNxgjfJEzzIGm8AoGKKG7W2YWhnuKOf7UmlZRCqaW4kDJ5LqpEDaUZuSPvZIepvj9IkmC3xOk4WN3K/fSkXGqvZk5/Ht0Vl7MkpRjbKgfBP5pD1qTe54z3QGXtzMCmfS4Wl3CgxAPBCUQadRRl0FedwtlLFpaby/xQAHi9SdYPv3wagkgNKeffVj70FmexTZHKuUcXt9mJebyvn3a5SPnxV/JsA/PBNDd9/U8/3x+bx8cQC/nqqlR9OL/5NAL7pXMWrrjW8PrOWN2c38Pr8xh4A9qQnPfmnZ2CvXr1omeNHu0Uwi838WWjqQ+ss31/8zp/hSdM0N+qnuVI21R79FFtKjV0pNXZFN9kB7URLyqbYMM/UgV0+IZyIFHMjPY07imzuaHN4UqHkRa2GV81FBgT+EU/AvuHscg6jbaYLLdPsDZdA5vqw1MKXlTa+rLPzYZOjJztdPdnh5sveADG7QhLZE5bOttBMNgZkUW0WTotzBm2+apQm8ZTb5VPnXkixbQYLg/VsT21jaVgFOotkimwziTbyx6mXBVKTWEqFtSxRb0QfVYvYOJ7YKbHo3HS0ShfjbxRE4uwUFicu6wZgvruG5sQlrNJu5ujyDlZq1+P/WRAxpjGslS8n11aG7wA7BEOcCO5nTXg/GwrNhJRYhCEdYkK+iQ+pU10JGDwHp3+djmvvWYQaeRAyxJOw/l4kjIsk3zQZnXMG7dJqDmrXUGIXS9woe2KH2xA7woH4Mc6Ix7gTOcINv4H2+A+wweX/mUlQf1PUNiEcVNdyoamZyy0N3Fu7gCebF/Ns21JeH1jLhyOf8/7IXk42N6N28CD4k6mIB9sg7GND5J/tEfa2RzTYCclwR8QjHZEaOZE4yoOYQdbEDrcjsq8JCzzi2RSRzRdhGSye7UXrdGd2OYRxwDmcQ45enPLyp9M3iLMBoVwKjeSaQPSHAPCp4u8QfKpSdg+F/BYAH1XqeVim41llMd+VFvG4SPOLIZAHmVncTknlYmQUXUE+XBOGcjs+jksxsRwLjeFoaCxbXUM44B/DNyFxfBssZZ9bEF85+vKllQuH7Xw45ynghr+YO4JEziWlc0Ov5+miFt5tWsP7jat5urSVlw11PK+o4K5GY7gBrFByLTP7V5+AzyekckyaSb25L3njbRAZOSIa40XU+CAE44IIGemJaJQryZ95k/KpBzkTXFBN9UY51Z06u3CUU50pnetDhUUgGmMP4gaakWrkQOYoTyR9bREPdCRrkhero+R8W1jLg2Xt3QD8prCEvbklpH3qhqCPOfkTvNBO8aLWMpAjKblc0hRys0TLFX0WF4vT6SrJorNMzpkqLZeayrnQUPz/kw5gAYc0cvYrc7s7f/uVWRxQp3OpRcP9VcW82V7O+90lfL/3twH48ds6Ph5t4IcT8/nh5EL+S8di/trRxseOxYa9fx3t3atf3nWu4G3X6h/xt4635zby5sIm3pzdyJszm/+hegDYk5705I/KwF69erFgjh/LLIJpM/NnwUwvFpp402rqw6JZvrSa+tAyw5N509xonOZM+XRbSqbZUm7iTPlMV4qnOVIyzZYaE3tazV3YGxBGR4yU29kZ3FNlc0+Xx7MqNS/rtH8oAL/2j2S7nR8tE81ZNM2OpbPdWWjqxkobfzY5BbDNNYDdngEc9PHngG8w+4IM3wAeFOawN7qAHZEqWuylLPNV0OiURd40MQ3uhTT7lqKZI0NlKkU3V0alTSaqGVKSPg0nYpgPkokCGmOb2d1whHiPfDSCSnKcFGTMyaBN2sa8qPlETowmfHwkS5JXsDCpnQbJAlQ+eupjF6KPqubwkhNsr99DmksmMksZ7Rmt1IUXEWrkRugAO4L7WRP457nEGzkiHjQD8eCpnCpdwpGiVnIswhCMdUT4qRdefe1x/5Mtwb29CevnR3h/X7ZkLWFr7hLKXNMQDrYieogFGRM9yJjkQ8YUX1KmBpFqHEGueSxKcynpkwJp8U5mZXA6B1N1nFXqOKNUcKVKy9WGIi43F3G1rZyry+qZJ44hdvosggZPQtDfkoi/2BP+L06kGkWQOjKchFFeSIbbEznUAtEQO+KNXBEPtiHOyJ7oAbNp803+zQ7gt+4BdPkFc8Y/hPNB4VyNiOZWtPQPAeCTAnk3Ap8oFTzVqAz1GwB8XFXMo/Iivqsq4XmZnid6reEOcIGcB7mGieOHWdlcE4l5KJJyNySS6yFC7osTuCZKoCsshjtJadxPSeVhSiL3kiTcEIdwJSacI+ExfO0r4FyIlFvCFK6LUrmpKeLV4sX81y8/58na5dxrb+XWgnk8qariSUkJdzUaw/UPjZa7cgU3M3O4lprB5aRULsUncVYcxylxIl8JU8gabYF40CySJgchmRyMYFwQgk9DCBnpjXiMO6mTfUmZ4EbeZ26opnqjnu5Jg4MA+SQHKiz9qbAIRDvDE0k/U9JGOJI33g9xHxskg5yQjXJgcVAah5UVPFy+jPMNVRzWqDmqK+WQohKtWTgJI1xIHjyXkumurPYR05Wv5IJKzkVNDheL07lQnE5XWQ6d1Uo663Wca678pwLwuF7JCb3hO8BTJVpOFms4XqT6NwCYyz5FFrvz0tgjT+eAOp3DhRlcX1zI43WlvN9dxoc9ej7u0/HxoP5XAfjDsXr+eqyJv55s4W+nF/FfO9v4L11L+aGzjY+dy/jYuYwPXSu6lz+/7Vr9I/7W8+78Jt5e3Mzbc3/v9v1a9QCwJz3pyf9pDGtgZrrTONODuumuNM/yZpFFIDVTnak3dqNhhjsNM9x/8QRcNtWZamMPaoy9qZ/hyzwTHxbN9WOlQwgHIuM4lZjGtfxcbmtyuVuY+w8AfDG/kBcLtLxcWMiLVg2v2rS8XlTID0vL+LiilB9WlvH9yiLer9DwclEB3zXl8rQyi4eKNO5kJHElXsyRgEh2uIay2MSJlplOLJzlQau5H0usg1jjHM56p1A2OQazzTWI3R4RbHMTcCImj6PR+ewIzWKdVyoL7aSUzRGTPzWC9MlRaC0zqfbSkTc9FqVpIjqrTAqs0oidIsSlnwPOAxzJccpiU/5a2hIWkGOZgvSzSNTOSjTOGlSOKtLmZpBumUXAiGAWxLWxRr6Zmuh5yCzSyfcqpDm+lRbZYo62nibHR0W2t5KV6nUsSF1A/Fwpjv86l5ChzkQOcyN5nB8JQ6yRDTLhWmUDj+Y3UWFhSdlcRzLHW+HRy4zgvh44f+KGcx8X/Ef5sSSpnqYoHQV2cUhGuRA5wBzt7BD0c8KpsBbS5JlAi28yzaGJVAeLWCCKZ0dcGl+GxvClXxjH09PZlihlizaTzaUK9i6o5Obuz7mzbQ8pMyIRjHTDr781gQNtCBloTVB/SwrMhJQ4xFMwK4ykT92JHWlHdD874oZ4kDDGm9TJ/sSMdqDSQ8zmeBXbZSq2BkhoNbFns5krB52COOkTQWeAkLPBIs6HGW7nng+L5HqMhOsxMdwQi7kpieGWVMwtcSy3fzq9lpTKg6RU7ial8DxPzrOcPB5k/rgOJi+P75RqHucX8DhfyRO5ikcFKh4p1DxSqHlaWGS4q6st5GFREY+Li3laWsp3pUX/UI90ah7p1DwsVHFXJeemPIerWelcz0jjRmoKV6VxXBVJuCGI4VZEDI/FMh6JZdyPjuNBbCLXoiWc8A2nIzyNLmkeZ9I1nC2r5sy8Jp7t+JxnOz7nuy/X82z1Mp4ubuVhcyO3aoq4Xq7huq6Qu5pS7isruJNRxKV4OddT87gQn8K5hDjOpYo5niBjnX8Kkn7WxA9zQ2TkTfhQT6LHBCEY40/4aG8EY9xJmOxPwhRv0sbZkz3enhIzX+rsQ8ifZEO5hTfFZu7oTN2RDphJ3EAzMke7EdvfHukgF6L6W1BiLWB/fgX3lrZzoaGW9fFSOquq+UZbQb1bLPnT/RH+ZTJ1VkHsji3geJaSq7oS7paXcUmXw7nCDLpK0jhfm8vFeQouNus4V1/I+dpizlYXcba66FdPvf29irox9/P6+ZTvT8Mep0q0HCtRc7xU84u1L1/rCjiqV/JNkYKvdQV8rSvgsDafw9oC9heo2K8oMDwBFyRzUJvMNyVJ3F2p5vnnej7uK+HjPj0/HCjkh/1F/LC/iI8HS3h/qIz3h8p/nPxt4O238w2dvq4VvDu7indnV/G6c/lv1puuFbw9s5J3Z1fx/txq3p5fy9tz63+sjT/Wpu5hkNddW3jd9QVvzmzlwTcbegDYk5705HfHMAQy15dFFoG/+AawcaYHzbO8aZ7lzTxTL8N3gCYeVBq7UGnsRrWxB3UzfWk08adltj9tFgGsdgrjUFQCp5PSuS7P4442r7sD+KJWw8t5Ol41F/0uAL5arOD5vDyeVWXzSJnO3cxkriZIfjcAd3pG8U1kJgfDM9kZls0mv0zanBKIHWBLZB8bYkcForHIoN6vhHo3DUrTRNInixCPD8WjjwPRUwSUhZawUNZCVUgpKXMSkEwSkDBVRIF9PkXuRaTNTkM6LY7KkBpks5JpiJ5PXcx8VD561L7FVInmsSCxjQJPDYvSl7Mwaxl6YRWt2UvZrN+MLlCD1wB7Agc5ED7YmYzPAkkZYUeqkSknFGoetdTSoZVzrriM9PEzce01GadeM/Ac5ES6dRwLY2tJnRJC4kQ/tOYS4ofaIxtsyzKvNNq9Umj3SWZdZCZfytQc1FTzTUUD15euZnd8Gmt9QtkWJGSJuwfrpSJW5CSxd141r08d5ezadVQKZIQNdyV0mBNBg+0JHGiDYJgD0SNdSP7MlyzjIJI+dUcywh6JkQ2JIzyRDfcmtI8VkUNsCR00l6bAJDbHq/gyXsFGLyHzplqyZY4bh11COOEd3g3AixFiLkZEcTEiisvCaK5ERXE1Opproiiux0RzPVrMzZhYw/m1hCTuyZK5LUviUUYWjzOzeZKbx5P8fJ7k5/MoT86jPPkvAPhYqeGxUvO7APi0uPD/Y+8+n6O+s33fc2ufPWfGARubnBFJZAEKKOecY0vdyi2pc1QndSujDEKAiMaAyMHkDCaYnDMmKyCSMcGA7Tm36t6q930gWzMce/Y+zPbcOqdKn6pVKqn0B7xq/b5rrc5qs5poNudzV6/hnkZFs0rJndw8bmd1nKm7l95RzbkSmvOktGu1tOi1XBXn0awu4VHxTF7MXsJP27bzdt8uHu5cx6Md63i6ZRVPmhbxeMEc2upruVdRxO0SG7ctVu6bi2gxlHJHbuW+spDruVouZcq4lCvniCiF9aGxmO18EXzgSFpPX+J7+BLXMxDh4FiSBoST0C+YlAEB5A2PQDIyFMkAV/R23lQ6RVHrFo1ptAczPKKxjvPCbO+FpI8jsr6uyPp4k/ahK2mfeJP04RQKHKLYnGfh3sJF3Jhdz8p0ESfLytmfX0StTxr5YyLI/mwcDR5R7BXrOW+0cKPQxs0iM1dtSi5apVwok3O5Rs+VWSYuzrT8IQA8W174G/ydLLb8UwDcm69nt07NXqOEw0UyTlTIaGkq4Nmmkn8IwNcHy3lzqIJXR2bw+ljHvd+3Z5fw+hfU/VEA/P7sWr4/u5bn5zbw4vwmXl7YTNs3a7sA2JWudOW9071bt27UTQykcXIYDROCOjt+vw6BzHUIZfbEYGaND2TG+I51ML8CsGZMMDPHhTFvciRfOEexyieBg8nZnMmVc1Ov5b5VR0uhrhOA39VbeTbL9t4A/K5Bx+NKFe0mOc3KPL7NTntvAO4ITGZfVA67I/M4mGrhQGoxWxMLyOjuSsKfnUn5PBjtuGzKfc1YJ0tRjRChGp1Gpl0igR96YvTVsVLXxGLpQmRTc4gbGIlgUDRZI1PQuqgp9Csk2z6b5GFCZosa0bjpWSBeQp1oDgVhpZTF1VCeNIPKpDoyJ+dSmlDNmuLNlAlrmSVpZFvlNmqFVUT09CW8uxvRH7ujsIsmp6cLir5T2CdVcKPCxhGdhP0KGQZ7R0L+fRQB/zaOqP6+yKeJqIu3ktbLn8w+AVgnpFA0Lp7yCQksD5GzLCSXpWE5bEzTsFddwsUZ82lbtZFbC5axPjGNFUHRrAmJYV5AIOvEmWwqKeDOtk38P9evs0imI2mYE4l9A0geEEhiXz/CP3Ym5hMXEnt6kDM0GOmIUHIG+5E1wJvsAZ7IB4UjGxBJ0ifuiPp4kfC5E3NjZazLMLIpI5/V/gnUj5jKBgdfDvvGdgLwYrSQqwmpXEtM6bihmyjgWlIS15KSuJHcUTeTRR3n4X4B4P2sHO5kiTvvAj/S6nik1/NQp6NFpaFNo+OB1kC7zki7wcxDUwEPTQXvBcDHJbbO+vU8XLNRT2u+jjathmaZnHsSKS15HXVLnMM9lZJ7ek0HHCtLuGM28cBSxZPqBl4uWsqb7Vt5vvsrHu5ey+Nda3myfRVPmhbwaP4s2uqruVdezL0iG3eNBTSbrLTk27gjM3JPUcClbA3nMpVclujZnZDGYo8oJL2dEX7mRlrfAGJ6+BD7eQDCwbEk9w9H0C+E9AFBKEZEoRwVjqy/K6ZR/tS6xlHjGoVljBezvOMoGOuJYaQ7qkFuaIf4IOvjTfpHbqR/6kPSh1MwjAtldZqGO/MXcHveHFamizhWXMJuTQG1PmmYJ8SgGTqVBQExfC3VcrnAwo1CC9dtOq7a5FwqlHCxXMGV2nyuzDJxvs7ExdrC/zIA/37Ny6/4O1Fkfm8A7tV3nH/bpVWxzyTlaKmSMzUqWldY+X5zKT/uK+0E4Nu9tg4Efl3Km0PTeXu4ktdH63lzvIE3J+fx47kvefML/l6eX/aHAPDXT78vzm/k5YXNvLq4hQdH13UBsCtd6cp75zcArLP3pc7el7kOoTRODuucCP6fATh9pA9VowOZMTaUhY4xfDkthjV+SRwW5nA2T8GtfB3NNj2tRfpOAD6dWcDTmQXvBcDnC408m63nSZWadpOcFpXknwLg9gABO0Mz2Bmew3lFNZe0czmlnE1uT29SPnZH2DME7bhsSr2NaEaloRohIn+CmOwRAuL7hdOk/JKNBeupT51B/KAownsFkTw4hozhAlSOCixeFrLtsxEMTWG2qBGzn5VFuUuZkTqXkpgqZqY1Up40A2OQlaTRIoyhhWyp3kNpSg212bPYVrmNeblzSB4aSVQPT2K6e6CwiyajuwuaAR5sy5ByxmxgoyiJuf5BGMc4E/PxRBI+dydjXCzZDvFIpySRNzAS7egESqaksybexsbkYlZGK1gRJ2VVkpzdGivHy+u4t7SJ1zv28o21nBXhCayPTqQpMIJNmdl8pVZwbtlS/t8b3/LT2StIp/oT28eB6M+8SB4QiGhwCMn9/ckYHETO8HCyBweSO6xjulQ8yJfcwT7k9QtG2j+C1F6+ZA0KQNB7GjPDxaxJy+erdD1rA5NoGOXEV1P8fwPA60np3BCIuCEQ/S4Ab6WkcluYzt20LJqzczs7gM150k4APtTpaNdqaVaqaVVr3wHgI7O1o96zA/grAB8VWzsuhJgNtBvyadfraFWpaFUoaVEqaVYpuS2Xcbcgn/slFh7PquS7L2bROrOKe4UVtFXP4LtFi3m5YyOPd62lfe9aHu9Zy+MdK3jSNI9H82bQNrOcltJSmq1F3DNYaDYU0Kq3cEdm5NtcHRcyNZzJ0HI+x8im8HRmTA4ju5cTGQP8yBocSuxnvsT0CiSpfyQpAyJI6R9K5oBgNKNi0Y+OQtpvGtaxwczyElDhFIbZ3pMGn3is47zIH+GGbpgXxhGByPp4k/2pVycANaMC+CI+l1uN82hevIBVGakcLSpmh9JEnW86hVMSKZnsxbKoWA4pVFwtNHPNpueKRc7VQgmXCvO4XKHiap2BK7MsnK354wB4utTauefvnwXgHp2B3TotOzVKDljknJiu4WK9nger7bGhOwAAIABJREFUCnmxtZyf9pfx475i3u4r6ATgTwfLeHu4gp++qebt8QZ+PDmHH08v4KfzS/8lAOwYBvmKVxe3dAGwK13pyj+d7t26dWPWlA7szRofSMOEIOY6hHbWnEkh76yBqbD3pmS4B4WDXSkd5k3lCH+WTEtghWciG4KEfJOaxzmJktsGPa1FBh6UGHhSZeG7GgtPZnTU+wDwxSIT38/J57saLY8sSlrVUm7lZLw3ALf6JXI8RcOFnCJumRs5LZvB1sQClAOCyOzpR/bAGCxT5dQEF6Efk0nhVDnF09SU+ZtoTJnBam0TBn892ZMziR8URXS/MOL7hZMxXIB8shTlFCVaZy1ZY8WYfAvI9zJRGVeHOaQYnZ+FueLFzMiYR0lMBTlOMqQeGnbMOEBN1mwssUWsta1llaEJm78W6TgB4mHR6O1FmOzSqJ0i44vAHLakKFkdl0nReG+Ug9wQDw5HMiKFrHGpRA8MxusvU4nv4Yt0dBx1gTp2KGezVV7NLkMl+201HKmayYXli7m8bik3Ny5nq07P/LBYlgREsDwogvleAZyvquVkQwNPjpzg0tqtzBUbie8zlZwRwWQOjybDLoIMuwjSh4Yi7OdLUi/PjtUiw4JQjAxFNjyYvCG+ZPfyJ7dPKGm9/cgc6E/C505U+ItYkaLhq3Q922OyWDLFly1OQRz2jeV4YCznIgRcihHxbXImt4Tp3BKmcyNZyLcpKb+8A0zhdqqQe2mZHYMgWbk8yJPRLpHTKpHxQK6kTaagWSanWaGgVaXigVb/CwL1nQB8bLHxpKDwn3oD2F5oob3Q0rEa5hcAPvxlOrhZo+Z+vpa7Bi23bQbuzizl3oJqnq5fyPd7V/Jow2Ja6uq4P6uOh8sW8vrINl4c3cLDA6t5vG8VT3Yu43HTbB7Oq6atrog2WwltplJatAW06s20ak3ckaq5kJHLNZmFM9kWDiTrqBsfhaLXNDL6eZIywIfk/v4IBoaROCCcuN6hiAZEktYvDOnAMEyjE7COiUPez5XyKdHMD0zHOs4HnZ0LtW6RlE0JRD/cFcMIXyyjQ1D290PZP4SMHr4kfjCZvEHu1Pkncr1hNo+alrIhN5tjxSVsVxhpCBJT45XFslgBm9MFHNHkcaVIw0VzHhdNYq4W5XK5KJerVRquzzRxeWYBJ6fn/yEA/Pshj3cGPP4JAO7SatihVnDQquRcrZEb8wp4tLaEV9sr+PlA+TsAfLvXxs+Hyvnpmyr+eqyWn0/N5X+cnc9fzy3m5wvLeHux6Q8F4K9DIK8ubuKHS1t5fXkbD49v6AJgV7rSlfdO927dulE7IYD6cQHUjPJmxhg/GiYEMWdSSOcewF8HRCpHeTF9tBfFdu5YB7pQNNiD6Xa+LHVLYqVXEhuDRRxNk3BequK2QU9bsfEdAD6uM/O4zvxeAHy52MzzuYZOALZpZP80AC+KC7itreVb4xz2pthY4JFJvl0kuf2CyR4Yg9FBwnQ/C7KhAmxTZFT5mFghXsAOy0ZswWaEY5JJGplA6igBMf3DieoZRNbIFGQOEqQTpZg8TOROlKBwVqN1z6cithadnwWpq4Y60RyqRbOpT5+L2jufnGkKds78mlmSBejCTKwuWM36gjXUxBSR75yNYowA84Rs6pxMLPQqpt4llWUhWayMFlM4xh+9XSCaMWnIRqYTNzAG/0+8cfm3yST0DkQxMZkV4pnsMS1iu24m+4pncriqgVPz5nNp/VLOb1zC2ZWNTA8KZKZ3IAu8g6l3dGOGoxtHS8q43rSchwePstxcTvokf+I/dyLx846l07E9vUgZGIR8fCIy+xhyR0QgHxWJakwUholx6MZFoxwZjHxQOMrBMaT38Sd7cCCC3tOYEZZNU7Kar9L17E7IZblzIFudg98B4OXYVG6mZHFLmM5tUcbvDoE0Z2R3TgE/lCp4KFXwQKagXaHigVzJPYmUezIZLUol7bp87itU7wDwSUEhT61F7wXA1gIjbVbTO8MgLab8zg7grwC8l6/ltlnHnRIzd2dPp3nJDJ5uWcL3h9byaOtSni5opG3+bB42LeLF15t4fHA9jw6u4sn+lTzdvYynTbN43FjJg9oi2q1ltBnKaNaaaNWaaNHmc0eq5lKWhFvqEs6KbeyM11A4NJCMDyaT1seduN5uxPXyQjgsiuTBUZ0ATO8fjnxQOAWjEykcE4+ivxsVjrEsCMrAbO+JZqgTVS5hTHcMfgeAqgH+aAaFk/mZH4kfTCZngCtV3rFcb5jNk5XL2Zgn5nhJKTuUJuaE5DLDN4e1wnS2i1M4osnhcqGSC2YxF03ZnQC8Vq3tBOCJcv3/VgDcrc1np0bNdpWcQzYV5+tM3Fxg4/G6Un7YUfkOAN/ssb4DwP9xvI6/nm7sBOBfLy7nx0sreHVhOS/OLf1DAfjDpc1dAOxKV7ryX0r3bt26MX2UV+en3/pxAcwaH9iJwZlj/Zkxxo/a0T5UjfKldLgf1kFumPtNpXDwNCpGujNvahDL3CPZFCbgeIaM8xIdd0wF3C00cK9ET3uVmcd1HW8Av6u38mJOIS8bbbyaV8ireVZeL7DxeoGNHxcX83ZZIT8uL+LN8gJ+WGrkaaOaJ/UKHlVKaDdLuK/M4lpmEgci49jsH8miiW4sHOfGovHuLBnvyTrnMFY6BLPVM4GdXslscIxms2cSG/1SuGubw03THLYlGlgTpWNZqBbD6EQyewaisc/E6qjF4KBAPDKJilAzKyXzWZE3j/nCGoRDIhENjSKuTyDJg8IRDAwjtncAGcPiMLvIyBslxOQsx+yqJG9sGvkucnQuMsTjUlFMzWFWci0zBNWURJdRkVCDZJqSReplrDCvoyipnH0N+1msXMiXkkZKA3VI7BOp9FNT4a1gbpQZm0s69aFqKnyzKXZPRT0ugtR+HoiHBBD/iTOh/z6RyD85UOyYwi7NLO4s2sZWUwk7Cgv5ur6UC8sauLBiFmeX1XNr0xK2GzTUjHVjR1A6c5x8WBgazJyIQHYUa3n9zS62FpcjnuhFaPexZAwII6SbA2m93En+1JmUHi7k9vNG3MedrJ7TyOvtiryfK+bhARSMDMI03Je8zz2R9PQjr5cXgg8nE/un0RjsA9iYamBbuoFlgQJWByWzzCWEg5FpHAiI4WRoPOeikrmakMqNJCE3koTcSkjhdlIydxOTuS9IplmQzP2UdJqFmbSmi2nLzuOBWEJrdh7tEjntEjltUjmtf1fNCkVntahVtBvyeWQy0m4y0GYx8qDARLv1b9299pKOtTDNViP3Cwy0FpppsZlothq5Z8nnrlnPPUs+LTYT94xa7hu1tOZrO/YEGgy0Gs20l5bQPKuOJyu+4PXuzTw5uIWWnatoXTGX20vraV4zj5eHN/Ld4fU82b+alwfW8XrvWh590UDrzApaqku5Z6vijqGc21oz9wxm7uUbuJSTwyWJlGu6Qs4pi1kfJUXSw5ncnt6k9gsgsa8f8b19iO/lRWJPDxJ7epDSy4Okz1xQjAxFPz4G7Zhw9HbuVE4OodE7ibIJgRSM9KTWMZYi+0A0/V0pHhOGbWQI4o8dUPfzI/0DL4Qfu5P+mSsmhwjOVs/h/pLl7M3Xs12h4qS1hNLxHqyLEbM1NpoTYiHXDHJuWDV8a9NyyaLgtFHCxWINt2cWcqPextU6CxdrLFyqeT8Anigr+E19U2T8TR0tNHK82Ny5A/Dv66jVwFGroXP9yxGLniMWE19rzezXaNmrlnK0SMrlWVruLM7nu61WXu0t4dWBYl7uL+LVgWJefD2dl19X8froDN4cb+CnU/P4+ewifj6/hJ/P/23dy8szSzrqwmJenl/yS3WA7+X5ZfxwYSUvz63kxdkVvDi7ipfnVncC73+lHhzrmgLuSle68v75DQBnjvXv7Ab+ugamzt73HQDaBrtjHehM8VA3Kkd5sNA5lBVeMWyNFHIqW8kluYF7FtsfAsDv5ml4OkvJ4yop7WYJzapsrmcJ+DoyiS1+sSwc58Y8+2ksGOvG4vHeLJnozwrHcNa5xrHONY5tfmkcilVwQ13BaWkx+5Lz2ZqQz8Z4EysjDZjHJqMbmYTMTohmTC5WZx3LMuew07KWnZa1ZIyII7Z3AMmDwikNzEc+KY2kAaGkDotGMDAMQb8w9FNykI1Jw+AoRTslF/FoIVpHCToXGfIpYhRTcyiPKKI+pRa5k4xchzxkriosEUU0iOexUP0F64vWs6NyG0ukjcxPryF3bBJm50yWi0rZKptBobMQ3bho8oYGYnJIJPZDB4L/r5EIejihto9AbR+Gdkw4X8blsz+/gSsNa9hXVs2eyjIurVzI+eVzubF2IT8d382Dr5ZT4+fH1tgsljqHs8g3jJk+ASxOTODhlvVcW7GU4J6DCPxoCHGfTyHxY3ckg6LI7OtFak83RJ+7ktnTjYzPXUjv4URur2ko+rthGx1CoX0opuG+yHr7IO3lj6yvL+mfTSOl+ySsE8NYFiNlXaKClaEiNkVlstQ5mD3BAg4GxXEqLIGzkQIuxwm5EpfElbgk7gpSuZcioiUllVahiAei1PcG4EOluuN9nlxBi1JJq0bNA10H2B4Y82k3GXjwCwQfFJhoLTDywGamxWKgtcDIw6ICWguMtFgMNJvzuW/S02zOp7XAyP2CfFos+TywGGgvMPHIauWhrZDvaqt5ung+rzev4f8+soeXp/by7PAWHqxawK0vZ3F3ZSOvj27lhxPbeXpgHS/2r+fVrrU8XjKXtvpq7leUcttcym1DKbe1Zu7ojdzW6rgkkXIuV8ZxiYktiQqqp8SS+qEj2b0DEPUPJHlAICkDgxANCiJtYADpgwJJ6dWxnFszJpL8CbGoR4dSMMaPWqcIGr2TKB0fgGWEB5UOkZRPCMM0zIci+1AsdoFkfjCBvB5uCP/kRuKfnUn52BHNmECOltRyfe4Cduu0fJUr4ajJRul4D7YI5OxKSuB0XhrXjQquWVTcsGq4XKDknEXOpRItt2bYuDajgMs1pv8QgKdKTb9Tlt8F4NFi02/qWJHpPwTg3+PvkEnLIZOB/Woj+9Qa9qqlHCuWcaVBx70lRp5ts/HDvlJ++LoDgT98XdJ58u3NsZm8PTGbn07N46czC98bgC/PNfHi7Aqen2nixdlVvDq/pguAXelKV/7l6d6tWzfKR3pSO9qH2tE+nV2/6pFe1I726cRfzShvKkf6UGLni22wO4WDp1Fq50G1vRfzpgax3CPqX9IBfDZfy9NZSp5Uy3hokdKiFnMjO5mDEcls841j/hhXGke5Mt/encUTAmhyjmC5SwxLnaJYMjWKneF5nEg1c9tYxwGRjs2RUvaIrGxNttEUrkc9LBrl0Fjkw0UYJsop87SwKncBm/VNLM+ZS2h3DwI/mIZoaBQ2HzVaJzHZoxPJHp2IaGgUokFRmJylZNsloZqQRb6TlLyxaUjHZ6B1lqJyykMxNQdrgJH6lFqS7ZKI6xeDapqaioQqvlQvZ03heuZK5rJt+hYaxfUskzWicc6iyFvKdnU9O5V16MZGIBnqh+hzV5QjIpDbhRHx38YQ/d/Hkz8+gnKPZGb4ZbBKYGSnYjrHS+eyv7KWA3VVnGuax6WV82nduorn2zZyorKUKhcPmgLiWeQUSlOkgGoPX9aIc3m6fTvzs3Jx/bceRPYYS9ZQHxL+7EJqdy9yB/mT3d+HjD6eZPVyJ7PnNLJ6TiOnpwvKAe4UjQmjaEwYlpH+5H7mgfhTL8SfuSPs7ojgowkY7ANYFJbNypg8VoWlsi0uhyWOgWzzjX0HgBdjkrkcm8jl2ETup6RzX5hKqzCNNlEq7alp7w3AxypN5/vANtkvCFSpaNfrOhCYr6fdZKDdZOCh2UiLUU+b2UCrKZ82s4HHhQWdv7cY9TQbdLQY9bSaDTRbO6rdZuJRYQFPiot4XFzC09pqni1bzOtt6/jrsb28Oruf50d38mTdMm5/OZfby+fx/OvNPP9mG98d+Irnezfycud6nixZwIP6GdwtL+NWfhG3dMUdANQauKXRckmu5LxUxf5MPUsCMzEMDyDlY3ey+oWS1CegE4Cpg4NJHxTYCcD0/t7oxkWjHx+DenQoxRODmeESxVyvxE4ATp8YTpF9IKZhPthGBWMeFkBO98lIPnMn9c8eJP3FhZSPHVHbB3C4sIorDY3s0mpYn53TCcDtQhX7hMmck2Vy3ajgiknBDauGK1YVF6xKrpTpuVln5WqdhUvVxv8QgKfLzL9Tv8XfibKOfX//cx0vNv9DAP66/PmIRc9hs46DRg1fG/TsVxvZq1KzRyXheImcq7P13P/SxPfbC98B4OuDpZ0n394er//DAPjy3Gp+uLC2C4Bd6UpX/uXp3q1bN0qHu1M90usd9FUO96B6pBc1o7ypHulF1QhPpg/3oniYD0VDPSm186BilA+1Y32oH+/NIqdg1vjHcDA5mxOZcq5p9H8IAL9foOPZbDXf1Sp4bJXTqsnhZo6QIxEitnkl0jjcnVlDXZk7yosFE4NpnBTK3CmRNE6NYrlfGue0M7lumsN+gZr1oRlsipBwXFrN1mQb87zz0NjFoB8loMLTyOywKhYlNLBB8SXLxHMoCzKQ0C+YjBFxJPQLJqFfMLKJqRhcJcgmpiIZL0Q2LpUCVwXC/lHkjkzB6qHBME1Bjr0IuUM2iqk5SB2y0LjKKY8qxuplQDZWTObwVNSuKmZnzmVdwTqq0qpplM+jRlTBMt0i5mTVslI2kwdLd3BQP53Mng4oh3iT+KepCP7sQtZnvlQ4p1Hvk82iyGwWRWUwP0RIU1Qu69J17NAWcqh+BkcWNnBp7Rc83r+Ft4f2slUiZ75fBBvCRawJTWKeWxBLo1O5UNHAm61fI53kRVS/ccT3mUr4B+MRfOKEwS4GSS9/pEODkA4NIneQP+I+nuT280Q20KfzE7BtdAjFY8MpGhuCbnAI8j6B5PXyIrOnG6k9pqAf5cfC0CyWR4pZESJke3wuCyb5sMY5iD0+ERwLiuFUWAKXYlO4Gi/garzgv9wBbJPKeSRT8jBPTnuurGNoRK7koULFQ6WaBxoNDzSajqlhvY6H+Xpaf+kOtmg1tOq0PDT+cgZOr6NVp+38e4tRz22rnltWPa2FJh4UF/C4rISHFeW0VpXzZMUXvNixjh+O7OTpmT08O7GL5mWLubFwLneaFvP22D5+PH2QZwe28f3uzXy/dQPPli6lvX42N4vKuKowcVNdwB2tkW/VOq4p1FxSGTijMrEkNBPD6FBEn3ki6B1Fcr8Y4noGIugfgHBQMMKBgaT09SG5jzepfb0RDwlAMyYS7dgoNPZhlE0Oo9YpgnrXGErHB2Ab7U3FpAh0A13RD/LANMwP4xA/NP08UPbxIetjX1I+ckPY3Qm1fQBfF0znwowGdmrUrMsSc7qwrBOAR8VZXFbncsOk5GK+lGsWFVdtaq6W6LheYeRGTQf+LlTm/2GfgI+XWn5TJ0os/ykAf8XfPp2CvVo1e5X57FGq2KOScKJUwbU5+bQss/BiZzFvDpTz5lAZrw+W8uZQGT8dn/HLxY8Gfjr1t5u/7wvA52eW8f3p5Tw/08Sr82t4c2l9FwC70pWu/Mvz3gAsGupN0VBPykd4UTnal7pxvsya4MMip2DWBsRyKEXMySwF17X5fwgAny/U8/0cTScA27S53MwR8k14Gjs8Bcwd6kb9EDfmjPRmwaQw5k4MY5FbIst8U9mapOe0biZHJWVsihSzJiiVTRESjuZVsjHeRP20DPJHJVDqmEuFp5Fq3yLmRNbQlN3IfGENBV5K4vsGkTkynvi+QST0CyZvXArKyRlIJ4hQOKQjHStCPTGTnBHJyMemY3ZVYvXSoXOSkjc+HcmkTPImZqB0lmALNjM9wMZ0byvZw1NJtktC562nKrmKpeYmZssbmZFVy2LNfFbkf8FWyyIu1ixhTUoesf82iLw+LiT9tymI/uKK6C+uNMWY2SiysTJRxhdRIhoD41kTL2NbnpF9plKONzZwcvkCbu9Yw+P927i/bgVfRMaz2DeaNT5xrAlNYrFvJPtVBXy/ajs35q0m4IOhRPWZSHzPqcR9NJmMnu6UjEnGNDwW8QDfv3UBP3clp68H8kG+SPq4Ies7DcuIQIrHhlM6IRyjXQTKfsHvAFBt58UXETk0ReWwPCiZrbFiGsd7snKqPzs8QjjiH8nJ0Hguxwm5npjCjSQhtxOF3BGkcF8gpDk5hdYU4XsDsD1XRnuOtKNyZTxRqHmq1NCuUNGmVPFApaZdq/1b/QLBFrWq483gL7+363U80Glp02p48AsAb1q03LDqaC400lps4WFZMQ+ml9FSVc53a5byctcGXn2zkydn9/L89H6erF1Ny4pltK9fzc8nDvH21CGeHdjBs11beLZlI98va+LhrEa+LSznslzPLZWZO1oj15UarsiUXNGYOC7Lp9Y1AXE/L+K7u5PQL57IzyJI6BdK6pBQ0oeFIxoUREpfHwS9vUjv74t4SADKUWGo7SPQjY2gbHIYNY7h1DpFUDo+gOKxflRNjkI/yA3jUG+MQ30xDPZF3dcdWU9PMj70RvDBNAQfTkEx0pe9xhLOVM9gl1bDBnEuF8qqKB3vwdZkBSfycriqlXDDpOS8Lo+rZiXXCjVcL8vnRqWJ69VmLlYZOF+h/w8B+Pvn3qy/C8Dfq5OlBf8pAA+ZtHxtULNXK2ePRsUehf4dAF6fa6B1eQEvdhbz9uvpvD3cgcC3h8v5+cRM/nqioROAP5+e/08B8PvTSzsB+MOFtV0A7EpXuvL/S7p369aNEjs3qkZ4UjXCsxOAFXbu7wCwcrgH5XaeFA31pniYF9NHelNl70fdOF9mT/LjC5dQ1gfFc0SUy2mxim/1xj8UgM/qlDyxKWjT5nIrV8Q34ens8ExmzhBXZg52ZfYILxZMCmOhYwwrAzPZGKPkQE4JByUVrI9WsCEskzVBqXwVnseh7DLWRuupdRSRPyqBanclNkcl5skqpntbaYgtpybShsYxm7BPPEkZHEFi/xBSh0WTOzaZ7NGJ5I5NRjUlk5xRAnJGJKGZJEbrkEO+k5RCn3wKffLJGZtKzvg0csanoXDKw+Snx+qqoz60AvkYMbEDohHai8iblsfuhn3MUy9kdt4sFijnsqFwFTuLlrIh10ClayDe3f6C8MNxJP/JEXEPP0wjEjmkmsdhTQNfpWtZn5rHqsRsNqWoOKAt4WhpDacWz+PMqi9o3v8VLTs2cKy+mjk+oawKSqZxvC8L3UNoCkvk3tylvNq4n6XpGkJ62BP++USiujuQ2d8b/egYSuwTsY6IJb23B1n9vEnv7UHqp85k9XJFOsAbaV93pH1cMNn5Uzw2nPJJkeQPDUPeJ5DsHm6IPnFC8NEE8vo7szRaworoXJYGJLElJpu54zxomuzLNrcgDvtFcCIkjivxIm4kCbmZnPpfHgJpk8p5IJZ0/l97roynSg3fqbS0/3I5pF2hol3d0Qls12o7bwc3qzp2+rVpNZ0AbNNqaNWoadNqaDHquWFSc82i4Y4tn/tFZtrKimgrL6W5Zjrfr1vO672beH1sN9+d38/Ls1/z1z27eLF1Ey92bOHt0QM8O7SrE4Dfbd7QCcAbtjIuSrXcVJo6AXhJruSy1sQ3eVqKHcIQfOJI1AeuxPWNJ+ijYJIHRZI5PJLskdGkDQlB1N8PQW8vMgb4IR4SgHxECKrR4ejHRVLqEErVlFBqHMMpHR9AyTh/aqbGYBzqScEIf4xDfdEP9EbRaxo5n0wj7S+eJPx3JxL+PAnJME926mycmF7NLq2GjTl5XK6opXS8B5uTZJyS5nFdL/sNAG+UGzoBeKEy/z8F4Pu8AXxfAB4vNL0DwD0aGbvVSvYo9OxWKNmjknCyTMmNRuM/BOBfT9bz1xMN/Hxq9h8CwO9PL+eHC2t5e3lDFwC70pWu/MvTvVu3buTbeWEY4oFhsDs2Ox+KR/pTPNyP6aMCO2pEANPt/Ckf5kf5YB/KBnsyfagHlXZe1IzypHFKIIunhbLKP5qvU3M4JdFwNd/AzWIDt0p0NFcZeVBn5unsQp7NLeZZYyHfz7PxfH4hLxbYeLnIxstFBfzQVMCbFYW8XVnE65XF/LC8kFcLbbyabeJ5jY7vCqS0qzO4m53AyVghWzyjWTjSg/kjfJg9zJeFE6OZPyGG7TEaTsmqOKWsZEmIkEWe0Wz2iWdHYCq7IiTsTStjeaSR6dPEqCdmopycRXSfEFJHJFISamV+ai3F/hrE9gmkDosma1QCoqExKCZlo5kqId0uGeGgJNST5WinKpFNEGN219EQX0tlaAk2byMl/gXonBQoJuWidMjD5KbF6Kohb0I2Vl8TtTGVpI0WEdU3AoFdEsURJdSLZlESW05daj3rrV/RZFpLnXg2SRNScP338YT1mIJylB+13smsS9VxIH86pyrmcnflZu6u3cHd1bs4U7eKUwtWcnPrDq7sXcW3e5dzbUkVO9UZLAv1Y0NYDCv9olgRKmBDejZHbIVcmbeMyug0ovo7EDXAjfC+LsR/5oioxxSKxoawJjiLhinR5A7yJ2egH+m9PUj/bBq5/TxRDPbrOFfX2xnrqGDKJ0ZTMTma8glRKHtNQ/K5C7m93BB96IByiD/1Xuk0RWtY7JvCplgxSzzD+cLRl1VOfhzwi+J4UAIXQ5O4EZHE7egUWuKTaU4U0JIsoDlVwL0MAfdTRbSkptOSnkFrVjZt2WIe5ObSmptDW14urZI82uRS2uRS2pVKWvKkNOfIuC/u+PlApqBdruzoDsoVPJDJuSfO4W62mDvZOdxWqLklV3FXpaVFZ6DdaOGuSstdlZY7Sg13VVrua/S06PU8tOh5bNXzXZGRJyUmHpUYeVRipLlIx91CLS2lBh7UWHlSX0L7zCJerJ7FqzVzebFiFvcbSrhVY+NWpZXm2hKeNNTwdFYd90qLOKdRciIjl4u5aq7kabk90UduAAAgAElEQVQuy+eOxsbZHBObwjOQ9HAktbszos99if0slLjeYSQOCCBjeChpw4JJ6utJ8gBP0gb5kDsiCOnIIOQjAzBMisI0OQrrOB8WBQooHueJzd6D4nHeVE0JpWxCIIX2fhTZB1I8JgRlH2fEn0wm+aMpxH44iei/jCOltxPrJTbOVi3kSt1cNmbksFeqYFlQINsE8Vw1SrlmzuWqJY8rVhmXC6Sct8q4XK7nenUBN2YWc6G2gHPVZi7PKOZ8jZkL1WbOVRo5V2niTLmps+P3t8seVk4UFXCiqIDTFYWcqSziTGURJ8utnWte/n7Vy9FiE0cLOyaBj9l+Wx1Tvx3v/w6bdb8MgXTgb5dcwl5VDlcq1bTMM/N0mY0Xm4p5sbOYl0cqeHm8mpcn63hxupFXZxbz5vyXvL2wlLcXlvLm/Je8Prfkd+un88v56VwTP51r4u35lbw5v5o351fz8txqXlzoWPPy6uJGXl7ezKtrv18vrnz1m2o9saILgF3pSlfeO927deuGbphHJwCtw7wpGuFHyQh/ykcGMH1UIOXDO/BXNtSX8sE+lA7yoHSQKxXDPKkd7cUcB38WOgez0i+KQ+l5nJHpuGEyc7PYwO1SPS3VJtpnWPhuThHP5hbz/bwins8vfAeArxZbfxeALxdYOwH41CLhgSqdO1nxHA6L5yu3CBaP8WaevR+zR/qzYGI0M+3DOKeo5Zyilj3CfBZ4xtLoGMJmvwS2+gvZGSHh65xqmmLMlDplIrUXkjo4msjPA9E6S5mVUMVaxWJqIgvIGycgfXgseeNSSB4UiXi0EOn4TERDEkkekIB8Qh6KiRKkE8RonRRUhpWyQDQHo5uW0kAbxf4FWL2NmNx16F1UaJ0UCIcloXdVUxdbhcnHQMaYNBKGxCO0F5Hva8AUUsD0xCpW5K/mC/UKlhvXURBZiue/O+L/JweKXVJYEqNhcaSMtVkm9hhrubNyN9/tPsUPRy7TtuMILQcO03rsMC3Hd3Bv32rWSVNYHhPK8gB/NvjH0OQezsZ4MTvlOp6t38RCoYykIVMI6G5PVF83Inq6dgLQOjaYtWFZzPNIJL23Bxl9PDsBmN3bDekAb2T9PFAOcKfQPpSyCVGUTYygbHwk6j5u5PZwQvz5NNI+noJqaEAnABvd41kbnsZC12DmTnRjxVQf9vpG8k1QPBfCkrgemcSt6BTuxQu4nySgRZhMc3oy9zIE3BMJaRal0ZyWTktmVgcCc3JoFmfTkiPuBGC7Us4jtZrWvzvR1pIn/dsbQIWKBzIFrRIZd7NzuJWRxbfpmVzNSuNadjq3pTk0q2Q80Km4p5BwTyHhvlJKi1pOq0ZBu07FA7WChyoF7RolbRoF9xQS7shyuSHJ5mpeJt/Kc7ijlXM/X8UdvYK2chOPK2w8mm7lboGeOyYtN7Vqmo0GHtuKaLcUckOu5rQwg6PJaZzJlHBZouWG0sgtXTHfZOiZ7RhO5icOiD5xRtjLl6Q+ER0XPwYGkTYsGNGQQAT9vBD29yRtgDc5wwLIHeKLxj4Ey+RYjBMjKBjrzQL/RKyjXSkc40nZRL/Oz8G20b6Y7byxjgxA1deF7O4OHat8PpxEzAfjSentxJocC2erFnK5dg5rRZnsEOexMiyUPWkp/xCAV6bnc726gOszirhYZ+V8jYVLdUXvDcBT022crijkdEXhPw3Avx8A+fUd4EGj7h0AXq3S0DrfwrOmIl5uLuHlrhJefVPJqxM1vDo1g1dn5/PD2S94e2EpP15c1gXArnSlK/9HpXu3bt1QD3Ylf7A7+YPcsAzxpGCoF8b+rhQO8aJ0uB+Vo4KoHhVM9ahgygZ5UzzAjZKB06i082LmWF9mjvNi7mQ/lnqGsl+Yzck8NdcMRm6XmrhTlk9brYWHMwt4NreY5/NKeT6/mBcLini5sJhXi4r44YsifvjC9rsAfDG/gBezDDyr0vDEnEebMo1bGbEcDIllo2s4jfYe1I3woGKYJ/OnJbIpVsspSSU7otWs8Exho3cKa1xj2egdy9fJSs7Iyjimns3CUC3K4VFkDIgi+hNfsoYlUhFgodRTz9yE6cyIKcTiKUMwMIzMkfFkjxaQOyYVxSQxacMECPrHIxyURNKAeER2AlJHCTH7GlmtXonWTU1hkJWauCqqYiooCS1C5aJANlWCdFIOueOzkE/OY46ogdnCWVj8zQhGJmMKMFMQXog1oog54nk05iyiLKaGeemLqAwqotBNzmH9Ym7VbWG/up4FiSo2a6q4s/4QzTtO0bz3BI/PfMP9E/toPraX2zvWsbPMxNKQcNYHx7A5OI4l7sF84R3FscJqHq3dzuX5qwj48zDCP51I9OcuCHr7ktjTi/gPHUj8YBw5vR2omOxPxZQQEj+eSuLHU0nv7UFaDxfSejiR29cD5UBv8u38OtfAFI4JptIhFtMQP7I+nkx696lkfuqEfJAvc/yyWZtoZKZjBKtChHzpFUH9GCcWT3Jnm1cI+/2jOR2awIXIBK7HJHM7Pok7Kck0pwm5l5nCzcwk7gpTuJci4p4olfvpGbRkZtGSnc29rEzuZ2d1AvChSsETrZqHyjweyHN4IM+jXSHhsUrNE7WWljwpR0Oi2ecdxLHQOM5GC7mYIOJupoj72Wm05WXRLhXzUJbD/ew07men0SxO526miFtpyVxLSui4SSzI4F5KFvdTsriTlM7txDSuRQu4FpHIzZgU7idl0CYU05KcxdM8BY9zZDSnZnEmNIYTgVFcT8jgRmImV+Mz+MYvhgMeYex3C+esKJXLubnc1Jm5aS7himE6S4IzyO0zmbRebqR85oagpzdJfQJI6OVD5pBQRH19SentjaiPF+l9PUnv64l4gA85/T0pmBiNzSGW/FFBFI3zpdEnDsOwqRSO8aRqajAzp0VjG+2NZYQX8l5TyB/siWW4H3mfOZLy8VTiPnJA0GMqKb2dWJAo41jJbK7UzWWtKJOtmWK2JQs4JsvlulnOjQIJ161SrhUquGqTc7FQwfUqE9eqLFyttXF5ZiGXZxZyvtr63gA8WW7lZLmVU9NtHC+1cLTY9N4A/HsEHjJpOZCv4kC+phOA+zV53KjV83BxIS9Xl/F6Wzmv95bz5ngNb07P4M3ZWby5sIi3F5by06Xl/HRpOT9eXPYP8dcFwK50pSv/u6V7t27dUA50QT/IjfxBbpgHe2AZ4omh3zRsgz0psfOlclQQVSM7qnSgF8UD3Cgb7EbVcG9mjvWlYaIv8x0DWe4dzgGRmFMSDdcMRu6UmblbbqCt1sKjeivfN5bwYn4ZLxaU/IK/En5YXMzrJcW8XlL4uwB8Ps/C8/p8vqtU89iUS6silVsZsRwJT2CTeySzRkxj+rBpVIzyYW2kjPP62exNNrHaO4Mvp8aywTme9c4xbA0ScF5exA3TLI4o6pkTqEA2NJyMAVGk9A4lf2IO5Z75qOzTyXfKweqtwOiWh2BgGFmjEhDbJyMdn4FmqoTsUakIByWRPCCBuD7RpI0WkT0hi6rYSjYY1lMRPZ2K6OlUx1VRET2d0vASjD4GNG5qFE4yMkaJSBmaSGX0dBZkzmO2qAHx5BxKIkvR+uUjc1dSEltOQ+Y8ikKKKQqwMTumnO3Kxdxr2Mm3Nes5YZ3PSrGJA2VzubP5IDe3HeLWrgM8PrOPtuM7eXB0BycaZ7I8O4NNsUJ2RAjZEpLEYv8YmgSZXFzUxPPdx1ilLCH4o7GkDvEluY8vyZ/7IR4QiuhTF4QfTyLj8wlYx7tRPjWEpO6OxH3g0PkGMPVTR/L6eSLv74luqA8mO38sIwKx2QdR65hI4cgQMj9yIPWjyWR84oikvxezfbNYm2ikxiGEFUHJLPeNZqa9I/MnTGOTZxB7/aM4GRrP+agErsQm821iErdFKdzPEHE3K4UbGYncEia/A8DmjExasrP/QQdQziNVLg+VObQrxDxU5vFUo+Y7rZ5bGVlsdfZkpf1U1k1wY9MUX7Y5enMyOIRzEZF8K0jmtlDE3dQ0rsYncC0hkeuJSVyNT+BidAynQsI54RfGSf9ITgdGc9o/ilM+4Zz0DuOMTwRnvSO4FBDLrfBk7sekcSc6lfYMCXeTM7kQFsfmiS6sGT2FA16hHPaN5nBALLvcw9jlHsZB/wSuirP5VinlttHCDXMJJ1U2SqdEIOwxkfT+3gh6ehL/mRvJfXxJ+tyL7CEhpPTyQvC5B+l9vDu7tbkDfJAM8MY2MQbz2Aj0w/0pnRhAo08c+iGTKRzjSbVjCDNcoigY6Yl5uCe5n04gf7AnZePDUfZ1I/VTZxI/mYqwpzPJvRypj8jkkHUG1+vn81VmLjtzJOzPyuS0Ws4Ni4JvrVJu2GRcL1JyrVDBpSIl39ZYuFZl4UqNlSv1RVypL+JspeW9AXii7G8I/BV77wvA44UmjloNnQDcr1eyX69+B4Df1uXzeEkxr9aU83ZHBW/3V/DjyTrenpnJj+dn8+OlL/jp0nJ+vtzUBcCudKUr/8ele7du3VAMcO4EoGmQO+bBHhQM9qR4mA+lw/0os+v4/Fs6xIfi/h6UDHSnYpgnNSN9mTnWl/mOwSxxC2dNYCyHMyScleu5YTJzp8zMvelGHtQV8HiWjefzSnkxv4yXC0t5tajkHQC++bLodwH4faP5HQC2yEXcTI/hWGQSW92jqLVzosLOlZkOoXyjrOKydSGrg3P40kXAl5OiWD8pim3uSRyMz+FWwQzuFM1jd04lDf4y1CNjyB4YQ87QeMo99BS5qMgZEEdy/1ByxyaRN05Aml0MCod00uziOnb7OUqRjMsiw05E6pBkEvvHkTE2HamzjAU5C1lnXM+ivMXUCuqoiKukNKqMsuhySqPKMAda0HtokTnkkjYiBZWLgrLwEhqEsyiOKGFe9nykbgqS7FOQuSupSKjC6KtHOjGT2pB89uoWcKFsOUeNDeyUF7NVV8z5BU3c2rKL6zv30XLkEM/P7OL5qV08O7KdtQoJc0Ij2BWdwc4wERv8ElkWl85Wg5Xb23dxbG4TGtcYYns7kzo4EEFPH9J7BiMdHE36Z66IujuQ/ulYzOOmUe4STkoPF2L/Mom0Xu6IPnFC9MnUziEQ9SBPdIO8MAz1xWYfRP20FMrHRZHx4SRS/jKRjE8cEfd2Y4ZHKitjdZSN8WWpXwJNfjHUjJ5C4zhnNrgHsMsvoqMbFxXP5RgBNxISuSVK4X5WKneyhVzLTORmioC7yULuCkXcS0vvQGBW1j94AyjlsUbMI3U2j1S5PFLl8p1OxTOdnm/TMtjm4sOacdNYP9GTdeO9WDvGlW3jXdg92YMj7kEc9QzhmFcox7xCOeETzpmAaM4Hx3E2MIZjPmHsnebPnmn+7HL2ZaejN1snuLJtjAuHnAP4xjmQUx7hXPGP5064iG/DhVxLTONCTDJHAyPZ4ODKmgkubHYNYK9/FIciU/g6UsjXkUKOJ+RwU5bHXY2Mb41mLuUXslesR9zfheiPxpExJICkXp7EfOJCan8fUvp4kjssjJTPPBB86kZGH2+yenuS0dOdvP4+KIf4UzQhhvzhQWiH+DB9cjDz/RLQDXbAZu9BtWMI/x979xkVhd33f95Hu/vfve8URemg2FuMBeltGHrvM8AwDDDMDDCFMgPDDL0jir0jdqPGeKUnJrbEGCsdAbvGJBoranLl3v3f//c+IOG+cjS5L/97756z5/A553MYEY8P9MHr/L6/0uQcTvFUDwxOnmT86xwKHbxodo6n0NGPdAt3kt50RmLpRpLFYuqEIj4tqmNg1Sbez87l8xw1J5QKzuWr/xSAl5qM9NSX0NlgpHtFOT2tFZypLX5lAP7jyPerimJOlOlfGYC/nwT+RwB+lq8eBeARnYJLy4r4YWsFT/bV8uzDOp4dqeP56WU8P7eC5xdW8XPXVn7u3M4vXTv4uXP7GADHMpax/P8qr40bN45sK0/Utn5obX0osBtpoZ03xsnelE7xwezkjWmKF2ZHd8onu1Ix1ZOKmb5UzwuicUkkre4xrPeJZUdgEkdT5ZyT5zJUqOVGRT636wq5u7yUH1aU8HBDOcNbqnmw0cz9zWYebCnj/lYTD9tNPNpm4ul2Ez/vLOXXXWb+vq2I51u0PFuvZrg1j3v1Cm4YMrmUl8aF9Dg+DpZw0DuNJidftnslc1pZw3lNEx8lFbBhUTRbFkSxbUE0H7lLORml4yuVifPmVs6b1tIeW0T1Uglap0hyp8RS46Em0zGa3Jki1LNFBP8vS0ia6E/6lEiUc8QULMlENiMR5VvpFHvpSHKII2NuBsWCEqJt40iwTyVhTgY1aavZXP4e64raaZQuoy6snMagCpqD6zAF1VERt4LlyeuoDK6jyMuA1i0XjasKc1Ahh0p2c7TxE1JniIiziyNjrhzlIg3BVvEkzZJSEaBma0IhnTml9GXpuJqZR59CTV9xBcPfnuHZrRsMnf+Kn06/y70vDnJtdxsrvMNY5RrJKudIViwNpz1GykcVRu4ceZcNBTnE2i4iaZI3YqsRQCRN9CDhzaWkWXmS9MYiRK8tRDJ+Mdpp/ujnhJDn6IfCxpOMiS5kTHQhy9KNbGsP8hz9KJwRTI69Dyo7b3RTA6hyiaZscTjSCQtJeX0+mROWkvHGUlpck3knXs8aHzErPWJp9Qhj2WI/VszzYOdSfw56BvClMJBvw0Loio6gPyacwfgoLifGMCROZCA5kYEUCYMpUgZTpFyWyLgskXElLYObmQpuZiq4laXk1m9XvtzKVvGjoYAf9Pl8X6Tj+wIt32vV3NHk0ZMspkeURFdiAh2xsVyMiqYrIpZTSwM5sUjA8UUCvl4ayGnPMM77RXNBEENHYDzdoSK6Q0X0BCfQ4xvGoCCCgaAYuv2jOO8fxYXAGE77RHBRGM9F3xh6/JO4G5vLjfhczku19KcXcjO9mB9EBVyOVtCVlE2nNJcuRR4X5Cq6MlUMKtTcyddwQ5PDjdJqjmZqaVgcivjNpaRY+yCe5IfYwhfJJG+UdgJyHIRkTw4g1coL8UR3Uie5k27tgdzWm7wpAozzw9BO9kFl44bawYN1vgnUzvWhcYE/1XN8qZ0nYJVnHMbpXuRZLSLj9bmorJey0i+NHHsvUt9YQrKFG6LxLsS9sZhyj2R2pZXS27KZk4Yy3s/M5HKNkR5TDpeq1PSUqegwyuksz6WzSs3FSg1dTcV0NRq52FzKuWW/18yp2hK+rTNyrtHMuUYz39YZOV1b8vLWlL700ufTNSZO15j45rdrYkYgaOCryiK+qiz4rUUj36so5qsKI8dNJRw1Gvii2MCnhQV8ml/I3+QqPlBkcMKQy5XVBdxpN/D4UBnDn1UxfKKR4QsbeNyxhUcdbTzpame488X+x0nfLX889fuHd33/o8PdB17oT32HuNt3mLt9h/nptz7oOcxPXYd40HmIh52HfjspfIhbX+0aA+BYxjKWV84rA7DM0YVyJw8qZvpSMz+YxiWRrPKMY4NvHLuCxRyTZHNBoeZykY4bFfncqi3gxxYjP6wo4cH6sj8F4MN2E493mBjeZeaX3eU8bzfwbGs+D1tV3G9U8kOVnOuFmQyq0uhMS+SjYCm7XJJoc03keKqRwZK1fCIuYnegjPULo9i6OJadi+M5IsjmdFIxHYV1nCyo48u8OtoidNS4pFEwPQbt9ETKXFRkOkaTMyMJ5Yx4wv6bCynWQWROi0E6JZrsWUmkT08gc3YKJr8iEu1jkcyQYA4qI2GyiEQHCYlzM2mWb2JP0+dsLN5JQ1ozZf4Gav1NNAfXUexfRVFwDcuT19Ec20pjTDNlQUaKvLWYgwrZnruBXZqtGP316Nx0pM/OxOBrJsEpmewlCtYlmXlfUcmgtoyhLDXXpdl0SdLp0Rbwy9nT/Pv3t7jTc4bhMx9w58PdfNNYw8bAWLb6J7DFJ5H24BQOSdX0t7dx+9P30Ab7E2X59shbsVa+pFj7kGrjS4qlJ2lWnojeXDwKQLWTH4WzglDZeZNl6Ub6BGcyJ7mitPUiz9GPPEc/8qcFkufoR66DL7qpAVQujaJscTiyiYtJeX0+WRYuZL7pwjIXMXtiCmhxjaXFJZLlbiE0LfSjdb4nu9wCeNc7iKOBwZwJD6c7JpLe2HD64yMZSIxhUJRAvziJgRQJA8lpDCSnMZSaPorA6zI512XyUQTelqu4rcgZxd+dQi138jWjABySpTOYJuFSago9iSOj3d7oBPqDRfQEJNApiKVbGE93UCI9wUn0hYrpj0jhcmw6V+JkXI3N4Gp4JjejVVyLy6M/RkVHtJKLMSrOxebSk1RIV7yOfpGBn5TN3M6p56q5kTvGJh7om7gvL+NGio6etFx65Tp61Pn0qDRcUmi4lpPPLV0eN3UaOnKKOBCVRsVcfxJeX/zbPj8/kif6IZnkjcLWjxwHIVkOAlIsPRFZuCGx9CDD1guFvS+66YGYFkSgm+JLjq072slerPdLpGaON/Xz/aia7UPtPAEr3KKpfTsYg5MnuVZL0E32Yo1Qhm6qP5I3nUm2cEM8wZW4NxZT5i5mR2oJ/Su2cspYyYdyOUPVJXSXqkYB2Fma/U8B8Js6I2fqS0cBeKa+9M8R+BcA/H0s/PtF0H8FwJPlJf8UAL/fXszjQ2U8/byapyeb/j8E4EHu9h/ip75D3O8d6YN/WAF82HmQxx0jvf3V2ArgWMYyllfPKwPQ7LAU82Q3Kmf5UftWCE3OUaz1SWSzfyJ7QlM4IVVyUanhij6f6+W6FwD4ZHPVSwF4v93Evd0m7u8182RfOU92lPCkTc+DFXncb8zlXmUudwpzuaFS0JeWxschMtpdEzmWUsK1is1cLd9Em08yqxZGsHZBBG1L4tjtksTJqHy6s2q4ZFrOJ5nFvJdcxJYwDQ1uMkrmJlE4NwX9AhlZ0+PJmZtMxvQY4iz8kNqHkTE1mkSrIJLtwkiZHI1kagKVgUYS7WNJcEigKrwa6ZwM4u1SSJiTwVrtLj7aeIYtpXuoSa5H76GhwttAc3AdpYG16IQV1MetYFncSlaKV1MXVUWpUI85qJDyED16Xw1NcXU0xjSSOl2KOaCCXGcVlYEGDuc0cca4gttFZVzPVHI3M5suURLnMzN4fPQj/sftAe73nWb4xPv0tLWyW55Ge2QCe6NEtAXE8b4kj68MlQx/8QVdu7YT7OBE5KSFJFh4kmIjQGrvT7qDEJm9YBSA4tcXIRm/mNzJPuimC1HaepEx0QXJG4vIsnQbxZ5miv8LLV8SQdnicDItnUl94y2yLFzIGu9K81IROyI0VL8VTOPiUFpcg2lY4EPrAi92ugVxwCeEL4JCORMRRWdsNF0xYfTGR9KfEEu/KJFesYh+cQqXxBIuif9jJfB3CF5JyxhF4G25iu+Uuf+Bv38A4PdaNbdUSm5my7maIWMgJYX+JBGXEsTcSsriRkIGV2OlXIlJ4/Jv+/euxKRxPV7GnWQFP6Sq+D5Vw82kQm6nlvFddj3XlHUMaZoZKmhlqGg1V02bGSrZwDVzG09X/I37K/Zzf9tunmzaydPlW7ibX8t1uYG+7Hz68vT0F+gZ0um5qi7itlrPdY2aW3o9H8ZJaXEOJH+KOzH/ugixlQCRpYDkiX6kWfqgtPUhx86fdBtvRBZuJE1wJc3Kkyx7H1SOAgpnhVD6VjjayT7k2nmQ7+TDBkES1bO9qJnjTdVsH+rm+9PsHE7jknBKZ/iS7+BOgZMPq/3TKZwRiHSCyygAE8Y7Y3YTsU2sZ3BVO2fKavlEqWSwqpguo5KBag295Tl0lmbTVZFHV7WGjirtKwPwpa01vfTVj9/x98cxsP4vAXistJgvS/QcMej5pCCfT3QFowA8WZzH1TWF/LCjhOHDFTz/opbnXy/j6cWNPOncyuPObX8KwEcXtr6k23jUsYdHHfte6EsB2HuAe70jX+/3jPRh9wEedLzDg453eNTxDo8vjvTWyW1jABzLWMbyynllAJbaLaHYdgk1c4U0LY6kxTWWDQIxbYFi9oVLRgF4uUjHtTItN6p1fN9czJ0WAz+tNfFoY8VLAfjTdhM/7Cnj7r4KHr5TxcMdZTxsK+XRWjMPl5dxv97MHb2JK0o9HeJcvpToOZZdwfWqrXyjrGGrp4jWeSGsmhfKurcjWfd2JG2uiZzPruVKyVq+zjayPzqb/dF57IsrZo0gl8rFUgrmp5LuEElVYBE1ocVkLxCTM1dEqk0w4f/qTtxEIUnWwYS/6UfWnFQaIipJnSoi2jqa2qg6DH5GYqxFxM6U0l76HqfeGWSDYQdl8ZVIp4vIdEpGv1hHXUwrNUmraU3dQENUC8W+Rgq9tJQK9RiFOlJmxJI6MwGDbwEbZRtZk7qeZTHL2Ji2iu2ZrXyU28h5QxM/Fhm5lZnFA3kGA6lJHI+L5sKaRn46d5QnHac4aSylLS6atYECtoUFsD8xki9zFdzdupXn7/2N43WrKPCKIGm6L2J7HyR2QqQOgaQ7CJHa+5Nm40OalSfJE5xJeXMJkvGLkdu4obT3ROskRGHjSfoEZ6Tjl5A5yRWFjSeaKf7kOfqhdRKOgrDkrSDMi8JQ2rkjnbCQLAsXVJZeNC5JZHOgguKpXqxwi2aNTxQtS4TUzHBj/UJ/2pcG8DfvQI4EhvB1WDjnIsO5GBNFZ1wcHYlJXEwU0Z0opjcxmd7EZPpFqfSLUrkklox+/QMCFTnc0uWN9judehSAP2o1fJ+bwy1FNpfT0hhMTuGSSEx/vIjBhGSuiSQjTUxlMCqRqzEibsalcFck4544gx9SMriRmclNdQ4Pasp4tKyOp9vW8mzPFh7s3MCDd9r5Yddm7u5p49cP3+Xp+wcZ/vhjnh54jwfr2xnUmOlWFNKVV0SnzkBXkZ4hg5FrBSVcVxcyqCumJ7+UynmeZFjMI93SmQQLb+It/Uiy8ifVWojM2g+VtScKG09SJrgS/4Yz8W84I7X2ItvRjzynABR2XqjsPVBYuS5/UBIAACAASURBVJBn70nJ7EC2h6VTM8ebsmmu1M33Z9niEKrnCzE4uZMz6W109m7k2bmx3DuF8oUxZFl5kmzhRspEd0QTXSlxjmdtVC7X1u+mu345x3Q6BioNdBmVDNZo6a/Mo9uspLtSTU+tjq6a/D8F4LcNJs41mrnQXM6F5nLONZo522DiTH3pi617+VNw//gc3MlyAyfLDZwoK/pTAB43G35b/Svis6JCPs7X8bE2fxSAX5WoubHewE97zPz8YQ3/dqKJX79t5eeuLTztHsHfnwHw8cW2l7Sdx517edz5zgt9GQAfdO8d7cOukT7u3Muji7t5fGH36P7B4fO7uXN88xgAxzKWsbxyXhmARtvF6K0XUTsvgJalMSx3i/sDAI+nKTifncdggYarZg3Xq7TcaTLw3TI999aU/ikA77ebuL+zgke7KxjeU8WT7RU83FrOD61mfmiu4Lv6Cq4UV9GlKuVUso7jOVWcMSznVF4dO4RSqqZ4sXJuCOsXRLB+YRTrF0axU5BGh24Z/cWr+DBeyf6ILA7GqNkdWUirt4Kyt1PRvy1F4hDBZtkK1kmaUSyRkD07gUQLAUH/mzPxkwJIsg4mZlIgRe551IdXkDlHSoJDAuUhFVSG1YzuAdxZ9j5f7xtgXVE7Ncn1JNlHEz8hjCwnKeWhjZTFtLBZsZO1qZuoCa9D75OPKcBAsUCDeFo0mW+lkjlfSmNMIxtlW2iMWcYu9Q725G7hYHYdJwsauF1Uxk15DjeSJXQmJXJSLKK7fT0/nj/Bd199wf7ENNYLA9kREcb+xGA+VyZxY00dvx7ey7MP/kZzTDpR1gvJnB9DimMAafYBSB0CR/BnJxgdAadYLCV1vDOS8YvJsFxKppULuqkB5Nj7kDnJFen4JaRPcEZmsfSlK4D6uULMi8LIdfQi3WIRWRYu5Fr7UDkvktXeUgod3VjjncB6QSwtzoFUTFvKqrcEbF4s5KBnAJ/4B3MsKIwzEVGci4rhYmw85+MTOZsgoitBRHe8iJ6EEQj2JaWM4u+SWMJliYyr0kyuy+TcyFJwQ5PDTW0uN7Uj9/X9DsAfNGru5Ki4pcjmilTK5VQJg8kp9IlEXBKJuZKSyo1kCbdSpQxExXE1KoHrMUl8H5/CD3EpfBcv4l5OJvcKFQxX6XlYV8KDlVU8WFfLvTW13F3fyK3WKr5rrWV480rublzFw3cO8qR9Lz8t38igysiAQk+PWk+HVs/FwkIGS0q5qjdyWV1AT34pX6ar0U52JnX8fFImupBgJSB6oh8iayFp1gFk2vqhsvRAaeXxBwCmWXkid/AlZ7I/chsPMi2dybRYTK6dB8Y5QeyNyaZuni/mqS40LQxipWsklXMFGJzcybVcSPE0X/KneLPaP51mLwnZNt6jAEy2dMewOJbW0GyurttFb2MrXxUVMVRdQo8ph6FaHf2VefSUqeip0vynADzTaOZ8UxkXl1VwcVkF55vKRhH4QuvLRlf7/rG/r/r9fijkRJme4+bCvwTgyOpfIZ8VFfKRTstHGh2Hs5SjALy1sYT7e8v45aNa/vvXLfyfZ1fxS/dWnvW0/yUAn3Rse0m386RrH0+69r/QlwKwc9doH/3WJxd38ej8Dp6c38HwuR08OzvS749uHAPgWMYyllfOKwOw2HohBZMWUDc/kBWucbR6JLDON4ktwiR2hyTzRXIm32Yo6dPkcMWk5lqlhjtNBm43F3F3tZGHG8pfCsAnbSb+vrWCf9tWxf+1vYbnbdU82VzFdysr+W5FA7dWLufmiq0M1m3ivHEl35S28pm6GvMsX8qmerFyUQT1jl4sn+bPxsUx7PZL46i0lD7zOr7JrWVfcCr7QzPYGySnZUky5tlxFEyNptpbjXxmIl/Uf8B+ww4ylqQQ+q9uRP6LO/ETBUS96Uvw/+6GZnEmKxMbqQ42oXHOIWNuBvmeBbQktZIxR0WGi5YDdZ9zYncfG4t3si5vI6oFGUgdElHNzKLItxyFhwHZWyoao5ezK28PreJlNMRUUxVeQo6zjELvPHTueZT4laB1LaBVvI4DpZ+wr+QwB/M38bV5M9eNTVzKLuC6XMM3ojT6iiv4taOT3pPHaa+qYXdgIp8mZ/CRWMRgvY5H7VXc3FjBF8VZ7EhPJuhfnIix8iDSQkjsBG8SJ3qRYiMgzU4wOgKWWnuROtEFyYSlSMYvJm3CIqQWi1HaeqGy80Zp64Xcyp3MSa7ILJa+9BBIwSw/zIvC0Dj5kjFpCVkWLqht/VBbe1A5L4Jcy4VsEIhZL4il4W0/yqe7sXJhAJuWBnPAJ4RPAsI4FhLF1+GRfBMZzZmYOM7EiTkdJ6IjTkRnbCJdcUl/gOA/joNHmybjWp6S62oVNzQ53NLkjuBPp+FHrYYf1Xl8n5vD7exsbmfJuZmVxaBMQn+KiO6EOPoT4rksEvGdKIUfRancE0m4n5jKT3HJ/BCdyp0EBT+mFvJQWcb9nEoe5NfzpKhlpPkruCuv5W5GDU+VzfygqOWKqYFbJQ1czyljMEnNtfQCLmuN9OlK6NYbuFxZyVVzOf35hZzKMbDKKwLJhHlIrFyIm+BKtKWQyIkCRNaBSG0CybITkGvphtLSFclEdxLeXErc60tImeiGzMYThb0vhbNCUNl7IBu/EJWNG4aZQt4Ta2heGEDZNFdaXSLY4JNAxRw/zLN80dktpXxuELrJXizzFNPsJUFl70eyhRupkzxItfakaGE0zQEyrqzdSX/zKr4pLuZKbSmXKjRcrsvnUpWa3vIcequ19Nbl011b8J8CsKOlko6WylEAvrQN5aMHPv6xv+NvZOVPz3FzEcdMBX8KwGMmPV8UF/G5voBPCwv4UKvhQ7WWw1lKPlRm8rVRw+1NRh6+U8G/fdrA//hmBf9+YS2/9m7jee92hru3/ykAX94dDHe/fLXvZX3YsZ2HHe08+q2PL7YzfKGdJ+faeHKujadn23h2ZqTfH107BsCxjGUsr5zXxo0bh8raD421P1orAUV2QgwOgeRbeqG38cJg602xtRd6SzcKLN3RWLqjtXKnZk4wKxaGs8Y5gh2+cez0imCXTxhfxqdwPkPFoC6fq6YirlcauNNo4nZTMXdXm3iwvoxHm8tHxrvbTDxsL+HxzhKe7CjheXspw+1Gnmwv4/HOWu611/L9xkZurarndmsTv2zdxrO1W7lZ0chRUTaHgpNpmOJGlY0L1TYe1E4WsnaRiDWuYv4mNtJRupZPc8rZFZXNO35SPgrV8Vmcidr5yeTahSG3DSdtcgw6Zzkfle2jOa6M9NkxiCdHkGATSoJNKDETgwl7XYBmkZKmiBqaI+rJmplBU3gjidYJLItpQR9oplm6lhPrznFuWy+VMQ1szd2J1rOIsEmRJDklY/ApweBTgmh2HKK5segDdewu2ENLUivlQVVsTG+jPLAGo9CMPsBIXUIDNQk1/K3qEJ/VHOZzcxv7CpsYbFhPj7yEvjApp3Vahg5uZfjqt9zbtYMdvmEci1PQoVLTUaDghy1mnrzXQvfG5axOSSd5qiuJjkHE24WQ6hRGqo0vUmsvMux8ybT3Q+7oj2JKAIopAYgnuJD0pjPiCS5ILD1IneSOzF5AhoM/mY5C0m28kUxyJXW8M3IbDwpmCCmc5o98kjN59u4Y5gRS+lY4hTOCybb2QvqmKypbf8oXJtDoIcG0IIyyRSE0+URTvkBAvu1SmmYLWTM/gH2uwXwiCOPr8FhOh4ZzLjyCi1HRXIyK5XxkLKcjo/k2KoazMXFcTEiiM0lMT3Iq3eIUepJTGZDKGEzPYEiWyYBMxhWlnCs5WVzNlXM1V851tYLragU3NMrRXlZlMpCdzlCmlO9kMm5JpVxNTmYoKYmBhAQui0RcFom4IhZzRSzmanIy18Vp3EhM506SgkeyfB7L9TySF/NIbuRnXQ2Pcqq4JzdzJ6OUm2kGbqUW8zirjruyCm6mFzOo0jGgy+dKmZ7LZXouGQvoL9QxVFBIn1rD5oAMSubFIh7vTqqVHylWQhIthYisA0mxEZLhEESGrT/pFq6o7P1QOQqI+5e3SLN0QzbJBanFYuRWrmgcvVFZL0E5cQH5Dq6Uzw3gkDif6rcCKZrsSt3CEJa5RP32DJwvZbP9KJ8jQD/FjbqFIWwNlZFnv5iMSe6kvu5G0mue5M0IY1OChu7lzfSvruZCXT6DTSUM1pdys9HM5WoDfeX5XKzK50JdId/WF/Dt8uLRnm0p5lxLMReWGTnXWPpS7P3ZCPhEVQknqko4WW3kZLWRr2pKRz+fqCrheGUxxyoMHC0v5mS1iZPVZZyoMnO80sSxilKOlhs5Xmni05JCPjbk87Ehn8O6XN7NVXE4K5e/qRR8Uazh2s5a7n64jAdftvD8/Bqed27ked8Onvbs4mH3zhEAdrX9B/A6dzDcuZPHF0Y63LGX4Y53eNZ1gKddB3nS+R5POt9juOswz7rf41n3uzzvepd/632Pf+s5yN+79vPLhd08P7edR2fX8ejs2n+qN48uGwPgWMYyllfOa+PGjUM+yZscSz/UVn4UOQRQ7BiEzsr7DwA0WLlTaOUxCsDq2UG0LopgnUsU231iXwrAK6WF/xMALB0F4E/barmzrpYby6u42lDJ3Zbl3Klppkdj4OMoCe/4xdPo5E6tvTv1Dj7UTw9m+fxY9oTncVzZSJd5PYfSi2gLlrLXT8pn0Xo+SyyjYnYiStsQsuzCkThGU+yZx0emvdSFF5M8JZR46yBiLYNIsAklakIgkeMDMPsaaAyvptLfjNRJwvLoFqROaTRENFIRXc/63O2c2tTBp8tOYI6ooVHcSk1sE9J5WSTPlFIsKKU8qJLUuSLSFojJ9ZCzKnUlGzI2s0aygY0Z26iJaGK1ZA0r01axPmsdxcEF7C7ayicVe7m44iCHza1016yiV1lKd4iMU9oCendtYuirj+hd3srGpf4cT8qgr0DLT6uquL+zih/2NPChUU91aAIpU72RzogjeXIs6U5xSGz9kNn6jOIve7IQpVMgOdOCkVh6kDJx5DSpzNZnpL8BMMPBnww7X2Q2nmRYeZBl7Y7GyZeCqQKU1q6jADQtiKBoZghKWx9kE9zJsRNinBdNrYuYknnBlC4IpN4zAvN8XwocXGmY7c+q+QHsWRrIB76hHA+K5lRQGKcCQzgVGMK3YRGciYgeBeCZ6NhRAHaLU+gSJf8lAH9H4LW87D8A8LpawWVVJoMKGUOZUm5nyLiZLuVKSjJDYhEDSSOvj/zeIbGIIbGIK4lirsemcCcunZ9SlTxIV/NTupaf0rU8VRl5pCjhgdzAvaxi7slLuS8v447ExM20Em7IDFzJK2SooJAhUyGDpkIuGQu4VFxIn66AM1nZrPIUkz89DNGbbqMAFNsEkWgpRGIXiGJqONmOQaRbuKKw9SF3ihDRm4uR2XiSZe1OhuVSlLYeLwCwYl4g28OzKJ3hTb69Mw2Lw1jpGU/dwhAq5vpTNtsP00wfiia7Ur8olLawDPKdRv4OmYU3qRP80M2JYqson66WJvpWVXGhLp+BxmIG6ozcaDBxudpAb5luFIBnGgr/ywD4O/Z+x99fAfBEVSknqswcqygdxd+XZSUcrzTxSXHBfwrAex+18PDocp6fX8PPXZt43reDZ727edSz6y8B+OTiLoY79vK0c/8/APBdhrsOM9x1mKddh3jadZDnXe/y9+4D/L1rH7907uX5ue08O9vOw2/X8/DM2hc6AsM/9ubRljEAjmUsY3nlvDZu3DikEz3InOiFfKInOVbe5Nn4orHxpsDemyJ7H/S23hTauFNg5UG+jdcoAFctiWKzZzzt3jFs9whjh1cIR2LFnE1XMKDVMVis40pZIbfrjdxqNHB3tWnkBZCXArCUZ+0mHrebebK9guGdtdzfVs3DrQ38uKqa63XFXC8pZEin5qJMxmHfaHa7hLN8ujeN03xpmBFA3Zww6hfE0FvexqWq7RzPrWNrUBpb/JLZKZRyJLWc9+JLUDuGILMJJMMhgszpiawWNfKBcTfF3iqiJnoTZSEg0TYMsUMkYa8LSLAOZ524lda4JvSu+cRNiqHY3UDOfBXmgAryA0p5f9kxOvdfZU1uO1WJy5AuUbFDf4CNqnaKg8upjmlkTfpGSoUGNM5KJLOTUblqqYpuZJ28nRbJWhpEK9hTuJstOZtoU66lVVzG8kQ9m6UmLm/9mCPNm/m6dAWXClZwNlDJF4piLmxpZ+DIJww0reertBzurSzn/gYTt1YX8u9fbKFrTSXZ8zxIdvAl3iYUyRQJiTaJSB3jSLcPJMtBgGJKAEqnQFRTg8idHkLejFDSbbxJs/JEZuszuioosxcgtfVFautL9mQhudMC0c0IIcfRF6WdO/oZARhmBlI4zY/iuUGUvhWOYXYYmikBKG38UNn6o3UKpHxhHIY5gejn+FHnEU75wgBKpvtRPUtI02whWxf6s8dFyCE3IZ/7BvGFbwBf+AZwLCCUEyFRfB0WwanwSE5HRnMuNp4L8Yl0JonpTBLTJUqmXyJlQCpjQCrjklTGkFzOkCKby0oFV1RKruaouJqj4lpuDtfzcrmel8sVlZIhRTZDcjnXM7K4Jsvkclo6g6lpDKRIGJJIRz/3JonpSRTRGxPHtbg4bsfGcic+nu8TRdwRpXAnScL9TAV3JFncFKdzNVHKUFwq/XFSeiQ6BuVFXFMbuWko4XqJgYEiLZcKdAwaCunVFfKlKJ3dvsGUzw0h28aXxNddRl74sPD97dk3ASJLP2T2gchsBMgmupHjICB3ipBMO2+y7H3ItvUk29YdlZ0nGkdvcmycyZ4wn3wHV2oXhrHBP2UUevWLQlnuFoPByZ36RaFUzPVHP8UNnd0Smpwj2B4pRzfFZRSAyW/6oHQKYk2Uko7mhtEVwJ6aAvqqDVyrMzJYWUSPWcvFqnwu1hdxtrHolQH4ZyPgU3Vmvq418XWt6Q/4exkAj5YX82VZCV+YizliMnDEZODzUj1Hy418bMjnwyItHxZpOaRRcUCl4FCGisPKbL4o1nBjdz0/fbycx8db+eXiOn7p3szP/Tt53reHx727edqzg2c97Tzr3sGz7l2/dTfDHSN92rmPZ10HeN59kOc97/L0tw53H2S4cz/DXft42rmP4QvbeXqhneHz2xg+s5kn327i/jfrX9qXXTB9+9jqMQCOZSxjeeW8Nm7cONKtvMiY5IVsgjtZFm7IJ7qTa+2F1tYTnZ0XOltPdNZuaK3cybfxIt/Gk7p5oax1iWWrdyLbvKJpdw8dBeAZaTaXNFou6TUMmfK5VVfCzQb9fwrAp+1lfwDgw22VPNpczd3WMr6rKeSWQcM1jYI+WRqf+MVwwDWK1mneNEzzpW6GkPLZwbR6pHKlcS+dpZt4V1TAVmEqO4Nl7AqU8UGKiW2hecjtA0izDUQ6OYLct9PZlrWWw0XbKXKTE2PhTZxVIMmOUaRMjib0NT+SHWJYk7ScSmEpuW8piJ4QSfpUKbrFWuqjmlD56fmqrYueQzdZmdNGpaiFiOliNuTtYHfJIZokq2lKXsl6RRv1EdWo3somdWoyGQtVJM7OQCMoY1P+Xjbk7aBdt42G+AqWxZvZp1nFsmgddYFyzjbu5YPqjRwpWsEl/XouRBj4TFFK57ad3Dz5JTda1nK5wMiP6438uMXE84PN3NjRyBZZIrIZAlKnRJAyWYTEMQ2xnYjsmYnI7IUvBaBqatDoCqDU2gu5oz9yR3/S7fxGAaiYEkDe9CDyZ4ainRZArqMXhpmBmOaFUTwrAP3sAIrnhqCfFYrWKZAcO3+yrXxRTxZS9nYsxXODMMwV0OgdRc3SUIpnCimfHkDdDCGbFgTQvljA3sW+vO8p5HNBMMeDIzkRHMOXQdGcCIngq9BwToVHciY6lnOx8VxMSKIjUUSXKJm+1DQupaVzKS2d/rR0huRKhrJVDGWruKzI4Yoyl6uqPK6q8riWo+Z6roarqjwuK3K4nK3iWoaCq7JsLkuzGErLZFCSMfp1IFVGr0hCd2IK3XFJXIqMZCginMHIcC5FRnIpOoaB6HiuJIrpjxXRE5VAZ0QCFyLiORMloi+vmCsFRm4Wm7lZYuSavoChQi0D+VoGi4o4lZnDHmEUK9/2wDQrkGwbX8Tj3RFZeBH3hicx40fe/o0b74nIwgvxeHdkE93QOAWidPAj29GPDFsvsqzdybZ1J9vaDY2jN7m2S5GPn0e+gysNSyJZ7Z1IxVx/Kub6U78olFaPOIqnetC4JJzyOQKKJruSb+9Mk3ME28IzKZg6gswsSz9SJ/ihmBLIynA5XS1NDK6r42J9Ad3V+fTXFHO1toSBisJRAHY06DnXpP8vA+DphnK+qS/jVJ35/xEAP9LrXgDguzIl7ynkHDGoubG7nvufrODJiZX8cnEdf+/Zwi+XdvFz/16e9O35SwA+7dzDs653eN59kJ973uV5z7s8632Xpz37R/YCdu3jSefOkRXDc22jmBs+u5EnZzbw4PQGHpze9EJ/3wP4j719bGwP4FjGMpZXz2vjxo0j1cqTdCtvMqy8UNr5kuMgIGOiC9mWS1FYuaCYtBTlxMUoJyxBa+WBwdGP1qXxbPEWs81XRJtnFNvcQmj3COKz6CS+TZPTl6emtyCXSyUabtQYuFFf9JcAfLyjlCfbK3jUXs7j7RUM76zhUVsFP600cH9ZIfdqddwpzOSGQky/OIqvAhL4wDWGlsnuVE72oHy6H+a3w9kQnsOFyq18klnFJv809gVlcDBCwZ4YFetDsylZEIHEXkDalFBSp0Rg9NPRLl/HRkkTeQtSiJ/oS5xVIEl24cRaBhFtEYRqfjoNYVXIpqeQaB1Lsr2IyDcjUM5VoHEtoDS+ge73b/PxutOsLdhNtWQl8QsyKI1vYGfpe+wwHqJZupbViq2sjm2l1NmAeoGGXLcSkuYqkXkbaK94n82GvezWt7MiuZIVCSVsTDTTLDRQMDudI0UH2KJcw6bEKrr0O/g6zMTFqhVcPXyAUzsbOJUv5UF9CTc3V/HwwEp++bgd7dIFhI63J3KSP1GTIoi2iCXKQkicpRdJ1otIs/V86Qg4y0GAeILL6P6/LAcBckd/JNbeSG19kdkLRr7n4IvC3peCmcFop/qRY+tO0XQhRdMFaKf6oJ3qh25qwCgApW+6kTnJneI54ehnB5A/w4sGr0hqXCNG/pyDH2VO/qxbEMTmhQLa3vJmn7MPhz2EfOwXymfCKD4WRHEsKIwTwaGcDAnjdGT0CwjsTZHQL5HSL5HSm5rOQIaSgaxcBuV5DGWruazQjPaqSsf13AKu5eRzVaXjqkLL5YxcLmfkMpiuGu2lNMUf2i/Jpl+STV9KOj3iNM7HizgXJ+ZsooRzSWl8myDhjDiDC5JsujLUXM4zMpRfSl95GQMVJgbLSrlcpGNAl8vNogKu5BcyqC1ii3sAhknTMNrPQ2PvhWyiB2mWPkisBSROGMFf7ARfxFYCMh2DybIPIMvKE/WUAJQOfuhmh438u9h5kePojdLWA7WDF2p7V7LenIvO3oUWtziWuURROU9IzYIg6haGsFGYSsPiMOoXhWKe5UvxVA9KpnnSuCScDQGpGOf4UjgzjDzHEDJtglE6BbEyXE7/qhXcbFtO33IjvbWFDP02/r1UXkBXqZqO6gI6Gw1cWFb8ygD8/VqYP7SpkjNNlXzbWMHphvL/FIB/NgL+wlzMh0Va3i9Q836BmoN5Ct5RyDmYruBQdhZHDGpu7mng4WcrefrVan7t3MCvvVv5+8Bufrm0j+H+vTzv28XPfTv4uXcXP/fu+a17edY10ufd+/m5511+6T3EL33v8fOlAzzr28vT3j086drBo46RK2KeXNjM8IWNDF/YyLPzG3h+YePIauC5HS/06fmdL/TO8U1jABzLWMbyynlt3LhxiCa5IbX2JsPGB/XUQPKnh5A+wZmsiUuQT3JGbrGELIuFyN9chMbSneLJAla7JdHmm8I2XxFbPSJfCsCe/Bz6i9WjALy3xjzyBvCfAPDxPwDw6Y4RAD5eZ2J4lZHhZXp+KpZzSyFiQBzBV8JY3neJpsnehXIHNypmCKhyjmFduIrTpet5P83MJv80DgZnsT9Mzr64XJb7p5E33R+JvQCpUxgpk8Mx+RewOX0lrfGVKOYkEj/RlygLAbGWQUSMFxBvFYZuiYK6kAqy56QjtksgY3o6UeMjEdkmEWkViymhkfPvXWdX/Ses0++lJWcrysASDNE1bCs5yN7yD2hKW8NK+WY2idezIqgJs3cFhsBaDBFNlEvWUyPfQKV0BXtKdtCmWs62jFrq/HJo9DFQNEvJCePHrJGtZVmIkQsFe/jUR8vQ8k38cOQwn2/U87U2if++oY7/cWQPHH+Xz4xK4q1tSZ6yiCTHSMSOYlIcU5BOiyZrdghSpyVIbF1eeghE7uhPsoUryRYjFwpnTxaSPVlIqpUXUlvfkYMg9iMrTRlWHminBaBx8iXTYjFqBy90U7xRT/FCPcUHrZMQzZQAcuz8kbzuQtqbzhTOCKZghgDNVHdq3cOoWhpG4TQhOjtvSqf4sfbtYDYuFLD5LS/2LPJhv7Mv77r684FvKB8IIjkaGMrxoBBOhoTxTUQU30bFjI6CfwdgX2raSwE4KM8bxd9QtpqrKh3XcvJfCsAhWQ5Dspw/AHBAqvwDDK/nFnBVpaMvU0WXTEl3Zh49WVp6lQX0qorpzzUyoCnjqqGWK6V1dFWY6Ckz0GfS01+gpl+j4pa+kKsFRQxqi2id747iv1ljsJ6L0tIFyZsuSK18kdoKEU8SkGIXQuTrnkgdgtHMiUM7K5psG29yHATkTPZH/1Y0yin+5Dj6onbyI8feaxSAmW/MQWfvwnL3eNb6imhyjqB5aSTVbwWyzk9MzYIgat8OxjTTh5JpnpTO8KZhcRhrBWIMM73QTg1CZReIdJKQTHsBy4LSGVizktvtrVxqNdFXV8TlzFW5owAAIABJREFU3w6A9Jfl/78GwLPNVZxpqvynAPhnh0C+MBfzQaHmBQAekGb/JQB/HdzD3wfe+acA+HPPAX7ueZe/973HL/3v8svAQZ737+Np7x4ed27nUUcbjy5s5cmFzTy9uJGnFzfy88VN/NyxgacX2l+KvTEAjmUsY/mvymvjxo1DYulOhpUXGVZeyG19ybbze2mVNn7kW/tQOcefrUGR7AqNZFdwBHsC4tgniGe/MJFjSSmcSZfQoUjkkjaNy4VZ3CzN5UZ5Lndb9DxabeLRBjMPf7sG5l7byB2Aj7aZeLa5lKdt5TzbVsHwtkoeb6ng/jozP60s4V6jnh9K1dzUZTEgT+YzYQTveYTT6uRCvYMLtZM9aZobRXuAkr7SbXwurWGrXxbb/NLZJJDT5CHHuFBK/uwksh3CkdoFk2odgNkjm3fVG1HMiSdjehRiu5FDH7GTQgl7w5cku2D0HlnoPbJImRJK2tQYFHOlpDgkEfF6JLF2idRmt/Dt4V5WFrWxTr+bdZo97Cs/QpCjhKLIJj5YdYYm9TbqtVsoy1xNfkwNupByNsl3sUm+i5bkDejCKlBHlLMhfzMr02rZn7sa0yIJ2iVZ5Pvo2FPxHluK91EeV8WW7LU0BOq4WL2JXw8foW/rMs5vq+LWh6vgzH7OtVRg9hGSYOlJ+JteiOxDSLYPItlBSJptIDLrMLIsI8i0CyTdxhulU+DIHj9bH7SzI1DPDBu5C3Ci28h9co7+KByFKOwFqByF5E4JRPXbr+W2vqinBpMzOWDk/4iDPzmTAyicFUT+dP+RVcBpArRT/ZBbu5Bt44rGyRf97JHfL1sYRZN7MqVzw8i396Zkih8rlkTSujCElrk+tC0R0O7sw143H973FfKRQMAnwnA+C4zmy+A4TkWJOB2TzNmYZDoSkukRpzGQKqVfnEJvkphLYslvI+BcLivyuKzI46pKw1WVhitK9ej3hrJzR35GnssNpYZr2XkMZeWMNDuX3oxs+rOU9ClyGMzVMJir4VKehksa7ciBp8IirhbpuVJYxOWCQm4Ul3BNbxjtzRIjt0vM/FBSx+3iCq7oSuhS5dGbX0B3YRFdRcV8k5NP1r/akzdxFnXz/ZHZCxHZBhE9wYvo8R7ETBh5tk9i6zeyGmvtTbqNN3IHX7Idfci0d0M7O2Dks+XItg7pm24oLN1R23mR9n9MR2U5nybXMNoCUiib5s7yJaE0vCWkTZhMy+IQKmd6UTXLG5OTKyWOzjS9Hchq91gq5viR8cZSMsd7obIJRWbtQ4N/Kueb67myqYn+VWY6anT0NhjprSnhTKmGb4x5dC0v49yyUr5tLuGbFaWcXl7K2ZaRXmgu5UKzmdP1Zk43lHO2uYqzzVWjI95vGytebFM5p5aV8nWzka+aSjjZYOJEfSnHakwcqzFxtNrMl1VlfFFp5kiFiS+rjHxZZeRIhZEjFSY+Ly/lM7OJj0pK+FuRgfcKijigLmCvSsOebC17JTp2Z2TxQWEWNw9W8ejYcp6eXsev3e/w9773+HnwPX4efJfhy7t53jcCvn+2w507edKxg8cXt/PoQjsPz2/70/5+z+Cf9VFHG4862nh4cSs3ToztARzLWMby6nkBgFk2PshtfZFOdH+hsgnuqCd6UD7Lj/bQGN6JiuNAVDx7A+N5xz+BAwFJHBelclaWRqcy6b8EgD+tNXGvtZi7DUV8b8zjhjaTS1lijobE8oFPNKumuVHv4EKNowf1s8JZ7ynlfP46vsyoZ1+4lj3BCrYF5bDKX02dVy6li9LRzIinYEEKpS6Z5M1NZHmkkWT7IDKmRyGyDSByfAAxE0MIe8N3ZEzsoyTfJZ3kySEkO0aQNSsVqVMKEsc0st5Sok8w8/X+DtYUbWOzYS/lCcupFa2jMXULecJKSuOXs3/ZUdYY91ItWUmdqJWVkvXsSN/J8vAVGNxLKRSa0IeUsy1nI7uyV/KBai1lMxORTQxEOV1Eu6aNtbkbWJZWx2FTO+3ycm5u2Q6nvuTX0zu4d3IlD79ax9/yMyjz8iJj2mISLH1JsAkmyT4Qsb3/yMsfNv6kWwWTOSkc8Xh3ki1cyZkWjGpqEOk23mRPFo5eA5P4xhKSLVzJsPMly84PmaUnWTY+ZNv5kWXjg8zSE+lEd+S2vijsBeRMDiB3SiC5UwLJm+KLeooPhTMDKJoVSP50f2QTF5P82jwyLZ3RTvVDPcUH3TQBhjnBmOdHkGPtRq7VUipn+VE/x5/G2T6sXeDDdpdA9rgFst/dn8O+QXwkCOcTYSSfB0RzPDSOE2HxnAyJ5XxsEp2JKVxKSRsF4EByGoNZCgblOaMIvKJU/2Wvq7RcVYx8vqrScC1Px2CuhqE8LUPafK7pDdwoLuF2qYnbJjN3ysq5V13D/do6HtTV86Cunh8rq7hTVs535jK+M5fxfXkFP5ZXc8dYw83icq4UGOnR6OgpGMHfZ5IstgqjSf1f7ci3XULD4ggkNv4k2QQSY+FNzARP4iZ6I7byRTTJk1QrL9JtRsb3KichOVP9SbNaQv7cIBSTfcmY5InCVoDK1h+llQd5tp7IXpuF2nYhLR6RbPEXY3JyZdmiYGrn+rFFIKJ5YRB18wTUzvWjYoYnFTM8Wb4klDUecVTN80f2ujOyNzzQOEaRaetHmVssnSuaudG2nMvrq+hpKGJgWRldlXq+Nao5Xaqms8XM2WYjZ5YZXxmAp3/b7/eHNpa9EgC/qCzhi8oSjlQYR/BXZuRTU+mfAnBXsppdssxRAD482sKTU2teCsBnvbt53rPnn+7Trl0vIPDRhXaedOx4oU87tv1lhy+28eTCVh6f38LNY6vGADiWsYzllTOyB3CSGzJLT2SWnmRae5Nl40OahdsLTR/vRr61D1VzhWwPi+WdqDj2R8axLyiB/cLEPwCwSyX6LwHgvTWl3F1h4Mf6Qu6U5HJDm0l/pojjYfF85BfL6unu1Du4UO3gTt3MMFYuFfOVsoUvM+o5FKvnnbAcdoSqafbMptI1G8NbqehmJWJyzaJBqEM9L4naAB2J1v5kTI8iyUZI5PgAoi2CCXvDl/TpMZgFuWiWSEiwFfJ/s3ef0U3Y6b7v8+Leu84+s2cSio27jTu9G1dZki25915kW7Jky0WusixLstx7pRpc6CW0kJACJCGBEEoIJbRAgIQAaSQkoQ2Tvc9d63tfKHiGmWTuZq8567zxb61ngS2vxUs+fv7P//mn2kegmiEj3zOXbCcZuTPyKQgp4ejWj1mmWUu/ei210a20pa1iuHQ3tbHdVEW18uaqE6zQbaE1e5CezOUM5Q0zkrqW1uBmKudWohMa0ElMrMzuYUfBcg4WDzGwUE6DdxYtSwrZqF5FV2YrDUk6duhXszy9jJ/37oVzH/Dn46P8dHw5Tz5ehzkwCLnzLBSu/qRYh5A9PY4MZwlZziKyXATkOoagsAtHZRNr2SFnJ0DjFUWJRwRKJzFl3tHP7AHMsvJD6SSmwClk/BeEpwBU2ASRZx1AnnUAKnuhBX6uYZRMl6J2DKTYKRCttxTdzHAqPULInbKAjD/OQm61iHI3EWWuFiSWu4loXJyIximAYrul1HuJaZ8rpXd+GH0zBQwvkrJhSRhblkjYLYjiDXE0b4bEcFASz3sRiRYEhidwMi6Z00npXM6UcSk9k0vpmXyWnceV/AKuKIueQeDTeoq+G0VlfF5cPl43Ssr5vLSCm2VVfFGp5bPySq5VVHGtqpovavXcMhj5pqGRr5ua+LalhXudnfzc08P93l7u9/bybUsLXzU2cqehgdtmM181NvJVYzO3DU3c1Ju4rtVzoUrL+Wot53QmdsZn0jZXQMb/7UiVYyAt8+LJsgkhxSaURKtgkqwEJFsHk2EjJHWqP9k2QSgcLMf2Je5SStxDyXf0o2p2OIUuQuRWART8evP6KQCVk2ZR6byEAUECw+J0DNOX0r0gjNZZIoZFaXTNl9IxN5S22WKaZwTTMlPIgE80KwKSaJwlRjnZF8WkQCqmJ6B0EFO7KJrzg73cWj/AjTUtXOrS8VlfA2fN1Zyo03DCWMbZHiMnu/T/LQD+ZnWYnguAbzfU8nZDLQfNegv+THreMtT9LgA3ZZSyWZ7P61oVt3Y3/1MAPrxgufTxPPX3CPz5zAYe/HoZ5Jk6M8bD079fDz4e5f6pEX7+aJgvDw1OAHAiE5nIc+dPL7zwAllWvuP/kStsgsi3FYyD8G8r3yoQvYuU9vkRbIhKZFtMAtui4scBuEuazuEMGacUuZwvzviXAfDbvhq+aaviTm0xX5QpuKRI43B0Cm+Kk1jhGUCHs+94B7BvUSr7ZU0cyGnm1RQ9O6JL2BRVRttSOYaFeVTPykA/P4c2cRnL44xoF+XQKqkgxUZMvmc8qbYh4wCMniRCOSOFRmk5JQsyibMSkGAdinp2HoUz80m1SSPFKZ20hVkc2XiSLuUg9SkdaMMaWSZfz/qyvTSnrqBc2siezndZo99Oe85yejKXsyJ7NStil9EYYEa7QEtNcB1VIj3NkXXsKFjOobIRtkqq2SKuZmuEnu3KPpqjqqgJL2SrdhkdCWrOrxriwf7dPDm5hRtvdfHROiN5DrPItlmA2jOSFKswct2TyXaTkuMmIsc9CMX0EFROkajt4yh0Cbd0kNzCULtKyXcUUT0ngSK3MLKs/MZnANWuUopdw8bxp3YKeQaBOVP9UNgEjXcAi10klhUkjgFUe0nGj3vzpi5ENmneeAewwl1MmauQMlch9QvjKXEOQG3rg95dQPOcUHoWRNLhEUj/rGBWzhEzukDCVt8oXhVG84Y4mgOhceMAPBKRyLHoBE4lpHIxPWscgNdk8nEA/hYCn+Lvi5IKbpZWcrO0ks9LK7iuqeDzimpuVtXwpU7/1+Pdai039HpuGo181dzEV20tfNPRxg+93fzY3zteX7e3cruliS+bGrjZaOZmo5nbjU3cNDRyXW/kM10dl3S1fKKt5VS1keHQBKqc5pLx/7hT5SSmflYC6VZCkqeFkGQtJNk6mJRpQjJshKRM8UNmK0DpZJnZfArAEg8RlbPCUDkJyJ8WhMpWiNJagNomgBK7AAqnzqXGzY/louRnOoBts8XjHcDOeRLaZotpmSmkfU4IAz7RLPNLoN47mGIbAaqpweMA1M6P4MKyPm5vGOTGmhYud9dyrb+Rj40VHNeXctJUzpluAyc6a/mo1/B/DIAHzToO1Ney36T/LwFwi0LJm7pCvtrbxv3DA797BPzfBeDDTzaPd/p+D4APT4/x+OPfrkenRnn40QgPTg7z4OQwt9+dAOBEJjKR58+fXnjhBTKnLv3rMe+0wHEE/n2ppgkwukXQtSiazbEp7IhP5uWYRHZEpLFLms7usAyOZOZwWinnQknmvwSA3y7T802vlq9bK7mtK+JGaR4X5akcikjkdWECKzwD6JruT4dbMD1zEuhblMqm8FJ2xmvZFV/N9sgiNkeX0y8spmpmOpUz0mgNLKZNXEarSIPBT0lXZA2ptiGovBPJcgondrKEuClhRE8SUTI/m/boGgpmp5BoIyJ2iohctzSUXnnkucqRz1SStTCbfX1vYUxoQBdZT3mQntb4QXrTh1mu2EBH5ir6C0bYWL+HZeUb6VUNM6BYyxrZGH2Jy2mJ6aFIpKMoREdxkJodVcMc1K1nX1I9b0lLOZpQw+HyQXqiNKgDsllV2ENHUi1rZHW83bCCe28fYr22jCg7R0rdoyl2jSdrWiRp1rEkTgsj3SWITBdfMqcvJscxALmdGOW0KLKmBpJt7T8+9/d0JUyBSyiZU33HbwGrXaWUuIX/7hHw03o6Q1roKEbtGIjawZ9SFwHlbqLxGcCn9fSzMlchGlchpe6B5NsvQj5tPmVOfhi9xbTNi8Tk5Ef1lLnoJs9l0EvC2rmRbFwQzNZFQexaKuZNYQQHQ2M4JInlcFg0x6ITOJ+awcW0DC5nZPF5npLLciWXFYV8mq8eR+BTCF5Xa/i8uJwvNVXcKqvmVoWW62WWbt8XulruGE18bW7gblsb3zQ3c6vBzOdmE182NfB1Rxt3+3u429/D9wO9fD/Qyzc9nXzd3cHd/h6+7u7gdkcrX7Y182VbM7dbm7lhqueqwcBVg4FPTWbO6QxsT8qj1t2HrH9zQTnVD71XIsbZ2SRPFpJoJSLFRkyaraXSpwWTMS0IhVMIatcwit3DUU8PocA5mOo5EeTaLiFr6mJqZsRR6RGN0lpAkW0gxbb+lNouwjRTyJA0gw3hOTR6BTG4NIau+VI2hMnoXxJFx9xQmmcE0+QtoHOehL7FkXQvjKTCfiHGGXGUOYajcYol316EbmEUnwz08OW6fq4PNXOxs4arvWZO1JZyrLaEU+ZKTnfVcay9hlN9xucG4NNdf89Um+G5AHigvoYD9TXsN+l4y1jLmwYdb+hr/+kM4E51MYfM5dzb38eT46v45fTIbwLw/icbf7t79zv154vbeHxh6zOdwAfnNo0fBf9tPTo5wuN/Uo9ODPPw+FoeHFvD7YP9EwCcyEQm8tz50wsvvEDGFJ/xY96nAPytUloHoXeR0rkwii1xqexOSmN3Quo4APeEZ/JBVu7/FgB+1VIxDsALeSm8G57AvuB4VngG0O0aQKe7kL55SfQvTmNUXMC26Apejqlga3ghm6PLGRCVUOqeSIlbAmYfJXU+CqrnZ1PrI6crsoY0u1BU3onIXCKfAaBmYQ4dMTpUs5JJc5QSN1VMhmMCcncZJXNKqfCrRuGXz862V6iNMWKOa6HEtxptkJnGiF5Gil5mc/Ve+gtGGNW/zMra7fSXbWBZ8XrWl+xgec4o7cnLUAm1qCQ6CkXF7DZsYH/dBnbG1vCmqICPErScrl3DYFw5ufNS6MhoxBRRxRvGdZzs28O50T1056qRTnHFuDAXjUcasf8mJM06nsgXg0l28CPVYSGpjnPJtFuCzFpA3pQw0idZLnkYl2RgWJxOqWckSicx+Y4i0iYtIfUly5uyBS6hFE2Xjv+C8LRDnGvlj2yKpXucM9WPXCt/8m0FFDiIKHIKQu3gT7FTIJrpwZS5Cim096PQ3g+ljQ9KGx/UDv5opgdTOj2YYvdAClx8KXBYQpW7gIbZUroWxVLn4EfJH7wo+zcvBjwlrJwVydoZfqyb7cOW+QG8FijhTWEEb4ujeE8SyYdR8f8UgJ/mq38TgLfKqrldruV2Zc34ce+X+jq+MtXzbWMTP/X28ENXJ1+3t3KzqYFbLU1829XBvWX9/Lh8gHvL+vlhsI9vejr5qqudH5cP8F1f9/jXdzrb+LqjjRumeq7U1XHVYOBKfQNn9UbWShIpsZlN8v/lSKGtEOPsDMzzFSRNCiZhqvAfAJhlG4zSRUKRWzjF7uEUOItQOgZROSuMtElzSHtpPuaF6ehnJ1FoK6LINpAiGz80dosxzxazJiyTjRG5NHkLWOYbS8/CcDaG5zC4NIb2OSE0eQto9Aqic56E3kURdM4Pp3TaXJrmpVDpEkWJQzQKOyG1i6J/cwbwuK6EY7UlfNxQxemuOj5s0/4fB+Bbxpr/EgC351Syu7iUw01V/HRwgF9ODvGfZ8f+twLwty6BPDo5wpMTv1+Pj63l8bG1PPpwDV8dmADgRCYykefPn1544QVSpwSQbRVMtlUwMmshMmshmVOCyLYKJmeaiFwbMTnTRMitg2iZE84KQQpDwiQ2h2eyM1bG9rBEdkhi2BkWyfsZaZxS5HK5WMkNjYIvKvK5Y9LwdWsl3y2v4+4qIz+ua+THdQ38uK6Bn9bVc3/MyIMxI49Ganm4zvIiyIN1Jn4eNfDD6jruDmj5rrOCO/oCPi+TcVGRyLtRMewKCGOFZwi9LqG02ocwMDeOZUuiGZamMBKZxVCYguUhFayU1GCcI6PQKZoSzyRU3omkOYVRtDCTkcJ+DCElZDiHk+cWQ6a9lFT7MNIcwom3EqGamU6TVItqZibxU8NItI4kzz0TmUsGBTMU1ARWogksYXf9DhqjDZiktRTMziXNIRGZexZ5MxQULCqhX76G1SUb2dD4GgNVmxhtfJX6/OU0qFYyqNtKS8FqDOndVIhqWSlfyztN7zCS3MuG0GreSW/lauM29uW3ULkgirrgNAoXh9GdVYIhKov9Haso8ZOQPz8EXVABBXNSyXCJINkuhAwHKbkuUcicIsi2l5JlE0q2rYR8BykyK39kUxZTPSMS7cwoipyFqOwDKXQUIJuyGNmUxShs/Ch1DaHUVTJ+LCybFmBZA+MgRG4fPP79pzsF8+wElNgLKLcPpspJTLVzCFVOYiochBRb+6OxDaLSUUSFg5AKByHVziHUekrRuoVQ7iSgyikYk1c4bXPjafAIp8YuiJKXFlH20mJqpgXQM30Jg+6LWDNzKVuXiNi5NJRX/MS8KZTyjjiCk1FxnElI4kJymuXVjqxcLucVcDW/yHL0W6ThWpGGy4XFXC7RcEVTzvXKam5oa7hRo+OavpYbhjq+bGrgTmszX3e08f1AL3f7e/imv5uveju509PB7e527vR08N1AD98v6+Obvi7udLfzdW/n+Pe+X9bHdwM93Gxv5ouWRi5XVnK5VsM1UwXXW2o4XVuFxnY+qqlLyPx3Hwqdw9DNT0EzK4xYBz9inUWkuUVayimCZGsJOc7R5DlKKXILR+MVQambkCKXAApc/MmxWUy21RL0sxMpd4tE9uJSCqf5/wMAN8TI6fOPpWmumNYFEnamldDjG03rAgkGrwC6fCIxzwqmxzeaxjkiSmxm0huQRalDCPlWwST9YT4VsyVcH17D7Q3LudBXz5UeMxfbzRypLeaosZSTjZWc7arjkx4j53qNnOk3cbrPyMkePcd6ajnaVcORdt2vuGv4hzrW3sSHbY0cbW3ggxYzR5rrOdJs5GhXPUe7zHzQWc+RdjOH2+p5r6WBQ81mDjU18k5DA+80NPC2uf7Xo18tbxlreNOgewaAr1Rp2VNZzZ6KGraqNWxUFLM+O59txXkc6anm+yMreHh2mCefbubJZ3t58tlrPLnyMn/+dAOPLq7mwfk1PPhkmAefjPxazz4L9+j8ll/XwbzM44vbeHRpK/cvbeLnixu5f2HDX2/0nh4dv9Dx80eWl0D+cnIdT06M8ej4KD+dHOHHkyPcOzXKgzNj/PzRMH8+tor/PLaC/3VkGd/srp8A4EQmMpHnzjgAZdZCcm3EyO1CkduFkjVVMA7CpwhUTBPQOjeCZYFJrAyKZ0yczCZpClsl8WwPiWJnWCRHsjI4rZTzaYnqdwF4b6yBe2Nm7o2Z+XHMAr37o4bnAuDb0THsDLQAsPtXAPbNjWWFfzwrRHGsicxkNFZNj6CY5sVKtJ6pFLnEUuKZhMwlkmT7UDQ+OaxR9qALLiTVQYLcPZa86dGkOYST5RJNqn0YeR5J6AKK0CxUEDdFSoptDPleMrKc0sj3zEUbUEFNWA17W/dijjNikOoomJNHlksqWS7p5HjlkeWZQ02oiW7ZSsb0u1hbu4MtHfvRZ/eiy+ymt2IDA1Wb6CsZwxjXSn/WCnZp97C3eCObo4wcL1zBmZoxXs1ppjtETqMgk7L5EbRFySmeL6U5IpuCWUEUzpGgDVCS6xlHsn2oZW3N9Cjy3ePImx6NzCGMDGsxmdNCyHeQorALRmHjR5V3BNUzItG4hVLqGkKRs5BcKx/yrJeisg+k3MPy5Fu2tT+5tkHjpXAQonQSk2XlR8YUy05BuX0wubZBlDgJKXMQUuEkpsJJTJmDkFI7wfifpXaC8c809sGUuwRTNzMCrUcopfYB6N0ltMyNw+QRhtYuiJJJi1H/cT6ayUsw2syh2X4uPa6LGJ4XzKZFIexcGsqrgRLeEoTxYUQsp+IS+CQ5lUvpmeMAvKL4tftXWMLVwhIuqtRcLCrhconG0vWrqrbM+el03NDrudVgHp/zu9vfw3d93Xzb383XfV183dfFV72dfNPXxd3BXu6tGOC7gR6+7u3k2/5u7g728sPyfn5Y3s93Az182dHCFy3NXCyv5FO95YnES6YKPtAUUzhlFvIXF5H5B1+KXKKonp2M2iOUeMdA4lzE4wBMd44k1SaMHOdo5E5hFE6XUuoZTrlnCMXTA1E6+SKbtgiZtQ9VntGUOEvJeckXlZUvBVY+4wAckmawMVZBj280phlBtC6QsDtDQ/uiMDoWh1M/U0CffyzN80LoD4ijZX4oJTYzGQzOpco1giJ7CSl/XPgMAC/2m/msr5Er3c18oNdw1KjhREMlH7fXcqazjtNddZzpr+d0n4mPeg0c76njw65ajnYa/lsA/KDTUofbLHWo2cyhZjPvNj7Fn5mD9Sb2m3TPAPCNuhper9Xxhl5vwd/fAXBjjoqdZUqOD+r54YOVPDw7bFn+/C8A4MOLW3hwcSMPLm60vCN8bj33z67j/unRvz7tdmItD46v5eePRvn55Bg/nhzhhxOr+P74Su59OMiTj1fy5+ODPDnUyf96t4P/92Abd7fVTABwIhOZyHPnTy+88AJpUwPJmSYiz9YCA6VjGNlWweMIfArAfJtgGmaE0r0kmhWBcawVxLM+JJEtoXFsD4liV3gUR2VZnC3I/6cA/GHUzA+j9fwwWs+9USM/jdTx80jdcwHwQHQ02wKlDHiJ6XQJodFBTO+8WFYEJLBamsSGpHy2Z9XQ6qek3C2RYodo1M4xqN3iSZ4mIsFGRIWfnDXKHvSiIlLsQ8lzi0HlmUCeRwIy11hS7KTkeSSh9StEs1BBzKRQkm2iUXhmk26fTLZzOqU+xTQkN7Gv63U6MtvoTGunbImaTOcUFB455M/IJ8M1C/WSMupj21hevI7VFZsZqduFMacfg6yP3ooNrDXtZrV2G/WJHbSn9TFatJFXNJvZrx7iVOUY7xQMsD5Oy8qIYkYSqmgNzmYopQLtwhjk0/0o8BRQOieS/JlJpDpKSbARkeEcTs70KAq8EpG7xiBzCCNtqpAMazE3XyUhAAAgAElEQVQKewlKBxGFjgLKPaRUeoVT4RlGpVc4hY4CcqYuIdfKB5V94K/fjxx/F7jAJdSyf845hFLPSLKt/cfnBXNtg8ixCaTYMRiNo5AyJxFlTiJKHYIpsg2k2k06/vcKlxAqXEIosRdQaO+HcV4MupnhqG19qZouwjwnhnrvCGpcRJRN86PoxYUUvbiQspdmUjVlFgabefR5BTI0R8TmxaHs8JPwaqCEw2GxnIhL4FxiKpfSsjiblsUnWXIu5ii5mKfioqLAUr8DwCsVlXxWVc0NvZ4vDAZu1pu4293J3e5Ovu3t4tvernEMftvfzQ/L+/lx5SB3B3v5pq+L7wZ6fheAFzSVXK2r5oZZx2ltMfvleeS/OAPZHxaQ+Qd/St3iqZiRRL6LiCSXYBJcQ8cBmOESRYZ9JDKnKBTO4aicQyl2l1I1Q0qpm4B8x6Xk2Cwmz9aPEmcJBXYi8ib7U2DtR6H1UiqdfGmeL7UcAccq6PKJpM7TfxyArQsktC8Ko36mgIHAeFoXSOgPiKN5Xghl9nNYLVFRNyOeCtdoMib5UD0vnGtrh8YBeH2gmc96WzluquS4uYqTjVpOter5uK2OjzsMnO4z83FvPR/1mDjeY+RYt4EPu4wcba1/LgB+0GniSIel3m+11LtN9Zaj3wbzr/ir54DJ+OvRbzVvGrQW/Om17NPV8HptLXsqq9ldUcXuci1bCkvZIC9ii1zNq9piTq82c+/oqn8ZAP98cRsPL2zmwfkNPDi/gft/s87l6YWOhyeGuX9sDQ+OreHbY2v45tgw3x4b4rsPB/n+aC8/vtfOw/daefh2E395o4H/eK2BX3Yb+XJl0QQAJzKRiTx3frcDmGsjJnNKEBmTA5FZC8mzDUFlJ6LcdjG1rn4s849hKDCWMVE828MS2RUWx6sx8RzPy+FsQT4XCuW/C8DvR+r5fsTE9yMmfhgx8OOwnp+G9c8FwDeio9gYGEq3p5AWZxFGeyEdc6OpnylgJFHGVlkJIykalC4RJP3Bj5zJInKsQpA7RJBqG0KGSwTG0FLaEvQ0hFeQbBdCur0E9YxkKpbIyXWPJ95KRPE8GbWBxeR7p4/PBmY6JZM8LZ7YSZEkOSVSFqHl5bY9dCv7GC4fxRCqI3t6Gnlu2RTOVFEyt4iWsBaao9rozhhkIH8NzWm9rKnexqhhN6v0LzPW+CrLqzbTmrucnvwhVhSO0p3Zy07dGNvLV3K0Yw/7qobQL86gXaiidn4ia5Kq6AxRoPIQovIUUTgzghyPWFSzU5B7JxBvHUyStZBclyhynCPJcbQsv862lViO9a0DKHQUUOQspNQ1hOoZkZR7SMm39Sdr0kKyJy8i39b/VyBG/m4HUG4fTLa1P7JpAeTZWZYTy+38UdoFoHYKpshZSJGzELVTMFXeEZS5S575d0umiylwCUQ3J5KqGVJUdr6UugjQektpmB+HeU4MhhkRVDgEUWK9lNw/LiDvT4vJn7yIKls/TM6BdHkGMLoolI1LQnkjOJx3Q2M4GhbHiegETiakcDpNxidZci7kKrmUX8il/ELO5xdwvrCIi0UlXNFYFjpfq7CsfflCa1nefKvOwC2DkTsNDXzV2MjXLc1829nO3e5Ovu/t5tve3+4AftXTwTd9XXzT18VXPR1cbzZzzdzAhdJaPqszcM1YxxG1kj2p2ShfnEvW/1hM1h8ElHukU+waT56DiAxPCSme4aS7R5HuHkWWawy50+PJcohA5RpFnl0wBS5iDAtiKfMQonTyRenkT5GrGLlVAHKrQNR2Yortgii29cfoLabXP56x6FzGInPo9Yuhaa6Yprlitier6fGNpmV+KEbvQJYJEmlfFEavXwwNs4W/2wG8OrSKL9cN8kmPkSs9Zi51NHCqwcDJhjpOmPV8WF/LMbOe400GjrWZONZmsrzh227iSJuRI231zw3Aw+0GDrcbeb/N8Ovcn+Gvt37N9RwwmThgMrHfaPgVfpW8rq9iX201+2qrea1Gy2s1Newqr2RnWQU7NVVsUhWzLreQHQUa3m3UcXVTNz8dG+Lh2WF+ubr1XwLAx+c28fjseh6dWTd+m/fxR6M8PP7Xeb5HHwzx8Mhq7h0d4scPV/Pz0ZU8eq+bBwdauL+njnvbqrm7Tsu17nJOm4t5pzSXlWGhEwCcyEQm8tz53RnApwBMn2T5LM82hAJ7MaXWC6hyXMygXzQrfCMZFsSwMzKFVyIT2ReXyAl5LmdUCs7my34XgHeHTdwdNnJ32Mj3w3XcW1vLj2trnwuA+6Ij2RAYSpeXkCYXEQYHIa1zozDNErApQ8mmrCJ6JDJy7EPJsg5BbhWKbKoYhWMkCo84lLOSaY2poSIwH5NEQ6KNiCRrIUUzUyhdICPPI4EMp0iK58koX6xANTOTFNto4qaEke6QSLp9MjEvRRBlHYlcoGZX3+v0qZexWrOW9vhmdAGVKD1y0MwponKBhsaQBpokTbQmdDEoH8Kc2MHqis2sqNxMm2o1I+ZXWFu3kxHdDkZqXmaodCMdsj6GKlczpl/L4eVv8UH/PppDiyhwj6TYK5Ke8CJaxAoqFseT5uxPunMw2W7R5HjEku0WTZqjlHR7CRl2ErIcwshxDCfPMYJch3DLTKetgDJ3CZVe4WhnRlG/KBntzCiUdgHIpiwm18qHAocgqrwj0M6M+d0ZQJVzyHjnT24fjMJBiMzah1wbX1ROAgpdhKini1BPF1HuHU6Zl2VZsdIxiCJXMWVeYZR4iinztqwyKXQKoMRFQIVHCKb5sZjnxWKaE02li5CSab7kTPYlZ1IAOZN9KbJaSoWtH41OS1k2S8iaOZan4/b6i3krKJSDQgnvSiI4Ep3I8YQ0TqVlc1Ym51yOgtM5cj6W53MmX8X5wiIuFJdwqbiUm5VablbVcLOmllu1f0XgbaOJ22Yz37S28F17G991W278/tYM4K3OVu50t3Onu51bna1cbTByxWjiQmkdn9UZ+cyg532VBYDqKYuR/U8fsv9dRLlHOkXTE1A4ScjyjiDNO3IcgNluscjdEslyiKDALZocmyCUTkLqFydQ7ilC5eyH2lVAmVcYOZN9yZsagMY5DLVNAOppvuMAHI3KYTgsi4HAeLp8ImmcI2JzvJLlwUm0LZRinhXMSlEKXT6RDATG0zRXTKXTfJaL5OMAzJjkg25hFFeHVnFzbICzXXVc7DDwSYuRE6ZaPjTU8oG+hkO6Kt7Xa3nfUMORRgNHGg0cbjLwfotxvH4Lf/9/AHy/zVKHmi1lWfli5GD9U/wZLete6qqfAeBruipe1VbzWk2NBX9/B8Bd6nIOtxq4sa3/XwrAv1zYxqOzG3l0Zp2lfsXf45O/Xug4usZSR1bz+MhqfnpvkJ/f7eP+2z38sLuOrzZquDEg53xLNidrM9iWHsuayEi6AqUUuy2dAOBEJjKR584zHcCnR71PO4FZUwXPAFDpEEq+VSAFtgGYZkXRuzSZkZAstkdl8nJ4MrvDEzmclsWpPAWfKOV8Vqbm85pSvm7R8VWHjm+WmfhudSN31zby/Voz99aY+XHIxP3VRu6vNvHjaBMP1jXycH0Tj8ZMPBrW83hIz/3+ar5rK+PzGjVXNSrOK2W8HhzM3qAwDPZhFEyOocAuk8oZWaxL1PFWsY7O4EgGonNoCCtjlayXZIco4qeFEmslpl5cRndMLa1hlZTNz6BmcTYlM+LIcRAjdwylfGYGKuckClwT0C6SUeQdj8ormlQ7ISk2ItIdY8hwTiTeKo7QSREEOsfwyor3WF65jgH1EFsrtlDpU4pseho5bhlU+5eTv0BJxowstKFaWpJa6M7spjdngBXKNbSkdVOX0M4G/R7W6/fSIR+mK3+UlZXb6VQPM1b/CgdXfMiBvnfYXDbKqqwetmnWMKroZk1OKytl9ZQHZhFt7U+ybRip9hEk24aRbC0h0z6STJtwsmwjkNlGkmMTiWxaBLlTRJQ5hVBm74fey58aryW0L40k76VF5FsFkztZSu6UUNJf8sG0NIKKWZb5vt+qp13Ap0fAcvtgsqb4kTPFH7m1ZaWQZT2MEI1bKOUeUoqnC1A5+KFxD0Y3O4zqGUKqZ4ip8pJQ7BZCoYvl5xsXxNOxOJHm2WF0eAtodF5Ema0PxfYBFNv6o7H1p8wugCpHf2qnB2JwD6ZlVihts0JpnRlCi2cAzZ5L6J/rz6olIkb9w9gqjGWHMI59Eem8G5/H0WQVH6UXcyq1iJNpRXxSUMU5VSVXyg3c0DZwTdfI56Y2bhhbuWZs4UZDB7dae7nbN8jdni7u9rbxXVcLX7c3cstcx21DLbfqdNytN/JDvYkfjAZulZfzRWkJl9Q5nMvP44xSzYGUIob8kpH92xxk/76EnCn+5DmFkuscSraLmFS3aJJc40h2jiLZOYJ050hkLpHke8SSZSNCZi2k2C2KKq948myEZFsHkO8sJcdOhMopHKW9lNypwZQ4S6j2lKLzFtC4SMKq8HTWJyro8I9mmTiFAUECQ9IMVolTMXoGYPIKZK0ojZUBCawVptLg6U+951JWCLKonxFD9fQIcqcuoV+aze2xNdwa7eXj5nJuDjZxuc1ggV9tDQeqKthdoOQVdQFvlmt4V6flPb2Oo/VGPjSbONZQz9EGM4fqjRxqbOBQYwPvmOt5v7mJo+1tfNjRzocd7Rxtb+NoexsftLXyQVsrh1tbxsty6cMy+2eZ/zPztrn+VwgaeafRxEGzgX26Gl7VWjp/r9fW8Wq1np0aLduKKthcUMZ6eSnrFYUcMFdwYV0Xt/au5sm5l/nPq7v45ep2/uP6Vn75zPL271/Ob+KXC1t5fHaMx+dG/qGenB/jyfm/fvbwzFoenh7j0emN3P9oHQ9ODvPo5AqefDTIf340wF+OdvDwvVYevd3C4wPtPHi9mSdbzPx51MC9VXWcN5ZxsEBBX3AMpdN9UDsHIrMVkGEbSLpNEHHW/hMAnMhEJvLcsQBwsv8zFz6e1tMj4KypAssxsI0QxdSAcQD2+CSxVpTB5rBUtoTGs0MSx/upmZzKU3CxUMlVTSE3tCV81VzDnfaa/xIA749ZVsA8HDXyaFjPg5U1/NxXxXdtZXyhK+KqRsU5RRaHY+JZPy8IrY0IjWM8Ja6Z9IXX8npRN+faVtIpiKEzNIPt5StpjzUSbyMhZqqIqMnB1PgX0CKtoCm0jNK5aZTNSaHYOxa5s4R8ZynFHsmonJNQuydRPjedfNdIFO4RpNgGkzxNSKp9FGmO8cRNjSXkpXACHaLYu/w9NtbvYrh6Ezu0L9McYUbumU3RXCWmED2FCwvImiVDtUSFKdpEn6yPQcUKlucP0ZTSSWloHcuK1tGjHKEqug19Yg9D2p30Vm1irGUfe/sPsbfzTbbqNjGqXs2++u28btrMy1Wr2VazgubkSjK9o4izDiHBOpQE61CSrSWk2YaTbReJzD6KXPto5PYx5NlFkzctFI2jmArHAEyzBNR4LaHNJwLl1KUorYXkTQlDbiUlc7Iv9b6Rzw3A7Kn+zwDQsj8wGI1bKBWeYZR5iCmeLqDMQ0jNLCnVM4RUeYuo9AylyFVMgbPl5+vnxtC+KIHWuRH0z5PQ5R2IySuUWk8pOtcQqp2C0DoL0LsGo3VYQo2jD8bp/jS4+dPoHkCzmx/dswNZvlDI0JJQRvzC2egfxWb/KF4Lz+DtmDyOJKo4nlLE8ZQijqUWcr6wmgtqLZc1ej6rNHFN18gVXQNXdA1c1pm5Ymjmurmd2+093Onq4k5XJ1+2t/F5c5NlxYuulk+1NXxRa+DLWiM3dQauaCq5VFzKxeICzqoLOFtUzsH0UtYEpKN1DUfjHIHKIYxsewky53By3KNJ94gnxT2BFJdoUlwsM4C5rtHke8SSbWv5Ra3EPZpq7wQUdmJybILId5YisxWidAz7XQCuDEtjfaKCdr+oZwC4UpRCy9wQGmcJWRmYSP+SKIZFabTMFGDy8GEwIJ36GTHUesSgmOZLb2gmt8fW8OVIDx83l/PFQCMXW/Qcqq7gYFUFb5aVskORxy6lgn0lReyvKONgVQXv1dbwvl7H4bpa3tPrecdYxzvmet4x13PQZMHgkdYWjrS2cLil+R/qUFMj7zU38V5zE+80WC57PMXf06+fAtCyCqZuHICvarX/AMBNKg0bFBrWKwp5p7mSSxt6uPPaGp6ce5n/uLKDX65u55drW/jL1U08vriBv5zfxF/Ob/qnAPzzJ6M8PjfCo7PDvwJwhEenN/Lo1Doenhjm8fHlPD4xyC8nBnj4XhsP3m7l4Vut/LS3lW9frud6r4bLDQUcq8hmQ0wEPX5BFDnMR2G9kFwrH1InB5A8yZ+kyYFET/KdAOBEJjKR5844AP/+1u9T/P1tZU62vAdcYBuAcWYk3UsSGQpOY31IIhuE0WwVRXEoOZ2PcuVcUqv+AYBfDxr5dlXDcwHwp2VV/NhTwd32cr7Ul3BVo+J0bjqHY9NZPSMQ/fRQqrxiKZ+ZyrGml/lp+zEudY2xMkJGZ2gWp5btYzCjkTjrECInCQh/MZCS+dkYBWrMohKKZiWjdIuiyCsGlVsEBa4R5DvFUOCSTKl3GoWe8WTZiclxkZBsIyDJOpgkm3BS7GOJnRKD+MUwgmwj2NX/Nru697PZtItdxj2MqUfRBlRQJ6yhPaaZUp9icmbIyJiRgU6qYzBvkLHyDYyVbaItoxdVUBVtsuU0Zy2nLLyJ2oRuRgx7WdXwCut6DrC56y02texhU91mxipGeLPjFU6seZe3Onbw7rI9jFT3oxHKSbCVEmcdQqyV2PIOsG04WQ5RZDtGk+sYg9wxljyHGOR2Uortgql2EdC8IBSdtw8ti8Mosg1ENU1E7mQpcisp2VP9qfeNpGzGX+f7/r5+D4C5UwP+AYClriFUeIZRNUNKuWcI5Z4iqrxDqPQSUOklpMIjBPV0ESonASp7AbXeYTTPi6F9fhSrfKJZsVCKyT2IWtdgtE4BVDv6UucSSJOXiCYPAU0eAtq8g+icEUzvnBBWLJSyXhDHVmEi20RJbBcns12YxI7gJN6IzOHdOCXvJxbyYVopJ9I0nEgv4bSilPOFlZxRlXGusIKL5bVcrTVztdbMFb2Zq6Ymrplb+KKlk1s9/XzZ08/nnT1ca+3gsqmRiwYzlw0NfGpo4HKdmYtaAx+pyzleUMzp4iJOqkv5qEjLnuRi+pYmU+okQe0YTq5dGOm24WTYR5LhHEemZzJpnkmkucaS5hpNlmsMcvdY8j1iyXWQILcLpcQ9Gu2MRJQOocjthShdwpDZClHYS8i3k5AzRUCxUyhVHhJqvILGAbghKZ92vygGhEkMBieyNjyLFcJkupdE0jovlEHfWLrmSxkWpdE+R4TRfQk9PkmYvKMxzUxEZRdAtzidW6NDfLG2i4+by7neW8+5Bi1vlqjZV1LEXnUBW2RZbM3JZme+nL3qAl4rVvNWuYb9FWUcqCznrYoKDtTWcLCujoN1dbyl0/GO0cj7DQ28ZzbzntnM+w0Nz9TTbt/T7t/BetM4/v62+7ffaOCg2cB+k559uhpeq3naBazllUodO0qr2aoufwaAhzu0XN3SzzdvrOXJuW38x5Xt/OXKFv5ybRNPrmzg0YUxnnyyniefrOfR2eHfrD9/MvoPAHzw8TBPzmz89dh3LY+OLufh0T4eH+nl5/3t3NvXyve7W/hinZGLy8p5WyPjVVkKwxFSar3mU2o/m4z/OZP0f59P+h+WkPpHf5JfDCTlpSDiJ010ACcykYk8f373CDjtJX/SJwWQMTmQ1Bf9SPp3H5L+sIjcSb6obPwxzIigfUEsy/wSWCdOYJ0gkg2BUl6PjOX9lDRO58n4tETFtaoibjdWc6u1mq8GDHyz0vy7APxhuIGfRur5edTM/eE6HqzR8UN/OT90lY13AC8VyTmekcjo4hiGfFLoDI5na2EVF0e28PObRznRPkqVhwTTvATqFsZzqGUtzdEFpDhIxmGU5RJN5eIcmiXlqGcmkWUnpsgrhpIZcZR4xSJ3iKLEI4OymRlk2IhJmRpIjouEFNtgEq0ExFtJSJgWSczkaCQvhRPpkshI7Va2NL7C6or1bKnfzaFlH9Cb3U+FoJLKgHKMwTUUz1WS6ZlGgU8BtWG17DTt4fXWA/TJVxLnlY0ysJIe5QgDRZvoVIyQJ9YxWL+Lsf6DbO4/yGjTTtrl3RgSjOT5ylitGWC1po8TG97h8Lr9bDWPoQspQzEvkwSnCCKmCombFjreFUyykZJhF0GGXQTZ00IosA1C5yaiyzeKull+tC4Jp9QhmLzJgaT/IZjsl0RkTfFDv0iC0nnBMxdA/rZ+C4C504KQWwehmCb4m5dlAlHZB6J2CqbcM4QKr1DUzv6o7H0ocw+gzD0IjasQlZMAhX0ACpsANE5B1LqLaZ4dRv88CYPzQuidI6Jnbgh98yWs9Y9lU0gar8creTNRyVsJ+RxIUHAoOZ8PMtR8rKjg47wKzim1XCis5aJaz8XiOi4W1/GxopJTyipOF2j5pFjPhVIDl0sNfK6t4ytjI9e1eq5r9dxuaOar1nZLtXdwp6OTOx2d3Oro4vPOPm50D3J7cDV3lg1xZ/ma8bo1uJqb/Su53ruMy+09XGzt4lJnJxc6u/ikrYvXNbWsTVFSNEuMamY4cu8oMj2SyHRPJcM9nQzvNNK9kslwjyfDPRaZexwKjzjyXC23gBX2EopcI6n2TqDQOYx8RzEKJwmZ1kGWW972UuTWIoocQ6hwC0HrGYh5QQjLJSlsTi2gzTeS3qB4louSGY3KYTAogfYFUlrmhrAqKIn+JVGsDkrC7OGHycOHjoVxGL2iaJybSomLiH5pNjeHV3FleTOnmsq41KbjaLWaHRnp7MzOZpdMxpbUVDYmJbE5JYXdOTnsyc1ln1LJGwUFvFFQwGuqQl5VF7GvtIx9pWXsLSrhjbIKDlRpeVen51BtHe/pDRw2mCxlqh/H39Mu4KGmxnH4Hay3XP7YbzTwlqFufPff67W6cQDuqaz+dflzBZsLNGxUlrJBoWGDsoCzqxu48+oqfjo0xi8XtvLLlU08vjzK46treXR5iPufrOLhmdU8OrvW0tn7jXoGfqfXcP/jIR6eGuLxqWGenBzi8Ycr+fFgF9+90cZ3e1v5Zmsb14fNnO/WsSc/k7VRYaimzyfbfhHpU+aR+tJi0l7yJfkPfqT8mz/p/x5EvnUohXZSihykqBzFEwCcyEQm8tyxvARiLSDPNgS5XSgKewkKewlZUwVkTA4k7SV/Uv7kS/Ifl5LyxyXkvLQUlY0/dd7htM2Pod8nlmFBDMP+UkaWitgrjeRQUgqn82RcLlbyWaWaWw1V3Gqt5k5/HV+vqP9dAH6/1syPwyYLAtfquT9Uw4+DldzrLuebllKuVxdwviCHY+kJbAqSsSZQzmhWPp9tWQefX2R/Sxu6peGUTw+nwjWS+kWpfNg1QuF8CRnTw0myCyPBRkKKnRTN/EzawqsonZtGnnOYBX+/ArDIPYnyGTJKvdNIsxaSZScm3yOSNHsRydOE4wCMmxpLxOQo4t3TWFO1kVHdVnoKVzFSs4XXug/SkdVL4dIiFHPkmIK0VM5Xk+QcT7p3Onnz81iWv5KNVdtoTe8ha5GaMqmRjYbX2GLez7KSLSQvUmNWD7HMvIudg4fY1vEaXXnd1EXXEukQQmmQHK2kkH0dmzk2doDjw++wSjVAQ1wdqiW5hE4KRPJSIFFThMRYiYmfFkqKXTgpduFkThNTaCdAOz2YzqWRmOYG0uEbhdomAPmUINL+pwDZJDE51oHoF0lQOM4jxybwN+u3AJhnI7Dg71cAWiqAAocgChyCKHUTUu4ZQqGTHwqbRWjc/NG4BVLiIiDfIZA8Wz/yrP0sK2Gcgyzrh2aJ6JstZK1vFMN+0Yz5x7JdnMye8EzejM3lULKCQ8kKDqcq+DAjn5OyQs4oSjkrL+RCoYbLxRVc1VTzWUUNn1XUcL60gnOl5ZwrLediRTWXtDqu1ui5WlHJDW0NVyuruFat5Wa95em3W82N3Gpp4mZrE583N3CtwcwVcyOfNbZys72bL7v7uNU7wK3eAT7v6ePmwCC3l6/g66Eh7o6NcXf9Or57eT3fvryRb7Zv4OKalRzu7GBYpaEvXY1OkkWKZySJrtGkeKSQ7pX6mx3AbKcwFM7hyO1CKXAOo9IzjgInKXJ7IXkOIaRPDSDfQUqhUwQqOwlqBzEVbiFUewRQP1/MckkKW9PVtPlG0h0QywpxCuti8iyrX+aF0jRbxGpBMgM+0QwJkmnw9Mfs5Uv3kkQMnpGYZiZSOl3Miig5X6xdyaWBBk41lXG+uZr3yvLZlprCjoxMdmfL2JaaxqbEJDYlJrEzM4tdWdm8midnnyKffYp8XpUr2ZOvZI9KzR6Vml35BewtLOaN0nL2l1dxoKKat6tqeFdby6EaCwifdvyeQvDdxobxrt8Bk+Xyx1uGOt6s0/O6XmupWh37dDr2Vlezq7ySHaWVbCksY5OqlA35JeMAvDTawt23hnj4wTp+ubCRv3y6gUeX1/LoymoeXFzBT2eX8eDMCh6cXsWD00M8OL3mH+rv8ffzqdU8+Gg1D4+v4vGHK3h4eIBvX2vjy51mbm42c32NmdOdNbynLWF1WDRN8/1Is11InPVSYicvJmGKP8mTgoj/H74k/cGPjD8GoLYTo3EJpdJVTIlLwAQAJzKRiTx3/vTCCy+QbSsa3/+ncgpH5RROnm3IePcv+Y9LSX3Rj/SXfJG96INymh913uG0zoumd3E0y30kLF8oYOV8f16RRPB+ShoXCvKfAeCXLVXc7tPz1XLTcwHw5+XV3Osu56umYj4tk3NOmc2HafHsDitnZ0I9F1YO8eTEm/xy9i0MEWK0PhJ03olUucXT4pfDG4ZO1AvFZLqGkWxvQWDslGDUs1Joj6imYmEWaq84NLMSKPaOpdgzhqo52WjnKijySN1D8QEAACAASURBVCbNWojSLYri2QlkOoWSaismwVpKok0UCdbxRFvFkuKRwWjNFka0m+lSrWCgbIS1NZtZWTyMIboejW8ptb7lVM9TE20TQaJrImleaVRLdHSk92KKb6EqsoHOvFW80fchO1sPMVC0CblAS1FcAy1Fa3il71329RxgXfkIA1ldaHwVZHtEI/OKoi/bwBvtm/lk41He6X2L3fXb6cvpJNpBSuikQCKtRBYA2khIcYgg1TGSLLtQihyEVDoF0rY4DPN8AT2BcSgmL0E1TUTmH0XIraTk24swLY0g32k+smkBv1m/BUC5bfA/AFA+zZ9iFxFqp2CKpwso9wyhyCUAlb0Ppa5+lEz3p9g5CIV9ALk2vuRa+ZI/dREaO1/M3iF0zxIxMFfMmkUhjPhI2RgYzW5pMnsj0ngjMp3DqQo+SM3no6wCTssKOJNTyJkcJWfzcrmgUnBZreJSSSGXNGouadR8oinkTKmK0yVKzlSoOa8t5VJNOeeL1FwoLuJyuYbPqiu5pq/hc7OBLxqMfNFk4nqjkc/MdXyq13HVoOe60cQXjY183tzEteZGPmtq4Hp7Czd6OrjZ382dlQPcW7+We5tHufvaJu6+sYl7+7dy983tfPnqJj5et5b3BlewzdiGPkpNUUAuuQuzSPFM/M0ZwAz7UPIcpb/u7QylzC0alaOEXFsBOXYi0qb4o3QMo3h6NEVOERTaiyh3FVPl7k/9fDHLQpPZllFEm28kXf4xrBCn/H/svWdQXHe27r3vueeembHHkqwsJJSDlQOInHNoMjSxA3TT3dDQNJkmg8hJIDIiKiFQsHKwJCvn4GwrOchBkpVtOc6ZM7/3AxJjT6gzc+q9H+aWnqpV/PfevWvzZXf/6ln/tRY9vtHUWftRttyNokWO1D8bEbfWKYzyJU4UzreizlJM9lwvMmaLSJjhREeghk/am3i3No8LRTquFOh5I17GppBgBsMieF0iYyA0nI1BIawPCKI/JJTN4jC2RUrYHiXldYmMbRI5g1I5W+RKtsiVDEhj2BajYpday05VPLvUWvbEJbI/Qc9BXQr79CnszsxgryGL/TnZw6ne5/A37PwZstiTlcnOjKHq3z1ZmcMAOKjT0x+f9Mz90w4DYF+smmt9ZTx8Yy3fn+7j5/fW8eNH3Xz7fgvffNjIk/caeHiljieX6nlyaQ1PLrbw5GLrX8VzJ/CXAPjkXDPfnGzg6fF6nhyu4YvBAm70GbjWYeByWRpH0uPYJpNQZupE2rQVhBlb42tkh2i8FX7j7Qme4EjoaDsixgy56qmzXTDMdyFvoRMZ817sAXyhF3qhf14jBEFAPcmWlOlupM8RET/VldhJDqimuhEx3p7wcXaIx9gRMMoKv5cskY5wRjPBCd00UzJmraRoqS3VK9yoXOhMxUIHNrqJOBgRzBVtGO9rpHysU3M7P5UvV6XyRU3W0D7A1nzutOZypzWXu63Z3Gs1cKfNwK2ubO70GHjUm8sPndn83JbF9zWZ3MtP5vPMZD5IzOC0LJHj0hSOlSfw9YFWfjx8gL3J+RSa+VBpFY5hoStJ82yJmWrOKncFeS5JRM4KRDTaCdEYB0RjHPAZbUfcIjEl7snkO8RhsJAjM3ZGOsWJuDkiMkxjiJkVSMRkL1TzxMTODaHcIxP1a6GETfIgylhE9MwAgse5EDLBA/WSaDal9bM+fRMd+l4qYxtJDSxgQ+lOttYeZI2uk6iVSsJXROM+wpkQI3+CJ/ujsdKyOraZJl0X2ZHldBdsYcOqHdTFt1EcVY3UXEWmfy4V0bX0pvfSn72RtZoGyv2zWR/fSK1fFilLI0iY40etm57jRZs43r2Pc5ve5OLAKYpkxYSZROFu7I1oqg9+k72JmOKNYpo/kaNt0c31JnWuG5UmIlZb+VFhKkI+0ZbIqe4EGfsSYixCNtWN1TZiUqdaEzn22Q/Q5KE+gs+bhCuN3VFN8yTayAXphKHq1MjRtkhG2yIba498nB3R4+1RTLQnbpoLqimOxE62Q21sh8rYGuUkCxKmWKKfMdQ4Oma8zXD6WDHeAs0kS1Kn21G73IuGlSI6zVzYaO3O687+vOEXzrFACZckKt6WqnhHpuZdmZJ3pdG8HSXjUngUl2QxXIpRclkRy1ux6qGWL5r4Xx1/oE3kwwQdHyUm8a42gfcTdXyUmsr1jAyuZWdxIy+HG3k5XMvP4WrBUFzLz+Fmdg43s7K5kZY5NEUkM4XrhlQ+LsjkZlUuN+ry+agxn4/7Kvls0xpuDXTyxfZe7uzawIMDg9x/Ywtf7t3I3YMDPHhzO5/t3cBbGxo5tKaQjEApGjcZAfO98Z/rS/CcIKLmRhAw0Zvg8a5EGrkSM9Md9WxnYmc6E248tEUhaLwDUUYeRE10RzLOmVgjZxJnuZG33JvCFR5U2wTQHaSmxjmUIjNvyqz9qbIJpMM7mlITL8pXiihd7kmdRQBrbEIoW+ZJmakX6XNdyVnoT/6KMHRzHGj1l3KtsZz3arJ4u1TPO9nJnEqIpz9MwvowCRvDpOxSxLFLEcfWyBj6g6PYEiZnq1hGv384m/zC2BWmZGeogt2hKnaHqtgZrmZ7xFBsDlOwOTKWLVINWxUJbFPp2KbS8boqiR1qPTvUenbGp7AjPoWd+gx26jPYkZLJzjQDu9Kz2ZOZy470THakZ7I9NZ1tKRlsTU5niz6DTfEp9CgS6YtNolOeQIckgY3xCdwYLObRkSa+O9XCn95qh3c74J0W/nCpnp8u1PH9mTq+P7OG78+sGYK759B3YSienm/lx4sd/HChne/PtvDdqSaeHmvgybE1fP1mA18fqefrA7Xc2ljEx5253GjO5Vh6EuvDI6iy8yZhmj1KI1v8XjLH/2Urgl62RDLSEuVoK3QTLMmZ6UD+XHtKVzhRZubIKjM70pebvgDAF3qhF/qnNUIQBDSTbUmZ7kLqXC+SZnkSP9UV9TTX4R/ziAlOiMfYEfKKLbKRLqjGOaCfYYZhrgWFS2yoXOZGxQIXyuc7st5FxF5xMJc04bynlnAzUfUPAeDdVgO3O7K535nD485cvm8z8EOTgUfladwpSOGL/AzeS83kdKyeU5p0Huxo497eFvakpVFq50vSLFvq7KVkLnQlYtwCNPPsaY/IJMksGtFY578CQPWCYIpcdOTaqUkziUQ9xxv1HG+083xJXS4jemYAkVO8iZkViHyGP9WiHNJWKomdG0LMrEBU88RETvFGMs2fYCMf6sJrqZevoSG2hfqEDvIlVXQXbGGwch9dhn6SPDIJWy7HbZQLoVODiF4oozBwFW26btpT11Gf3MX21YdoTu4h2SeHBNc0sv0LSfbKICcwn9XRq+lO7qQ9rpESvxxWiTLolFVQ7KgldKw9WaYSdqW1s79hM7vrN7OtciNbyreQH1GIy2R3PIw88TXyGiowGOeCdJwD+vnepL/mQfVKXxpsAqgy8yXGyJ7wKa4ETBYRPMUbqbErddYhpBhbDU+HUUwZcp+e94uMmeyK0tidmMmuyCc5I5vohGSsPbKx9kSPdyRmggMxExxQTLRHaWRPzERbYifboZ3hRNJcF3SznH4FgIpn+wcVE+1RTrAkzsiKtBn21K3wZo2ZD51mLmyy8WCHS8AwAF6MiuVt6RAE/qMAeEWp4m2VhnfUcbwfn8CHCTo+TND9CgCvpadzPSuTa9lZXMvO4mp2Fh/m/DmuZxm4npHFtZR0rqekci0jmWtZKdzIS+eTmnw+aSjiWnMhN3sr+HRjw68A8P7+Ae4dHOTeoS08Ovo635zczZPTe7h3dDtfvLGZ/U0drCusR+cmRboyiPCFfoTP9idyViDSGT4oZvoQO9sX+RRHIibaEDXdhZCJjognOSOd4oXUyBP5RDfUU1zRz/WkaKUfJWYiVjuE0BsSR61LGEVm3pRa+VFpHUCrh5SSFZ6UmXpTsszjVwBYssKD3MUiileEUrQykpT5LvSEqX4FgG9lJXEiXsM2qYIBqYItUiX7NTr2qRPZKVczGCpjW0QM20LlDARGsjkggt3hsewQx7AzRMmOECXbxUq2hsWyNSyW/pBoNoUr6I9QMijVMBgdz2B0PNuitUNAqExkuzqJ7Ro92+KT2a5NYVtCCtuS0tiuT2d7csYz8Etja3IqW/RpDCalMqBLo1+bOgyAXdGJdMp09Cfo+HhrCU+OtvD96dYhAHynnT+93czPF1fz4/nafwgAvzvXytOzLTw93cS3J9bw5EgdD4/UcudQDbf3V/LVrlI+W5fHzfZcbjTls1OloNUrkIIVbsROsid6vD3iETaIR9gQ9qo1qnF2JE60J2OaIwVznShe4ESFqQsVFq6UmTmStXzlCwB8oRf6F1aWMPQC1//i3G8FQWgWBOGhIAjfCYKwTRCECX9x31RBEPYKgvCDIAj3BEGoFgTh3/+J544QBAH9fFfS5ruTNn9oHNjQTFhXFJMdiDFyQDHZGflEB2RjHIl+1QXFaGvS51qTv9CW3PnWFMxxpHCGI0UznWg1c2ezuz8nJWFckoXxoVrO59lJfF6UzBc1WdxuyP2bAPig2cDTxuzheNKQw8OGbB63lPBZVQ7vFaZws66Eh93t/OeOQa41FLMzLpI44wXopluRvySAEvNI4mfYkbLEmd2p1bzfvAPxJGf8XnXAZ4wz3qPt8RnriOhVW6QzvElZKaPQSUuaSSQyY2dkxs6oZnqSsCCM6JkByGf4EznFm4jJXrSFV1DimkbaSiVRxiKijEVD14xESGaEkGCiQW+dRFHAKtblDNKd1U9GYCFZgUVUKxvZkDVARVQtyfYpJFglorVOJEOUS15oGU36bnasPszr1QfJ9C8gxkKD2jKedNdMikLKyPYtIMPDQGloGeuSe9mUso4qcQnKxaHEm0ioDS6gwFVHkaeOA+VdrEuvoVpi4HjzAU6vPYrGWonfVG+cRloRauRC8BhbUhYFoJvn+VcOYPQkO4InOOAzwQP/ie5EGjlRYxlE8hTL4SbhsVM9hl3AaCOX4erx2KkeqKZ5DsHgJBeUw+FErNHQJJn46a5opjqjmeqIdoYT2pkOxE21RTvZAv0MB5KmORE7yR7lJAdUk51QG9kQP9matBn2rDYR0WzpT5e5K5vtvNjtHsyRwChOBMs4Fx7DpYgYLkcqeFsSwzsS+TAAXpRGc0H+Zwh8W6UZjucw+F7cUBPo9+MTht3Aq/qh8XDXU9P4IDmZD5KTeT8lmXdT/xwfpKbxQXIqHyal8FGSnqvpeq5mJnM1O4Vbq4v4srWcT9eWcbO3ght91XyxpYMvX+/izq5e7u3fwNcHN3LvUD/3DvVz99Am7hzp596xQR6c3MbDc3u5d2YfH+/fzqX1fewuq2ZVkIK4lSJCjB3wHz/k9kmn+xE925+omV6IJzkhnuSMZLInkkkeSMe7oJ7iStIcD8qsgqm0DqDeUUx/lJ4GjygKV3pRauVHuaUftXbBFC5xpXiZO8VL3Kg196fRVkz5ci8M82ypsAyjxiaaopWRGJZ5szM+i6trynirIo23S/WcS9ZwWBnD/rg49moTOJCg482kFN5MSuFwQhJ7FWr2KtTsksSwM0LOzgg5u6OUDIjlDITEsDk4mv4gOZsCZWwKlNHnF8k6/yjW+UexPkDCusCh6AuIoi9YynqxnE0RSjZGxbJJph4KuYYN0c9CEccG1S9DywaVlvXKBAbiU+mRa+mNTqBLoqVXrmdLUjK3dlTw9EQ7P5xp44+XW/mvKy384VLDEPydrea707V8d7qBH842/l0A/OZ0E9+eaebp6Sa+Od7A/QOVfL23lC935nJ7ex5fbsrjrXIdx7PieCNBQ+kKF3RTzZGOWE7YS1aEj3RBPtEBxSQ7VFPsyZzlSsFrXlQv96HexJeGlSIaLLyos3KnxsKVAhObFwD4Qi/0L6qVgiB8KgjCO8KvAbBVEITPBUFwEgTBRBCEs4IgnP7F9f8tCMJ7giAcEgRhmSAInoIg3BcEoeyfePYIQRAwmPuTs9KPrBW+6Oe5kjDLEd1sVzRTHFBPtkc92RHlRHvkY+xRjHEjdpwNGfNsyFtgg2GuFVnGNuQa25M/1Zn6Ja702vnwZpiYc5Fi3lVE8VlWIrcK9f8tAH63xsA3jQaeNORwv7GA+01FfN1Wzic1+bxfZuDJhlb+tGsjf9jex5ZwX1oc7Uibbk7efG9KTCMxLA1GPsmcjkg9bzds4srqQbxfMiXcyBO/sU7DAOg9yobwKW7ELRJT7JJItmU0waMtCBi5kmhjF9RzgpBO80U6zXcY9NojKmkKKRlOBcfODUH9WigxM4ORTgsmxMifkGlBqEzVtCZ20ZPVT664FJ17BnlBq9iW9zob0/vpSuyhVd0+5BTGtdGk62Jz+R4OtJ6iI2MDspWxqK0TyHQ3oF4ZT2V4LSUh1Ri88snyymGtdi07CnfQqmomwNgb6YIw+tN6WKuqp1NVxcHidjboy6mNzKDAP4UteX10JjSR6hCHr5Ej/uNtCJlgR9xcT+JmupA004nSpR5Umw25PlFjLQkab49ovPswANZaBZNibIVkvANR4+xRGrsPp3vlk5yJHGtH5Fg7VNM80czwRjXNE4WRK7FGrsMAOBQOqI2dUBrZEzt5aBRc3HQ7NMY2aCdbkDzTEf10Z9STHVFNdkJj7ILayIY4IytSptlSt8KbJgs/ui3cGLD3Zq+nmKPBUk4EyzgbFs2FMDkXw6N5K2rI/Xs7SsblCAkXJHLOy4amflyKUfJWrHrYCfwlAL4Xp+UDjZar8Ylc1eq4qtNzLSmZa8kpvJ+o4/1EHe/qdLyT9Of4IDmV9/UpfJiUwlV9MlfT9VzLSuFaTiqf1xfzVVsFn3WWc7O3gpvravhyWxtf7VzL3T3d3DvQx90DfTw5Mcg3J7fwzemtPDw5yP3jm7lzdCO3Dvdx+3g/Ty/s4/HpvXy6d4A3aupoidWiWeFJ4GQrPF81JWCiM2JjD8KmuhE4zo6AsXaEjnMmdIwToSNtiZngQNw0J0osAim39KPaJoABaQr17pHkm3hQauVHhZU/VdYBFC5xZdVyD4qXuFFj5keDdTClSz1Im2lBycpgys2jyFkagmGZN/uS8vhg9Souluh5qySJM0kqDimiORAfz/7EBN7Q6TiSlMSRpCTe1CVxOD6Bg+o49kUr2SdXsE+uYI9MyZYIBQPhSgZCFWwWx7ApWM6mYDnr/aJY5xvJOt9I+nwi6POJoFcUTpd3KF0+YfT4RbAuUEJvsJSNUbFsjIplfZSSdc+iL1JBn+wXIY2lTxrLOpmGzcokusJVdEeoWRuqojcykW0Jej7dXsY3x1r5/nQrf7jYzB8vN/PThdVD8Hemiqenav5bAHx6toXvzrUOV/wOAWAZX23J4XZ/Prc6czisi2ZTaBDtbr6kTLUgetQyQn+zhPBXbIgc44xiih3qKVZop9mSM9eZkoWeNJj40mzuR4u5H81WIhqsvKi39GTVSscXAPhCL/QvqN8LgnBdEAQXQRCOCX8GwJGCIPxBEITgX3z2NWHoJbd4duwpCMJ/Cb92BTWCIHwjCMJ//IPPHyEIAhXuEqrcJJQ6RpCxTETKfDfSF3mhm+FM4nQntFOd0Ey0RznGDtUEd7STnUifa03WHHPSZ5qROtGSrIl25Bg5UznXmbaVXhwMDOF0WAhvycP5JEPLZwVJfFlr4M6avL8JgPdbDDxuMvCwMYt7TTl83VbK1x2VfNZUxmdN5XzRXMEftnTw86YWrpen0+tsR9NKa7KNrTDM8CT/tRByTMKJm+3MnoxqTpd3Mqgtw+V/LSB8giv+44b6APqOc8JrpDXBExyRz/Ih105Nno2S0HHWBI4yI3aGB/KpIsQT3Aid6I5kqg9RxiLqAwppFpdS45NL3IJw1K+FEr8wgugZQWjmSfAd7YHnKFdCpgfTrG5jS8EOyiW16N0ySHXNoCqsmtrIOjp1PfSmbWRD3lY2Fr3OYNkedjW8ya66w5TK6hBND0BtHkexTxEp1ikU+pVRHFRFcVAlmR65VEvq2JDRT520DpV5LHFWGrp0HQzm9HOm6Q1OlXUxqC+jKzafiHkeVEXmcbLxIF3aBrTmEjxHmRA0zoqISdaopzuQMM2eVYvdqDDxoGixKxGjzQkab4/PBA8CJnkgmeLCahsx6dNt/+4ewOfn1dO9iJ/lQ+xUDxTP4E8x0RnFxKE0cPR4WyRjLIgabU7MRGvipjmgn+dK0mxn4o3MhwFQM2UI/uKnuRE70QrVBHN0ky2pXupBo7kvPZbuDDqI2O8dxnGxnJMhck6LZZwPlXEhTM6VyCH3761IKZcjJJyPknFe9mcX8IpSxVuxat7VxP9VvK+O53pcIte0Oq4nJHEjcQgCP0jU8cEvIPB5fJCcygfJqXykT+Vacgo3slK5kZ3Gjbx0Pq8vHnYAP1lXxacba/nq9Va+2tnO3T2dfL2/mzsHuvn6UB8P3tzA45ObeXxmkAcn+7lzbD33j2/m66ObuH98M49ObeXx6de5c2g772zoZm1cCtnuYUQvdsFrrBnuI00JnuKI76tWiEZaEjjKjoBXbAh8yQLJaGuURrYUm/lTau5DuYUPA9IUVrtFkLPMdTgFXGHpx6rlHpSs8KR4iRtVpj7UWQRQvMiVtJkW5C3xoWBpMBkL/Mk18eWN1CLersrnbGECb5UkcSpRyWFlDAe1ag7q4zmSkshhXTyHdfEcS07kRLKONxPjORir4FCskkOxSvbKFbwuV7FVFsegRM2WSBUDoQoGQhVsCpTRHyBlo18UG0QRrPcOZ51XGF2eYro8xXR7hdItCqPLJ4z1odGsE8vpDZXTHSqjSyylM0RCZ2gUnaFRdIVJ6A6T0xMeTU+4gvUSDa3+UtoCZDT7SukSaxhQa7kxWMzDw418e6KJn8438oeLjfx4vo6npyv59lTFPwyA359v46cL7Xx/upl7+yu4u6uMrzYW8HFzLm+vSqbXz5cqU3ty51gQN9YE+e+XEfHScmQTbImZ7Ez8DBsSZ1qSPMuagvlOlC92p9HElxZzH9rMfGi28KbJ0otGa28qLNxeAOALvdC/oPoEQVj9bH1M+DMAOglDL/Sov/j8LUEQkp+tiwVBePsvrs94dt/yf/D5IwRBoDM6mQ2xGayPyaDRT0Wdq5xyu0jylweQu9iHzDmepE5zJsHIifjJXqTP8SJ5pjlJU5ahN15OwqiVpI62J3O8M8VTnVi90J3d3sEcCwzgYlQIN9Pi+CQvkS9rDdxtzP+7ewC/bMvi83YDtzry+aqvjrubWvhhxybYO8jPA928l6Xi7aQoLqmD2Ofpy2ZrX8pmelA8J5Aq01i6xIW8rqtjb3YdRc5hxC1wJXiUOT4vmRE0zuVXAOj7qjXiSc4o5/qRsVJCga2CHEsZ2WYS/F6xxvHfluP0v1cQMdmLcCNPsiw1tIaV0xRSQopJDPrlclJMYlDOFlPlnkfoRD9s/5c5K4RlpDil0Ra/lrVJvXQl9dKqbidqXiSBxgFELJER55RMnGsqiSIDzWl99FfsIcpag8xSQ4aHgSJRISXehZSLSki0SiXNKY++pEF69P3k+qwiz7eESkkd+cHF5AcXs0bbytq0Xo427GNQlUOBQwhVoliUi0WIpzuxNbuHPYWbaIkpw/GlBYQYWRE72wXNLKe/6QCGTHTEb5IXwVO8kU9zp8kxEsNsR8QjLRGPtByGvrBXrYkYY4tkvAPho22GAVAxxY3oic7ETHBCPs4B2VhbpGNskIy2RDPVmdjJDmimOg6NhXu2B/A5ACbPcCF+6hD8JczwIGacOdGjVxA33pTyhS6sNvGix9KdrU6+HPSJ4GRYDKfE0ZwKkXImOIpzYimXI4bg7zkAnouUck76ZxfwsiKWK0rVsOv3riZ+2A18TxXHDU3iUMTruBE/BIJXtTquav8Mgc/jo9R0PkpN53pqBh+nZ/BpbiafFRi4tSqHW6uL+KxxFTdai7m1sZavtjRye0cLt3e3cXdvB3f3reX2/rU8Or6BR8c38PD4Bu6f2MCDkxt5cHoTD44Ocv/wII+PD/DtmS08PTvIg2Mb+ebsdp6cOcCdw/t4Z+MmisUK4qx8CZpig88oS7xHWOA/wga/l63w+81Kol61Imai9bADWGYuoj9KT7WTmMxFjpRZ+1NjF0yllT/lK0VUmPlQvMSNihXeVJqIyJ1rT/4iJ1JnO5M+x4u013wptQnleHYF51dlcswQy+XiRE4lKnlTpeRoSgLHMvWcMqRyNCWBoykJnMlM4YIhnZMpOo7Eqzim1XBMq2GPIoZ9Wj27tKnsUunZodSxQ65lhzSerREqtoUq2R4Uw6CvhAGfKPpFkfR6hdLjKabbI4Q2lwBaXPxZ6y1mrbeYVu8Qmj2DaPIIpN7dnxa/EFr8QmgLCKU9MIKOoEjWBklpD5BQ4xJIjUsgVY6BNItk9MkUvNtn4PbeGh4cruOHsw38fGENP5yr5ZuT5XxzspxvT1b/twD46EQDT0418t2ZZr453sAXO4r4fPMqbnWUcVCjpsvNl9QJS4j7/TxUv12AepQJqtEmxBlZkrTQCd0Se9KX2JG92J7cxQ6UL3OmboU7bWY+tKzwonm5J82mHjSZe9Fq5cNqa9ELAHyhF/oXU5gwlML97bPjY8KfATBCEISf/8Y9FwRBqHy27hAE4eBfXH9JGPoi8Pw7z/yNMPQl8TwmC4JAR2wqm7U5DMTnsCFKT29IPGvco6ixDaLSyp+iFR5kL3QkY5YtuXOdKVzqRPp8E3QzlxA/fSlxk2xQvmqN5lUbVs11pWaxM9s8RBwP8ONyRAi30rV8kZfE7eos7tbncntNNncaDdxtyubrxiweNBt40JzN7bYivurI4/bafO5tKObxQCkP+oq4257DF7UZXM9K5ANdHJeV0ezxkLHBMpTMScupNvNkm1xPf1wWn/cfpCY4CenMoXSY78t2RE3wQfSKDT4jbPEdRxXGuwAAIABJREFUaYf/qw4EjHYkcIwT4gluxC+MINs6njq/fJpCSnB7yRbRKBcCxnkQPNGbyGmBpFqoWK9poto/lwJXHQZ7NZolYlIsYyjzzcPhJWvMhOVY/8ac0LkhxFmo2Zq3hS2F22iOb6VSWk2Gj4HIZZEUBRdQFFxAgl0CPck9DOZuwW2iJxrLROqjWykJqSHbu5hc72JqxFVUB5aT51XMamkzzfHryA9ZTW1sB6XhNVRHVlMWkEOjrIyNGW20ZNSS7iwndamYOlMNJctiyHZMQG0pZ0fFIO4jlqOc5EDOJCeSJ1qgm2BOqWkIVVYSspcEIh1vTfjoFUSOWkLUiNfQzzCnzMQV/dSVw9Nh5JOciRpnPwyAv3QG1dO90MzwJnyCNfLpTkQY2SAeZ07EJGvCx1uiMHZEM92VxFkexBk7o53min6OG4kzrDEsdid/hT+qSbYoJ1iTMNUV1UR7FOMtUIw3I2WuA3krPGl3DabPPYjNolD2B4ZxKFDMcd8ALkVEcDk8goviKC6ERnE+RMppsYRz4TIuy2J4OyaWdxQqLstiuCSN5n1VHO+r4vhAHc8H6ng+1Gj5UKPlo7gErml13EjUcz0hiWtaHTd1yUNuoFbHR3EJXI1P5FpCEh8m6PkwMZmraRlcNWRyrTCLj1YZuF6Ry6ctpdzqqOCz7gpub27g3vYWvnjmAN7e1cGd3Wu5vauDr/d2cW9fNw8P9vHtm5t4erSfp0f7eXxyMw9PbebByX7unxzg/skB7p4c4N6Z7dw5u4MHl/Zz/8J+jvbWsLmqkFypCptxy3AYbUbwWA/8f+eI/7/ZET3Kg+SZAeSZBJO9XETWSnfa/JW0+ERTYOpJsbmIMgvfoffd3JcyU29Kl3tSaSKifLkXq5Z6krfAjcIlgaTN9KDSXMJaUTRH9Fm8VZbO2QI1l0p07NXGcCgpmWOGdI5mpXA0K4UjGXqOZOg5nJ7E8ew0jhlSOZSm42BKAvuS4tir1bBHE88+dQJ7VVr2xMazWxnHbmUcWyUxDEbKh6qKg8PpCwxlXUAY6/0jWOcXTq9PKGvdg+lwC6HZMYAWp0DanMW0u4TT5hxGs5OYRtcgGlwDaPcNoU8cwcYIKevCwlkfFkW1vSerzF3IW+ZErX0o3SFyPuw28Ojgan462cp/XWzj5wtNQ9B3tp6n5xp5er6d78538/2FHr672Mh3lxr47nwTP5xr4fszbfxwuotv32zlm0OtPD3UwfdvdPDJ+iLea87lSm05TaJQ0hZZETlyPlGjliAbtQzVODN0Rtakz7Qjb4Ed+QttKVpsS8liO0qX2FO9woVaUzcazDyoN3GjwdSdZjMv2sy9aTXzonaZywsAfKEX+heSsSAIXwuCsOQX544J//cBsPDZ9V9FtyaTQX0BW5MK6FdmsCFKT5u/knrXCFY7hlJu4UvBMjey5zlSMN+N4uUuZC5ciX72MrQzlv3/BoB324r4sj2XrzryuNdXyKONxdzrKeBOWzZf1GZwMzuJD5PiuaSQs9NdQp9VKCWv2dPrI2ObXM+RvFp+OvIWOQ5RREx1ImCMDSGjXQka5ToMf36j7IfhL3CME36j7FHMDmKVSyo98tW0R1Ri928rcfh3C1x/Z0PAOA/CpvgRPTeYtfIaWiLLKXLXozONItUymkq/LFqktbiNcsT5FTtcX3XEc6I7YfPENCrXMJAzwKasTazL3MAadRM5vgYKg/LROSagd9LTk9zD+vQNSJdFEzQ7jDpZM21xvRQFVlIRWkdFYBl1YTXkeheT71dKq24TbUkDVCvaKImooT6mgeaYatpja+jRr2Fb1Tq6tBU0BxnInBVC+lwxua5J5Pik0ZXWQoFbHBGjLUh81YKUidboJllRYhpKmWUkmQv9kIyzQjxyOaEjFhL2+7nopptRusKFpClmw83Bo41chl2/5yME/xIAJZPtUc52I2qKHWETLIk0siF8vCXRk+1RT3NBO8MNzRQn4qe6kDTbFd1MG7IWuZG/wh/NZHtUk2z/WwDs9xYPA+AJv0AuhIVxMTRsGAAviGWcDZNxITKaK3IFb8fE8nZMLJek0VyUyH8FgL+Ev6vxiX8FgL9c/xIAP0pM5iNdCtfShyqFrxcZuFqSzbXyHD5pLuGz9nI+6Szjy02rubu1ic+3t/DljrZfAeDtXR3c3dPJvX3dPD60/s9xYiOPTmwcBsB7JzZz9+QA98++zp1T23l4YQ9P3j7EzUObubJ9PRvLaoixCSJoriueL1vh/VtbxK+4ohjrTersIPJNQ8gz9aPUIYgW3xiavGXkrXCncKUXJWai4T2A+YucyV/gRPEiVwoXOJP7mhN5C9zIX+RPynQ3Ksyi6PJVcCw1h7fK0jlXqOHiqkT2JSg4rE/hmCGdY4ZUjhlSeTMzeRgCnwPg4fQkDqYksF8fz76EOPZrEzkQp2O/JnEYBPeqtOyMUfO6PJZtUgWbw6X0h0noF0vYGBjFev8I+nyH0sFr3cW0OgfR5hJMm7OYNucwWhzFrLEPosU1mCa3ILr8w9gYLmFAEs3G8Ej6IyU0uIiotPagyMSZWrtgOoOi+LDbwMMDdfx4ooU/Xmjlp/ONfHuymu/PNfD0XCPfXegYBsBvLjXz5HIj315s4tsLLTw928JPp9v44Xgr3x6o5/HOGp7squVGewZXqpM5kplOub032pkmSF5dSMyYFagmmGN4zZP8hZ4ULfGieKkzRYvsh+GvfJkjNSau1K10p9HCiyZzL5otvGm1ENFh6UO7hYh6kxcp4Bd6oX8l+QtDL+wffxEIgvCnZ2tn4f9OCvhvOoB9+ly2ZJawNbuMgfRiNunz6dMa6JToaBdrWOMeRbVtEOWmvlSa+FNp4U2hqR2GxZYkzzMj3sgWxSgrVCOtKJjpSNVCx/8RAN5vKRpODX/VbuCr9ky+asnkq4Z0bldn8EVuKjeSErgsk7LZW0KPVzTbpMm8X97KuggNj7Yc5sd9F/AfuwzJNBdEIy2ImhGA8/+xwH+046/A73lo5oehXRRJqqmCblkda6OqEY1yxvMVR1x+a43Lb60JGOeBfqWC/oQ2tqV0k2alQDE/gJrAbFqiSilyy0A02gXJrBAipgfi9HtbZPMjSHdMJk+UQ7ZnFqXiEjoT11IZVU5RcAFl4SXsLt3NQM4AlZFVRC6WkmiXQvCcSBLt0unR91MSVEVpUBmN0U3kBZShstZTr+1jd+0ZerK3UyqrZ42mhYGcdbRp6igPyaI1tpi9+V0cXdWP1NgD79+bU+adSX1oMeX+mbxZNoDBVobC2B7dNHt0UxzIXSYme1kI2lmeRIy3xf/3ywkasZjQEQtJnGVDhaUvKbPtkE5wHC4CeV788bwyOHKsHTGTXVFN80Q1zRP1HE8SF/uhmOWKZIodsqkORE581ih6kh2qKY6oJw+NKdNOdyRlrgOp8xzJXeZL6lwvEqe7oJvujsbIkdiJVsROtCDtNSfyTbxodQ6kxzWATV4h7A8M40hwGKcCgjkVGMiZwCAuhERyMUzClQgFl6WxXJHFckWu4IpcwWVZDBclci5K5LwXqxmGv+fQ9xzyrick/Qr4rml1XNPqhgpEngOiLpnr+jSuJ6dzMyubm3k5fFySy43yPD6uLuBWWzmfr63ks+4Kvuqv5+7WJm5tax52Ab/a2c6XO9qGgfDunk7u7+/h/v6eIUfwzV4eHu3m4bG+4TTxg5P9fHdpF1+fGuTe6S08PL+Txxd3c//cHp6+d45Lg1vYsqoO+VIRvhOt8BxpQdAoG+ST3VFNc0Q23pSkuY40i+Ss8ZSQs8yVfBMPik29qLD0o2DxUHPh4iVuQ+7fYjfyF7iQt8ANwzxvEowcKFkRxuZwHW8VVw0D4LnCeA4laziRkcXJ3CxO5mZwIid9GPqOGVKHj9/MTOZwetIzJ1DHkdQ0jqRkcEifxiF9Ggd1KRzUpXAgMZm98Tp2axJ4XalhW4yKbXIVgxEKNodFs0ksGyoC8ZfQ6R1Bp3cEa70iaXYJZY1jMDXWvnR6iekShbAlQs5uhZJ9KjU7o+Vsk0TRJQqkyVlEmakT1RYiOnxCuNqbw8MDdXx3tJGfzzbxw9kGvjlRxQ/n1/D9hWa+v7iWHy728sPFXh6808n9dzt48FYrjy428OR8PT+equXn43U8fr2Iz5p1fLo6gQPRrvR6WLHKxA7l+CVEjZiLdrIZWXPsKVjkRulSL8pXeFK1wotqE09qTNypMnGhysSFmpVuNFh40WTtQ5utH+02frRZ+9JqIaLN3Js2c28aTNxfAOALvdC/kF4RBGHRX8RFQRDWP1s/LwIJ+sU984S/XQQy/hefUQlDRSC/+Qf/j6E9gEnZbMooZlNOKRuyS1ifVcz69EJ6VOl0y/S0+ytZ4xJBnXUI9Vah1Nn6U2rpTP4KO9IWWA4DoPIVC/Km21Mx357tnj7/FAA+asrmflMh91pyudeSy+3WLL5qSed2Yzpf1aXyVWUaX+SkcEOn5W2plK1hajbLUjhhqOL9mg7a/KXc27ifc+VrEb2ygOhZHniPMCd8mh+uv7MZBsDn4f+qA/6vOpBvr6PWN48ip2TWRlXTFl6B5ysOuL9sj8O/m2MpLMNvjBv1IavYm72JTdpW1IvFxC8Lo9Ivk3yXRLSLpQSOdUc+M4SQSSJ8x7qRZpVAvoeBFDsdymVyohZGYPDIpDAon5LQYtq0LWzI2EBhYCExpgoiF0sxeOUTNDuCkLkSioOqaIhpoyqihoboRorE1SS551ARu5b1xQfZXneMGk0btapG+tLW0hBbSaFvMvVBaQzo6zlWtZWSwCwi5voQtywSnYmMRnEBe3J72JrRgniaDZoZjiQaO5G1OJjUhQEoprkRaeRE0BgLxGPMiBhjQvJrrlTahZA+f6jwQzrBkdipHsMu4PNzUePsiZnsOjxJRjPXi6SlAShnuyGb6oB8miMSo6HZwfKJtiiN7NFMcUI7zZX4aQ6kveZE0ixbcpf5kr04gOTZQyP9ngOgapIl6fOdKTD1psUpgG4XfzZ5hXAgKJwjwWGcDgzhZEAApwMCfwWAV2Qqrshih9O+l6TRXJbFcFkWMwyAH8UlDBd83NQlD6+vJyRxNT5xGBCvxicOu3/XE5K4mZTCjeR0bqRk8LEhh4/zc/mkNI+bFfncWr2KL9dW8VV3DV/0VXNnYA33trfw2S9cwOdxZ/faoaKQvV2/BsDDnTw8vJbHb3bx6FgPj4+t4/GJjTw5u4VHZ7by+Ow2Hl/YwYOz27h7aivfvnuEO2cP8+HunTRqDMSaB+AxzoyAsbbIproRP9uD6AkW6OY40ewd8zcBMH+RM/mLnCld7kmVqQ+lSz0oWOhK3gI3MmZ7oBlvQ/EyMdtlaVytbuStsnTOF8VxOk/Nm2lazmTncjo/m1N5mZzKy+RETvow+D1fH81KGXYGD6cncyQ9gyPpWRxOy+RQagZvpKTzRko6+3TJ7ElIYld8IttiNWxVqtkWo2arTM2gJJbNkQo2hEazLjiabn8pXX4SOn2ltLhH0OAUQq2ND13eofT6hLBDKuegRs1hrYa9SjlbI8Po8QmgydGTkmW21Jh70RsQyo31+Tx+o57vjzXxh3PN/HS+kaenavjxQiPfX2jmh0ud/HCxlx8v9fH4nR4evtvFoyvNPL7YwDfn6/jxRA0/vFHBg4F8PijTcCkzhjab5eTNmE3CxKVIfr8I6SuLyZztQPGSoRZMVSs8qFruStVyV2qWDUWtmTt15h6stvCk2caXVjt/1joEDsGflQ+Nph40mbjTZOJO3fIXKeAXeqF/dR0T/roNzC1BEByFoTYwZ57Fcz1vA3NQEISlgiC4C0O9AP/pNjAduiz6MovoyS+lt7SKnpJKNlbUsiG7hE1phQwoM9kQmcS6QC1rXWNodgmlzklEubU7hqV2aCfbETPSkpiXzcg2tqFsni2ve/n+0wD4cE0Bj1ryedJWyMOOXO63ZfH1mgzuVKfw5So9t9ISuRkfx4eyaE7klnG+oZsbXYOsU+jIs3RjmzKTVdYBiMesIHisJYHj7BBNcMVvggeiV+3xHWmHzwhbvH9vjdfLVni9bIVidhC1vnlsiG1ivbKRfk0rDSEVVPoUUexmoD64nB5FC1uTe6gLKiDTRoN6sZiklRK0y8OJXxxKpnkcEiM/gka5EjrBm1L3bFrCqkmzSkC5SIJqiQzpa+Gk2upYn9ZLk3oNq8RFaG21yJbLCF8YQbxNIvLlseT6rCLZyUDYfDmVEfWsUbVSF9PI6rhOqlXtrEnbzMaKN+kt2Ut3/jaa9J10prWzNrWFtepqcpaGELfIB4VpML1FfVRrKoeKXn5nQfqicJolhRxq3E64pS+RU+1RGTmS9FogcXN8iZrsinyWD+JJToRNtCV8vCVJCzwptQlFP29oTnS0kQuaGd7DLuDz5s+S8Q5EG7mgNHYfGis40w3tQh8Us1yRTXUgZoYzcmMHFMaOww5g4gx39LO9SJzpTNYiN+KnWpC9RESpRRRZC/3Qz/QkfoozaiMb1EZWZCxwoXCliCYHP7qc/djgEcSBoHDeDAnnbHAop4OCOBsUPAyAl8NjuCRRciEymvORUs5HSn/l/D3/ezU+kZu6ZD7Rp/Jpcho3dcnDIPhRXMKvUsTPYfBGop5PktP4JC2LT9INfJabPzQvuKKQT6uL+LS2aNgB/KSzjFvra/hycz2fbmkcdgG/eL2Vz7e3/GpP4PO08Fc723l4oIVHbzTz5HArT95cy7fHunh6Yh0Pj/XwzenNPD07yLfnt/HD5Z38+PZO7pzt5fG7u3j89iE+P3WKE32DrMttIHSuG97jzImaZEPIy8tQjLeg1jmCKscQUl+zJWOhA9mLnChc7k7aTEvSZ1lRuMiFsmWeFMx3Imu2HXkL3NBPdSJmlBkFi4M4EJfPnY51XClN40JxPCeylZw06LlUWMzZwlzOFmZztjCb0/lZwzB4MjfjV87g8ew0jmanczgrkzeyDBzMzOJARib70zPYl5bO3tQ0diensDNJz9Z4LVvi4tmqjmeHWsf22AS2KuLZLNOwSaKhV6ygJySGnhAlawNiaPWR0uweSqdnAOtFgeyPlnNMq+GkLo43YqXskoSxwdePNkd3KldYs84rgiMJKXy5tZzvj7Xw86k2/nSpnf+60sbPF9bw08UmfrzUyo+Xu/jp8jp+uryOP17u4Y+XOvnPs838fGY1Px+v4w9HGri9aRXXG/PYKI6i0twH7Wg7VK/YIv0PC7Rj7THM8mK1ZTANVj7UW3jQautJo7kbq1e4ULPYkZrFzjRaiWi08aHZzo8OxyA6nUPocwujyyGIDlt/1pi4s2a5K40r3F6kgF/ohf4f0DHhbzeCfiQIwveCIGwXBGHiX9wzTRCEfcJQI+j7giDUCP+DRtAdydn0GYrpLSqnt6qW3qpa+uvWsLmwkq3ZZezQ5rNVkclgRCpd7kpa3cJpcPWj0taTnOUOwwAY/dJKDFOs/8cA+KhhCAC/aS/iydp8HrVnc68xcwgAi3R8lhzPTY2Gj+QxnC9bzfu9W/lkww7q/CLIWGFPk7eUvJXeRI5fiffvlhI0yRGvcc4EGnnjPcoO0Ss2eP/eGs+XLPH4nQUev7PA8yVLNPPDaAxeRZe0ll2p69ifs53NCb10RTexO3OQ3ZmDVPnlkWwWQ+wCMXozGdrl4cjm+JBsKqXILpnw8d54/9YW2bQg1se2sVHdQez8KAInehExPRCtiZLKoBIaYuowiDKRrZAQYxqDxkqDZKmUyMVSVOZaUpwNpLrkkOxkIMYkjkZ1G3XKJpqS1rE6sYfOwt3sbbtCfdpG1pftocOwgR5DN/0F69ie1UnqLC+CJ1hgM3IJ3aXrGagaRDbbn4hxLgT+hynFIh3dmWtIDU0kzHho2kbCawGoZvkOjRabE0DIRCdCJtgQOt4C7WvuFFsGkzh7aF50tJELcTNFw/Oi/x4ARk9zJm6+NzEzXZBNdUAx04XoqY4opzoRY2SPaoojSbM8SZkrQjfLBcNid+KMzcleIqLcSkr24oC/CYBFZj402vvS6eT7VwB4JjiYc8EhwwB4KSyai1EKzoXLOBsexbkICRcl8mHoe1epHl5/nJTCp8lpfJaS/lcA+L4q7u8C4KfpBj7NyOZWXgG3igv5vLKIz2qKuVmVzyfNJXzSWsr1tmI+7qngsw01wwD4+bOCkM+3twyvnzuCX7zeyq1tzTzY38yjA01/AYB9PD29gScnN/DwWB/3j67j8ZlBvr04yP0LfTx8Zyt3L+zg8btX+PL0Bd7beZwU1xhCZ7siMbIdAsAxZlTahVBq449ulgXJc61Jn2dLziIn0mZakjHbergKuGihC9lzHchb4EaSsSPyEabkLwrkUEIR97s3DQPgcYOCU9nJXC5axbmiPM4V5XC2MJszBQZO52dxOj/rVwD4PI7lZAwD4IGMTA5kZLIvLZ19aekcyMgchsDXE3Vs0yawPS6BHXFJvK7RsU2VwOboOPpl8fSGKekNU9ITGktnkJJ2/2havSLo8vBjg7cfB6PlnNSqOZ0Yx+FYKfukEWz296PT2Z06Uzu2BUZzISuX29sr+fFEG/95pgMud8DbHfznpaa/AsCfr6yHy91wsZM/nWnkv06t5g/H6vjDGy3c6i3h3ZpC6p1DSZnugnKkFwljgpD+xo5UIw9WLQyi1S6CZht/6i08qFlhQ/VSGyoX21C7xIk1y9xptvGlydaXFnt/1joF0+0ayjr3cPpcQulyCKJppSdNJu40m3qwxtTjBQC+0Au90D+tZwBYQH9OFZsLaulftZr+VavZUdXKtlUNvF5Yz7aMSjYkFtKjMtAarqEjUEKznTt1KxwpWWhPwhR75GNsEb9sinaCJSULXNjuEshR/3AuRsj5JD2Zz/KT+aI2jduN6dxpy+RO+9Dfu22Z3GvJ5l5LNl+3ZHC3OZV7rek86kjnQWsK99ekcL8+nc9KEvk4L5mzKhmn5FKu7+jlwaUj7EzNos7Bnz53Bb2uOsrNolG9FkCosRuicbZ4v2qF/6s2+I2wJGiUDQEjrPB92ZyAEVaEjLZDYuRGwvwQ9IvDSVoURuqyKPKdpKwOSqQ7JpeemCJaI3JJNolCuyiULEsNOVZ64udHI58aiWqenLjlciRzAtEsjaLKL4+NqmZW+xcQPMmd0GkiAqd5obaNpSWxmSJRNnFLpETPFSObE4p6sQzVYjnS16KQzpNSFlBJaWA1KfZZJDlkkudfTqW0iY6kjTQn9rE2s58NhTtoz1pPa1YfPYUDtGT30rNqgN2Nh/Gc5I3rGBf8p4loV9fwyZZLVIvTcBm5GNG4laRayqgLzuV6+0kyFooJ+//Yu++vqO+8//9+P9/vtdduNjFWiiIq9l4RqcNQh+kDQ5lhht4Z+tC7gArYQelVwF4Qjb13E0ti1sSe2GNsKZpscn3O/fsDCbu5drN7ZT/7+Y3HOY8jePgDbuf5er5e7z8sINpSSshIERFWSoLGKFAOFyIfshDFu3OJHO9GsUMAyVM8iRktJmq0F5GWot4J4CgPQkZ5oDUX4mcmQG3mhP9IIVpLN2IsBSSNdyVxspTIsb1/FzFRQeAoD/QWHmiG2xFh6ULaZE9iLR3ItVWTMcWRinluNNnJqV0gI2+0E4axYkJGeqIxEZA63YNSeymrF7izwdOXPT4hHFAFcFyt4bS3L1eCgrgcqOODwN5bvxdDojgTGMq5wBDOanScDwziYnAY1+MTuZ2U2jfZ+8XFj7hEbsXEcicunrsJCdyOj+dGXCyfxMbwaVws1xLiuJ6cwI2URG6mJfN5npF7+ek8LMnhflkuny/J4+6SXO4vL+LuqmI+W72Iz9eW8bCxkkcty3m8YQWPN6zgycaVPN60iodbV/NoexWPd1TzaGc1j3rW8ahnHY931/Bsdx0v9tTzcm8jrw4089XBFr460sbXx9fz9clOvjnVxbdnN/Lm/GbeXNjGywvbePHBTl5e7Ob55T08u7KPF5cP0p6fSZK7F94j56IaNg+NuROldsEUzvMnZbyI6BEOZEz0InOiJ0kjHUi1FLDKPoCVtmpKZohYbqvFOMEb/bs2GEY6EGs6gwtZedxauphrpdm8n5/C0dQYTuSmc3ZRPmdKcjlTksvpRTmcKs7mZFEWJwozOVGYydE8I0dy0zhRmMnJoiyO5KZzsrCAEwWFHM3N43B2DgcyMtmfnsF7qWnsSUlld3IKPUnJ7EpMYldCMlvjU9gan8KWuGQ2xyaxKSaRrsh4OiPi6AiPpVkfTr0mmBqVhnZNCFt0weyLDeBYkprTSWrOxWs5oPFmq0RNo70Hq+c7cCBcx6XiJO69V8aLE6v57v16vv+goe/fv9cfrmzm2wvtfHOmkh/OL+bHM6V8vaOU2zX5nM4xsnShigRLJwLenkvk8IUkmM+jfI4XVfY+VDuoWWPnzRo7b1baKFixQM5yaxkrFshZaaOgTuBFs6uY9SIVGyR+rPf0pt5Jwjo7L2odJKye78GyWS6smONGjcCnH4D96U9/fnMGDhgwgHUxWbSlLqIjawnbllSzo7KGPaub2LWsjt0VtbxXUs2OvOVsTl9Ce1wmbWFx1HrKWbHQneLpApLHuRNp5kLAoIUYTGwpneTCZifZrwLwSV0WT+ozeFKXxRd1WXxZk8uXNbk8rcnki3VGvqzN4GVDBs9r03i8IpHnazK5vySZ69kJvB8Xzo0MI//78jF+uHaOFUpfasVa1jkHsmROALGWnkRMUhI2xZvgiQp8TYR4D3YgYLiQQDM3NCYu+A5xQmPign6EB3GTfMiYF0zIKC+U79gi+f189GOEJMxWkL5QQ/hEEWHjvYiYqCBotLj36yAWSvSjVKTOiSXPMZU8tzSqApeyVlfOSvUikueEEGghQfSOPe7v2CE1d6PZ2Mj2sm3IzT2RDXEhaJwPwRP8iZoeRKJ1DLqJWjRWGiJnx5AvLmHZMF2HAAAgAElEQVRFYDWJjukkuWST4pZLvnIJZdqV1CS10Wjsoimrg2pjE61Fm9hc0U3nkm1sLNtBqXoxqtFKHP64kMh5AaxPXs3DnZfYnl2DfqIHhe7xZDhEcKf1PDsNawk1cyVqnAJ/EyEaCxEqM3d8zNxQDrNDNXg+kePdKFioxjBOSJi5G6Ejehs20p1gi59q6UHgKDc0o1zRjfEgeJwXBitXUid5YJgoJsRCSMBwJzQj3dCPFhFsKUJn5kj0WHcyp0tIsBISP9GV7KnOrLKR0OEoZ6O7hnULvYkd1XvZxHewHTGjHcmZ7kblbCHtLkp2KfXsU/hx1NufEwpvTqpUXNIGci0ylg+CQjmu1nJA4cshhZoLumCuRsb03ei9mZD8TwF4x2DoA+CncbFcj4/jk8T4XvylJnHLmPIPAXhn5U8IrC7lfn05D5oqedSxjEcdy3jc2YvBRxtX8njLap5sXcPDbWt4vKO6t91r+bKnlue763jxXgMv9zfx6kAzrw638tWxdr460dGLwDMbeH1uE6/Pb+Xrczt4+cFOXl3s5sXlHl5ceY8Xlw/w8sIJPtq8kQxXb/zH2KAdbU+RbSCLFmjJnq4k3tKZtHEeGEY6kDnOjbzJXqyw9aNivoKCya6UzFKSO12D/l0bYs1siTefxZ9KlnBvxTKuFmdwIS/5/wiAJwryOZ5f0AfAg5lZHMjI7IPgPmM6e9OMvJeaxnspRrYnpLE9IY1thtQ+CG6KSWRTTCIboxPoCI+lNTiS5oAQ2gJC2RwYwnvRARw2qDhuUHA6Vs0BjZIdChVdHmLa3D24kpPA/ZpCHh0o56vT1b+Kvr/u6/fbeHW6nudHS/jqSD4v92XxeUMml0qS6QmPINNKQOig2egHzsRgbkPuREdWL5RSK/ChxsmbGidvagU+VNsrWLlAzLJ5nqyxlVEr8KHZTU6bh4xOsQ9dYl/aPVTUO0lodFbQ6Kygxk7K2oUSau3l1Lv69QOwP/3pz2/OwAEDBlAXnUV7UhEd6WVsL6uiu7KWnpUN7FpWx55l9exdWsvO4tVszVtGR2o+HfEpNKv8qRLKWDLfg7TJXsSM8iBwqH0vACcK2egg4bji7wPwi/psvmjI5Iv6bJ7WZ/OsNo9ntXl9AHxWl8mrxkye16bxaHkCz9dk8mBpCp9mGbhoiOR+YT5cPs5/fXyOlqAIjqWVsDc8n3LbILRD7dGMFaEbJ0U3TorW1BXtEGdCRnkRNlpCyCgv9CM8CBnlRcRYGSkztRTYRxM70RutqSu+Q5yIniIn2yGIYrcooibLiJgoI2FWAOHjFYSMlaMdKUZnISd2ip6EWWEY5ocSPy+EmFk6Iqb4o7eU4W/miefbdogGOeI9WszWRZvZXdmDfrIfviPEBI3zIWRiAHGzwzDaJxI2PYSIGRFoxutIsEujMmA1ueJFJAuzSHBKJ80tlwLvJdQktNCY2kFbzgbWJjfQmtvF1vJumgs6e39PbidyXgQew12QjXQm3SWca21Hudl1inLvVKq1ReS7xnOmfBdXVu4lbbaGsAkKlCYCvM3dkAx1xtfCE19zAX4mtsRNElFo64thnJDwEe6EjXTv3fEb5UnYaBFho3u/FqIZ6UKAhQtaSzeCrER9AEycLCXM0pVAMyE6S09CrCSEW0kJsRBimCgmb46ydwo41oOiGZ7U2CvZKJCzQ6ylVehPwhg39MPtCRhsS5S5PZmTXKic7UK7i5IeVRAHvTWc8NVyUunDSZWKy4E6PgqN5JSfhgMyHw57B3DSL7Dv0sfPFz5uGJJ+FYC3Y+N6Gx/Prbg4bsbHcf2n/gzAW2nJ/xCAD1YU9wHwblUJ9+qWcr++nIdtFTxqr+RReyWPO5fzqGs5jzet6u2W1TzatobH26t4tL2KZz21POup5cV7DbzY1zsFfHmoha+OtfPqpyng16e7egF4bgvfntvB1xe6+eqDXby61MOLK7t5cWUfbz46w7OzR6mPTyPJTkzgRDuMM2Rkz1CRMUVGrIVT7xdYTBeSNd6doukyVtj6UT5PTskMEYvn+lAwS4f+XRuiTWxItJjLrYoV3F+5nA8LjZzPTeJoagwn8zI4U5z3mwF4LC+XY3n5HMnJ5UhOLoeysvv6MwZ/huC+tAx2JqWzI9HIjkQj2wypbDOksiUuua8bogx0hMf2fhJOE9YHwEPxSo7FyzkZreSwXsUubx82iyVsknvxyaJEnjQV8fTIcr45u44/X2zsg95f//zX/e6DFr46vY4Xh4r56kAOz3Yaub4qmdOZcWzy15MyciFhA2cROXwuGVYOLJ7pRo2DnEahD/UCFQ3O3jQKfah1VLDGxouV8z2ocZDT6u5Pl0TNBqkPm+T+bJT60yHyoUkop0HQ21p7GbX2chqcVNS79AOwP/3pz29PLwCDUmmLyaU9qYgN+ZVsXLSSLUuq2LS0iu0V6+hZXs/OJWvZVLKKzqIlbM4rYGNUDC1+wVR7+pM6TUL0GBG6YQ4kmtmzeKILWxykvwrApw05PG3M4mlDDl825PC8Lp/ndfk8q8vmy9oMntdn8XVzNi/r03m8IpFnqzO4vySZW3nJXE6M5m5uNpw7zJeHdrFC4s3GoATOZq+mTZuHfJA1boMW4PGuDeJBtgQPdSF8uDuRY2REj1cSaSUn1FJMpJWc2IneJM/QkDJTS9wkH0ItxQQMFxI8VkzSHC1ZduGEjpMSOMoDP1MXIieqiJvmR/IcHXHT/AgZKyVorAxfSxHu79ghH+5CwCgJoVYqoib5IRvijNrCi8DJPhT65rMmdjXF0hzCJvmjHO6OytSL2FmhZAlSiZsfQ5pDGuEzowicHErsgiRW6tay2GcZxZIykh0zSHfJYW1UPW2pXWwq2EqTsZWG1GZac9azImY1Oap8NmZtpj6mjgrNYpKdwslwjWBr5lrubj7H+TW7KPFKInaWP4tEyVxtOs6ewvWoRrujGO2Op6kALxMhKkvP3mmehYC0GQqWOGhJnuCGYZycuHEyYq2kRI8REzFWTPgYL0LHiNBZuhM42p0gKxGhEyTEj3UhdZIHqdOVxE7o/duYqT6EjpMSMU5G+Gg3kqbIKF7gS/Z0OelTfVk6U0WLox89Im/2KzRscFFSMM2z913AEUKihjmQOdaDZbPc6HT3YZ9fOCe1oZzXhXLeT8M5Pz/e9w/glI8/hxXeHFb68UFoNNcNKVyNjOl7B/DnHb5fA+CduHhuxcRyIyaGm7Gx3DLEc8MQz80EA9eTE7iVlsxtYwp3MtL+KQDvrCzi9uri3jcBaxbzuHEJj5qX8qh5KU9aK3jYVtE7DfzrieBPIHzavY4vd/UeBT/f24vAFwebeXmklZc/IfCrUz9NAc9s5fvTO/nubA9vzu/mq0u7+OpyDy+v7ObbPx3jh+sXeHLiKCdq6ynVBhFoMo/okQJiLZwJGjyPyOELiTFdSJyJDVnj3SmY4kHuBGcWTfekaLqMnGkBBL5jTeQwazLG2/GwqoZbSxdzMTeZczmJfQA8XZT7mwF4JCe7D39/3Z8BeDAzi/3pGb0ITMugJzWLXSmZ7ErJZGdSOjuT0n8BwE0xiWyIMtAVEseGoFh2BMewPy6Qowm+nEhQcipGwalIFXs1Cnp8JewNknJvZRIvOvL5+sza3uPdS019x78/XGr6uwD8r0uN/PlsNa8OFPBiVwYP2hO5kB3BvshQmtx9MJrbkTbCjqLprqxcKKHWUU6LUEWzs5J6BylNAgWtLt40Osmps5dQZy9hvbsvW2R6dvmHsMs/iJ2+QWyWa+gS+9LqpqLOUco6Oy9q7KQ0CrxpdfXrPwLuT3/68y9l4IABA1jhE01DiJHm2Fw6cpbSUVDJ5sVr2Li0im3Lati9qpHuylq2Lq1mc8VKdpQtZrMhgVZtGGvEAaRMFRM12hPdMAeSzB1YOtmNHQLFrwLwy8ZcvmzK5svGXJ415vKivoAX9QU8r8/hWV0mLxqy+bo5m1cNGTxZmcSXq9K5tziJz4qMXE6M5uPkRP58dDd3t3WwSOBBobUb28NzWCQIQTLEGrchNrgPXohskB1B7woIGSwk1NyTUEsxwRYiAs3cCLYQET5GinGOnoSpfqTM1JI4zZ/wMVK0I0VETPAmZoofgRae6EaJ8DURkjhbQ6ZtGNn2ERhm+hNi5UXYBDlyUyGiQY4oTd3wNnUn1EpF2vxwpIMFSIY6ox4rRTdXi1GSxmpdBWkLYwiZ4Nv3dmCidQxh00OInh1Nkl0qEXPiCJkRxWKfZVTpa1jhv5p0QTZJDkZWBlfRltLJ5rwttGd20JDcREtGK6tj1lDgU0SHsYst2ZtpjK+lSJ5GmXcadRGLaI0vZ19xG2WSFDSjPYmcoebYim7+1HUO0QgBPpMkuJsJkFp4IDET4msuQGPuQMo0GWV2ASSNdyVhvIK4cbK/3AIe5UGwhTtacyG+pk6/2AFMGOeGcYqIlGkKoseJCLX0JHyCnMBRHgSN8kRv7kTceBF5c5QYJ0nInq6lbKqMVgc/DisCOOarZ7ObiuIZnsRbOBA70pXIQXakj/KkfHrvEfBe37A+AJ5V+/c9A3NaHcBpfy3nAkO5GBbDn2ISfvG1j5/f9PtnALweHd0HwJsJBm4l9u7+3TamcCc9lbuZxn8KwNsrCrm1qojb1SV8Vl3K4/rFPGroheDjlnIetZTzeP0yHq//6Wj4p/3AJxtX8uWOtb0I7Knl2Xv1PN/bwPMDTbw43MKLo229CDzZwdenu/j29Bb+fHonfz7Tw/fndvP1xb8A8JtPjvL62gm+v3aRx0cPs3vZMnQjrIkdJSTWwhnN2zMJHTyfaBMbki0cKZwmpXCqJznjBSya7knBVAnpE33Q/HEekcOsyZ7kyKPqWq4tKuL97ETOZidwLC2WU/mZ/xIAD2dn/Q3+jubm/c30b2+akb2p6exOy2Z3WjY9qVl0J2fQnZzBpphENscm/WInsCskjs2hBnaFxXMoIYjjSf6cSvLmTLySU5EK9utk7NfJOBbjzYvGTP68cwmvz9fyw6Umfrzc/E8B+OMHtXx3ajnP92TxdGsad+pjOZqopztQR62jgqwRTmSPcWbpPBFrHeQ0CZW0CRU0O0mptxPR5CihTaigyVFCs5OUFoGMzeIAdiqD2OUfQrefnu0+OjZI/Gj3UNEklNPorKDWQUK9o4I2N386RYHUCX37Adif/vTnN2fggAEDWCzSU6NJpCEqi/asxbTnlbN58Ro2lVezfUUde6pb6FnZwLZlNexcvY6e5cvYmpxMqzaMVV7+JE31ItLSg8BhDiSbO1A52Z2dzsr/IwB+05LDq4YMvliV3HcJ5H5JJpcTo7kYG83z7g180l7PEjcJCePm0qKORzfSHvEQazxM7RGbOKIa5oR+oBPB7zihG+bStwPoN1TQtwNomOJLqKWY5BkajHP0xE70RjVEgL+ZJ/5m7j/97I7PMAF5TtEsFqVQKIwjbroPOkt3wibI8bHwQGHqhsLEFa+BDhhm6FihKED8riPOv7dGYuaK5yh3QmyCaTPUUy4vIMsxAekQN3zMJURMC0I7PgDtOC2ZLjkkOaQTPD2SbI9C6sKbWBtUS6ZzDgabJCo1K2hL6mBT9iY6czb0AXCtYR2lmsV0GLvoLtxJk6GOAmkKi32MFEvjCJ8ppTW2nHW6RfiOdMV7hJDuRR08PXwHFxM7fKcpcDUXIB/thetQexTD7fEzsSVxspjShX4kjHEmYbyib/oXOsKNQDMhWlPnv7sDmDTBg/SpXiRPlRMxxh2duQv60SJ8TZ0JMBUSMMyWyNGuZM2QkjzOk5xpgRRPENNs58dpv2BOa0PY6qGieIY7cSPtiRnhQtjbthjN3Vg8xYkWgYw9PiEcDwjmrDaY096+HJFKOSaVcc4/kEsh4XwYEcf7IVFcDInkWkx879t9P93u/TQu4f8qAB+uXNQHwJsrC7lVtYi7VSU8qivjcf1iHtcv5knTT5PAtkqetP20H9j1l4sivxWAP57cxQ+n/wqAV7p5eaWHF1f38eziPn749AN+vHaJGz3bCR1tR6KVBwlj3Aj44wyCBs4havgCDGa25E4SkTHWieQR1mSOdSDZwpEUKwUBb80lcpg1uVMEPKqu5cP8XC5kJfxbAHg4O+cX+Duam/erO4B7jDl9CPx5ErgxOuEXe4BdkfF0BseyNSyJ3RFJHEkK42SqP6eTVZw1qDgZIeeAXs7hEBXnkgP4vqsADiznzYU6frzc/AsA/ni5+e/vAZ6v4vWJcp7uSufhhkQ+rQ5nf1QAW3wDqLKRkj1SQL6VkOULvKhz6p32tTsraHaQUGfjQZO9mDaBnGYHCa1OMjpcVGyTaNmlDKZbHcQOdSBblBrWe3rT7CKjzlFMs4uKBoGcJmdvOkWBbJaF9O8A9qc//fmXMnDAgAFET/RikVM4VT7pNEUWsT5pMVtylrNjyRp6Vtaxv76FvfWN7Ktt4mR1M4dWrGJTRhobklJpDo6jYI4PBnN3gn83H6OJPWUThGx2U3FEqeGiLozPs4x8XpjKw5UZfFmb83cB+Kwhn2eteTxvK+RlayGvmgp5WVfA4+XpPFueyf3SZB4Wp/BxYjA3jZHcW7eOTVEJdIUbSZvlRuIUd1z/nwmoh9qjGGSP91AnfEycUQyxRzLQBuVgB3SjRASPkSB9ZyGaEe4kztISOVGFn6kLYePkP+34SVENEaAZ4dX3rWDZQEdip2pYIsqk2reUQuckYqdqSJwVRPqCcKImeSMdaINqqAMaCw+0oyUsU+UTOUOH27uOuA0UIB8hRjdZQ7GkkEKvfIrEBcTOi0Zt6Y23hZJ461hi5kZhWBBH9JxIQqcFk+aUSqJDEkXKRZT5LyXFPYOywEpa0jvpKtzO2qRm1hgaWJPYSHvxdhpzu9hQsoHNZV30VGwm1yuKhvACUqxV+JvZkGHjx72O9+mMWo3vKBdKfWN5duwy0dZK3IfMQ2UmRDpQgM5Cju8QJ3zenk/8BE/SZ7iTNMGJ8GHziRvhiHG8JxGm9sSOciXMxAHdMDsCBtsSOsqDoBGu6M1dSBgvJGWSC0mTRUSMdUFn5ohuhDO6Ec4EmQrQD7bGYCGgdJacwski8qxErJ4nodNdxclALcc1ARz21tLpFEiplYi4dxfi99ZMNCbWVC6QUW+vYKOnluP+4Rz30bHfxYNTcjkXvH24ERbOzYgorodF8aE2hI8C9VwPDedWRBS3o2K4ERXN9cgobsTEcMsQz+0EAzcM8XwS33vb92Z0b2/E9PZ6bAy3kxK5lZjA9eQEbqYmcduYwmdZ6dzJS+NuvpF7xVk8KMnhYXkBD8sL+GxxLp+X53OvooD7y4t4uHIRD1aX8LC+rK/36kv5vL6U+y1LedBazoOOyl8cAT/eXsXT7nU831PP0921PN1dy8tDLTw72MSzwy08P9LKi+O9CPzq1AZendrEmwvdfPf+Lr45383rD97jz1cO8ebKYb77+Djff3yK1x8e5+Wlw5xfu4XqgBwiJ3sROtIRv7dnEWNiR5y5HamWzqSPdSdhlDOJY91JmyAlwUpGyFAbokzmkTfNgRdNjVwtyuFsejQnM6I4kRHDyfw0ThdncaLI+Ks9mp/CkbxkThQZOVmczpHcVI7lZ3IsL/tveiQnk8PZGRzKSudgppEDGWkcyOidAO4x5rDHmNM3Bdwan9K3D/hzuw1JdEeFsj82hPNpEXyQHsrldD2XU324mKzgYLiAY9HuXMrx48ctFXCohldX2nh9tZNvP+rgq4tNfHOxkdeXm/nxais/ftTIny/V8P3FdXz3wVpeXijl6Yl8Hrdnc3d5OpfTDXSJ/Vm5UELZPDF50z1ZPFtCq6OGDmctHZ4aah2l1DhIaHFV0uIio1EgptNNQZe7nC2eKrplvuxR+rHbR0u3UsNmsS8tLjKahVKaXRTUOclocFbQKgqgTRzIeqmeek9NPwD705/+/OYMHDBgAPpRzmRba6kQG6gPy6c9sYwNGeXsWLKG3avq2V/fwr6GJvbXNXOmtp0ja6rYnpvFVmMm7RFJFC/wJ8nSi9C3bEg1sadkgjOb3P89AHyyIoPnK7K4X5rM45I0bqZHcS/XwDcbNtAVHsf+jCUscQ0gaaoHASZ2+A5zQP6uXS8ChwtQDXNEPtgO2UBb9JZeBI0W4z3UiYgJSvIcYwi1kqEe7kyolYxQKxnBYyT4mbqhGyXFZ5grfqYeKAYJSJodzBJRJmt8FpG+IJLgMQpS5oZSIDCQNFODaqgD3sMcCTB3Q2XiQr5LIka7OFTmIrwGuyA18UQzzpds10xS7JNIsU8i3zOXxIUGAidoCJ0WTMTMMFIdkom3jiV0WjCpjilEzI0k0zObpQEV5EjzKdNUUBPfSH1yK0tDV1ERvoZVcXV0Fu+go2grO1d0817Vbo7UvEdNVCmdiZUkW/ugGmaNr5ktnzQc5+q6Y3iPdCFPFsrjgxfIE0ciNl2IZIg9snedCTATox7siPcf5xFj5UbqVBcSxjkQbbaQhFHOpE8QEWFqT/xod6JHCgkycUA71J7w0SJCLNwJHulGvJWAxPECYq1cCB8jJHSUC4Hmgj4A6gbNJ36kEyUzZRRO9CDL0oW1C6RsEftyRq/lhMaPYz4aNgl1lE/wInGIPQFvzybQxJrFc0RUW3vRLlSzXxHIYUUARzwlXAoI4GqgjlsRkdyKjObT0Egu+ev5WB/M9dBwbob3/v/1yKh/CMBbMbHcionlZmxvb8TF/ioAb+emcicvjc+LMrm/KJsHS/P/IQAf1JX29WcAPmqv5GFbBffXV3C/cxmPNq7kyebeCyFPu9fxbHcdX/TU8HR3LS8ONv8qAF+e3MibC928udDdB8DvLx/k9eVDfPfxcX64dobvPz7Ft1dP8PzoBxxa2kKxVxiBZjZoh84jZNA8YkwcSDR3JmWUEMMIJ+ItnUkaKyJ1khL9oPlEm86nwlbMF7U1XM7L4FRqBMeNERxPj+ZEXiqnijJ/MwCP5mVwNDfrb/pbAPjf8bfNkMrO+ET2xUVx1BDRB8BLRh0fpHjzQaqSI7FunEgU82Gxju+3V/K/D9fw1YftvL7ayeurnXx9qZlvLzXx5koLP3zUwg8fNvTh78371Tw7W8LTI4V81mDkWrGBE5FB1NqJqJzrQelsESWzxay0UdLuFECnwJ8WFzUNzgqaXFS0e/jQ6iqnUSBmg4eKrRI1u+QB7PUJZJ+Phu0yNVslaro8VDQ5S2gUiGkSymlyUdHi5kO7WMt6qZ4OWRD1Im0/APvTn/785gwcMGAAfia2JE9XUeQcxrqgbNoSSmlPKWXn0ireW9PI/voW9jc2c6ixjdP16zlSvZbtBTlsycymIyaVMnsdyVZSwt62JdnEjqJxTnS5K/8tAPxiZSavVufyoCyFh8Up3EyP4rPsODh/nvfScmjVJ5JrIyXHWkXoaFd8hzkgG2iL/F07VMOc8B7uhHKoA6ohjuhGiQgwd8PfzJWUuXoqpZnoLb3wGSYgeIyE4DESgkaL0Y4UETxGga+JO/5mnngPdSF9QSTLZHms9SsjcVYQ6uFuJMzUs8g5kYTp/qgHO+D9rh1+w52RDbQnZW4wJaIsYmYG4Wchx/WPDnibSyn0yidxoYHwGaEUSwpZJC3CsCAOvzFqQqcFUyDKI12QRtTsCJJsEwibEUqaUypL/copVpVQHriM6qgaSvyXUqAuZVnYGqoMDXQUbGN94RZ2Vx/kYN0hTjQdpT2tipa4pYROFqEaboPnH2ewJ7eDW22X0U9RkOaq4Xb3MdaE5CIf6YDrW/OQDhTgO9wT9WBHlH+YQ+RoIcmTnUkY50DsCDuSRruQMdGL0GELibN0I8bCBf1wezRD7Aiz9CR4pBtBI1xJmuhK2hQ3YsYKCR8jJGKMO1ozJ0JHuxM20hX9YGtizR3In+xJ9hhnciycabCT0y3z55xOw6kAX457B7DdVc/yyWLShtsR+PZ0dCZzKZvhypp5nrQKvNkj8eegzI8zCh8+0um4FhTMnajoXuiFRXFFE8y14FCuh4ZzIyyCG+GR/xSAP98CvhUX13cL+J8B8LPCDO4vyub+kjweLM3/VQDeq1nE/doS7teWcK++lHsNZTzpWM6j9krutZfz+foKHm5YwRdb1vBw62q+2Nn7HMwXPTV80VPzDwH44sQGXp/fyevzO/n63E6+fX9PHwDfXD3GD9fO8OMnZ/n+kzP8+aM/8enW/bQmF6A2m4Pf0LmEDLVB/858Yk0FJI0QEj5kHtFmNiRZuZEyXo7/WzOJMplHjYc/n69ayYXMFI4nhXI0NYzj6dEcz03hZGHGbwZg70WQzL/b/ykAf34a5q+fh9kRl8D++GiOGiI4kxzKuRQ951M0nE9Wci5JxjGDJ6fTlXxcHsb3u1bw47FavvqwnTcfd/Hm465fBeCb96t5faGKZ6cW8/RQMbfXpPJBehjv+fuwcqaAillCSmd5ULFAzjpHHzqc1LQ7eFNrJ6ZRqKTVXU27h0/fBHCTyIedigD2qYM44BfEPh8NGz3ldLnLaRNKaXDyosHJiyahnDYPX9aL/OmU6emUB9MpD+4HYH/6059/KQMHDBiActA8wixdMUyXs1geS014DnUxueyqWMv+tS3sr2/hYHMrx9q6ONXYweGadWwvyWdbfj6dCRmUu4WTOkmJbuBCogbNI8PShiZHEYdU/54J4LdrC3m81Mjd3Hg+TgzmYpQ/T5ubOV5QRo06kkJ7JTviFiN/ezbyd6yRv2uH91An/Mxd8R7uhHywHQHmbmhGuOM91InYqb7kOkRT4paEerhz3/GwdqQHgRa9u39Bo+X4mXqgGyXFz9SDzIXRNOgq6Yxai9E6AuVgZ8LH+5BtE0nsWAW+A+1Q/H4+foOdEP/OmhALCYtdM6iU5JNjl4joLUekg9xY5b+MHLcsgqfoCZ8RSr5nLktUZQRP0RM1O4IK9VIqfcvJ98wlXZBGoJU/QRO0xEGb2hQAACAASURBVM+NJsPZSHVwFU0xjWR75VKhW87GnC2sDK+mImglBf6L2bj8Pbaveo/T68+xpbCd5qTVuLw9E8nQhbi9PQ/fMVKWqBZR4V9Ekos/77dsZ29ZKwETPHD4f6cjeccJ1WBX/Ic54/3HeYSPEpA0SUDSBCeizRZiHO9JzlQZunfnEWHmRJiJA5rBNvgOXEDQCFcCTZ3RmggwThNRaueLYYI7+hH2hFm6oh8pJGailFgrMfrB1kSZ2GIc7UTSsHmUjHdjk4sPB1R+nPGXc8ZXwRm1mm63QKqmisg0sUX3h0kEDJxE2QxX1tlI2OChYb8ikCNKDR8FBnNZo+FqoK7vCPhmRAzXw2J6j4NDw/k0JIxPQsL4NCLyHwLwTlw8d+LiuR3f21uG+F8F4M3sZG7lpHC3IJ3PizK5tziX+0vyfhWAd6sL+WxtEZ+vK+4D4K9NAB9s+ekYeFcNj7vX8rh7Lc/2N/4qAJ8f7+Kbs9v59twOXp3Zztfne3hzcT/fXjrIN1cO893Vk/z5T6f5/pMzvL5xnu9vXeLe8QPE23siHjQZ77dmo3l7AYkWYrLHy4gaMp/4kQvInykjeKgdqv9vMtGm89kaaOBKYQHvZ6VyNCGY48YITmXFcbow/V86Aj6cY+Rwdsbf9LcAsDv5L8/D/Pw24LaoOHZHhrI/Qs/JeD1nk3V8YNRxOVfDBzm+nC/y58Nl4dxpMfL6YBXfnqzlm6sdfH9tI9/9aQPfXmnlzZUWvv+oje+vNPH95bo+/H17fg2vTi7jy71LuFIUzUG9ik0urlRNd2TNHHdWzPWk2lFJs1DNBgc56xeKWT1PSLOrN+2efrS5e9PurmS9h4rtsgB6vAPZpw6iR+HPdi8FrQIPWpw8aXTwpN5RRJOzhHYPH7okWjZIA+mSB9EhC2K9VE+NW/8OYH/605/fnoEDBgxA+vYsAk0dCB3rSo6LnuWaZNZGZNJTuY6DNW3sr2/hUEsbx9s3cLp1A0cb6+leuoidixaxMS2XJW7hJE9Won3HhtB3ZpFkPpcaO7d/CwAfVKTyTXUBX1Rk8Hl+Ap+khHEhXM3WkBB2JWVwMKucCo9ANkUUEWLpgvgPc1AMssfP1AXtKE9UwxyRDLTBe6hTH/DSF4SSviCU+On+qIY4ohhkj3akBwHmbmhHeuAzTNgHv6DRcvzNPDFaR7DWr4z28DVk2EShGiJEbykjdXYQSZN80Q11xuctGwKHChH/x3wCTdxJmxVGqdBIiXM6IWPU+JlKKREXkuueTey8aPzH+pK40ECJrJh0QRrJdokskhZRoV7KElUZS+Ql5AgzSFlgIHxqMInWcSwPWMa60LVkeWSzTLeCHYXdVEWuo0K3nDzfUtZX7KazvJuT6y/Qkl5HbdwKfEa7ojR3xvXt+YhN3EhxTKQro5UsSQgXmrdxumo7ITPkCH8/B/kgId5D3NCauqJ+x5rwUQKSJzuTOllI7Ag7sqdIKZ6jJmiwNRFmToQOtydwqC3+gxYSYuGO3twFnZmQeCsBixb6ED/eDf9h1ujNnYiwEvV2lDu6QfOJMrEl00pImpkNlVO92OqhZr9SzSm1F6fVUs6p1exyCaB6ijtZwxag/Q8r/P5oRck0IetsJGwSBXJAqeOwIoArGj1XtFquBur4NCSU62ERXA+L4pOQqN5pYGg4nwSHci049J8C8G68gbvxBu4Yens7wfAPAXgzO5k7+UY+K8zg87Ic7i3O/VUA3qkq6EPgzwD8tR3A+5tX8nh7FV90r+PRzp8eh97X8KsAfHask2/Obuebs9v7APj6g318e+kgX18+xLdXjvH6w+O8/vgkr26c4M1n5/nq2mlWRRrQTbJH9dZc9EMciTV1J3mkGzHDFmAwn0eqlQD/P85F/Z/TMFjYsicinUv5eXxcnMuxxBBOpEdyNjeBc4uyOFuS85sBeCg7jUNZ6X/T3wrA7uSMvwHgrvBgDoTrOJ0QzMX0UK7mhnNjSSS3lkXzaVUsd5rSeLSlkG+OVPPq+Fq+/biT769t5PtrG3n9YRvffdjK9x+18d3lRr67VNuHv2/OrebZkQoed5dwxhjETm8RbXaO1M1ypdZGQrWNlHWOCpqdlXTae9Fu48laG3faPf3oFGvo9PJjk9SfbcpAdsg1dCs19Cg0bPFUsMFFRLOjG00O7jTYe9Dg5EWLi4xOL78+AHbK9KyX6mkTB1Ltou4HYH/605/fnIEDBgzA/T/monzbHvVgB5JmeVPiEUlNcBZ7K+s5WNXIgdY29ne0sbe9jcNN7eyrW8fuFcXsKM1lY5aRSlkECVNl+P1xPgG/n0XI2zOpcZBxyFvN1fBg7mYmcjvPwMOVWTxcnckX9Xl82ZTNs+Ycnjdn8rwhjWf1qTyrN/KsMZPnTVk8b8nlWXMOT2qyebwmnUcVKTwsiOez9HA+jdPQJhLTE57IhcIqosYuIG2OFNngeXgMnId8uBMKEwHyYY6ohjmiNnXue84lYoKSmClqgkaLUQ93xtdEiM8wAZoR7gRaePZOCQc5oR7igp+ZJ5IhAkSDHEl2jGGZppQtGe0ET/RBNsSZUCsVSdO0lDjHEmElwn+4Pd6DbVEOsUc5xB7JwIUohwuJnallubqYHOdkwib5UOiWTL5LIl6DHAmd7EuKbQwZziksUZUQMSucRIcUaiLrKVUvpTJ4FUs0FSQ7paAZH8Bi2SIWeRWQ5pRKhXYZ7RkbWBlfx5qUZjaW91Aev5Kdq/bQvbyHMr8ixMOFxMzSETbJF/G7jmjGyDDax3B7+0fUpJdxZuMuzqzfT5RAh9OQBfiMFOM9zB3Ff1qjGWhDygQv8md5kTBiPgVTPCibqyRriheh5gJCR7gRZO6O7xAnfIc4EjrChVATRyJGCEixtGPRLC/iLB0INV1I1Bg3vActINBMiHqwHUFmDoRbOBE10pbU0bZUWbuyydmTbjcvjnlJOKNUctHXn26BJ63zXVk8ZgEhf5hO1DA7Vs2X0GgrYZObmhNqPef89VxW+3EzWM/NIB3XdVo+0ev4RBfEpyFh3I6M4FZEODfCQrkeGsInwUF8EhzE3ego7kRFcicqks9jY7gfH8fDBAO346K5Ex/DnYRY7ibGcTcpnrupCXyWlsjdjGQ+y0zhbkYyN40J3M5I4k5mMp9lp/J53k8ILMrk85Lsvmng/fICHlYW8XB5MfeqSrlfXcaDtYt5VFfOo/oK7tUt5UFDBQ/bVvC0q4qnXVU87ljNw41VPNhczcNt63i0s5bH3XU87mng6b4Wnh5s48tD7Tw70sGLY128PL6BV6e28OZCN6/P7/wbAH5z5TBvPjrBd1dP8uZPp/juzjGeXd3DN1ePcGtbD3XB6Uj+1wzChrij+08noge5ov8PawymTgT+YQ76QQ5o3plEpaOYQ4lx/GlxOrcqczieGMPJtFTO5WRxviSbc2VGzpZk9GKwOJMzRRmcLkznVIGR47kpHM9N4UReKifyUjmZn8bJ/HQOZqVyMNPYB7+fJ4C94Pvb7jOm0GNMYrfRyC5jJtuT09kUY2BrdBzd0TEcjIno/d6vTs2BYC3HIkO4kpPA1RIDny5P5l5bJo825fGgO49He4v54kg537xfw5tLDfzwURs/fvhzW/jxo2Z+/KiZ7y+u4/X7q/n2wgq+OlvJ82NlfLstnSc1MewKVNHiIaV6oYzV8xU0CPxoFPZ+zaPRRc5aWzlrF0hpd1aw0a33sscuhZpuHzW71L7sVGvY5h3IJpmWZhd/6hy9WWsrYq2tBzW2nrQ4Keh0UbNdFkKnh5YOr0BaZcE0KkKpkQezVBTQD8D+9Kc/vzkDBwwYgMfv5qF6xwGfQfYYpisocg2jWpfOnvJaDqxp4GBbOwe71rO/Yz1HmtdzoKGWfWvK6F6cz8YsI0u8QoibJMb3rXlo35pD2MDZ1DjIOKjy4aOwoD4APlqVzcPVmTxtyOd5Sy4vWvN42ZrNi0bjTwjsBeCL5uxfAPBJVQaPK1N5WBDP5xkRfBqnYYNcyZbAKHpi8shdIKHQMQD3P0xDNMgalZkQlZkQxU/7f97DndCMcCd4jISICUoiJijRW3rhZ+qCn6kL6uHOaEa4900B1UOc8Rvmhr+5CMkQAV6DnTAKDVSFVLI9uxP9eBWSQU7oLWUYJvuzSBBD+FhP1EMWInt7PorBdiiH2ONr5oJyuJCQCSqWyHMp8crGMEdPqVc6Re4peA60RztWTszsYOKtoyiW5BO/II5kpzRWBVWx2K+CpbrlLA4oJ8sjm7AZoZSIC8lzzSLZPolsr1xqDU20F2ylvXg721fupzx+JVuXdbN16XbKtaWoLERox8qJnBpA8HhvdOOUxMzScWvbh2xf1siFre9xqm0vQTZq7AbORfCfC1AMdkH+u/loBtqQPF5E7gxP4s3mUjzdi8qFfuTPlBNs6kiIuSvBIzwIGC4kYLgz4RZuhJsJiBzpTPIYR4pniokZaU/QMGvCRwnxGWxD+FhPdGYCIiyExFgKiR1lT4aVA1XWruz0lHNA5s1xsZTjEgknJTJ2OYtos3ZjyVibPgCutpbSZCftA+D5gCAuq/34JFDDJ9oAPvb35aMAf64GaPlYF8TN8DBuhodxIyy0D4HXQ0N+AcDPYqK5FxfLA0P83wDwTmJcHwDvpCdxNyOZO+lJ/zYAPmio4GFjJQ9al/OkYzVfdK75vw7Ab24c4uW1fXz36Um+PHyMnpzliP/XVMKGuqL/gyNxw9zR/W4escPsCfzDHAIH2qEdOJnlAimHk+J/AcBTxjTO52b/jwD4M/7+gsBeAP736d9vAeC2JOMvALg/KowD4Tre06k5EqnntCGCq4tS+LQyhTtr03myMY8n2wt4sqeIJ/tLeH60km8/qOW7y4388FHbX/WXAPzuwmrenF/BN2cqeXa0lBcbUri3OoqtvhIahGKqF8qoWqCiQaCmUej9EwCl1NgrqVkoZ71QySZ3BVtF3n0A7PH1Y4dPAFtVWjZKNTQJ/ahz9GadnRfr7DyptRPRKlDS5erLNmkwG0Q6OsU6miV66mXB1MiDqZAE9gOwP/3pz2/OwAEDBiD6/fw+AMZOkZLrpGeFXxK7Fq9l36o6DrWv5/DGTg5t6OJoSweHmxs4tK6c3eVFbMwyUuSiIdLKHfUf5qJ/Zz6Rg+dR4yDjgNKbD0P13MlI6APgozVZPGsq5GVbPq/aC/iqPZdXzRm8bErneUN6HwBftObxvCWXL2pz+gD4qNDA5xkRXI/XslnlQ7u3nlbfWDqCjdT5p+L1zizEQ2xQj3RDPdINlWnvMzCKIfb4m7kSPl5B5EQVQaPFBFp4/rTv54qvibBvR9DfzBX/4a4EmHjgby5COtQZ2XAX8ryMtBhq2JW/Ce1YOaJ37PE38yTKSkWxUzQRViJ8Btvg9fvZyAfZojYRoB3liWyIEyoTFzKd4in2zKTQLZlVvsWUy3NQmbkTNMEbw/xwdBP9yXBOJUOYTpowg8Xqcso1yykNKKfYp5QCaSFx1rEUeeaR6ZRGurORRKdkVoZX0738INuW7Wfbin2sy2pk2/JdbFmyjbVRq9BPVuM1yJGoaRpSbSLRj1ehHSvn1rYPOdW+i3Obd3O0cRfqGWJs35nD/AHTkA4UIP/dfLTvLiRlghc50z2IGT6LstkyqoXBlC3wQz/cniBTIaEWIvyGCvAb6kToCBdChjsQbu5E6jgX8mZICTOzRTNkPsHmTvgOtSV2kowwS3fix7phGOtM0lh78icLWLfQg71yX46rNRzzkrDf1ZW9AiG7XcSst/FgqdXCPgBW2chptpf9AoAf+gX0AfBPAX5c1QTwsSaQj3VBffD7GYK3IsK5FRHeB8DbkRHcjY7i89gY7sXFcjsuuheBCbG9/RcA+NmirL7j4HtL83lQUciDZUV8vqakD4EPa5fysK6cR03LeNS0jHvNlTxsW8Hj9at40rnm3wbAby4e4OvLh3j94XHefHSC1x+f5Pm1vXx94wh/vn2W/7ryIddat6N8azq6d23R/Kc18WYeaH43l7BBCwh8ax7+by1AP3gaq12VHEtN7APgyeQ4Tqcb/0cA/O/4663xV4+A96en/t3uTUtmV1oiPWlpdKdlsC3JyObYBLbFxLMzKpo9YUHsDdGwN9iX04kRvJ8Vx83lmXy2LpuHLfm86C7l5Z4Snh0o4/mRpbw4uYI3F+t6j3mvtvXu/P0KAL87v4JvTlfw4nAJDxsMfFoaQofEnVpHD9YulFBn70ODk5JGZxnNrmKaXCTUOyqpt1exwcWbzR5Ktnn50KP0ZZfalx5fP7Z7+7NZEUCX2J9GZ1/qHL2psRdT6+BFvYOYdqE3G9z82CYNZpM4iE6xjgaRlhqxjnWyIJbLg/oB2J/+9Oc3Z+CAAQPw+oM1Pu864TPInvBxHqQt8KVMFsWWwhX0VFZzqH09Rzdv4OjmTRxv6+J4ewtH65axp6KYDZlpZNmpCLYQoPrdLIIGWhM1ZD41DjL2yZVcCdFxJyOBO/kJPFmTy5PqHF60FPfib30hX6/P4+vWLL5qyeRFYwYvmrN51ZrLy7Z8XrTm8WV9Hk/XZvHFciOPixK4nxXFDUMgO/017I81sjU0nRtrN9MalI3W0hnvEQL8Rnnga+GOytQZ7+FOqE2d0Y70IGKCklArGX6mLmhGuBM0Woy/mSvq4c59+3/+Zq4EmnuiMfXEz8wThYkrAWNk1ESsZEfeBrrzNuI3SozXQAek7zgQaOpBvl04STN80I8UIn/HmoARrkROUuJr5oJ8qACViQu6cUq0Y5QEjpESMcWXqGn+yIe7oB4pInKGjgArHyJmhlCqKKFAWkyWRy7L9aspUpeR6pZOhlsmMfOiKfLMI98tmwxhOkXKRVRF19K1aCcdJTtZX7qd9tKNNOS2smXJNnpKt7NY9f+zd59fUaDZ3ve9z5meztoGxJxbW9scyVBkiipCQRWVgSpyzjmJCRTMIJKjCoiCOSvmnEObbe1sTh1nzvd5UcpMP3c753ZWzzt+a12rwl/wWfu69t6ZOH5shqy/C+qh7sgGCpH0deRq02nOrtvDyXXbWDOnDKchlsz4cAJO3axw+0SATzdLAvvZkTlJSvYkV8KMJ7FguhdlzkHkmylR9TTFt48tgUNEyI0E+PSyxq+vAG1PM/x6mxP3mQsJY8Sv4DcDWS8zlMY2qPtZoe5tRthAS6IHm5HzuS1FZiIaHDzZ4OLBJicRm61s2GJjw3aBHTtdPGm0FFEw0gL/D8YR2NOUFeYSqi3daXKQ0u6l5phcyyWlmpv+vtz00xqugX21XPP155ougKv+fh3we42928FB3AkJ7rgevhkYwK2gQG4HB3E9JJAboUHcCA/mZkQINyJCuBkTzq3YCG7ER3IzIYob8ZFcjQt/IwBvz0zm9iwDAu/MTedefhZ352dxe/FM7izJ5e6y2Xy1Yh5fleTxTUUBX5cv4E55Pl9WzOer6sI/tQL49MQ2npzawfMze3l5rp0XF/bz4Mount8+yJMr7fz98hk4d5F8kRavbp/h3GUg/j3N8PzvMag+nob2EzM8/jKZ4P7TqHBXczglgXO5sVyek8Dh+EiOpiRzIjOd47PT/iUAX5/X+GtPj2Vf2j+6gF/D758rfX90tsRF0xYXSVtsLK1xiTRHxrEmOJyWkHDagkNo0yrZ4ivnULSO03MjubAklm9X5fBDy0weteXyfNdcXu7P59mBBbw4tISXR5bxy6lyfjlXzdPLNTy/VMOLizX8dKGKny8YAPjbyWJ+PbaEnw7M5+mOXL5dl8zZHF/2B3uz0syKEhNHKiw8qLb2oNLaiUobAVUCW6oFTtQJ5DQIFLQ4K1nvKqVN7MNmiQ8bpTI2yXxocvOi3kXyatWbhJWWEkqtxJTbiKkSuLPa0YcmJwXNQg2NQi31LipKHHwoclZSLNay1EvfCcDOdKYzb53fAdC7uwW6YQ7ETfNmlmsAjZkFbJi/jJ01texpXMWexjXsr13N3uoKdhXns2FeFg2JsaRZeOE30AaPd8aj+nAyAZ9MpsTSja1id874qjoA+P2yDL4vSn9jBfBxRTKPq9J4Up3Ok9osHtdkdgDwh4WJfDcziq9Sg7keqaY9JIyLsxexITidg9nLyTCT4tZjKrJBdgb8vboClvW1RTXIqWPMi3qgMz597FD0c0A90BlvI5vfvQFU9ndE2ccRHyMHvIzs8ezjgO8ob1bFV7I+YzXNSbXIBgoR97BB+KEZPj1tSZikJH6SDwHDnJF0N0U9yImI8T7I+zvg3dcB9VAx+jE+SPu7IuxmjoeRAPlAFyR9HZH0dUT/uZKQyXr8xqiZKcphjlceKY7pFKgXM1e5gHiHJFIcUwmfHkamfSrptskETQpktvdcikJLqctuoX5WK6vmtbE0oYT5YYtYm7eOpvQGiv0L8ezjgIeRHcJulnj1c8KrnxOXV5/g4ob9XNl+gAUhWbgMs8b040k4f2KNe3dblD1sCBvsTO50JTmTRYQZTyJ/qidFtn7MmuqNtrcFuv4OBA9zQ9vfCU0/BwIHOXZcAceOdiNmjDu6QQ4o+tggM7JE1UeArJcJPt2nEdbfhJgB05k33pYKGwlrnCS02LvSYuPAFmsBe5ydOezmwV6xlGZrNxZ+ZtUBwJWW3tRYedDkIGWfRMVxhS9X1FquadVc06gMVUCVkssqDVd8/TsqfjcDAzqg9/ra9zUA/xmI14IDuB4SyPUwAwKvhwdzIzqMmzHhXI8zIPB6XARfxIa9EYC3cpK4PSuFO7NTufOqCvjPAPxy6SzuFc/l3op53CvN515pPnfK87lbabgK/qZu8X8EgC/O7uP5+XbuX9vHo1sHeXB5Dz9fPg5fnGdzxhz8hkxC+JcBaHpMwfOd0Si6TkPd3QL3/55E5FBz6qQ6jqUncyorknM50RxNjOZYagonszL+VwC+/n4gM/4V/mLYkxLDvsxk9qansDs1iZ3JCWxPjGNbQixb42P+8GyOjaI1NoK22FjWxybQFBHL6qAwWkLC2RASygZfFdt1Kk6nh3OlKJHr1Sk83DiHx1vn8nTHbJ7vncOLA3k8P1jAy8NL+fFoMX8/Xc1v5+t5cqWGJ1cMCHx58fcA/O3oEl7umcvDtnRu10VyLF7JLpWE0uk2VJgIqbP0otbSlRorO2qsraixtqLOxoFGOxXNDhpaXdS0iX3Y6K5gi5ecTTIfNsl8WCPypNbJgwqBGyUWnpRYeFJu406lrTu19hIanRU0OytpFmpY5aSi1klBqZOCElcNJe5+LJHoOgHYmc505q3TtUuXLji9OwWvboaH/K8rgK8B2Jq3hG2VVexcVceOhnr2165mZ/lKNhbmsHZmCnXx0cy0U6IfYof7X8YhfWcsfh+NZ6WVO1tEbpzWKjsA+MPyTO6vyHxjE8iTyhSeVKfztCaDp3XZPKk1dAffL07lh4WJfJ8bzVepwdyI0vBl3nweVzXR5BvPUrEOhfFklINsUA13RtLXFtce5gg/McV3mCuhY6WEjpF2vPd7PfJFZmyLR3cLPLpboOzviHaw0FAVNLLDu4ctHj0EePd3JmSihh3zNrA6oYrq8BX4DHJF2s8Z4YdmSLvb4DfQkfhJPoSMFCHtZYFmsDPRk5QoBjji0tUMDyMBkVP90X0mx+kjE1y6muEzwBnFEDGuPayRDhQx33sOvqNVJNsmUahaTI7bLPLkBawILyfXew6LNIvJcskkeno4QeN06MfryJXM7qgAVmQ0siSunLLMGmpmruLE6lOkChMo9i/Ed6QXsv4uuH5ihXSAC+697ThddYBDdRs50bIVpxFmKKd4IB0tRtTLDpcPLVB0t+4AYMZ4ZwJ7jGX2BBFzp3iSNMoJfX8BIUNdCRnujqynNdIelqiNLFF0nYaq+3SixngSMVpC2Ggv/IeJ8eljh7KvAE1fG/z6WBI7yIzYAVOYP86aWlsPagUi1juK2ews5rC7J2eVSq766zngqWC9nYTFY2zQfTiewJ6mlFnLqLOR/A6AV7V+3Nb7c1vnZ6gC+vtx49X2jy9DQ7gTEtxx5fsafK8B+M/vA6/rdVwN0nMtOIBroQYEXg8P5npUKDeiw34HwCsxoW8E4M3sRG7lGqqAt+ek8eW8DL7Mz+TWopx/VAGL5nC3eC63imZzZ8VcvqyYzze1i/i6ZiH3qgv/NAA+Ob6Vxye38+z0Hp6f2cuzc/v49spuvr++jye3DvM/t0/BF6d5vns3iyRK9EMmoTGegrTrRKQfT8P7QxM835lC4mg7mtShnMhM5XByEMdSgjmeHMuJ9DROZWf+rwB8/fs1APemRrM7OZr2rBT2ZaR2APA1/rbERf/h2RQTyfqYcFpjYlgXE09TRCwNASG0hISzMTSMzTot+0J13F6Yzv2WuTzcns/fji3l12OL+PlIAT8dyedp+yyeHsjj+cGF/HSkGM7U8z8X1vDwixoefmFA4ItLVfx0sZJfz1fy9xPF/HZ4MU83Z/NVQwznl2nZHyxls6cnlSaONFh50WQnp9LEjlorK2qsTKmxMqXe2o51jhraXHRsFPmyyUPJZk8VW70VbPaRs9lHToOLG1X2hlVvxWbulFh4UiHwoNrekwYnKWtd1bQI1TS5qKmy8abKXkaVSEuFh45ST13nFXBnOtOZfysGAH4wGfEH03H7cAaaPk7oh4iYYx9FS9IyNuaWsLPYMAR6W1kVe+pXs6uuks3L57BxwUxWpyUy005J0BB7vP46Ef1H0wn7ZCpLpzqywc2NgyopX6ZHci83mvuL43m2IoUnpck8rczgSXU2D2uy+aEim+/LswxjYOrTedSQwcP6ZB7UxvOoIo77xdH8UBjOt1khfJ0UyO1wLV8VzuJC3hzWaFMp8UghcpQCSTcH9CMlePY0wb3bVKQ9TQkb5k3USDlqYzu0A2yR9TJD3dcWdV97fHoZdgIrezugG+SOpq8QSVcB07tMxb2fBJGRCP3nShZ4+uufTwAAIABJREFUZ9GaUsH6pJUs9klDOdAR0ccm+A4UY/9fk/Hp40D4WB/8hopw/8Sc4M+8yLIOw3+YGPVAZxT9HNAMckE/wh2PrhbIe9ujGuCCZ08DMmX9XUkXxKMfrSZiSghz3eeSaJVIniyffPU8Cv0WEC+II8o0mmTLFKKnxaEc4UeMdRJl0bWsmtXC4pgiZocsZGlqDbXzWmku2EJVYh3VcTUsVBcSbx2DYy8HRANEOPZ25NzqK5xcdYk1uRvxnaanLGolOeIUXLvOQPzBFNSfTCd6oB1zJkiY/bkr8f3MyJ4oJmOciKRRjoQOsCBkoAWhg6zx62uOf39rfHqa4NvfhoAhDgQMF+A7yAL9cAdCx4oJ+VyMtKcp/v2tCRlgQ/wAC1IGmbFskpB6Mze2OohpF4o45ObBCS9vjntJOSaV0+6lpc1VztIJdvj9dQgRvadQa+tBs52IVic39nt6cVwm47JawS29mlt6Ndf0vlzV+3NZp+eyTs/N4OCOqt8/n9eVwf//uRLgzxeBOq6HBXEzIoSbkaFcjzKcqzFhXIs1VAKvJ0R2nJtJ0dxIjuZ6WizX02L/EIB38zL5Zn42Xy/I4ZuCmXy9KJd7S2Zxt2gOX5Xk8XVlAXcq5nOnYj73ahdyb3UhdxsLuLd2IV+tW8rX65fx9YYVfLelgu+313J/ZwMP9qzmSXsLT/ev4+mhtbw4up6Xx1p5cXwDz45t5OnRTR0VwKendvPs9B6ent3Ls1O7+fHMPn652M7PX+zlxcWdPD65nX2lhQSYzMBrwBSEH4xD2c0J2UcC3N6dROYEaw5GxvNFajwXkgK4kBHKoZkJHJ6Xxb7ZGRyZnc7xOUkcmpnAwdwkDsxMZH9OAu3Z8ezLiuPw7BQO5iZ1/N6XFcf+nAR2JEexMyWaPenx7EmPZ2dK3Ksr4PiOHcCbY+LZFB3H5qgENgUlsCk4mbbQZNZFpNAclURzZAzroqJYHxFEa4CM/bF+PKiey/OdxTw5sJJfT9Xx25lafj1dw4/Hy3h2uIinh5fw7IhhpMvPp4r5+XQ5P51r4scLjfx0aTU/XSznx4sr+Pn8cn47Ucivhwt43pbJ1xWRnJ/jQ6uHPeudXWmwdKTWzIE6MxdWW7lTby5ilaUba+3dWe/kQZtQTJvQlR0yGVu8pWyWSNkiUbJZpmaLzJ9ae28qBB6stHCnyNSNYjNPql2UVLkqqRGrqXX3pcZNS6VYS40kkBIXLYsdlJSIdVRIgsm36+wC7kxnOvP2+R0AxR9MR23siH6IiFxBOM0JS9iYW8KuFVWG7t+KGvY2rGF3fdUfAlDyzgT8P5hKaLcpLJni8B8F4O28LC7Nn8dyYSA5Jn7oBrjh3d0J32FueBmZ4d3LFGUfK8KGeRMxQobSSIC6nw3SnqYojW1Q9bFD1tMKz65meHWzQt3HBXkvB9w/tMKpqwOuvd2wfs+aNNtYKoIWsyamiNbkUoo1Oeg+dUP44XS0A0SIPjDD28iW4M+88B3iimcPS4I/8yLDMgS/oaJXm0UM3cW+Q1zx7GaJvLc96oFCwxVzT1uk/YQkmkcSOkFHnGkUs0SziDWLZYnvUlZGrKA4dDlRFpEETAgkeFwIfiP1KIb7EmWZQGlUDY1zWylOKqMgppiKWU2smr+BlsItJLgmk+2Zza4FO6iLriLWJpoomyiCTILYt/IQrQXbWBZdRppXNvtL9lGfWIVLdxPE3aaj7W1O7KcuzJ3hQ85YMTEDLEn73Jnkz5yIH2FHSH9zggeYEzzAkuAhtgQNsUfeyxRNXyv8BggI/cwZ3VBrfAcLCBrpTOhoEdp+AnT9DABMHGxB+lBzSqaKaLTyYLerF4fdPTkm8eaMj5zTPgpOylUdAFwy3hbde8OI7judSisRq62dWecg4qCXlFMKBVd9Dfi7qVN1APCKPuDfBuDVIH3HFfB/AoBfLzDMBry7OPdPAeCT9haeHGzm+ZF1/ysAn5zZ0wHAny/s46cre3hxcSdPTu3gXHMliS7OiHuPw+ndMUg/sEX83ya4vTuJnMm2HIpK4EpKHBeSAjifHsKhmQkcycvuAOCx2YlvBOChWckczE3qwN++rDjas+P/DQDG0xacQFtoIi3hyTRHJLI2PJp1EZGsC9WxIVDKoQR/nq7K58WeEp4dKuO30/X8/Vw9fztbx08nyv8QgL+cLeen82v48eJqfrrUwE8Xy3l5oZifzi3jlyPz+WnfPB40JnJzWRDH0z1YJ7ZnnZOQegsHas0cqDV1ZpWlG3VmrjRYiGm2c2Odo3sHALd5e7NVKmOrtw9bJEo2eivZ6KX9HQCLzdxZYS6hRqiiWqT6QwCWuvqxzFlDqXsA5Z5BzLGWdgKwM53pzFvHMAbm/Um4vjcV0fvTUPV2wH+QkJQZ/jRELaA1u4i9pbUcqFtDe/0a9q1qZE9DNVuL57G5cBZr0pOY46QlZJgjkncmoH5nAgEfjKdwguA/CsBDUQFcXpBH1AhrPN+fhOQjK3x6CdEMEaEd4oB+uDNBI4T49RGi7GGPTw8rFMaWeHabhk8vS+RGNki6meHTywZ5LzvkvRyQ9bBD0lWA48f22H7sgGc/T7ZktdCSVE1l0AJWRS4m3yMe7VAhju9ORtXXBa/uAty6WaAa4IRmkAvqgc6EfS4jfqovyv6O+A8ToxrghPDD6Xj1skbyiRUKYwd8h4hRDxIj6+OExNgJ/WgVYRP1BHzuR9CEIBTDFKQ6pbEyYgUVMWVkiTLRjw9AM1xL0NhQgiZGkGCXxsrIalbPXkd5Rg0V2XU05q9jw+LNtM5vQzlOhmqsjNXJNawIXkKgiT8LAwtpmbeO/dWHWL+4lcrsKg5U7+PJiR/YW7wFq4/H4dh9AtI+MwgfIyRlmjeBgyzQ9JpM7DBroodYEzPUhsghNoQOsiSovwUxo12J+kyEytgCbT9r/AYICBlmj26AFUpjM3z726AfbE/QYAGhg6yJHGRJ1ghL5o+zZq2jF9vd5ByVKjkjV3JOqeaCSs15lYYzKi3tXlrWOnqx8HNrwj4ZQ+pwG0rNnGmwdGSdg4jDUh9OK5Vc9VVzw1/JDX9lBwC/CAjki4DAtwbgm66A/wwAfp2fxb38LL6an829why+XDTzrQH47eZyvt1azffb67i/exWP9jbzeN9aHh9o4tnhFl4cXc+zo608OdLGkyMbeXJ8K49ObOPJyV08ObmLx6d38+zUbl6e3suP5/bw4+XdvLy0ixfn9vDj2QM0Z2dh9e4gBP9nBO5/scC2yzjc3p3EIoEnx+JSuJAQ1QHAI7OSOJqfQ/ucTA7PSuPorIQ3AvD1f6+HQe/NjGVfVtxbAXBTdByt4TGsD41lfWgs60LiaAmOZl1IGGsD9TT5y9kUIePUrDD+vm0Fvx6u5OcTNXChES6tgQur+OVUJc+PFPP86DKeH13Gy+PL+PVMCb+eq+DlhTpeXqrl5eUqXpwv4vmZJfx4ahE/7cvj6YZMbi0K4lSyN7v9rGlxtqHZ3qkDgDUmTtSaCqkxcaHWVMhqayFNtq60CcVsFInZ5OHBdh85O3yUbHT3oVkkYbWThGpbCeU27oZuYSsvym18DEOexWpq3TTUuGmpFmsod1VT5aGnwk1PqXsAZR6BrBD5kzFd1AnAznSmM28dwyDo9yYifHcKru9NRWlkj99AFxKnaqmLyGdd5jL2ldVxsL6R/Q2NtK9uYu+qGratyGPLwtk0ZiQzX6Qn/FMXvP46EfU7E9C/P+4/DsDtOjkX8uYQM1KA5IPJ+HS3Q2ksRj9Sgv5TIYGfCgkc7oL8E1s83jN7IwDVfR1QGTsi7W6LpKs1Hh9Z4/ixPcpPNWQ4ZLAxvYlCWQ7L1TMp080h0cIXaR8BLh9MQ2HshOgDM9y6WeDTxw7tYCEBn3oQPtaHiHFyfPrY4TdUhGqAE87vT8X9E3O8uluj7OOI/zB3/IdLUPQX4t7LnoAxaiKnBKEYIkU7SovPEB8CJgcyX5NHSXgxhaoCwqaFoxyiImJyNEk2GWSKZlEaVUNN1hpK06qozKpjy9It7CrZxebCDeSrcomxDWVNSjVFwQvxm6IkTzePxnlNNM5vYsuyNhpmVrBrWRtHyrexInQuQqMpiHtPwaefKVHjxCROlaDta/I7AMYNtyXuUwcihtoQ1N+CyJHORIwUoulrhW6QHYFDHdEYm6MxMsPX2BL//jboBgjQ9TEleriAhKGWzB5tTtE0AVvcpOyXKjkmU3FGruSsQsU5hQGDJ+Uq9nqqWS1wY/4ocyJ7jiNzlD0Vlq6ssXGhzdmdw1IfTsrlXFDIuO6n4Lqf4ncAvBoY9NYAvBYc8DsAXgsL+tMA+FVeJvdeIfBeYQ53Fua8NQC/2VTGN1uq+G5bLT/sauDhniYe7W3m0f5Gnh5ay/Mj63h6ZD1PjrTx+PAGHh/bwqMT23h8YidPTu7i0aldPD+9hxen9vDyrAF/Ly8Z9gX/cuEwR8pKEXwwFNv/+hT3v1jg3GUKbu9OokSo5ERCGmdjw7mQFMC5tGCOzk7uAOCh3FSO5Ma/EYCvf+/JiOk4ezNj3xqALZFRtIRHsy40inWBEbQEhtIaEESLzpcmPyk74pRcKIiBvWX8dqSKX0/VwcUmuNzYAcAXR1fw4thyXhxbzo8nlvPrmRJ+O1/+D/xdKuf5ueU8P7WQH48X8vOuuTxZm871uf6civFkt8KaFidbmu2dWGXlRL2FE7Wmzh34qzUVssrKhSZbVzaJPdji7sFmT0+2yXzYLlPQKvJmtbMbdXZuVAk8KbN2o9TSg3IbKVV2SurFWmrdNNS5a6lx01IlUlMmVFEu9qNM5M9KNz0rRP4sdVKTNlXYCcDOdKYzb52uXbp0wf7dCQjfnYLw3SkoetnhN9CFhCkaasPzWJe5jL2ltR0A3L+mmX2razsA2JSZwiLPEGLGuCF7f0oHABdOtP2PAnCz1psTOZkkjXVCY2SJto8Q/0HeBI+R4T/cGf+hjvgNssf7IyvE78xA0csGZR8rvLrPQG5khaK3AO/uFiiN7VAY2eP+oQXi983w+Mga3Wg/slxmslK3kuXqBQRPVFLgncpSRQahE72Q9hHg/ok58t6OCN8zQdLTBpmxLf7DxESMkxMxTk7QKAkyY9uOmYPCD6cj+tgE7x42qPo6oR/hSdBnPqgHiRH3sCVgjJp40wgUQ6RoRmrQjNQQMDmQPNVclgUtYZn/UhJtktAM1xIxOZrZbvOZ7TWfsuhaylPrKEmpoDqngd1F29iysI11uatYP3MVBepc1mbVURFbRJxzBFWZlaxf2kZNbg0FAVmkugYyWxJJiqM/yuE2ePWZjnaoDf5DrEie7En6dCn6vmYE9jP9HQATRjkRPsQafR9TwoY7EDbCGU1fK/SD7Qke7oy6uwm+Pc3QGVuh62eDrp8NAX3NSBntSNpIK+aPNaPc3J7dUhlHFEpOyP8BwDM+ck5KfTgmlbNTLKfWwoXZQ6cR1Ws8OWOcqLQS0SgQslHoyRGZnJNyOWdlXlzV+nDNV85VnZZrATquBgZxPTjkrQF4PSSQ6yGBXAs1nKuhgX8aAO+9+rybl8ndgmxuF2a/NQC/3ljaAcDvd9Z3APBh+xqeHGzm2eEWnh5Zz+PDrTw61Majo5t5eHwrj47v4PGJnTw8ubMDgC/O7OLFxZ28vLSLXy4f4MXpdu5u2YzIaCz2fxmF+L/McH/HDPf3JlMt0XE6OZNTUSGcT9RzLi2YY3NSODZ/ZgcAD8+MeyMAX3/fkxHD7vRodqdHvzUAN8TE0RwVSVNEJGvDIlgfEMp6fTBt/n6s81Wy1s+LfWl+XF2eyP/sW8mvx6r/AcBLa/if8w38dKKcl8dKeHFsOS+PF/HjieX8dnYlv12s4MWVKl5eKePlpVKenV7M8xOFvDyygJdbZ/OwPplrmVpOhXqyTypgvbMdLY4G5K22FtJg4UqtqZB6cxH15iJWWwtpthOx1cOLnd7SjivgLV4yWlw8aXAUUWsrptLGowOAlbY+1DioaXDzpc5dS72HbwcAS12UlLioKXHRstxFyxJHFQUCGenTXDsB2JnOdOatYwDgX8fj8tfJuPx1MvKetvgOcCZxqpba8DxaMpayu6Sa9ppV7K1dxYHGtbSvqWN7ST5bF82hOSuVFYoYkidJUXU1QfvuJAI/nPAffwO4M0DJ7rhoUsa7EDZMSMAgD+InBqEfKUFqbIFXTxPDe78e9ih72P/LJhCVsSM+Pe1R9nYiYIgXVUEVlAVVkuGQgWdfZ2SDXWiMLabQO5k4UzXRk1WGd329HZH1skfZ3xl5X3uCRklINtETOV6BdrAQaW9Bx4YRr17WiD42QdpTgLqfM4EjvQgfp8Z3qAeun9jg9LE1cSbh+I5UIR0kRTlcSbY4h6q4CuZr8likWUhlaBXF6hUsV66g0GcZeT4LKY2qoTS5hvKMGprz1zJHkYF6ohcRVjpq41fQmFzOhtlr2LpgHW35zdw9dI+tlTvJ0qSgHSPA/i8D8O4xDte/DsPtvREUCPyIG+VMWD9L0j93I320OwHdphPd35rIQeaE9TcjarAVMcPt0PeZgfzj8YQNdyB0uBPK3ub49rdBN8iOiCFOhA2wx6+XOb69zAnqZ0PGODG5k13JHWfL0inmNNg6cFjpw0m1knMaLRc1vlxQazkrV3BKJueYVM4WZy9WTrEho+84onqNJ3esC0XT7Kg1s2O9o5jjChVn1WouqxV8oZFxVevTAcBrQcHcCAl9awDeCA3iRmiQAX8hAXwREvCnAfDu3PSO718uyPq3APjVhpV8vbmSb7fW8N2OOh7sbuThniYe7DN0Aj89tJYnh9fx6NB6Hh5s5eGRTTw4toWHx7bz6PiO3wHw+emdPDu/nZeXdvHbF4d4cHg73LpJ0ARHnN4dg12XiXi9b4X7e5NpUkdwLi2H4+GBnE/UczY1iONzUzm+IJf2OZkcnJnCoZzYNwLw9efu9Gh2pUWxKy2KPRkxbwXAtthYVseE0hgVRnNYCOt0QbT66dmgVdOmldOm8+L4nCBuVqTyYvdyfjlawS8na+G8AX+/nanlxdGV/Hh85Sv8FfPTySL+dq6Uv10q59kXZTy/UszzS0U8Pb2QZ8fyeXkwn/urk7hbFM6lWAWn/dw5ILFno9CJNqGY9U4etDh40CTwoMFCTKONJ2usPWgUiFjn6M5umYL9KjW7FQo2e3mzXuTOGnsRdfZCam3FVFi7U2olpszKk2p7BfXOvqxy96Pew7cDgJWuKlY6K1hqJ2OpnZz51t7MNfdgtqkbWSZunQDsTGc689bp2qVLF2zfm4DDXydh/85EPLtZIjO2JWaKmorIeTTnLGdt4TI2l5Szt66W9toK9lSVs624iHXzC6hLy2GBTwAJ011R9hqL8p2RBH0wgcKR9rQ4CtkjdedWShhf5kTyXWEMj5Yl8HBFAg9WJnO/LI0fKjO4X5nD/eqZfFubzve1KfxQk8LD6gQeVsfxfXEE3y4K5d78EL6aG8mXOZF8kRBAqzaMamkEc6zUBA5zIHiUCP1n3kRM8UNi7GTYZtHNAllPa3x6WKMbKHw1rsQKZV975H3t8eljh6ibKXbvT0Y5VIjfKA/0Y7xItwohZLQ3mkEuCP5rHL5DXGkMKyLdIpgMyxCCRknwHeKKop8D7p+Yo+zviLS3gPipvmTbhHfMHPTsYYm3kU0HBkUfG6qFmkFigkbJCB+rInSMAp8+Tkh62pIwLYA08zD8hnogM3ZEM9CdxMkhJE2LZLZLNoXyApaFrmRpeClV6Y3kagtYEllGeWI9NWmNbJq7lbmus4ieGkbIOD3FfkvZmNtGVVwFuxbtoGX2Wm5suc7Ooh2szmoiS5hH4OhoHN6zw/EDS8I+l5FuosCr6xgSxjiQNcGN+BF2hBqZkjjUgWBjM3y7TSa0rwVJI11I+cyVQCMT4oY5EDvUHn3P6UQOtCFumAOa3lb49rHFr7c5/r1MCO49g4wRlsweZcH80RZUTrWlydqFA95KTqr8OSZXckql4rRazWmlkhMKBcfkSra5yVkxXUBq/3FE9ZvM3CnuVFi6stramVYnN47I5JxVq7nur+WKWtpRAbzsp+WCr5+hChhomPn3etPH67Ewf4TCW0GB3Aj05WaQHzdD/LkVquNmmJ5rof6GE67jaqSea1EBXIsO5mZcGDfjIrgVH8mN+EhuJEZxIzGKO1mJvxsK/eWsVMOZl8HteencnpfOnfmZ3CnM5tuieXxXnMc3K/L4tnS+4ZQt4HZlHreq87m3ehHfNC7nh5YSfmir4NvWcr7dUM13G+v4fvNq7m9t5IftTTze28bj9g082b+Rxwc38fjQZsM5angD+Pjkdp6c2sHj0zt5fr6N5+fbeHZhC08u7uXppX28uLyL327s48XZbRQH6TD/r554d3PAqctEPLr0p1XmS3toIMdSgtkbr+LsnBjaU2I5mJXB+YL57JsZx7b0IPZkxbEvM/H/Oq+Btys1ll2psexMiWFHcjTb02MMJy321Ylne1oiW5MTaY2JoTUmhg1x8ayLimZtWBQbIxJYGxVPY0QsDaHhrAkKoU2jYo/ej4MhGk5m67lTlcrzQ8t5cbqCn8/X8feL1fxyegU/HlnEj4fm8+JAHj8eW8jPp4r59VwFv1yq428XGuBsA7+dqeTX0xX8cmIFzw8v4tmeAu5UxHN+bgBH9F4cVnpw0MuVTa5ObBAJaRO6sd7J0PW7ytKVFnsJa+08WWvvyjonV7Z4uLHdy5OtEhlbJEo2echpdvKkzs6NahtXqu3cqBC4UWYtotJOQo2jlFpXNQ0eehq9g6kS+VHqpKJSpGORjYwlAiWFAhXzzH3InS4hZUrnG8DOdKYzb59/CcCy8Dk05yynbWkJ28uraW+oZ39dJXurK9hRsoLWgoWsypxFWXACufYKgoeaou86gcju01n6ucsbAfi0LIXH5Wk8KE/n+4p0vivL5NuymdwpyeZuSTr3StL5ZkUK35Qk8O3SeL4piONuXgy3s2O5kRbL5ZhwNvnH0haUSa0qlcTJUvTDnRF1t0T7qQTvvi54GTkiM7ZHaWyH0sgWtbE90h5WyHpao3m1Bk7Z3xFpH1v0oyXMdk0gxTqEoHEylAMNV7birqaoBjgRN0VLrl0UsZM1zHaIIX6qLzJjW6S9BfgOcUXc1RR5X3sixsmJnqjCb6iI8LE+ePWyxq2bmaH5o6cVkp5WyIztkRk74j/Mk5DRcrx62eHWzQqZsSOJ0wNJMQ0h+DMf9CO88OrpgLSHM949XfEdoSRiRjgLA5ZTEltNaVI9KxPrKAxdwfLIcqpT19CU0Ux54CKWa+aR55lOvHUQcTaBpArDqIlbyoY5tRSFzWF1xgpOVO/hzobLHFqxhxWBeSzXz6I5sYjgCSJ8R9mTaKIgZbqaoBFCpF3N8O9jh85oBv69phM5xJbUsW7kW2iZZ6Ymepg9EYMFBPU1J3KILdHD7PHva41/XwHaHtPR9ZxCeJ/pzB5jR/4YKxaNtaLe1I4NdiKOSpWcVvlxXKH6HQBPKpUcV6hodfRg0XhTEnp/RnT/KcyeJKbOzpMWBzc2i7w4JldyRqXqqAC+fgN4xd+Xi37+XAsK/rcAeCPQl5sh/twM8edGqO6NALwaFcS16FBuxkVwMyGK2ymx3EmN43ZmArdfIfD2TMNquDu5KdyZm86tuWncmpvGnfmZ3C7I4t6SWXy1dLZhRVzx3H8MiK4t4G59Id80LeX7tSu4v24l9zdUvhGAj/a08mifAYGPDmzk0cFNPDq4icdHt/Lw1SzAxye38+jUDp6d3cTzc5t5em4bTy608+RCO88v7eb5xa38enkXexblEzLREuFfp+Hc5XNkXYayRR1Ie2ggR5ODaE/UcHpWFPtT4ziUncnpvLnsn5XAruywPw2A21KSaIuNpS02lg1x8ayPjqElPJoN4fE0R8bRGBHLqrAIGoND2ar3Z39wAEcj/LkwN4xvV+Xw8kgxz0+V89O5Wv52oYqfTxX/SwD+erGBv5+r5m+nS/nt1Ep+OrSYp7vyeLxhFlcKQzidruGgnyeHlBKOSL3Z7iFmk5uItQ4uNNm60CgQ0WzrYcCfnSctDiLWO4vY4uHGNokHmz282ejuQ6vImzX2btQIRFRauVBm5UKZtYgKgRu1TjJWuSqpclZQ7aqlRuTLSkclxXY+lDiqWe6gYpG1nHxLHwps1BTYqEma6NIJwM50pjNvnX8JwJKQXBqzlrKpqIydlbXsX9XAgfoq9tVUsnNlCRsXLWFN9hxWBsaRY+tDwKDpaN4bTfCHE5k/XPBGAD6vSONJRToPKzL4rjyNb0sz+HplNl+unMW9lTl8VZLDtysy+LYkjW8WJ/PNgiTuzkvgZkYiVxPjuRwTxe6wNHZEz6VRl0PKNDmBnwpx72WDVz9DV613bydkxvaGOX9Gtih6CfDubolPLxu0A507hkErBjgSMt6HbMdowierkPS1RTHAEbduZsiMbTu6ehOm+RE/1Zc5jrHET/Xt2CGsGeSC+yfmaAcLCRntjX6EO5pBLoSP9UHaW4BnD0t8+tghM7Z99SZQhKKfC0GjZESMU+P+iTWePQT4D/MkyzqKpBlBBI6UEvCpN6KPrFD0FiEzEiMf6IVunD/z/RZTElvNysQ6qjOayA9cxtLwUiqSGqiKraIhqoil6hxmu8URbqLAY6AFfuNdibVWs1CbQrqrnlxJGGszlrNn2WrqUgpoyS2mbXYZW+dVsViVSoFPIkXqbAq90kk2C0A72I3IMTJ8e00jeIAl6RM9yZkmY5F9IIsdggjqb4HO2AT/3jMI6m9B8ABL9H2tCOhjja7HNAJ6TiG63wwKxjuyaKwNReOtabZ0ZJujGyd8lJxRaTmpUHNareaMRsMZlQGDJ5RqWuzEFI6dQaLxaBKGmJA3zZNVjt60Onuy3cOHE0o1Z1QqLip9+EIj44a/kusBflzx9+VHdryXAAAgAElEQVSSv47rwSFvDcDrAVquB2i5EezHjWA/rof4vxGAVyIC+CIyuAOAX6bFczc9gVsZ8dx6hcBbOQYE3p6ZzO05BvzdnJPK7fwMbhdkGTqBF+caNoQsn204RXP4qq6Qew0L/58B+HD3eh7uNSDw4f4NPDywkYcHNvLoyBYevGoEeXRiGw9PbufpmU08O7uZJ2d38vj8fh6f38+zi7t4dmELf7+2hzPVJeQKpdh1+Rzx/5mA6i8j2KULpz00kCNJgexP0nIqN5KD6QkczsnixJxZHJyTxN7cyD8NgNtTk9kQF8eGuDg2xifQGhNLS3g0bWFxNEXEsiY8htXhkTSFhLEjKICDoUEci9TxxYJoHjTP4cejK3h+qpwfz9bw2/lKfjpZxMvDC3l5MP8NAKzjb+fK+eX0Cn49UcSLvfk83jiTB40ZXMr142isjAMaTw4pZByRydkhcWezu5gmOyfW2DjRKBDRYi+h2daDZlsP1jmKaRO6sdldzBYPNza5e9Eq8ja8/xO4UmUtpMLSmZUWTobqn607DUIFa8RqVrn7UefmT63Yj3IXDWXOasqFfhQ5qim0lDHPXMoiO1+WOPh3ArAznenMv5U3AjByooJl+kxWpS9ic3E5u6rqaG+o50B9Fe21VewuK2XzkmU05+ZREhBLtkCGbsBUVH8dRcB745g3xOqtAfh1xTy+rZjNd+WzuV+Ww/3yLL5ZnMx3hSl8lZ/E9bR4rsTHciU2mqOJc9ibsIA6dRqJk6WEjnZDPVSMqKcNHkYOeBk54m1ki9xIgNLIFnlPG6Q9rJAbCfAd5IJqgBOKfg7I+trhN9Kd6Om+aEaIce1hjnKgE95GNvgNFSHtLcBvqIh0i2DSzIPItYsiYpwc9UDDuz9pbwHyvvboR7ijH+GOvK89in4OBH/m1XHN7DvEFdUAJ2TGtmgGuaLo50LwZz6Efa7ErZsVkp62RE/0ZYEondjJ/mgGifEf5onwA4uOCqCsvyfa0RryfRdRGl9Lfc466rJbWBxRSmXyKmrSGimPKqchdgVzJUkkCgKJt/HHucdkhEZTMHtnOMrhNiRaK1AMtyTaXEKcrQfyMdOoS5jNqsQ8igPTaUwqoiV5BW2plTTHl1Lql89S+UxWhSwiY5qUQscgVvvlkG0iJ2a0C/oBFvj3M0NtNA3/fmboB1igH2CBro85AcbmBPaaRmjvqcQPNGHRRHuWTxBQNllAq8CZ3UJ3zsiVnFdpOKXUcEaj4axWy1m1AYMnVRrW2oooHDuD5L6fkz7KmkIzGWucZWx09WanRMFpjS/nNBouKAzv/274K7kR6M8XOj8u6/TcCAl9awBe02sMCAzy5UawH9eC/f5tAN7KTDC8B3yNwDkG/N2ck8qtvHRuLcjkzkLDOJjbi2dyZ9ksw1k+m6/rF/LVqkV807SU75qL+aGlhO9by/9XAD7c28rD/Rt48BqBhzcb3gC+Ggfz4MQ2np42nCdn9vDo7CEenzvMs4u7eH5xK3+/toerTdWUBYRh1WUYXu9Nwu/90bQHx9AeGsjhxAAOpvhxIiecQxmJHM7J4mhuDofnpbB/TsyfBsAdaSlsjI9nY3w8mxISaYuNY11EDK2hsb8DYHNoOLtCgjgUFszxKD03FsXzZH0+L48U8+xkWQcAfzyxnBeHCnlxIO+NAPztQgm/nFnGb8cX8+P2WTxsTuX7qjhOJys4EupBu1zCAR8fDsnU7JB4/iEAmwTuNNt6sN7JjQ2uBiRudhez0U1Ci4snjQ5iaq2cqbB0ptzCqQOA1faerBapaHLXssZTR52bP1XCV/hz0VDm4ssyeyUFFlLyLGQscfBnmZO+8wq4M53pzL+VNwIwaLSEPHkclfHz2FRUxvbyanZVV3GwoZoD9TXsq6xge9EK1s8toDwkkdmOKkKGmaH7eDwRn0xj8WinNwLw8cokHpamdFwB/1CRzfeVM/muZiY/1GRxvyaDR9WpPKpJ5ofiWB4VxXN/aQI3MkP5IjmYG8nhnM0qYEt4LvNstASPcCJ4lAjFICEexvbI+rsi6+OCt5Et6r4O6Ae5GhBoJEDVxx7NACd8+tjh1csaj56WePS2Rj7YGekAB+SDnQka7dWxG1jc1RTtYCHZNuEkzdCRNEOHbrgbmkEuKPs74tHdguDPvNANd0Pe1x7PHpZoBwsJGiVBPdAZmbFtRxOIR3cLXD8yxaePEwGfeuM7xB2ZsSPS3g5kWkVSpl6A/zBPHP46DZmxIwEjZDj+tynij+xRDZHh97kvufK8jjeAUcIUslX5VCavIl+3hCRhOtUR5dTHVJPvNZvl6gXkOCXg3ssG165miLuZUKmZR/RYH+TGpqgGTEIzaAKJ08R4fjIeqy6DEX00iZQZvqSYqEgxURI/w4syvyR2Z5dQ55fNQtcwiiSxxE90J3a8mOixrugGW6E0nk7YKEdCPrUncJgA1ScTCOg5ldgB5iQONiNrhCVLJwgonyKgzsSWnc5ijnhIuKSSc0VjAN9ZrZZzvgbQndFoOKXW0mDuwNxPJ5LUZwwzxzmwxErJKkdvNgi92CNVc0EXwGWdjstqBdd85YZh0EE6rgXouKIP4GZo2FsD8KpOzVWdmmuBWq4Farka5PtGAF6PCeFGbHgHAF+vhruRFsuN9DhuZsRzI8uAwJvZidyclcL1Wclcn5XMzXlp3Jyfwd3Fho0gXy41bAV5vSLubs0C7tQu4O6qhdxbtYSvVi/lXlPxGwF4f2cL93ev48Ge9dzf18r99jbut7fx4NAmfnjVCPLg2Bbuv7oOfnJyF49O7ufhmSM8PHOIJ+d38OzCFn65vI0fj27nWn09Zl36IvtoEqE9J3IiNo320EAOxus4kq7nWFYoR7KSOTIzmwOZ6Rybn87RBUl/GgB3pqeyKSGBTQkJbE5MYkNcPK1RcawPiaExPIY14TGsiYhibVgEu0KCOBASyJFwP24vTeLFxkIety/myfGVvDhdxS9ny3l5fBnPDxbwfP+8PwTgL5dq+Pn8En46XcCvR/N5tj6NH8oj+LowkNNhEg6oXdnt6c5eiQ/7JBo2i93YKHZlvbOIFgcRzXZurLEWs8ZaTJPAnQ1CTzaJPdnkJmKj2JU2kYeh+cPaiQpTO0rNHCg1c6DMyoUqOw/qnaWsEas7KoAVziqKBd4U2coocVCw3FbOAgsJC8y9KbBRstBWyyI7X2Zb+XQCsDOd6cxb540ADBjlwRxpNGUxs9m4vJRtZVXsrKrk0KoaDtTX0F5VyfaiFbTOK2RlYBwz7eQEDTHB/6NxhHeb+i8B+DZNIA9WRvOkJI6Hy+O4mR3E1ZRAbqaGciYzn9bADLJNZOiH2BEwwgVxDytkA4Wohnig6C9C2tsw0iZkuAeq3nYoehtAqBnghLS3AI/uFnj1tsHdyAoPYxvEvSyR9LUl0USH7xBX5H3tEXc1RTPIpeN9X/xUX3TD3QzXx/0c8OplTegYKb5DXPE2ssGzhyUBn3oQOkaKeqAznj0s8exhiehjE8RdTRF+aIJ6oIjQMQr8h3niP8wT9UARGZYRlKkXoB4owrLLOKS9HYibHIBnV3vkxu4EjvEjcGIAGZJc8nVLaJi5Hp1VBDnq+azKXkee/2LiHJOpCK9mT/5uqkIrKNcXU6EvwvkDc1T9xXh2s6ZUNofUqXp8+9jg+s5gAodMI3iIFS7/NQJZ16l4fzyD2HEyAoY7oO5vinevsaSZiyhVRRE03JakKRLq/XMoksSSa60lboIb2v5myHpO7sCf/yBL5B+PRdd9MgmDLUgfZkXuSGuWjLehYqot9aZ27BGKOSbx5rJa0QHAc76+nPfz47xW2wHAmhkCZg0bR7zRKHLG2rPIQk6Dg1cHAC/qA7mi13NFo+S6n+JPAeAX/ioDAgM0/ysA39QE8s8AvJ4Z/4cAvDE3lRv56W98A/hl9Xxu18znTn0BX9Yv4m7DYu6sXvbWALx/cCM/HNnE/aOb/wHAEzt5fGI3j04e4MGpox0AfHJuEz9d3AKXDvFkxw7Mu/TD6/2xhBtN5lR8Bu2hgRyI8+doRgBHM0M4mp3CkZnZtKencnxBBscKkv8jANySlNwBwHXB0awJi2ZNeAyNkdG0hEeyMziQ/cEBHA7z7QDgo32LfgfAF8eW8uzAAp61z30zAC8s4qfTBfxyJI9nLUl8vzKEu/n+nAr24IDClZ3u7uz2kLHbU8sGV9EfNoGsthL9IQBbXd1ZbedKjaUD5Sa2rDS1Z6WpPeXWQsPeXxcZa8RqVotUrJUGGd7/2fuw0lFJhVBLiaOaeSZuFFhIWWirplCgocBGTZ6tqhOAnelMZ946HZtAXg+C9u5mZbgqNRYw3yuG6ug5tC5YxpbiMnZVVtK+qox9DaVsL1/O9tIVtC4sZHlgJLNdlYSNMUfx/ghCuk+icIwjjQIR+2QyrsaFcjMjnIdLk3m0LIEHxfE8Kk/iYUUK96tT+aEyg+8q0/m+bib36zJ5UJvJ45o0Htem8KAknh+WRPPdomi+zI3iUkIAF2P8OT97OS0BM5k5Q46+vw1+fWzw+cQCeU8b/Ac64j/QHnU/K7x7TsK75zS8jCzw7GH56hrWpQNvMmNb5H3t0Q13I3CkJ4EjPZG/6hKW97VHNcAJ/Qh3Eqb5ET7Wh9AxUnTD3fAbKkIzyAXNIBd8+tjhbWSDt5ENPn3s0A13I2iUhKBREqS9DTMDJT2t8OhugUdXC3wHuvL/sXefwVGYyaL3qbrvuXuO1yYKRI4GmxyEhOIoa0ZhgkaTg0ZhJI1yzlkIgQhKKAdyBpNzzjkYbLBNjgYMxl6H3fWm//tBaNYc23eLc/d+U1d1SRqp9PlX3U93x05QI7fxJqinG8rBAeR5pFEpLSNifCimD00IewvRfmCgUFpCtn8eEdMiiZ1poTywhHL/YlrCGqhQzKU6vI5c5WwWJbSwIK6BIk0xtZYaVuQsY3X2ElZntmGeIkc+UIDMxpE2fRH18iz0Nq6EDfIkeVww6p5OaHo7onzPnvTJctInB5M0MYio0d4o+04na6aM1En+xI0SkDDGg7TxflR6GFkcEEOzNIGUD3yIGyUgzHYmpgF2mAbYYejlhqmXF8UfBDNvsoz5E/xY4SRilZMnGwXeHJJKOKmWc8ag4qxOy3lVONcjorhi0nPRrOV8ZChH9SaqpviTO9iZjEHOtHgbWBpkYLsoiGNSKZf0ej6NiOCT8HCumkzcMJu5YTbzeXQ0X8TEcNNi4bYllruWaO7FRFuBdyfKzJ0oM48T4q0gfGMtzOshkJ/n/djIX+S92Chux0dxO8HC3aQ47qYmcC8jifuZydzJSOJ2djJ3clK4W5DO47JcnpTnc7s8p7P9+7MhkHs1ne3fe3Vl3Hvd/r1fX86jtjk8bi/n6fJ5fLlqIc/WVPF0fR3Pt7TwfHsHz3Yu5fnu5Tzft5rn+9fx1cFNfHWkE3+vTnROAn97atcb3//h9G6+O7OHHy/u5ceLe/nu0gG+uXyEby4f4tXVHfzx8+18fWkt35/fyw/HTyDpZ4fqvYlkDhrO8XAdRyJ03CjL4VhuIucr8jlensupymKOludxfHYBJ8oKOFKQYc2jhZkcK8riWFEWJ0pyOFaUZcXfwdxUjhRksDsnkT25SVYA7slJZXd2Gvtys9mTnc3urCx2pGd0DoKkprEuKY4NybFsTrawO9HM/sRIDsRpOZyg5kSqls8XJvC8o5C/7avi76er+OncAv56YRE/XajmT+cW8c3xuXxzvJI/XWzg79c64LOV/OP6cv76aRvff1zFjxcX8ueTC/h2ZS6PFiVwJz+CswYZJ5USjioUHA3RcECuYp9cxd5gJTuCZGwRBbHBW8gqN09WC7xY6+HDZmEgW/3FfOQXwAYfKWs9tTTOFFNvJ6TFJZA29wDa3ANYIVKwIkDFarGRNRIzayTRtPoYrdnia6TZx0CTr4FqDxWLBAoWeampExpoCDAxz1vVDcDu6I7ueOvo2aNHD/zftUP8jgOS389C2dsdVT93dIO8mRecREdCGZsra9mxuJm9ra2/CsDGmGQqxAYSJrmh//044vrZWQF4RKnk81QLt/Pj/iUAn60o4asVBW+0gL9tz+bl4lSeVSdzrySB6xlmPs+I4m5VGzvjZlM2S4VluCcxQ73R9nZD08+DsGEiTEOFaAcJCLaxJ9jGAWmfzmlc7WBfjMP90QzyIcTG3Yq2xClaUqYbsIxXoOjvgWaQD7ohfqgHemMYJiJ1hpHYCUpiJyixjFcQ/YGc8NFiwkYFWQdCFP09rMufu5ZCawf7IuvjinKAJyE27gT3ciNqTDCpM0xIersjescJ3QgpFUFFpDjEki1IpyywDM0oDYrRalI90ykNKSfeKQGLQyw1uirmK+ZRETyH+YZFdKSvJF1aSKGhkhLTfHJleVToK2hLamFryQZ2zfmI+SF5RHwow+edaSxW5tGsKyakzyyMg7yIHR2E/Pf26Pq5YOjvRt5MLcnjxSSME2Ee7oGqzzQyp4lJHOeDZYQryeO8SXzfk7hRAnKniZkr0JM01ovYkW5vADC0jwuRfdyZPV7Kgiliqib5sspZxCZ3X7Z5+3FcHswZtZLzRh0X9UYuaEx8GhHB5VAdFyJ1nDEZOKg2UjnelyxbJzIGudLoqWFJkI5dgWJOyuVcNhi4HhnJJ+HhfBIezmdRUXwWFfUGADsXQXfC715MJwTvW2K4b4n5BQDvRJl/E4D3LBG/yLsW828C8G5mshWAd/LTeFSaw+PZedwuy7Yi8P68gt98A/igvpyHreU8apvNl8vm8mTlAp6uXsTT9XU829zMs23tPN2xhGe7lvFs7yqe7VvL8wMbeX54M18d2cLXx7db4fd/BuAhvrl0jG8uHePVx7v54+e7+eGT7Xx/fjd/u3CGxBkSJP97OHnDx3AsTMuJ6FBulOVwsiCFc3PyODEnj9PzSzhansexsnyOleRZwXesKIujhZlWDHYB8FBemjX/JwDcmJrI5tQEtqfGsz8lhsMp0RxJMHA0Xs3xJBXXZpt5uDiDP22t4KejlfzxeAV/PjmPP56s5Ifjc/n2yBy+PTGfP19q7ATgjRX8/dNl/OWTVn64vIgfLizgj8cr+XpZFg/mWbiZFcpZrYSTIWKOykM4GqzmQLCSPTIFu6UhVuSt9/JjtcCLla4erPXwYat/5xDIei8/VrqJ6JglpXaqiLrpvnS4S1nmI2W5r4xVASpWBWlYLTayMjCcFQERNHnqrNno1ZkN3joa/AzUemneAGClT3cLuDu6ozvePnr26NGDgPdmIn3XEem7joT0dEPRxw39YB/KxXG0WIr4aF4N22ob2dXU9KsAbI5NpVJmInmqB6ZeE0job8+iCX6s8wjksELB56kWbuXF8rI2i6/r0n8TgE+XF/N8eT5fLcvn66U5fL0six+W5fOqIZ2nVUncLY7nRmYUt7It3J7fyMGkcqq9TSSO9iZmiCemAd5obTwwDhViGOKH4nXVK7i/C+JejtbFzNrBvij6eyDr44p2sC+mkYGkzjBaAdg1uat/3SrWDPIhcYoW81gZ0R/IrQgMHy227gPsmvJV2XqhHyrEMExE8jQ9oSMCkPVxRWXrhaK/B8p+nljGKUidYcL/986I3nEiaoKOMlEeprEactwzqNHWkOWehfZ9HfqJRlI80igUF5Ppm02WKJcsUS5mx1iKNXNZU7yZstCFFOjnka8sJ9oxmmSPJMpCSlmfuZI95VvYkrOCUlE6iqHeLJRlUa8pQm7jgqKfC4ZBXgT8bhp6WwHhw3zIttMQP9YfyyhvIocK0PScStbkQOJHexA/youk932xDHfH0NcOy3B3MicGkTjGB8twd8IGzCLUxh5TfwcibFyI6e/G3EliqqYFUjPZizXOQrZ5idjt689xmYwzSgUX9Fou6fVc1IZyLczEJaOWCxEGTupN7JIamD3am/R+TmQNdmexIIT2QAX7pMGcUSr5ODTUCsBPIyL4IibGmjctFisAb0ebrQC8b4nhYVwsj+Lj3mgH/7xC+GsAvBsT/ou8ExP5mwC8l5XSib/XAHxYks2jslzulGZxtyyb++WdOwEfVHbuAnxQ1XkW7n7t62ngutk8bukE4JOlFVYAfrmulmebm3m6tY2nO5bwdOdSnu1dxdO9a3h+YCPPDn30BgC78pcA3P3PCuClk3xz6SSvruzn+0/38Kcbu/jD2e1w+Qw16jjE/3sgsz+YwFGThnMJZj4tyeJsSQanSrM4NbeAMwtKOV5RwPHZBRwvzedESQ7Hi7M5XpzNkYIMa+v3eHE2x4qyrCDs+nxPbhJ785LZn5/G/vw09uamsScn/VcBuC01jc2pSWxNTWBnajyHUiwcSY7mZJKJEwlajicouZBn4It5cbxcmcePu0v5cX8JfzpYxncHyvjD/lL+cHgO351YwJ8vNfKPT5bAjRX89ZOl/HSthR8uLeTHM5X88VAFL1vTuFMWyY0ULWc1Yk4GB3FMJueYTMUBSQh7JEp2Bin5yFfCBq/O84RrBEJWuviw1l3E9oAQtvnLWeXqS7uDD/VT/Fg4wZvaaT4s9w5htb+CtYEq1oq1rBZrWS02skwUyhK/UOoF6n+mh4YGTy31XlpaXk8CV3lrugHYHd3RHf9X8QsASv7LEfE7DmhsPcnxDKU6NIOP5tWwva6JnY2NvwrAjqQsqpRmshyERPWfRsogJxZN8GONwJ9DISHcSI7mZq6Fr6ozeFGT+psA/HJZEc+W5fF8aR4vl2Tzcmkmf+jI4UVdCk8WJnCnKI4bmVHczonlk4JyzmXOYYM6lcyxXkQOcCR3mh6tjSfawf6EDPRDbOOOv40Aia0nkj4u1qqebogfhmEiTCMDmeOXSoUwjdgJSvSvh0Pk/QTW6qBhmIiwUUHWil/EGIkVfrohfmgG+RA2KojQEQHW1TJda1+SpupInqa3DosoB3hiHOJPxEgJ4aOlKAb4YhwhIcMplkyXRCxTwgn7wIBluoUFigUYPjDibyNC8K47tVGNLM9eS5ayjMq4RhaltDPXUk91UhtL8tbRkb2GKnM9iQ6JRE8zEzU1klzvTOpDq9mSt4516ctpDF1AWWAmhX4pJNgZSHE0YpmiwPM/JqId4kHkGBHxYwOwjPbDPNiNqIGuGHvPIH9CIHGD3UgeG0DUEA8iBroRPdQT82B3wm1diR3hQ9QQD0JtnAi1ccLU35mEIS6kDnWiero/jfZ+tExzZ7OrDwf8gjgsDORkkITT0mDOq7RcUOu4rNNxJVTDBYOS82FhHJQbWOepImeAO5k27swZL6PBU0ZboIRjajWX9Ho+CQ/nemQkn0ZE8Hl0NHfi47kTH8/tuDhuxcZaAXgvNsb6BrDrHeDDuFhrJfC/568B8E502C/ydnTEbwLwQU4ad3NTuZubyp38NB4UZ/GwJPuNBdEPy/N4WJH/z9vAC4p5tKiEx1WlPKwu5WFTGQ9aSnm8ZA6PllfyZOUCnqyt4ctNjXy5pZUn29r5cscSvty9gi/3rObpvvU8PbiJZ4c+4sXRrbw8tu2NSuCvAvDiEb65eJ5vLlzg1eUTfH1pLz9c28MfL+/iLxcOcLV1KbkznWgRuHEsTMtneWlcLUznfFkW+zLjOFySyfGKAg6VZnOsLJ/jpfm/WQE8VpTF8eJsTpTkvFEN3Jefwv6CVA4WZnCwMIP9+RnWNTC/BsCtyYnsSE5gd3I8h5NiOJkYzfnUSC6khHIuScv5dDUf5xq5XmHiUVM0T5fE8mJNMk/XpPB0XRo/HJrDn08s4m9XmvnHJ0v4x40V/PGTDn682sSP5+bzw/E5/LCnlCc1sdzI1nIlSso5eQAngkQcC5BwNDCEg/4ydgao2CpUslYQxGrXAFa7BrBWEGQdAtnsG8IGTyntdp40THGn+kNvFk30oWGmiHUBOjbJ9HwUbGCdRMdqsZZVQQY6fPW0eumodVFQ56pksZuKBk9tZxXQR0+zv4kGPwN1QgP1/qEsFhkpcem+BNId3dEdbx89e/Togbj3LEJ6uyLv5YLs986drWAbAemuWhboUqwt4N+qAC5JzqZGHU2uUwCWgXakDXGxAvCgXM71pCi+yIn5lwB8srSQp0tzebYklxcdWbxYksHL5nSeVSfyaH4cd4riuJ5h5mZWDPcqFnIlZx6rZBYyRwuIG+zGHNcYdP29UA8SEWwrJLCfF34DPAiy9SawjzPawb4Yhokwj5WRNFVH1qwICgWxZNiHYRzu/88q3esBEWlvFyLGSIidoLRW/8xjZdb7vtrBvmgG+WAeK3vjXWBXSzhluoECNwvmsTJrtTF0aAChQwMwDg8k+kM1CVOMJNlFkuJgIWpiKJapZsLGhzFHMocM90wCBwQw6z8cSfRMY3FiO+sX7mX/0vM0F69nyezNVCW30Z61mtaMlcxWzyfHLZvEmfFETggncWYsNer51BkWsTJxCauSO6hUlVIqyaUkKJ1lCXXMl2fj/bvJKAe5ETFaSNy4QCyj/Yga5EaMrSsRfe0pmhBE3EBX4kcKiRzoTlh/V8yDPDAP8iDCVoBlmA/mQR6E9nMmtJ8zJhsXkke4kjF8FnV2QpodfGmb7s5WNy+OiWWcDJJwTiLjXHAIl9X6zvu/Bi2XQ0M4r5dzzhTOflkoq1yVZPb1IMfWh6oZWpp9gmkPCuSkXsMVo5FPIyK4HhnJ9chIvoiJ4W5CAncTEt4A4M3oGB4mxFnR11X1exBreaMd3JUPYi2/CsBfy1tR4b8JwIe56dzLS7MC8H5RJg+Ks7hXmGH9/lFZLg/L83g8r5AnrxH4eGFJZ1Z1AvB+cwmPOsp5uGwej1fM5/Gaap5sbODJ5hYeb23jyfYOnuxazpPdq/hy7zq+PLCRpz97C/jy2LZfB+Clnfx4cXcnAC9c4psLV3h16TTfXD7AD9f28Y8bB/nT2d18tXM7bWoNK0W+nIjQc6ckhyv5qZwrzWRHspmdWfHsLemN8pwAACAASURBVEhjV24yBwoyOVSQ9ZtvALsAeKosj5OluRwvzv4fAXBXagp7UpM5kJrEiZQ4zibHcinVzOXUMC6nGbmcoeVKpo7LeUqulSv4YqGGe80R3GmK5N4SC9/tLuGnk1X87Uozf//0nwD84eNGfjxTyfdHZvP9zmIeL4zm0zQll8ICOSMTcTJAyFF/MUdFwRwQSdnhr2aLn5LVroGsdPZnlUsA69wlbPKWs8lbzgZPGWvcgmid7kH9ZA/qJvpRO1VEi2MQG4IMVgCuCdKwKkjDykC9FYBd+KsXqGn00tHsY6BFGEq9r57FPjrq/UNpCDBR66cnd6awG4Dd0R3d8dbRs0ePHsj6OlvPpMnfc0X2nhMhfV1JcVJRqUliy/w6djW0sru5+VcBuDQlh1pNDPkuQcQOmkn6UFcWTfBjtZvo/xqAzxtSeLIwjoeVsVYAfpEZzdd1TVzLm0ebMJT0ka6kjPRmgVciuv4+KAb5I7X1Q9TPE7/+XgTZehPQq/NkW+iIAJKm6igUxDLPP4OoccGobL2sAyEqWy/UA72R9nYh8N1ZRH8gJ3mansj3pcRPUhPzYYh1BUxXOzn6AzlR44KJfF+KaWSgFYCpM4zM8UslYbKG4L5uGIaJCB0agH6QEMOwADIcosicFU30RD2G0QokNkIsU82oR6rJcs+iTDwbwzgdXu954trbk2ivFDbWHGBb83FmJzWxtekYjbmraU5bTk1sMymemWQ4pZM4I4HwcWHETouhXl/FAmUF69NXsbtsKytT2mizLGZJfD3nGg6wNrUBr/+cgszWmdCRviSOlxA7yo/oQW7E2rph7utAyQQxCQNdiRnqTYStwAq9CFsBUYM7319GDnR/A4BpI1zIGenIYnshbQ4+tM8QsE3gzRmZgrMyOReDFVxUqLimDeMTnYkrBjWXjHIrAPeKjSx3UpDeW0DeQCGLZ4XSJlTQLvbnlEFrbf925U2LhXuJidxLTLRWAbsA+DgpgccJ8da2b1fL9+dvArtQ+O8C4KO8jDcAeK8wgwfFWTwo+CcAH/8MgI/nFVqrgI8XlvBkUSkPG0r/HwNw738D4Fn+8PERfrx2EO6c4E9nd/LTycPsSE5ivcSfk5EG7s/O53JeCudKM9kSH8ampEi2ZcazOc3C7uwU9uV0vu3rau92oa+r/Xu8OJvTs/M5VZb3CwAeKsrkUFHmvwTgvswMDmSkcSQjlTNpiVxIS+ByipmrqeFcSzd14i9Dy7kMKWeyhHxcIubGIg3Xq3R83hDGq+0F/PVnAPz79eX8eK2dHz5u5IfT8/j+yGy+21HEw/lmPkkJ4YJBxDmZiFP+Qo6JxBwTBXPAT8IOoYrNvgpWuQSwwknESmd/1rlL2OKnZLOvgnXuElY6+9MyzZ36yR40TPGnfkYgbc4SNoqNbJLp2STTszpQzcpANSsCdL8KwCZvPS2+RlpFJmq9NNR5a2kMDKMxMIxaPz2Z07y7Adgd3dEdbx09e/TogfCdGQT9lz3idxyQ/d4Z2XtOyPu4kGAvp1QWzeqSeWyprmdnYyOHVyzhyMql7G9v5UB7K9tralmVWUhrRDIVfiqSRtiTNtSe+eMErHL24bAsuHNdRraFlwvTebkoma8Xp/KqJYNXrVm8an+9DqY1lxdLi3mxNJ+vl+bz7ZIc/rAki5f1KbyqTeFFVTIPiuK5lRnDF6lm7lXO44t5VSyXmUgdPYuc8X5Ue8cRMcgP02B/NDa+yHp2LllWDxRiHO5P6gwjWbMiiJ2gJHy0GONwf+tC566Wb1cVUNLLGXk/AXETVdbp4DS7UGInKFEP9LYueA4fLcYyXkHMhyHETlASN1FlrSYahomI/kBO/CQ1ke9LCR0RQLCtOxIbVwyjA6gJLmCuXyoJH6oJ6eOJ2tYfxVAx8uESjFMMLAxdSI4wgwQnMwH9PfF6ZxbRU/QoRgSiHRfMbF0ZhdpiWktWUl+8jNLISuKmhKMeJiNkoATlSA1hk6OpMbdQHdPCutlbWDNvA8vLV3BmzTHWFjQRbS8nZLgrihFuKIe6Ej1ORNgITxQ9ZxAx0I2k0SIShnoTN9QHw0BPjIO8CB3sjWmgByZbN8IHuBHa15FwG0ei+jsS2nM64X1nkDtGQOlYAfV2QpY5BbDBQ8J+PynHpQpOSpWcDdFyTmXkvD6CywYD1zRiLqolXDTo2SEz0+gop2isL5kjPZkzNYAGtxA2BKjYpdRy3qjjapiB6+YwbkSF81l0BPeS4rgVF82tuGjuJFi4k2DhbmIs95LiuB0fycPUWB6nx/M4PZ67iVHcjv/Zfd+f5S3L6/d90WGdyHt9FeTnP3e1hO/HRXM3MYY7ibHcS47nTko8d9MTOzPz9QRwbuf5wrsF6f/Mn52Ju1uWzd3y3M58PRn8cGFnK/h+XRGPmkp42j6Hx+0VPO6Yy/O1tTxeU8vjDY082dTCl1vaeLZjeWfuXcVX+9fw4sBavj68ma+PbOm8CnJsJ1+f2MOr0wf55swhvjl3mK/P7bMuhu66EfyHywf47spBfrh6mFcX9vLdlYM8P72DR5vb2W8O4UpiGF/kp3IuLZ7d8RaWqjUs04eyJtzMhsgYPoo081FkBFuiw9gRZ2ZXkoVdKbHsTo1jX1YSR4qzOFKcxeHiLA6VZnOoNJuDpbnsKchgb2E2B0ryOFCSx76iHPYWZrO3MJs9BVnsystge3Yq27JS2JmZwoGMFI5kpXAiJ52zuWmczUvicn4iV3Pj+Tg3mo8zw/g4w8TVNAOno+RcSNBwIdvIuYJQri2M45vdC/jpTCN/u9oKN5bA52387dNG/vZxNT+dyOfHfXl8syGdL4pMfByr4oIhhJPiYI6LQzgYIGeXUMYWnyA2+klY5yVmqYuQpc4iVgqCWCtUsspPxXLvEBqdAqmxFzJvkifzJgqotvOizT2IlUJF57JnWRhrpSaWB+hp89PS5KWkViCn2i2EBQIJ8z2kLPQKpsZPTa1Qw2KRgRpfHXXCUBYLw6nyCmWui5q0CT7dAOyO7uiOt46ePXr0wPc/p1kB2DUEEtLXlTg7GcUSMyuLKthSXc+upiYOLG3jwNI29rQ0sbelia1V1azOKqItMoW5QrUVgAs+cGeVsw+HpDK+SIrmTraFFwvSeLEw6a0A+E1TOt8uTuNldQoPixO4lRnDjaRwbpQUc2t+DUvEBlJHz2L2zGDmC6KsANQNEBLSx5Pgvp4o+neuc7GMV2AZr7Be5QixcUc/VIhmkI91HUzXe73gvm7W6l7EGAkJkzUkTtESN1FlRWPk+1JrezhsVBDho8XWSmDYqCDMY2XETVQRP0ltnTwO6O2IxMaViA9lLJLkUuIeR/ToYOS9PQju4418cCCa9xVEz4qiUl9JriiTFDcLmjFSDO8H4/eeM7rRUgIHeKGdpCTCKZx5cVXU57bTmtNBpksi6mFSpDYBaEZpMIwPJ807m0XhdbSmL+X4smNc3HiWQy07KJTGIx/mgmqYG6phbuiGCYj9MADDEDfUfeyJGeZFyrhAEob7Ej/CD90Ad4yDvDAN8cE00ANjfxeMfZ0w9HYgrN8sovo7Yuo1g4h+dhSP92LuRC8a7UWscA1gs4+Mo2IFx6VyTspCOKtQc06l57w+nMv6UC4rg7igCeac3sBaPy3zJ4vIGOJC4Tg/qp0UtHlp2CzWcFhr5EKonmvhRm5EhVvzbmIsX1jMfGExWyF4Oz7mNQbNPEix8CgtjkdpcdxLiuZOgplbcRG/yNuxEdYhD2ulzxzaOfX7GoZ3Y8K5Z4ngQXzMvwWAt7uyPIe78/K5P7+QBwuKuF9XxMPGYr5s61wJ86i9gqerq3m0uoZH6xt4vLGZJ5tbX+8EXM7TPSt5vm81X+1fw8tDH/Hy8ObOqyBvCcDvPz7Ei7O7+PbSfr65uI+X+9ZxqSCW8wlh3CzJ5mx6EhuNRpbIVTRLVSxVGVmuMbFcpWOVRscag5aNEQa2RIexNTaS7fFR7EqJte7/O1iQbm33HizJYX9xJ/4OluZzsDTfCsB9RTm/AOCOjGQOZiZzPDeN0/mZXC7J4nJJOh8XJvJJQTxX86K5mm3iamYoV9MMnLXIOR+v5myGjnMFoXxalcB3+6r467lm/n6tDT5bCp+38Zdr9fzl8iL+cqyA73fl8GJVCtez9Vwwh3BGE8xJcQhHxQr2+MvZKpSw0TuI1e4BrBL4s8xVxHLXAFZ7SFgnUrHSV8lSz2BqZ/qxcLo3C6b6UDXdh1p7H5Z6y1gToGa9xPh66lfPMn8drb6aXwBwoVcw1b4KFvvrWOyvo8ZXS53QQJ0wlBqfUOYLdJQ5yEkc69ENwO7oju5463hjDUzQf9lbh0CCfm9PmouGhfpUNlZUsblqMVtqa9nb3sy+jhYrALdV17A2p4R2cyqV/lpSRs0iY/gsFn7owQpHLw5KpHyWYOZWZjRfzU/lqwWJbwXAH9pz+K4hg5fVKTwpS+ZOdizX4oycTErkakkF9d5y4oZMo3SGlOQxAcSOFBM6SIS2vx8qGx/k/bwI7tv5pq/rTJtmkI91uEPR38M69NF1tUPa2wXDMBExH4ZgGhlonRLuaiGHjQrCNDKQNLtQCgWxxE9SWwdININ8rPsBzWNlmMfKMI0MtLaUfd6ZQcggTxLt9BS4WbB8IEc3wBetrZCQfr5oRgYTPyuGkuBi2pPaaUloYoF+DlHTDOR6JiF6zwXLZD2RE9QI+wrwH+SNeEwg2cE5bJnzEXMkOahHBiDsJSB8opE0t1QME3UUifNIdIthRWYjJxp3kOFlRNLPDtHvxhM50hvDIFdMQ90x2rqg6mmHttdMood6Ej/Kj0hbN6IGe6LtL0Bv64He1gNdPxc0vR3QvDcTQ28Hwm0ciRvsRlR/R2IHO1M6yZvKKR60OPmy2kPENpGY4zIZx2VSTgZLOKtQcE6t4rzByCWjnvNqGZdMoRzXhlE7Q0TOCBfi+tlRMTmQFncNy7wUHFBouGAycsWk59NIE59FR3DdHMZ1cxi342P4PCaSz2Mi+cJi5mZslBWB95KiuZ8cw4MUCw9SLNxP7vzsdnzkL/JO3Osdfz8D353oMOtnXfkgzsyjxNh/CwDvV+R35rwCHi4s5nFVKU+qy7hXW8iDhiIeNZdyr6mUu02lPFw2n4erqnmwdjEP1zfy+KMWnmxdwpfblvLl7hVWBL44uIkXhzoXQ78NAP9w+QA/XD3Mi7O7eHVhL3++fpy/XNjHN5vaOJoUwbmsJHaFm2jxDqLJU0KtWxAtQiWtIhU13mIWi8S0BUlZHqxgtUrLep2RjQYTm81RbIuNY3tcPLtTUtibkc7+rEwO5OWwJy+TPQVZVvjtzs9kV16GtSK4vzjX+rsDBZkczIrjeF4CZwpTuFKWxtXyNK6VxPFpUQzXCiK5mm3gSoaWK6lqLsQrrRXAq+XR3GvJ5s9H6uFSO1xfAp8vg89a+ePlGv50bgF/3pvPq7WpPFgcxcVYOSd1Yo7LpBzyl7PPr3OoY6V7IEsE/rQ6eNAxy4sVgk78rfWSscZPQbtAQqOjiHkT3aiY6EadQyDNLhLaPaSs9lexXqxjTaCOpUI17T4Klgg1tPioafRUUOceQq27klofBXUiNY1BepolJuoD9CzyUlHjq6PaR0+Fs4JiOylZE/yIGjarG4Dd0R3d8dZhnQLuAmDQ7zq/Br4zk1RnNQt0KWyYs4iPFtXxUXU1+5e0cnBZO/vbWznY0cauxfWszSmhIyqNSn8tqaMdyRzhyKLxnqxw9OKAWMJnCWZuZkTxvDKF5/MT3gqA37dl8+3iNL5alMSzOWncz0uwAvB8bjHtgToyx7lQbi8n/QMJKR8oMA4UourrjbKfNyE23sj7eVn3/3WdZ+ta8hxi4468nwB5P4F15YtygCeR70ut7dzw0WISp2hR2Xb+n9ARAUS+L7UOkSRP02MYJnpjF6BygCfqgd5oB/uiHuhNcF83Qmzc8Xt3JprhfqQ4hJI0VYdukA/qfl4YhwSiGiBCOUxC1PRw8gJzaU1up9Iwl9VZy1CODEI9Ioi4qUakfTxQ2voR1M8D5bAAAgb7EO0UQW3kfCqVBURMUSId7IdpvI5c7wwWqudQrasgySmSOfJ0tha1keasRtHPDlVPO+LHiIga4kHCaCH6Pg5oe81E19ueyEECood6YurvTPggd3QD3NH2F6Du54qq1yzUvezRvDeT0L6ORA5wJmm4Z+e08EgPSiZ6MH+qB0sE/mzwDWRnoJRjUgnHgzvXaZxVyjmnUXDeoOeSUc85XQjnTCYOKoxUfOhB+mAH4m1mMn+6mFaBkmXuMk4bQrkWFWFt/34eE8l1cxifRpq4FRf9mxXA+8kxv5p3Esy/yLvxZh7Emd9AYFfF7/9VBfDB3ALrSphHi0p4Ul3GlzWzuVtTwP36Qh42lXC3sYTbDcXc65jLg5VVVgA+2tRsBeCTXZ1VwGd7V/HVgY18dXDTWwPwm4v7+PHaEevnP904wV8vHeKng+vZnxLJ7pgwlsukNAoCqHUQUmMvpNlTTqOXnPnOQhZ6imjwCaBVJGGpOITlMhUr5RrWqA2sD41ggymSzdGxbItPZGdSCnvSM9icmsCWjCS2Z6eyIyeN7dmpbM9OZU9BlrUS2IXBw8U5HMmL52RBImeLU/h4dioflydytTiGTwrNXM0P43KmmktpSi4kBnMxQcXFRC1XCyO5uSiZZytK+MuxRriyBG4stQLwx0vVnetftuXwYmkSd+ZHcDZSynG1mKMyKXv9ZGz3krHMxZ9WZz8anHxotBfQ7uDJKo8g1nrJWOslY4WXjIZZQmrtvKkY70LFRDcWzwqi1U3GKpGatYEa1gVpWSlSs8RPRbuPgg4/tRWAiz0U1HmoaArQ0Rikp0lsoEkcSn2AnipvNYu81CzwUFNqLyVvSgBp47yIHGLfDcDu6I7ueOvo2aNHD0S//2cFUPqOU+c6mPdmEWcno0QaxcqiCjYuqGFrXR2HVyzh6KplHFm+lGMrlrG/uYV1uaUsiU5nfoDOCsCqCV4sn+XJ/iAxN+IjuZkRxbN5yTyrjH8rAH7XmsWr2hSeLUjgq7kZPCpM5tMEE8fi4zicmM6K4DBKpvtRMUtB4XQNWZN16Af4EtLLA3lvD5QDfFH076zKRYyRYBoZ+Mawx8+veHQBzzjcH8t4hbV1ax4rI+bDEOval65J4vSZJjIdwt8AYIiNO8F93awVxy5QBvd1QznAk8A+ThjHBJLmGEbYqCAk7zmi6utJ7AdqwkeFoBouxTheS7JHEo3xzZSry+hIaibeMRKprQ85zrFoB/ujsvVD+K4z0gHeyIYI0U1QkOwaRb4wkegZGjRjxISOV1MszGJFXBM12tkU+iRSFhjPutQqYif7o+tnT2jvWcQP8yHS1o3kMf6o3plG2AAXjP0ciRwkIHKQAIONE+ahXuhtPVD1dUHecxYh785E1XMmul4OhNk4Ez3IjbTRviQN9yRjrC+lk9xZON2DNUIp28XB7JeHcDxYzPHgQE4GB3BWKeOcRs55o44LoXrOqEM4aTCyLVBF/ghHkgfMIKG/PdUOctoFKpYLZHxqsXA7Popr4fpfALCr4vdrbwB/XvX7eTXwbmLUL/JeQhQP4joRaF34/N/eBP673wDem5PXmXPzebCgyLoKpguADxqLuV1fxM3Fhdxpm8ODlVXcX1PHg3UNPNzYxOMtHTzZuoTHO5f9swq4fwPPD2zkq4MfvRUAX13Yyx8/Ocp3Vw7y3ZWD/HTjBD9dPsQ/Tm1nb1o0y1UyqlwFNLsFMX+yBwumeNPoLKXORULZdA8qnH2ocvGmXiCk0TuQJp8gmn3FtAYG0yFTsVSuYbXOxFpTJBsjY9hsiWO1JYo18VFsSo1nc3oiWzKSrLk9O5WduelWBB4pyeZkcTLnylK4VJ7OtTmpXKtI5kpRJFfzw7iSZ+Riegjnk2WcjZNwMUHBpSQdn5fH8agxh283zOOvx5vg6jL4bJkVgN9fWMSPJyv5bmMmXzZb+Hy2gVNhEo4rJRyTydnpKWGTm5hmB1/qZnpRbe9Jw0x32h08WeMlYZ13MGs8pSwRBFE93ZOFUwRUjHdh7iQB9Y5iWt1kbJKZWBekZbW/imW+Cjp8lXT4Kmn3VdHsrbICcLGnmnapiVaZiWaJkYZAg7UFXCkIYa5rCIXTA8ma4EfK+x5EDJ7ZDcDu6I7ueOvoBGCfWYh7OhH47izEP9sDqB/jQZJzMKvyytm1qIH9TW0cW7mc42tWcHr9co6vamVvazWrC7JYm51JvTECyyg7kkc5UfS+G232XuwMkHDFEsknqWaeVKbxdGEqT2vSeN6YwfOWHJ625fKsrZDnLUW8ai3j6/ZiXnUU82pZHt8sz+PLpiRetWbybWMGT0vj+DI/lrspJk5FpbDXlM6SgAgKJgdQOCOYAkcTZV4xKPq5IO3pgLy3A9r+zoQN9SZlqhb9UCG6IX6Iezoh6eVsXfmiHeyLfqjQWu1LmW7APFaGdrAv5rEyEqdosYxXWKt5uiF+1uGPuPEK8p0jCB8uRDvAHZ2tB/qBnmj6C1D0cUb8jh3BPWdhGuqLpr+A4H5eWCaZkA/wxzBaibifH5oRCuJnxlMsKqVIVEaqIJdsn2Lm6etoy1rPwvhWlqWuJsE5EdMoBUG/cyNlkolilwSi31egsPUmyT6MkCEigkfIkA+XEDJCin6cggKfVJIdwomfYSTTxczauMV0hFUi6WmHso8DOhtHIod5EjnMk7DBAtR97DEMcCZiqAfm4V6Yh3uh7++Epq8DBhsntP2d0di4oOjjjKKPK4peLhj7uxA5wJnc0V6UfehDxXgfWifNYp29K0fFCk7IlJwMVnEqJIRTIXJOBMs4pZBxQafgkkHFOa2Sk2o5O8R6mh2k6P/XZGJtXCifFsxiNz+W+fmyRyHpnLqNMHEzzMTnYSa+CA/jZkQ4tyIjuG2OtE70PoqP43FCPI8T4nkQH8vDZIu1/XsvKZovLGF8HmPibmKUtRrYNRhyyxLO48QYHiVEc88SYYVfFwJvmUO5GWnkljm0851gbERn2zixE5Z3k6O5kxTFvfRY7mTGcTcrnrtZ8dzLTbTm/bwkHhak8KQkg0ezM3lQnsnDOVk8rMjm0fw8Hi/I58nCAh7XlvKodjaP6ufwsGEODxsruN8yl1vNc3i4qpqn6+t5+lETTz5q5OHGRr7c0YnAJ7uW89WBjdY3gC+P7uDVyb18c+YQ3549/C9bwH+4fIDvPz7E9x8f4sdrR/jj1WP8dPUUO9LTme/sTekYexonB1Iz0Z9KeymVghAK7f3JmOhK3hQX5kwSMW+yhAXTpNQ6KqhzUlLrGsJiDzn1niE0+MppEMlo9A+mKVBJu0xHR7CRFaowVurCWRtmZl14FKsjzWyMj2VrShK7ctLZnZfGvrxUjpamcWp2OhfmZ/FpbQbXapK4ttDC5fJwTuap2RsbwN6YII4mKDiTqORcspovqpJ5tq6c7w8u5scLLXBzJX+50crfrzfDJ438dKqSnw6U8KolgrsVKq5lyDihkbBfImGXbzBrnGSsdJKyaJoXc6e6U+ngQa2dLy0OgazyVrPCW80S9xDq7EWUv678LZrpR51LEMv8dawSh7FSFkGbyECjt5pG784bv20iAw1eqs7Kn3sIiz0U1HsqWRIcRYskgqagMJrFETQFhbPIU88Cdy0VziqyJohIGeNN/HABEYO6W8Dd0R3d8fbRs0ePHni+Mw3hf9rh97sZBP7OgcD/nInG1hPdaPd/CcB9bTWsKcxmXU4WjSYzsaNnkjzKieKxgn8LAJ82J/N1Swav6tP4siSWpwVx3E8L51RUCjt0SaySWSizk5E/TUqpm5lyn1jkfZwQvzuT4F726G1dCR/mQ8JEpXVti6SXM9LeLtYqoG6In/X8W9S4YCzjFYSOCEBl62VtBYePFlt3/3VVBeMnqUmYqCJzpoHQIT5oB7ijH+iJztYDVT9XVP1ckfdyRNnXBdNQXwyDvAjp70P4OBUyGyGa4cEYx6jIcksjqH8QlukWmiPbqDE2Mke+gNmqRdQlLKUqrpXNZbuoMlQTOlqJfqCY2HFaKrzSyZ0Vg26YPwl2oWhGBaIcLSZ4uD+SIX6kukbTaJpL8qxQkmYayHENY1nkHJr1heiHCFD2tUdn40j4EHfCBgswDHAm5L3phA50JXyIuzUNA5zR2ThisHFCZ+OEtq8zyr4uKPq4ouzt2rkLcKAbxeN8qJwkZMFkIR1Tndno6M4xiZJTcjWn5GrOKJWcVnQi8GSIlNNKKWfVwZxWyTmt07DWS86iCX4Y/2MqSQPdmWenoMlDxCp/P/aqxNw0h1kB+EV4GF+Eh3ErMsIKwK5rH78FwK4q4M3Y8H8JwIfxUdbq3/8JgLcsnQj8LQBaEZiT8AsAPi5O52FZxr8E4MPF5b8A4IOVVVYAPt7U8AsAPt+/gReHPrIC8OsTe6wAfHX20NsD8NoJjhQXUyUQUvq+A+0zpdRNDmSho5wFHkqKHQPInSqgeLqAsgnelI8XMXeyP/NnBDJ/RiDz7AKodpVQ7SqhxkNMtVcQNd5ian2lNPgraQxQ0yrR0SbXs0RtZKkmlA69kZWRkayzWNiSlsy2jGR2ZiZxpDCZU2VpXKzM4tPaLK7XpHJ5nplLs8M4U6jjaKqco6khnE7TcCZZzblULTdrU3m+fjY/HKrnx4vNcHMlf7vRzN8+bYKri/nx+Gx+3JPH8zojnxeHcDFRzAF5EDuFAWzxlLDcXkyHfRDzJ7tTMUXAAnsPmpwC6XCWstpH8wYAZ3/oTMVEN2pm+dPoLmOZv46VQSZWBUdaAVjvqaTRW02Tj8aKvzr3EBq8VDT5aOiQmWmRRNAYaKJZHEFjYBgLPXTMdVFS5iAn/QNfEkd6YBniQphtdwu4O7qjO94+evbo0QPvd2fg/449/u/YI329BkbRzw3NSDcSHKWsyitnilNuQQAAIABJREFUd1UjB5rbrQA8u3Elp9Z2cHDJYj4qL2JTQR4d0fGkjHchYbgDs8d7/VsA+FVbGi+b03lenciTYgtfFSfyKNPMIaOF5SIDeyLzqfeNIHtSIAtFycwVJiB+dyai301F1nMmoYPdMY8UYhouIsTG3foeT95PgHawr/Xdnm6IHxFjJCRO0VrXwoTYuFvXu3T9jXawL2Gjgoj5MIT4SWriJyiJGx9M2DA/wocLiRodSOgQH9Q2bqj6uVorgoZBXoQN80MzxBepjQfBA3wI6O1B0kwzLeF1+PbyxP2/XCjyL2SBtops3zzSvHOpjKynLqGDhRH1nG69wEL9fBJnWTBPNaIZEYR5vJqEqXpyXGIo9E6gRlfAInU26W5GqjXZrE1eiLjvFKT9pqIcMJ3wUS6Ej3JBP2gmYcMERAz1IHSgK/r+Tqj72CN/dxoRQz2sVb+uiqDJ1hVjH0cMfZwx9HFG29cVbV9ntH1mETtUQOpwVyone1E3049GBx82uHixy8uf0yE6zio784JWy2lFCGdVSs6o5J3t4BAxp7RqDmpDyRtuT+zvJxPbcxbFY0U0uqpY6x/ALnkQZwxybkaFcjsinJuvswt+d6LM1lu+d6Oj3lj6fD/OYsVZFwBvxUVwMzb8NwH4MD7qV98B/hoAb8aEccsSzr2Ezhby7UQztxPN3EmN4Va6hdsZryGYHc+d7HgrAB/kJ/OwMJX7JWncn53RmeWZPJiXY0Xgw+piHtZ0noV7UF/O/fpy7jbN4XZLBfeWL3w9DbyYx5saeLSpicfb2nm4vROBz/at56uDm3h5eAtfHd7Gy+O7eXX6IK9OH+TrMwffCoA/XjvCN5cPcGtVB20hKoo/sGOlWwgN0wOpd1dR76vpnFp19afWxY+FdkIW2QWxyC6I+TNEzJvmR/lUH8qmelM21ZuSqR4UTevMgqmezHYIYLZ9IHMcgyh3DmSOWyAVgiDmeAYx3z+YaomKVkM4yyKiWGOO5mBaMifzMzhflsXlihSuzIvjZJGOs7MNfDwvjOuLYrg238z5EiPncnRcKQrj0dI8vt5ewY/H6vjp42b+/kUHf/10MX+/UsvfLlTy9bY0XqxK4Ha+jotxYg7rRWzw9mOFk5AOO39qxvsxf5wX5WNdqJwgoGamN8vc5axwV7BUIKfVRUqDQwALp3ox+0NnKqd40OGjYkWggRWBBpb5G2gT6Wjy0dDgpaLBS2UFYLWrjBq3YOrcQ2gV6ukICKVDZqZZHE5DQOfC5zqhgXmuKortxORPDSR5jCdxw9yIGezcDcDu6I7u+B9F5xqYXjMJfHcW/u/YE/h6CETexwXVcBfiZ0lYmTv7FwA8t2kVp9ct4dDSerbOLWVzUQHL45LJmOxO3NCZzJno828B4Iv29M5rIFUJPC2N42VpMg8zItkq09PqqWR/dBHN/tHkThGzQJhEhV88ge/MQPS7qYT0mYVpiAcRw33RDeqEn8rWywrAn0MvdoKS5Gl64iaqrCtilAM8retflAM8rW8HQ0cEEDUumJgPQ4gZF0zCxBDMowKIHhNE/IfBRI70Rz/QE0UfZzT9BdbWcOgQH7RDfZH2FyC39ca/twthHygo9c9CMtAfhx7TCZ8cSq4wjzSPdBIEyaQKc2lNW0WWpIS1hR+xrnADi0yLWGisJMjWG7GNJzkuMZR4J7NQmktH1DxWxM6nRGgheaaCTGcNITbTUQ6wQzPQDv2gmYQOnUXMWA9ix/gSM8oX0yA3DAOc0fabhbqPPRFDPdD2m4Wylx2KnjPQ93fCZOtGWC9njL1dMfZ2xdDHFUMfR0L7OhI/1IXUYfbMn+JGg70nLY6ebPEQss9PzBmF3grAizodp0LknFEqOKdRcEYl47RSyjG1mrVBSmL6TML4vz8k3VZA5RQpSz21bJdIOKqTcClcwc1IvRWAXZW/O1FmK/y6MNh17u1BbOcZuHsJUda3f13Tv7fiIn4TgF1vAH8++ftbAPwi2sTNmDDuxputALyVEGkFYBcCb2fFvQHA+3lJ3M9P5m5RCvfK0jtzdgb352bzsDKXR/PzeFhdzIPq0s77wItnvwHAu8sWvB4Gqf0FAB/tWMrTvet4fmAjLw5t5qvD23hxbBdfnzrA16cO8PL0gbcC4PfXjvDVhd082bGO9VFm5kx1pM0xiEY7ES1eShpFKqo9pdR7iGlx96fWMYBaxyBqHYNYaC+icoYv5VN9KJnsSclkTwonuZM7wZ2c8QKyPhRQOFVI4VR/iqYFUDBdRP4MP/Jn+JHn4Euhi5AyjyCqpBrqlaG0acLZG5vA0bQUTmSlcCovhjMlZs6UGrk0L5zrNdHcak7kel0MZ2frOFeo5VpFBF+uLeKbPfP448la/vJJM//4vIW/Xqvh75cW8dPpcp6ts/C4JYLPUnWcDpeyN1jECjdfmu2FLJ4qpGKMF7NHujF3rIBFkzyot/Ojw1lCu5OEJocA6uyEVE/zYcEUT+ZNdqd6ph8r/PWskYaxItDAEqGOOvfgzjd+HgqafDS0+OloFeqtAFzsoaBNZGBpUBjt0kiagsKo9zeyWGSkxlfHHKcQimYEWQEYP1xA7FBXzEOcugHYHd3RHW8dPXv06IFPTzv837HH73czEP1/doj+YzrBvZ1RDnMmzkH8qwA8/9FqzqxfypHljexcMIetJUWsTkonZ7o3lsEzmDvZ798CwJcdGXzdksHz6kRezEni67IU7qWGsdQ9gEa3YPaaC2jwi6RguowKr1hme1sI+K/pBPzXdNT9XTAN8SB0sCfqAR7Wtq+sjyuyPq5W0OmHCkmdYbS+/fv/2XvP6KYPbN2b9d77nnNmMqFj0yH0DsbgLkuWLMuS1btsyb33gisu4IJ7wTZg3MD0kgRCCSkQQksgjUmmhGZaIAmQnilnMuV3PwgrYTJz35uz5q7zfvCz1l7L/stL/qIPP+29n2cPGUN+eM936JnJLYiomWEkzNM5T8PNVpO93ELSHBXJc9VkLDK4uoDGMc5RqWW8APskMY7JEuwzQjFPDUY/UYTGTYh6QiCxi03Ixgbi/f+swDrHSHZgFnlBuWQF5RKxPJqtWQNUWOopt9byfP0xDlQd4vm6F4hdaUc/TU5dWCG1ofm0aErZltDM/vRNtOrXEjdXSfhkARY3H6zuvoS7+2B39yJqsi/pc2VkzJeTMltG1CQBERN8nWNeNz+iJgmwjvXCOHIlhqc9sI3zJmq8P9FP++MY6U/kqAAixwiIHOtL9FhfMqb5sGaGFy0eAWz1EdLvH8jRYAUn5VreMITzhsHKGwarqwN4weB0AL8TYeJ1jZyjYUoaV4uxP7WYyP9YTulMGR2rjOyTRfCqUcNbkTp+HW92AeBQ529o7Ds0+h0Cwh9e9riZnMjNtHgXAA65f2+kxf1TALydEvej+mcAeCUhkmtJ0QymxjmzBdPjuJYWy43sRK7lJnEt9zEI5jsh0AV/JZncKsnkRmkmN9fnPgGAd+qKuFtfzJ2Wcm63rONW23putVdyq6OKwc3V3Ni6gRv99dwaaOLW7lY+OtjJvee6+OhwD3de6OPukX4+PrGXT185wMOTz/Hg1GEevn6Mz86/wucXXuXRhVd+MgB+8u4xvjh9iFOlBbQGBtOxQkyPj5JuiZGtMhOdYi09Ui39EiWdvqG0+ylo91PQ7CWjfqWE6uViVwewbHEQxYtEFC4IZM08EYULpBQukFEwP4Q1C4LJXRBE7oIgshYJyVoSSN4KMeWBamqkBlpkJp4Lj+VYbDwnEuM4meXgwtpYftWSxNXONG73ZXNnII8rXalcqLHxdnU4v2lO4LNDlXx1soHfv9HGX37bxd+ubOEv7zfzl7fr+dPZCu5sj+RGq40PEm2ctig5HCpjq3cIbcuk1C+UUjZdRNlUfxoXBNOxXMZWTzldqxVs9gxl44pgWpZLnOURzEavULYEqNmtjGSvNoYBRQR9ITZa/FVsDNS7ALBLamNrSDgbA/W0Cw10BpmeAMDNYVF0hNrZGBJBi8RKpZeW0hUKipaEkjlLRNr0QFKnCUiY6jcMgMMa1rB+slwmkCEosowTY50QhPppbwxTfEhZrfwRAJ7bu5O3n9/DpYMDnNnZxUut9RytWs+BvCJKV8tInLiChhXyfwkAft6fzxfd+XzekcPXjWv4sjqXK6k2qucsp9Nfw6GIPJoDI6j2tVK82k55YByKn3mgGelF1DQJkZOFWMf7Yxof6AJA9Sg/lE/7oBsrIGGejiLfeBLm6VyxLSa3IFc2YOpiMxnLbC4DyNDt37QlFlIXm0mapyNvZTjxzyiImykncbaSmOky7JPE2CeJMY31x+YmJGmOiuhpISQs1JC8zIhqnC8xC7UE/ttSQsf4YpqpIGqRGfHIAFb9jxWEugdTY6phc2oPGZJ8eov2saVgJ5uKByiPqqMxo4P+/D5qTBUcyNjKRk0ZjbIi8lelUuSTToOinOqgNaQvsGEdJ8Y6WoRllADH+CCi3YOJcROSMjuU+OlirGO9MI9ehWXMaiInBhA+3gfLmNWYR6/CNMoT8+hV2EauJuapAKKeCiD6FwKixwYQPdaPuHE+FM72p2yeN12+QnaJJRwIFnMiRMEphY7zOivntCbOaU1cNJt5J9zGeb2OC0Yt70SY2O+zkvpZc4kaPRvLUx6kuIloWmqiLyCCI2GRvBGu5TeJBgZTLVyNDedGbIwL/oY6f0Pmj2uPX/vhjd/BpARnuHPG913AmxkJzsiXfwKAQ12/2ylxrm7gPwPAD+MdXE2M4kZKrPO6SFosV1NjuJ6VwNWcH0BgfgrX81Oc4Pd4F3CwKJ1rJekMrsvh5vpcblbmcWtDgQsCbzeXcau5gltt67m5cT032yu5samKwe5arvfVMbitgcGdzS4AvHuom9uHe7nzQh/3X9zDJy/v58Grz/LpyUM8OH2UR+de5rPzr/Dw/Ms/CQC/+dVrfP6bl/nu8knu7O7hgN1O3QIv9oZY6JEY6ArWsUmsZGeojl1SFdtDtPSH6OkP0dMj1dMVpKdDqKHBO4z61SqqVigoXyZn7eIQChfIyJgmIn1qEKmThSRO8iduojex7l443D2wTVhCuNtS4mZ5kbpQQN5iIe1+oXRLwtgmV3Aswcxb65L45vlafn+klj+8VM9nh0u5tTOLNxttvFNv5+rmNL56qZZvzzbwh0tt/O3KVv56pZO/XG7krxer+ePJAm5sMvCbSi0XDHqOSkPY6SOiYYGQdbMElEwNJM89gOIpAjqXq+j30tG/KoxNy6VsXCahZWkQLcsldK6W0yvUs11qYWdoOHvV0ezRRLMt1Eav1Mpmicm1/9caoKXZT02jj5LOIBOdQSY2ic30hNrpD4ui5/H+X7ssgtZgm3PP0lNF3vwgsueISJ7qR8JEHxIm+hAz0WsYAIc1rGH9ZI0cMWIEhjGemEeuwjJqFbETfYmfJiB+hj+Rs71ZI9AykF/JsYZOzvXs4uzAPt7cf5A3Dx3k7PN7ObV/O2/s381Lnc48wHI/HbmzxTQvUzLgL+dwiILLyXH8Ji+RW1XpfFSXwYP2NTzqKuBRTwkP+tbysK+CB31lfNyVy0dd2Xzck8fne4r4bHchn+8o4ZsdFXzdXc5XTWU8qirhcnwkdSuFdErDORSzljqBneKlOtJna0mdq0f1lC/Kp/0wTxJjmSZBPyEQ3XhnNItmtL8r888yUULKIhPpS604psuxTZYSNTOM6GeULsdw8kKjawdwCAqTFhjI9Ywkcb6e8CkhJM7XEzNL5boTHDtbjX5cILGz1STM0xE7W41xggjdWAGKp7xc5pIho4nJLYjE+Xqsk4KxTJSgHRNAyL+vJHmRjWZdNY36WmodzfQW7WFb3RFqc3uIUxbwXMsrdGb0si2+m03mZrKXJ7A2KAfrDCVxiyx02mrIWmlHOdIbzRg/DGP9MI3zxeYuIHlOGNYJgVgnBD6xp+iYLMExWYJprD/mcQHY3IToR/mg/NkqDKMDsE4IJGJ8ABGjPIkf50m6+yrWz/Glfp4fvZ5B7PGT8WyQnBNSldMBrFJxXq3gHZOGixoZl4wqzmk0nDNFc9qYTP0sEclPLcL61GLiJq0i+xlvNvvJeF6h57TJxvuRNn4bE861uAhuJ0VxJzmaGwkx/xAA/1HdSkniRkoitzJTuZmRwvXURG5npXEvL4vbWWk/qjuZaS4X8A93AYeiX34YCXMlJsIVCn07JY7riVGujuDtrCQGMxMYzEzgRnYiN/NSuJ2f9n33rziDO6XZ3F6X+8QI+GZNvgsCb9YVM9hQyp2WddzeWMmdzmrudNVyu7eewd46BnvruLGtgVu7W7m9p805Bj7czcdHennw4oDzKsjL+x5fBTnE52eO8cXZ43xx/kUenj/BgwsnePjGSzx682U+u/gKn196la/fPc3X757m28tn+PbyGX7//jn+8P4Zvrt8Et49zZcvPsepsrWUrvCj0VfGdpmNXfJwdits7FKZ2ak00qtQ061Q0S3XsFmqpD0olNZAGW2BCloCQqnzCqZqhYiKJQGULAwgf1Eg2fP9SZnhQ/JMHyInrSZ8wipsbqsJn/jYTDXGn/BJEuKekZE9T8A6TwmdYjVnsxP4sLWQL15p5OGrNXx8ch0PjxTzcFc2dxujudUQx4MtOfzp1Tr+9EYzf3ivjW+vbOTbD5v54+V6/vRGNX88Ucy1Wh3v5YdxQKOgN0hEm6eAylmBlE4WUTheRNnkENbPCKFpiXPU275KTOuqEOpXhFC9OIja5VJavVX0yux0SW30yh3sNiaxy5RMjzqarYoomnw0tPjoaPXV0+pvoFVgpFVgpC3IQps0nE55JFvVcWzVxtMpdzwe/9ppFJmo9lVTsiyUrNkCcuYGkfGMkKTJfsS5eRHlNhwDM6xhDeuna+SIESMId/MlboqIpGkiUmcGkToziKRZgcTM8yM/UEd/bgWHN7Rxest2zu3cx8UDB7h05FnOH97P6YM7eH3nNo62trIjr5i13moyZwRSt1DGgH/ofwkAP+ldw+d7ipwQOFDMV9vL+LKrlC8a1vJJRQHvxtpp8ZHSKQ3nREoVrcFxFC3Rkj5bS/JsLZqn/dGMFmCdEox5qhjNWH8XAA6NfsOnhLhiXxLm6QifEoJlooTIGQrCp4S4Mv1+mAGoHxeIcYKIpAUGsj3sJMzTETFVRtICwxMAGDdHg2G8kNjZauLmaIiaGeYKnFaN9EU3VoB1UrDrzNzQhRLLRAlmdzGqkb6E/PtKHDPUxMy1UiDIpd7RQlvqVva2vMS+ja+yLqWDdTHN9BfuoVZXQ7m4iCZVJetlhZRKsimVZFOjKCBliRnNGD80Y/zQjvLGMsEf+2QR8TNlrhH1DyHQMVni6lwOvaYf5YPq56vRj3oMhWP9iBzjSbK7NzlTfama50/TQn+2ewWzL0DOCxIlL8lUnFEbOKdScUET5gLAd6063rXZOGuM4TmJjZIJq0n8jyXYnl5M6nQfShYEsk2s4rjWzPlw+xMAeDMpilv/TQA4dBHkh2firsbauZkU8yMAvJ4c4zw39xgAr2clcDMvhVtrUrlVnMHNonSnK7gk80c7gEMAeGtDATfrirlV/z0A3u2o5vaWDXzU28DNvnpu9tUzuL2R23vauLN34z8EwAcv7f0vAeA3773Ot5fP8LtfnuUP75/hr79+Hd47zX+efpGLjXVUeApoCVCwLcTKgNzmAsAdKiO9So2zwnR0ydRsCg6jPUhBu0jJRmEYDT4hbPCUULlcSNkSIYVLROQsCCB1pi/JM31wTFyFbbwnhtHLMY3zdn7+fuGFYWwA4RMDSZ/lS9kKMVtCNFwuy+F2VwVfn2rmi9O1PDpTw6OjJTzYmcVgvYPbzXF82pPDn1+r47tLLfzxl638/mob3/y6kd9dquH3pyv4+nABH1breStXzTZpMBu9fdmwaDWl030pnhxAwYRA1s0IpWauglYPOe2rQ+nwDqF+RTC1y4KpWSKmbkUIG3019Msj6ZU72KaMZpchkQF9AlsUdjql4TT7al0A2OKnp9nfWa0i54WPTYooujXxdOsS2KSIpFPuoF0WQX2ggUpvJUVLQkif6UfmrEDSZwaSPMWfxEm+wzuAwxrWsP5LGjlixAjyloaw3lvPBj8z61ZpKV2hpNhDTq5nKBXBVrqSi9hXXM/xxi1c2L2Ht57bzzsvHuTisf2cO7yDM7t6ebGjlQOl5WyQmChaFEzTstCfDICfbM3jfncun/bl8+W+Er7YW8zDbYU87C7kYUchn1bnc2NNGm9EmOgPNbFZZufN4g4GzPmULNOTNktDzFQ5pnFBmN2DiZguwzBJiGq0L6aJQUQ/o3Tu7T2+3Wuf9r0zeOg6SNTMMJc5RDPa35X5lzBPh8ktiPApISQtMJC80EjsbDUxs1SkL7USN0fjio9JnK93waR9WqjLeTy0V6ge5Yf856uJna0mdbGZuDka5D9f7XrfISDUj5c47/pOUhG1PIYyQxW7qg6zs/owO2peoK90P52ZfdQ7WigILSZ2RQxdkS1stNZQpynl+bxtbAmvxjpZgmaMH8qnPHFMCSLuGdkPsvx+XDY3IcYxfhhG+35fo3wwjfTBPHIVtlGrSJ/iz9q5YmoWS2lZKqJrpYjnhAqOh2h4VaHlpFzNBZ2RCxoVb2qVvGvWclaj4G2blTdtdgb8NKyb6U/CUx7Ej/QkZuQiKpeK6BKoeckQwQVHJJdjovlNVAQfxtq4Hm9nMDGSG0n/PQA4dP1jqAYTo7kW5+BGQpRrXHz9sSFkMDXuCUPItcx4BnOTuZmXwrU1yVzNS+JqXhLXC1K5WpzmGgEPrs9lsHoNg9VDIFjE7Q1rudtQzt3W9dx7nAn4aW8T9/oaudvfyN2BZj7Z087H+zr46MBm7j7fxb3D3Xx6fLvzKsiJPY+vgjzHo9NHHodCH/+nAPjl26f46p3XnoTAy6f584dn+NPbr8KvLvLw8LPUBclpFCjYIjHQHWJiu8LCDo2FAa2ZHXqTs3QWtmvM9CkN9CgMbJUZ6ArR0y5S0xqgpMlXTq2XnHJPGUXLJWTOEZA6yw/HxFVYx63EMt4Tm7vzS4hhbAC60X7oR3sRNWEZBQt92a4x8+2OZr473sIfztfy+4s1fH2pio+fz+NmVwIfVJi4uyWDB7sL4HwDvNfE395v5m8fNvGny7X86cwGfn+0ioe9BZyMlnNAKaJ6iR9FM1eQM3EJayb5UDhVQNE0EVULwqhfpmGjt5Y27zCaPKWsXxBA5UIhDR4y2nzUdInM7FDFsteYzG59In3KKDaF2KgPUFPro6LFT0eLj7MavTU0+DirVWSmI9TBVnUc24wp9JtS2BwWRafcQZvURpWPilKPENYsEJM1W0D2HBHpM50GkOQp/qTOGr4FPKxhDeuna+SIESMo81JS72+gIcBInY+ODT5aqn30lPvpqJNH0hWXz56CDRyr28T53Tt567m9vHviABeP7+X8C9t5fVcXJzpbeK6igiaFlbLlUlpW/HQA/LR7Dfe7c3nQX8CX+0r4cl8Jj7YX8WlXPg/aC/ikag0fZiVyzqpnIMxKd1g0bxS1s8NSQPlKM8kzlDgmSl0AGD4tBONkEdpxAdimSklfaiXXM5LkhUYX/A1B2dBpuKE7vxFTZa7nkTMULnNI5AwFSQsMxM3REDNLRfxcLVkrIoifq3UBYPJCI+FTQlyxMSY35y3ioVNzxgkitGMCMIwXEjFVRvxcLaqRvq59w6H7w9qxQYTP1KMcF4pmmpbUgAw2ZfbRV7iH0og69lUfoS29m67cAepjN5IUkEqLsZqKkDxyfRPZmdzJ7uR2bFOC0Y0LQP30aiKniomdGYJxtDc2N6ErsFo/ygft016ofu6JeVyA65lupDeG0b6Yx/pjG+mNdaQnjtGryJ8lonKhlMbloXQuD6J/tYSjwSpOhuo4rdRxRqHmkt7Mmxq1CwDPaJW8E+ngFY2JDXP8yXX3Iurnq7D/+wqSxy+hdZWE3VIdr1sieNth54MYB7+NCedqbDjX4+3cSIrmamIM1xP+8Q7g/00A/OFe4BAQXo+PdO0C3kqO5cbjSJibafEuQ8j19DiuZsRxIyeJwdzv4e9KbiLX8lNcADi4LofB9bncqMpzQeDt6kLu1JRwt66Me03OE3H32qv5tKeRez0NfNTbwEfbmvhk10Y+2dPO3f2buPPcFj46tJVPjj2+Dfzi7sdXQZ51xsG8fpTPzh773wLgjyHwNH/44CS/f+tl+OBNvn7lOBvDDFT6BtMepGWL1ECP3MSA1sKA3sJOg5ldRgu7DDZ26m1s15jpV5npkZvoDjWySaKjQ6SlTaCiyV9NlY+SUk8ZuQuCyJwXSMxUp1kpYqI3NnfnDq1xnADdaD80T3tiH7uU/AU+7NRb+fPBdjjZyu/PV/C7i2V8damcW3tTudIeyfsVFu73Z/Pw2WL+drEB3quHy7Xwfi1/fbua717dwLf7K7nbkss+qZCNyzwpnRNA3pRVZLmtpHB6AGtniSmdLaFyoZwNS+U0rFRQ7yGnZlkQ6xcEUr04iFYvJZsDjfRJI9iliWefKYXd+kS2hNhoFRmo8VFQvVpBk4+GZm8tzd7aJwBwo9jKJkUUvbpEBsxpLgDsCLXTIrFQ6a2kbKWMwsVSChYFU7AohMxZzgzApMl+JM8MHAbAYQ1rWD9ZI0eMGEFDkJoOsY6NIh1tAh0tAXo6peG0hUayxZBKX1wxB/ObeKWxh9Pbe7iwv5+3ju/ijaM7OPdCD6d3dfDS5iaO1KyjU2+n2ltOm2coA/4hPwkAH/Tk80nvGh5uK+TrA6V8tX8tX+4q5cHWAlcH8IPUGM5Z9WyVaNltTuNoQgXtskSaRPFEuwdjGStEN0qAbqwQ08Qg7LNCiZ6txDHTOe4dCnQ2u4vRjwt0jX6Hum62yVLs00KxTwslfEqIKyzaMV1O+JSQJ0bCkTMUpCwykbcqisR/lz7tAAAgAElEQVT5elIWmYiaGUb6Uqtr7DvkNB7aH4yYKiNqZhiRMxSuiyRDXcW4ORrSl1pJWWTCMV2OyT0E6dOByMfJCJ9jxTTTSHpAJg32Zvpzd9Jfso8TXefZWXeUlvxttGZupSgwkw2qEtptG+hy1HMwswujmxCTuwiru5CISUJs7gJMY3ywjBe48gqdwc7fd/2MY/zQPu2F8mcrMY7xI8I9kKgxPkSNXUXKRF/WLw6hfmkIjUvEdC0PZKePmFdkas6G6TinVPOGWsu7JgsXtRou6sJ4x6znda2GAyIxrQtXEfn/PkPM0x4kTVaT4i6lfkUwz4ZqedVo5R17BO9H2vgwOpxrMVauxUVwPT6SKwnR/DbhvwcAhwwhQ89uJce6xsBDXcAbj7t/tzOcUTNXU2O4mhrDlfRYrmcnciPHaQa5tiaZa2uSuVGYxrWSdK6XZ3GjIpvrFdlcr8zleqUTBG9XFnB3fRH3NpRyv76c+43r+Litio87N7iCoe901XK/v4l7Ay3c3dfJ7WedXcD7R/q4f3yAj4/v4tOX9/PpKwedbuDXXuDh60f+KQB+fulVvnjr5BMQ+PW7p/jsneP8+Tdn+c+3TvGH86d4IbuAQg9/GoVKNkq0bJYb2Ka3st1kY0BvckKgwcYuQzg7dFa2a6z0yE30yE1skRrYJNY7IVCop06go8pPzVoPBcUecrIWhZA6N5ikORLM432cn8mxAWhH+aJ+ahXREzwpWSpkl9HC1zsr+NOLFfzprSL++G4hX72Vz7WdcVztiOb+5iweHCzlsxPr+culWv72VgV/fqOE714v4M8nC7m1MZW31jg4btFQP9ODwtFLyZ4kIWuSiNypEtbOk7F2npSSuWKqlstZtySY0gVCShcIKVsoona5lCZPOb0SGzsU0exRx7NHl8gOTRx9ikiaAzRs8FZQ46Og1kdFjUcodSvDaFilotlXR0uAcw+wS+6Evx2WdAbMafToE9mkiKRdFkGz2Ey1r5pKbyWVXlpKloW6XMApUwNInSYgc27wMAAOa1jD+skaOWLECBrFajaHGNgsMdAm0NDqr2dLqINOZSzd5gz640t4vrCFU809nNq2hfP7erl0bIALR7dx9nA35/d3cbpvIy831dIXkUBjoJbNvuqfDIAPewt+BIBf7ynnYXchjzqLeFBT4ALATUIl+2yZHHQU0hQUTVtwMpETxJjHBKIdGYBmtACju4iouWEkLNA541d+AGJDd38jpspcI+AhQ8aQQcQyUeL6fcgUkjhfT9ICg6szmLbEwprV0a7A6KiZYWQssxH9jNK1b2iZKHHlDdqnhbo6fEPGEJNbEEW+8STO15PtYSfXM5LY2WoiZ2qwPaNHMT4U6ywzsUtjsC9yEOMRR7m+ipqYVraW7OFYzwW2NRylLaeHmPkW0j2j2WSv50BWD9tim9CPF2CeGIR9igSbuwDzeD/MY78f75rHBWAZL3DtAupH+WAc44fmF6sJ+w8PjGP8cEwSET3Om5jxzvFvzZJQ6pcGU7dQQNdyAbu9xbwaquJsmIZzKhUXVVouGy28rdNySa/kHbOe0xo1jbPmUThuBqYRU3E85UnBkhjWeUSyxV/Lca2ZszYHl6Mc/DrGztVYO9djbT8AwNj/3wDg0F7g/ykAXstKcEJgQarLETxYlM6N0kyul2c5qyKba+tzXAB4Z30+H60v4uMaJwB+8hgA77dXOw0hnc6dwHt9jdzd1sSdvR3/EgD8YSdwCAAfvX0Mrl/kdxdf5Q8XXuPVskoKPfxpCAyjTaxhs9xAv8HKNks423VGduhN7NRb2am3sUNnZUBrc3UA/x4AG4QGqv01lK9SUbZaRd4yBVmL5GQvVRIxyfklxTZRjMVNhHGMH7HuXpQuF7LTYORhbxG/O1LAX94r5rv3i/n6nTVc3xXH4JZ4vtxezKNDZXz+ynr+8lYN310q4z/P5fPHk9n86cVcfllu5bhDzoAwkJpJHpSMXkW6m4SMiUHkTgumZJ6M4nnBFMwWUuOpoGKphOL5gZQsEFK2WEzDylDavFVslznYrYpjnzaRPbpEtimj6ZZF0OCrpHp1KBt8w2jw11K5TEqth4J6TyUtfnpaBUY2Cs10h8XQb0hmly2TAXMaW7XxTwDgBn8tNX4aNvgZH3cBQ8h4RkjqNAEZM0WsWSwfBsBhDWtYP1kjR4wYQZ2fllaBkWZfHW2BJjaKrWwOi6ZZHUWHLZnu9EL2l9fx8sZuTm3fxZm9+7j4wkEuHTnAW0f28PZzO3m9ZxMv1FWzJTqRGpmRam8ZAyI5R0KVvB0fxQfZcdypyeSTphw+bs3h8+4iPutdy6e9JTzoLeez7eV8sn0NjwZK+XxHJV/tquabXWV8uyeXT7rjub8pltsNOVxIj+eQwUp3kInDEbnsMmbRLkukOSSZhDlqdOMDiZiuIGK6AutkCeYJAqwTRFjGC7G5ibFPkhI5RUbExGAs40UYxwjQj/LHPkmKfZKU2BlhrhHwEASa3cVoRvu7QG5o/Bs3R0OBdyypK2xEz9MQu0BH5BwV4TPlxC3U45itxDYjFJ27CMu0EExTgtGNDyRqZhhpSyxETJW5HMl5q6IwjBdS7JdA7Gz14/8vJWaenviFFuIWmLHP1pLiEUmhMJ1s/yTiPew02arpiGtmT+EAxxuPsi66lgJ9EWXGUuKX24iYFUb4JAn2ScE4Jom/7wBO8MMyJQjzZBEGdwGGCQEY3QRY3YVofrEa5X94oP53D3Q/X0XkBBEJkwTEjpxG2vg5FE9fTtvSILYsDWLLIiG7Vks5FmLgFZ2ZV/VmTkfYeDPcwhmNhtNqI+dM0ZzURtE6P5CUf5tF3P+chf3fFxA7biUVq81sFBg5KlfxnkXHrx0Wfhvl7P5djbXzYXQ4V2IiXKD1w927m0kxT4xkP0pP5E5qvMuwcSs5lrsZiVxPjuF6qjOmZSj/739X9/LS+Cg31WnkeJwZeCMtzhUdM/TsSlIUv4m389sEB1eTo13h0kNh039f19PjuLUmlZt5Kc56fCP4ZmkWN0uzuFGayY0KpynkTnU+g9UF3Kwudu4ANlXwUfM6bjdXMNhYxu2NlXzUWcP9rjo+7m7gXk8Dn+zq4N7uDu7v6eTT53p48MJ2Hhzbxf1ju7l/Yh8fn3yeT187zKdnjvDJueN8ev5FHlw48cT4d6gDOGQG+eKtk3xx6WW+evM43/3mLL97/zU+f+sEl7vbaQ1T0uoRxHaBht1iCz0hNnZbU9ljcbDPGsE+i4O9Zge7jRHs1EewTWWjX2llq8zEZomBziAdbUItdQGh1ATIqPINZZ2XlOJlEgoWBZM3X0ryFCGx4wOIHO1H1GgBCaMCKJ8uoWmFnF1qC9c3F/LZoXX84XwF354p4qvXCnl0vJCHL5Tw4FAZD08U8dWptfztfDV/PbWO/zxawu/3lPFgaxGHrGo2+vhROs+D7MmryXT3JmW8J/GjlpE8biUlc8WULxqqIArn+FC60J/1y0RULg+iUaCiRaSlXxvNLlMyO41JbJbZaZfYaBVaqVmtpXKlhsqVGqo81dSt1lC9Uk71SjmNAXraxFY6Q+z0aBPoN6eyIzyTPmsaXYZE2sMctMhsNEhM1ImM1AoNlHupKVoRSu7CYJJnBJD6jJCMOWKSZg2PgIc1rGH9dI0cMWIEtQE6ZxRBkIXOEDtblDF06xLYbEthW2I+2/MrOFDZyIsd3bw2sJvX9+zlzcMHuPjCfi4edl4EeW1rB0cbNtCXmE6dwsL6VcH/EgD8YiCDT7rj+bQrgTuNuVxIj2dvmJYDugRejCliQJdOiySWqoBIHFND0E8QYpsaim1qKJZJYufYc6IE01gBNjcx4e4SV9ncxJjHCTGOETwBgLGz1S43cMRUGfZpoa6IlqGYFrO7mKQFBhLm6UjzCMc8VYp5qhTLtBBiF+jIXOUga3UkkXNU6NxFRDyjwDItBO04AbqxAmyTpZQFplDsl0DMLBXKp32ImCojc3k4hT5xj/cJlejdJRgmhlCjKKIiJA/jVDmR8wyUSHNI9IwkW5BMtiiVmJV2Kk3lbC8c4Lmqgxws3YN9thrtmAAiJkqwu0uIcBdhnSjA4h6A0c3fBYB6twD04/3Rj/fHPEGAbqQ3xtG+WMf4Ez5OQOQEEVHuAlKfCSB/URBli8XULgikfamQXo8gTkg1HJPIeU2p5LxexxsWLecVAi4blZzSh7PVS8GaST7o/udKjP/hhe0XPuRO9aV2kZBnpXJeDlNyVqPggwgTv4m08iu7+QkQ/D8FwKHu3JBT91ZyLHfSE/4pAP7wPrAL0lJj+Sg3lbs5KdzKTHQB3xD8DT27kRbH1eRoPkyM5EpSFNdSYp5476F8wR/WrewkbualMJib7DSFPL4RPLg2k8G1mVxfm8H18ixurneeh7tRlc9gVRF36su421TB3aYKbjWVPwGA97bUcq+rjrtb67i/YyN3d27k3u4OPj64lU8O9fPJkR3cO7qLey/u5f6rz/HJqUN88voLfHz2mAsChzqAX7x18p8C4JeXXuQPvzrN1788xaO3TvDR0f0czcujbmkAXd6h7AgysTXESp8xgQFjOLtNVvaYIthjsj8eA4fTF2ahV2GmK8TIluDHFWKhUaikXqhkQ0AYVb4KSj2klCwPYe1yOXnzpWQ+IyFtupj06VJypwVTPkNI3ZIgekJUfNCUy8f7y/j6tTK+Pl3CN6+v5dtTFXz7aiXfnKjg82M5PDqcyqMDqTzalc69riQurrFy1B5Gm5eQitk+rJniTaZ7EJnuQWRN9iV7ih/5M4WsWxxKxWIJZQuDKJztR+EcH2pWBtPsp6RDpKc92EiH1ESvOpJt2jh6VdG0CI20CE00+hup8lSz3kPtAsCalUo2rAqjzktFu8RGlyKaXnU8202pbLemM2DLcMKfKtoFfzWBWir91FR4h5G/VErOwiAy54rInCtmzWI5xSvU5C1TDAPgsIY1rJ+skSNGjKDaT0Ob2Ep7cDhdqlh69Il0m5Lpjs5iZ8ZadhRVsr+6iaPtW10A+Mah/bxxaC9vPL+Dc7t7ONXVzrHGWranZNGoCv+XAeDn29P5tCeBB1sTuduUx5uZiewKVXHElsFLcSUM6NJpFsdQ4ROOxU2EfoIQ6xQZ1ikyzBODsE0U4ZgsxTRW4AI/64Qgwt0l2CdJsYwXYRobiGNyyBMA6Jgud+0FRkyVYZ0UjMktCNtkKcYJItf4N3KGggxPOzp3EVo3IaYpwSQtNZPvH0+ebyyRc1RoJgRinxWGdboM1Wg/VCN9sUyUsEGWS21oHjkrHch/vpr4uVpiZ6tZL86gwDsWy0QpETOV6NyCqVeX0mKqxDhVjnl6GFl+iaxTFbHBUE6xPA/TPC2lqkJ60rs4VLGfo+UHyPaMInJaKBFuYuwTgrBNCMTs5o/FPQDTJIELAHUT/NGN80M3zg/jOH/0o3ywjAvAPkGIw01ElFsQkW6BpM6WULRUSfmyMGoW+NPhIWKHn5TDQgnP+wfyhkHLZbuN9yKsXNIE86ZSSudiX9LHLsH0PxZiGBmMbbyC2Ily6haH0O8j5ZxCzCWVhHcMYfzKbuY3kVY+iDC5fv4pAPgPDRtp8f8UAO/mpPzoPNy1lBju5qQ8AYdDf38rM9FVg+nxXEuJ4WpytKv79//VXRzMTHDB342cJAbzU7lZlM6NkgxulGS4AHBwXQ63KvO4XrmGG5WF3K4r5U5jOXcay58AwLsd1Xy0eQN3N29wjoIH2rizo80Jgfu3cP+5Xu4f3s69o7v46PgeFwB+fPowH5895oLAh2+89KMdwB8B4Fsn+OaDU3z1/ikevn2CL19/kbdbmtmwLIC2VRL6hQa2hFjYqo9lm976xA6gcwzsBMChHcAtwUa6pCa65eG0iDU0iTXUC9VsCFBRsSqUspUy1q1WUrIslMLFMvIXyshfEMra+aFUzRXRsNwJgO835vLxvvV881o1vztTyR/PV/LnCzV8d7aWP76ynq+OZvNwfwK3u6O43RnLhzVRHLHJ6REJqFkUQNF0P3LcBaS7ychwDyFvuoCi2WLKF4ZSuVTxBAAWz/OjdlUIrQFqNomNdCvtdCvt9Gmi6NfE0qOMojFAR4O/jjofHes9lKxboaLKU0v1Kg3VHk74a/LTsSU0kj5NAtv1yey0ZjBgy2C7NZ1N2jhaFQ7a5BE0BpvZINSx3ldF2Wo5eYslZM0XkjFHSM4CKQVLwyheoSZrUcgwAA5rWMP6yRo5YsQISrzkNEostMsd9JlS2BaeQa89g82xWfRlFNNdWM6O9XUcatvsAsDzz+3l3LO7OHdwGxf29vHa1g4XADZr7NT6Kf5lAPj59lQe9SRztymPywWZ7FfpOWLL4FB4DruMWXTKkynzsqJ+2hv9BCHmSVJME4MxugmxT5EQO0OBzS2ImOkKIqfIsE4IImpqKImzNURMDMY6IYjIKTIXAMbP1TpNGI8vghgniFx7gya3ILI97BT7JZDtYSdnpYN8/3g0EwLRugmxzQgl2yuKUnEaBQEJJCw2YpgkxjxVinW6DMXT3ujGCoicoaBcmEq1NJv14gyXAcQwXkjOSgfV0mz040SkLo8geq6BHK94SiXZpHlGk7A0nMiFJjbHtXCwaCctkXXYFhkJX2TEMUuPfbqKnOVRNIhzyV5gxjE+iIixQkxj/DCM88EwwQ/zNBHWqWLMk0Vox/uhGeODerQ32lHeaJ/2wjjaF9vYABxuIuImS0maIqZikZxaDwXNq0Lp8ZNwMDiUF5VqXlapeFGh4KQhnJfU4ewXaciZuIT4UfMw/49nCP/ZImJHryJ1vC+tqyx0eZs5HKzjpFzNRaWYS6ogfmnR8GuHhV87LK5O4E8dAQ91/e6mJbi6gYPJMT95BPwPu3ePr4j8fddwqDv493UlKepH9WFylNMIkp3orLxk505gcTrXitK4WpzG1dLvu4BX1+VyfX0Bt2rXcqu+lNsNZQw2lHKzqZxbbeu5017Fnc5qbnVUcaOjkjv9zdzc1syt7S3c2dPJ3QNbuftcH3df2MHdY7v56OWD3H/1Oe6/doh7rx/h/pmjfHz2mGsXcAgC/x4AP7/0Ml+89zJf/fY0X314hk/ee4nvfnmeRy8cosVPRt2KQLYEqNkYbKRdG0mXSk+/Wsc2tfHx/p+F7RorO3UOtqlsbJE69427pCb6lA42hYbTIQ+nLcRCs8TIhgAVVb4KNgSoXFXjr6TGX0mDr5L21Qq2CsPYb7RxZWMFDw828d2FDv56qQ3ea4d3G/nz+Sq+OlLIp9vSud0az7l0La9EqTisV9DtJaZxgYD1s8QUTQ0iy11AxhQJedOlrJ0npXKpkurlaioWyVwj4IrFYmpWhtDkG0abQMNmiYkdxni262Pp00TRq4qmS26nwV9L1SoF6z0UlC0NpXxZGFWeWmpWa6ldpaZVYGSTJJxt2kR2GFPZbclgly2T7dZ0+kwpbFRG0SQLZ5M6mjZ5BPViI+t8lKz1lJE1X0juIjG5C4PJXyKncJmSvEWhRE0evgQyrGEN66dr5IgRI8j3lFIrNrFR7qDXksp2RxZ9kVm0R6ezOTmPTbnF9FfU8GxrpwsAzz27h7MHd3L2QL/zJnB3J0cbNtCflEGzxk5joPpfAoBf7sjkyx3pLgD8VUkuhwxWnjUksc+Qyh5zDlvVGVT4hKP6hRf6CUIn/LlLMLoJcUwNJm5mGPZJwSTMUhMzXUG4u4TYGWGkLTBinyTF5iYmamoojskhxM4II3WxmdjZamcW3w8A0DFdjm6sgHyvGEr8E8lZ6aBOvoZiYTL6iUEYJomJnKMi1yeGUnEa5cEZ5PnG4pitROcuwjQlGPUY5yUS+7RQ1gYkUSFKo9AnjpRFJlIWmVzmlLLAFOLn6rFNV5C0JJzExTZiF5rJ9Usizz+ZbP8kqrRr2Z3bx4GSXVRoS4hbEUHibDOGMUHETFHRHlpM+coYIseKCB8TiHmUL7oxXujd/LBMD8L8AwBUj/ZGNcoLzUgvNL9YjfYXqzGN9ME2NoDEaaFkzAihboGEpsVC2pcK2OErYJ9IwHPBIl6Qh7JXFMyW1cE0LhFTOt0HzS9WI/+FF+FjfciYKqBijoSO+YE8K1BzJDCMU6Fqzqi0nNNpOa9T867FwK8dFn5lN/Mru5kPo8O5kRD1kwBwaO/vo/RE1z7gUDTLPwLAobHtYHq8C+6GuoL/qIZev5Od7ALAH3X5HgPgtZSYH9XV1BiuZydyLSvBaQp5DIDXitK4VpTGlaJUrqxNd3UBr67L5dq6fG5uKOFWfSm36ku5Ub/2CQC83VHFzfZKrrev51ZvI4P9Tdzc1szt3R3c2d/FnWd7uXN4gDtHd3H3pQPce+VZ7p16no9Ov+CCwKFdwEdvvvxPAfDLy6/w9dUzfH39PPcvv8QfL5/jixPH2CTRsGGFgA4/Jc0SPa0aB5vDtPQqNfSrDM5omMcAuNcUww6t3WUC2Swx0BtmZ4vCzqYwO+2hNlqlZuoCVWwICKNWoKReqKZBpKFBpKJeqKRFoGSTj4I+iYrnbXautVfx6b4mvju/mb9d2gTvdfK3i3X87lQp93elc6U+ll8WR/KcRkK/0J/Nnj60zhdR84yAipliCqYEkunuS+4sIcULQyhbIKNqmYqqZSpK5wdTtjCIdUuCqV4ho8lXRYdIz5ZgM/1hDrbpYuhVR7JFbmNLaAQdwRY2eCtZ5yGjfJmM0iUyypYqqPLUssFLR4O3jnaRha4QBwP6ZHaa0lwAuM2SRo8hibawSJpk4XSqomiR2agV6SlbLadwuYTUWX7kLZawZnEIJR5q1q7UUrA0bBgAhzWsYf2X5AyCXhnMhiAjG+UOeqyp9Ec6AbDVkUJ7fBatmfl0l1Wyr7n9RwB4Zn8flw4OcLq7kyP1NfQlptOkjqAlSPcvAcCvd2Xz1c4MHvUkc6cxl9+W5XPEHME+TRy7NInss+bRq8tmvZ/9CQA0uIkxTAgkcpqU+GeURE4JIWmOlriZSiImBhP/jIrMxRYck0N+BIBZKyJIWmDAPi0U4wQRJrcgjBNExM3RoB7lx5rV0RR4x5Kz0sHW8BrWBqVinCzBPFVKzHwteb6xlIrTqFUVUB6cQcJiI+rxAvQTg9BPcF4EsU2WsjYgiVJBMulLrSQvNLpOy4X+bBX5XjHke8UR8pQ3qcsdxM43oXGTsCYghdLgHAqCMoj3sNPmqOPVxuN0p20izSeOrMWR6J4OxDZGQqtkjQsAbaMFmEb6oHkMgNYZ4h8BoHLkatRPr0b1c09UP1uJ7uerMI/yJWm6nNxZMro9Q+n2ENHnKeRgUBCHg4N4QSpmwM+fjcs8yXNfQtLIRTj+bQHKySrkUw3EzFRQND+U9pUqTkk1nBRKOSMK5rw8jHMaLafN4bxutvK21eSCv187LK4rG/83AfBKUhTXU2MZTI/nTnYyH+Wmci8vzTXmHYK+oa7fDwHwdlYSg+nxrr/9ewD8ZyaQHwLg0I3ga0VpXC1MdQHgtbJMBtflcKUixwWAN+vW/ggAb2+s5HZHFYMb13Nt4zpu9TZyo88Jgbd2tXN73xZuH+z5lwDgF5df4ZtrZ/l28A3uX36J318+yxcvH2er3EitRyAb/cJolOho0TrYpNDQE6amT6lnu8b8uKzst8SxSx/JFqnTALJZYqBH4aArzOHMvXvcBawXqqkVKKkVKGgQqWgSa2iSqGkUq2gTqdjkG8o2qYbDEZFca6/i4z2N/OncFv7y5iZ4p53vLlTx+Yt5XO+O5e2icC6khLNNEEDTghVUTV1K/fQAKif7UzpNSN5EX9LdPMif50/FihDKF4ZStUxF5VIlJXPFlC4QsW5JMBtWytkYqKdbZqM/zMEeQwI9Kgdb5DY6pCbaJWZaRQaqVskpXy6lbGkIaxeHULpE7gLAJl8DnWIb3aFRLgDcZU5npzWDfnMq3fpE2sIiaQ6NYKPCTmOwmWqBhpKVIaxZIiJxupcLAMtW6ajwMrJ2pZa46X7DADisYQ3rJ2vkiBEjSFosYK23kiqhkU2qOHoMKXRq4mnXJdBmSGBLbC4DORXsK6vlRE8Xr+0e4NzBvZw9sIfzB/dyfvdOXt/azbGGJranZLHJGs0Gv2C2C50xMBdj7FzOiOZ2dQafNOXwSVsuDzav4WF3MQ/7S3nUv45H2yp4tHMtn+9ayxe7S/lqTzHf7inhs74CPust5lFXCR+3lnJlXS7HwjV0ycLZJE9iizaXysA4EuYoUY0NRDEmENPkEKxTZFgmiYmZISVpthLrBJFrBBwxMZjE2RpyloVjcxOjH+VPuLsEy3gRNjcxSSusZAfEEb3EgGlKMGZ3MVHT5URMlmIcF0hBQAJrxWk4FuvoS2yjVJiGeaIM1VgRlulhZAUksSYonSJJFiXSHDaoSjC7h6AeFYh+pJDY6RrM44PJ9Yyl3VBJuSSH4Kd8CB0VgG2OFvNsNZGLzRwo2UVBaAamuSqiF9sIn2UgYUEMeV455HhlUxCUT5G8kCNNR9lbvZu66CqSl1tRjxcQ8YyCpEVGHDMVGMYK0Iz0Rfmz1RhG+mMbH4TdPRjT+ACM4/wxjPXDONYH0zhfrON9sY71InzcaqIm+JAw2Z/c+SEULAph3dIgKj2CWbdcTM4sH1KmeJA4cQXhoxcSPmYJplGLsY5dRvQkbyoXCmheImSbn5K9QRoOSQ0cl2l5WeEMin7PbOV9m5VfWUx8YDbyS6uFD8Jt/CoinN9GOrgSHcWV6Cg+jIrkSnQUV2OiXdEv1+Mjn7jNeyMhimtxju+dvz8YATvDo50mjSHYG+roDe31/RDu7uakcCvvn9fN3GQGc5K4kf39qbcfOoOH9gj/EQAORcNcT4/jRkY8gzlJLjfwzYI0ZyxMSQaDazO5WZrF9bIcbpSvYXB9AYNVRdysLuZW7VpuN5Rxt3U999urud9Rw/2OGj7qrOFO9wZu99dxd5yYTysAACAASURBVHsDH+1u487eDu7u6+TeoT7uvdDPR8d3c+/FPdw/sZeHJw/x6OQRPjt1lM/PvMgXZ0/w5YWX+eriSb588/s4mEdvvcpnF0/y5Vtn+Oa9s3x7+RzfXj7NN2+/wu8uvcyzeemUBgSwdqUvrX4qtvhr2SQzslllplsXTpfGymaVmS1qC70GO926cDrDjHQoDHSGGdmitrFJZWOTKoJNYc5R8MZgM21BRjrFVrqCI+gOcdDzuPokdvoFOnaG6HjeZONydRa3e0r4w0v1fPdKA3852cJX+9ZxqyOHM9lR9Co1dIi01K2W0eynpsVPx/qlUkoXiCmZK6ZkbjCl80OpWqplg4eeupUqapaHUrlEStVyGdWeIWxYHUpniJnNShvbLbHssMWz3RpHl9LGFrmNVpGJBn8dG7x0rF+hpXRxGMULQ1gz15+C+QFUrhJT6yunTWKhQxrB1rAYdtky2RmeyYA1nV5LKl2mJLYYE9moi6UxzE6dxEqVv45iDxlps/1Jnx1I3iIZuQtlrFksp3CpmoIlGnLmK4ibNuwCHtawhvXTNXLEiBHEzPUlb3kIJV4qmoLttCtiqZdE0CCPokEZw+aYPHbkVnKwoomXerdyes8Ozj+7j3MH93Lh2X2c372TM909vNjUws70XDbbYqj2ETMgkvGCLIyLMXbeS4/iVlU6Hzdm/yQA/GJbEV/0r+WzrWv5dGM516vyeSXaRItAS5MoktbQVNZ624meIUM7IQjlOBHmKTLCp8kJnyolcqqYmGkhOCZLiZ4mxz5J6gLA7KU2HJNDMI8TuswhNjcxGV6R5AYmEDFfjWGS2BnePF2ObaIE20QJ2V5RZHtHY1+kpS+xjRJBCpoxIhSjBFhnKMkVprImKJ0mSxWVqmKqw4qIn2tENVLA/2LvPYObzNN07+ecfc/Znd1pumnA5JybjAHnKFmSJVk5RwfJOWcbY2wTTDZgjAkm2JgMJjSZJtNAQ+cwM900wSaHDrMT9pyteuv3fjDWwHT37PacOVvvVPmqukqP9FiWvtj1q/v+39et7y3C0EeMuZ8U+2AlVdF5LNdVEf2LWYT/j+mkTnUSP8GMdpCM5uz1bMlpICvMi2FoHKlTE9D2jiN/Zi4FgfnU6hYy3ziPjUVNtC3dx6nVRymLTscwUIy2XxTWoTKcw+RoeoaifC0QxT/PxNAzzBeHY+oT1hmT0zcCi18o5j4hGHvOwtY7EFffIBL7hZA8MJTM4ZFkjYgieWgE6SOj8AwOQftPo9H/YhTm18bheOMtPH6TyRkaSOm4KObPVLA5TENrmIp9Ih2HpHqOxpp4J87ERa2ZqzoLn1jtfGZ38LnFwqcm0w8AsAv8Xr6+mZTI154kvkpyctPj8gHgreT4V563p3t8AyE/BoBd0Pe3AMDbOck/AMCuz/kxf5WR+AoA+qaB/woAvL9qng8AO+rnc6+pE/46ti6hfdsK7mxfxd0dq7nX1sS9g5voONLqg8Anp9t4evpQJwSeP9oJgZdP8N3V0z8AwGfvneG76xf4/sOL/PYFAP72/VP87r2TnFk4l1p5LBUzQ6gLVbEmRE19jI41CgPrNVYaVWYalEYaVWY26uxs0NpYG2fyeZ3aRqPaydo4Fw0KB2vkduolJtZITGyU29midNGsiqclLp5mpZsdcje7wg3sEms4oNbzYWkKd1YU8N22ufzrzip+v2s+d1cV8H5pPDvUElYERrF4hpQVQUrWRBhYE2Fg3uQYaibGUD1BQvUECTUTY6mdpmLRdDULpsiZN0nCvEkSav0VLA5UsCxExVqZhQ0aJ9tsXlqsHjYZ42mINVEfY6Q2MI55M+RUTVVQNUXN7LfklIwVkzcikKIxISwMlLAsXEWDzEFjrJtNai87HXnscOaxzZbtA8C1ei8rNQkskdupjTZTHaSmaJKI1GGBZI4Mp2xqHPnjpRS8JaNgvJy8sXIyR8Tg6te9C7hb3erWz1cPQRBwDg8ia5yYgslyFoRaWRrtZmGkg9qYeBbJk2hwF9Ocu4A9lcs5tqGRs9ububxvF5f37eLK/t1cam3hwoaNnKxbxc7cYtY7PMwPjKYlSsZhmdIHgLdrMniwJOdnAeD3zeV8t6WC5+tn82T1XO7UlnEhxcG86THUzDJQG5lIwRQD9gHRGPrHoO0Xg/7FGUBj30js/SNwDRARP1iGa6DUN/2bPFJNzkQLCUPk2PuJfbb1FZEfkkRxdBrW0Z1n99zDFLgGy7D0jcY1WEbaFAspk824JurY6FlBaUgKyh5hxPYIxT5CTbEomxJxDhu8q1hirGZhXDlzwrNwDonDPVyD1k+MY7ga6S+DSZvsYIW+GmWvSKQ9Qkgcb8I1Woe2XwxzYvLZU76V5c4FGIbGkRuYRtwbsWROSacwqIBVjpXUxa9gqXcZuxfu5GrLZersNSRONqIeGI3izRB0/aMx9I1C2zsc1evBmPpEYusvxtpPhP7NYIy9Q7H1j8IxIBJbv3DMvQKx9Q7E6RdIvF8QCX4BuHv74+w1C0OvEB8kav95IqbXJuDsOYWS0aFUjItg6XQxDcFKNkXqOBxr5ojMyFG5gVNKI2fVFq7obVw3O3jf7ORTu5PPHU4+t9r5zGLzwd/nDjtfOB38yuXkVy6n7/plAPwy0fFKG/hWcrzv+gc7e/+DIZD/UwC8k5vySlzMfzRo4oO/bC9fv9gO8nMB8M7iCtpXVHFvZedquPur59NRP58Hm5dwr3kp95qXcrdlObdbV3K7dSUd+zfScaCJ9re3vQKAT04d7ITAc0f45sIxvrl0nG+vnOLbK3+aCH5+4x2eXz/LNzcu8N1HF/n+40t8/8k5vv/gFL+9fpL3G+uoN5uoCAhleWgc9aFqVok0rI7V+SCvQWn0VQQ3aG2s11hZp7awXmNlvcbOeq2bdep41iqdNChsNMptrJPb2KJysk3rZrs+gR06Nzt0bvaoXbSJzOyP0XBYoeb9zHi+mpvOgxX5PFhRwL1ledzIT+SYQ09DSAh1ATEsmymjLiCOVUFq6gLiqBoXzuJpsa94qb+Cpf5KaiZKO6t/kyQsDVBTF65ldZSB9Qo7m/TxtNqT2WpOZL3WwaoYHcsj1FRNk1AxScTsCRIqJ8VRNk5G8RgR+SODKBkXxrJwJfUxRjaqEmlSeWjWp7HbVcBOVz7bHbk0mdNpNCSzVu+lTh3PIpmVqhANFTPkFE6MJmNkCNmjIymdoiRvnIS8cRJyRkvIGC4mZXAktt4zuwGwW93q1s9WD0EQsA8JJnVkNBljYqiYrmdekI0loiQWxXiolXmpsxawIbWa5sJFHFyzihNbNnJ+Vyvnd7Vyac8OLm5r5vz6DRxfXsfu/FK2JKZTJ4qjVSTn7dg4HwB+XZXGvUVZPxsAv9lUzuOGEh6vqqRjSQXXc70UjQqg+C0Z5f5GkkdI0b4RiG2oAuOgWJQ9w1C+HoK2Vyi2fuHY+0Zi7yfywV/SMCWpo7VkjDOQPFJNwhA5zgESkoYpSRgipzDMS3VcId5pFhQ9g3G+qP6Z/aLwjFThHq0ieZKJtAAnq+0LyJnuQtsrGsUb4ZiHKCgR5zBXWcIG7yoa4pexTF/FctUcsqe4MA6WI+kZhrKvCONgOd5JNuYrSsmdmYRnvJlQYRLyfwnGO8aIdYiSrJAEljsXkB2UgmeiE+cwK7bBFpIneFnlWMnqpFUs8Syl1rOAea4q9pRvpT5pMRXKfIwjY1EPjCbOLxx5rxBi3wgirlcoqt5hKH4ZgLpnILqeQZj9wrH2DcPWLxybXwjWXgFYevpjfX06ltcmY/qXtzD/81uk9g0gtY8/+YNDqQvQsHqWmlXTZTRMjaRxWgQ7w6QcjI7jkFjOOYWKS0oV17R6bhhMfGCy8LHVzqd25yv+zOHiM4eLzx32n3QXBH6ZEM9XiX86F/jyHt6XH7t29H7tdXM7LZFb6T/ejv1bAODdvNQfRMa8fDbwz93VNr6V7eXmi7OAPxcAb9WWc2dZJR111XSsrKFjZU1nLuBPVADb922gvW0jdw+30P72NjqOtPLo5D4enzzQCYFn3+bZuSM8v3iMZ5eO8/zyCV8u4LcfnOXbDy/w9P0LPP/4It98colvPj3Hs49O8c37J7l9YDsHyoupEUtZEChjZYSGJeFylovjWB2ro16up16up0FpZL3Gygatjc1Gl89NOjebjck06VNYF5fAOpWTLXo3LYYEWnR2dhjt7LLY2W22sstsYq/RwgGVlQNKLQeVKs5YNFyJN3Dda+VSgoXTNgPbZGo2RsVRH6xhZUAcdf5KFk8Ss2RyDCumx7I2WE19YCxrgmSsCZJRHyhlxYxIlvqLXlQEY1gwRcaqMCNrYyxsiO2Metmkj6dJ72JtnIXlMRoWBkuZP0vC7IlRlI6PoHhMFCVjJBSOFFE4KoqKSSIWzFKwXmFlizaBbaZ0Wgzp7LBks8ddyE5XPq32HDZZMmg0JLNGm8QypZMFMSYKp4gpntzpwoli8saJyBwZSc4YMVmjokkbGknyoAg8A8Kw9+keAulWt/6eVCV0/sG+7N+8dP+fBEFoEAThG0EQfi8Iwn5BEPr+2e8YIgjCUUEQ/igIwlNBEJYKgvD//Mzv0UMQBKyDgvEMiSR5WDQlkzRUzjAzP8zNvMgEakSJLDXk0eitYnPeAvatXM6RjY2c2d7M2R0tXNjVysVtzZxbt56jS5ezO7+UZk8mjQoj28UKjshVvJfo9AFgR23mzwLA77aW8WxjKQ9WF/KwroKOJRW8n59C4chZFI2XUjpNT+IQEarXZuIcoULbLwZNnyjMAyQ4h8pwDIjE0jvMFwTtGigldbSWtDE60sfqSR6pJmmYEvcgGSmjNCSPVJMfksRCXRnZwQnEvh6IdUAMpj6RPgB0jlSSMd1ObriH5aYqkscb0fUWIX89DFWfaHLDUqlUFLPcMp/GxBXU22pZra+hKioXWa8IRL3CiHwtkPSZCeQFJVMWlU2DbRHFgSlE/repxP5jABY/CVmTnbgn6cmNTGWhdi6pUxNIm+jFMzYR8yATq52rWOFezvKUFVTaK/BEJFDvXUJDyjKWOmtwTzGiGSImtk8osW8GE/tmMLr+0RgHxaD3i8TULwKzXzj6N4PR9wxA3zMAY89ZPgC095yBq9cMUgaFkDU4mIWjg1g8JpgVEyLYNCuWLUFSWgKkbA8QszMomlMyDedVJi6ojFxRqbmh1fCpxcxnFhufWWx8ZO5s/X5itfOx1c4nNgefOxP4whXPF84fQuBndtsrVcGus4C/clv5TYKdr5KcP6z4vRgS6WoT305L5HbGD4cyXt7a8X8CgO35P54Z+FOTxH9LAGxfUeUDwDsrq3/yDODdveu5u38Ddw41+yDw4Ym9PDrR1gmBZw53QuCFozy7dLwTAl8A4HcfnuPbDy/w5IMLPPvkIs8/vcTzz87x9KNTPP/gJM/OHeHSymUs0+iYO1PM8gg1i0JlLI1WsFLaWQlcHaujQWlkndrCBq2NreZ4mi0JbDXHs0kfz1ZzKpuNaaxXJbJe7aLFlMh2SzzbTQ52W23stTvYZ7ew12Ziv9XMfp2VfToDbRoNxwwKTpqVnLLEcdyk4YBWyyapgYZoAyuCDawK0LBmlobVM1TUz4xjbaCGrSITDUEyGkM63RAsYoV/KEunRlAzUdrZ/p0mZ3W4iXVSG00KF5vUbjZqXTQozdRJtCyOUlI9M5pqfxEVk6IpnxBFydhoCkeKyBsWSeGoKObNkLM8XM8WrZttRi+t5gy2GTPYYclmt6uAHc48WqxZrwDgUoWDeSIDpf4ySqdKKJokIndcJNmjI8kaFUXWqGgyR0aRMjic5EEReAeGd7eAu9WtvzNVCYLwuSAI/V5y75fuNwqC0CEIQrQgCP6CIFwVBOHdl+7/gyAInwmCcFoQhKmCIMQKgvBMEISFP/N7+CqACcPCiR8aRvJoERlvySieqWdOqI3KMDuLZclssJbQmj6PQ8sbObF+C+e2beXqvu1c2buV861rudC8hlNrlrKrpIBdeYVssDjYIo9jn0rFebeFqylW7lSk8GhBJs+W5fLdmiK+Xz+bbzfP4cnmuTzaVMXD5vk8bq7maXMl37SW8G1rEf+2ezbfby6mY0Umj1ZU8Lyuls8Kc6kYE0vpeBM5Y7R4h8txDBRhHBiFbYQUdZ8QHMMkJI9T4xkuxzNcifwX/pj7ibD0F5M+wUT2FBtpbxnJnGQhfYIJ97DOAOj44UqcI1SsNi+gKqYAQ38piWONKN4IR+snRtc3htRJdkrDMpgTnUt5RA72YRqM/ZXo/GJR95GSOcNLlayMvJBMkqcn0pS6jiXWRSw0LyDmtWD0/SRo+ojQ+okpCk6lVlnOavMCdmVtRPRPs5C/HoZxgIykcQayZjgpiUimSpbD7vwNBPz3icxXl5E2K4FCUS61pgWscC9nsX0JyxzLcIwzsUBTwdqE5WTNiidnlhvTIDGmQWIM/cKxD44mcVQsin+eTtwbocS9Ho72jRB0rwdj7DEL62vTyBkWSeGQEMqHBTN3dDh106U0zJDSHBRNa7CYnWFS9kfLOSCWczhGwek4DWfj1FzSanlXr+eKwcANo573DXo+NBn50GTkI3PnOb+u60+snUMgH5lNfGgy8psEu28LyKd24yth0F35gF8mOnzn/H7MXZW/rvOAd9OSuJ+Vwv2slFd2+t7LTOZ+VopvWORlt2ekcCs34we+k5/F1znpfJWVyu28TO4WZHMzO427henczk/lTkEaHcWZ3ClI42aOly+zkjpbvC/8VbaHL7M6J4Hv5qXSnt8Jk3cK0/m6MI2vC9O4+SIS5mZZJwjeLMvm1ux8OqpLuVdTRntVCTfnFnJ34ezO7SBLKrm3vIoHdTXcXzWPe2vm0b52Hh2N83mweRkPm1fxcNtq7m1fy/3d63l0oIVHB1q417aVjsOd4dAPT+zmydk2np47wJNzB3hy8RBPLx3m6dUjPH/vGM9vnOCb90/zzftneHrjJE9vnOTJB8f59uMT/O7jU/z7R+e43dbC7pwMZs+MoCZITG2EgkXRcSwRq1kpN7JaaaZBbWONyspajZ2NxniaTAlsMieywZTEOpOHtaZk1hs9bDInssOaxF5bEvttiRw2OzhitHNMb+Ko3sAxrZETBgdHDU6O6B20xVnYpTCxS2llh9xMi9TE+igtjRFq1oaraAhXsS5KyxaZlWaZjWaZjc0xZraKrawP1bImQMnK6XJWToulzl/JoiA1i4LULA7WsFbqZLPaS4s+jfXyeBplLuoiTZ0DHwFx1AQomR+konqWgvIpYoreiqBgXBgZw2ZSOD6cxeF6VsbY2KRLYas5nfVGD7uS89nhyWV3ShGtCflstKSx3pjOWl0Kq+I8zA0xUOKvZO5UNXPGyykYEU36wGCyhoSRPzaG/IkyssaKSB4VQcrYKJLHRKLrO6UbALvVrb8jVQmC8PFP3HtdEIR/FwTB8NJr44TOP/DAF89jBUH4f4VXq4KpgiD8VhCE//kzvkcPQRBwjwjHOyqapBGRpI2TkDVRTqG/lvIgM+VBZhbGJLHOXERLajWH69ZyuqmZSzu3cePgTm4c3M6VvRu4unMD59avYG95Mbvzi2g0WtmqULFfrf5PAeDjTVU8bl7As5Yanm+r4rvtpXy/o4Tfbivit1vKeLK2kCcrq7i3uJqraSmUjpJQPNZA/ngDaaNVJAyTYR0ag2VYDHG9gjD2j8A2SISjfzQJQ2JR9wjENlCCdUAMKeP0pL1lxDNaQ9pbxhdr1+QkjVJ35v8NkVMVU8BccT6G/lIsgxXE9ghF1zcG4wAZ7lE68gO8VETlkDktAfMgJdo+MtS9JCjfFJM6NYFKSQllokLiJzpYZJhPg6eelQl1xPYMR907GmXPCDR9RGRMdVEjLWKtfTGHilvR9Y1B+stgpL8MRtdXhHOkktLwZColWTSnrkLVX4R1lIr4SRZyIzJZYJjHCvdyVrhWsCaxnszAZKoUJSw11ZAX7CFnlhv5G4Eo3wwmrmcA1oGRJI2Wo+sZhPqNMNRvRGB8Mwxzr1DsvYJI6D2LzIEhFA4MYPbQQKpGhVA3Vcxa/xhaAqPZHipid6SUw9I4jsvVnFRqeUel5ZxK4wPAq3o9N4x6PjAafMDXBYBdj13Vva7X/hwAuyJhvnBZ+MJl4Vdu6yvn/v4SAHZNCHcBYFckTBcAdmR4uZeZ/LMA8G5BNrdyM/gqK5U7+Vn/IQB+le15BQC7XusCwI6C9FcA8FZROjdfhEL/OQC2V5XQUV36VwNgR2sD93ev52FbMw/bmrnXtpX2Q9voeLEj+D8DgM9vvOMDwMfvH+Pbj0/wrx+d5N8/OkfH4R0cLM6nZFoIc2ZEUBuhoDZKyWKRirpYA6uVZtaorDSobTRqHT7422xJYqPZwwaLh3WWZJosXrZYk9hlT2Kf3cNBl4ejNjfHLQ5OmqycMJk5abBwwuDguN7OMZ2NtjgTe+RG9qqs7FZY2SYzsylaT1OUjvVRWjZEa2gS69imsNOqdLBNYadFamWLyMK6EA31sxSsnC6nblosy/2VLA7WsCREy/JwA40yF01xSWzRJNMg6dzxuzRU1wl//rGUTRZRMU1Cpb+M8iliSidFM3tqDLmjgymbLGKFyMKaWBdbjem02rPZaE5mpzeP1sRsdnjy2erMptHgpVGfyhqNlxXyBCqD9RRPV1A0Xkrx6BgKRkSTOSyczGHhZAwLJ21kBMnDQkkcHETiiFASR4Si9+sGwG516+9JVYIg/EEQhIeCINwWBGG70NnSFYTOqh+CILzxZ+9pFwQh78V1jfBDgBz+4n3Tfsb36CEIAomjokgdG0PKGDHp46VkT1KQM1lJ0QwdRTN01ES5aTDks8VbydHV6zjf0sp7bTv55NhePj2xlw/fbuHjg828t20dh6sr2FdczBqd4RUAvJZq4+6c1L8IgN+0LODbbfP4bnsVv91Rwe93lvGsKY/vt87mX7dUc2/pXD4uKeCgyUT+kEjyR2oonGAic5wW7yglzpGxmIaI0PiFYuwfgcEvDHPvMBKHyjH0CsM5JBbbQAneMVq8Y7S4h3Vu/fCM1uAaKvddGwdISJ5gpVKUh3mQHGXPCB8AWgYrMPSXku2fQFVMAc4ROvT9ZKjejEH1Zgyxr0fhmeikUlJCrbYG2xgTGQEptORtZXPOJoyD5ah6RSF7LQR172icIzSUhWeyyjSfwyXb8b5lQfFGONH/OBPxL2aifD2I/Jku5ogyWG2toSg8laD/PhHd4FhSZyQyVzGbJdZFrHTVsT5lHSWiPHJDUsgPSyMnMJFMfweSX84g9vUA5D1mYOwbSvwIaWf0S89QjG+GY+8djssvlKS+YaT1CySz7ywKB/hTMXQG80cHsWaaiA0zY2gNiWZ3uJg2USyn4nSc0xq4oDdxTqXhglrNu1otV3Q63tN3wt/LAPixxeyr+n1qs/KF08EXTgef2qx8YrX4ALArDPpzp9n3/NfxNr5MdHDT4/LFvfyYv/a6ff6xTMC/BQDezE7jTn4W7YU5fxEAX4a/l93VNn4ZAG8Vdfrrkj9V/zqdw+2KAu7OLaa9qoT2qhK+rir6qwDw3q51PNi/lQf7t/4AAB+f2c+Ts208PtvG4wsHeXLxEE+uvM2za0d5dv04z2+c4vmNd3hy/QRPrp/g8fvH+Oaj4z4AfHqqjbPzqyiYFEDJ5KCfBMBGrYN1OiebzIlssXrYYvXQZEmiyZbMBnsyWx0pbHOmsNeVzAGXl8PxHo473ZxyODlttXHaauG02cpJg42TBhsn9FYOxRnZrzSyV2Vht9LM9lgTW8R6Not0bBbp2CbVsT3WwB6Vlb1qB7vjHGyX2dgcZaAxWM3qmZ3wVzdNwXJ/pQ/+VkVbaJS5WC+PZ708nuXhBpaG6pg/U0H1dBmVU2IomRhF+RQxs6fGUDZZRMnEKOZMl1IyMYqqmXLWxLpYr0qi1ZrNLnc+m21p7ErOZ1tCFi3x2TRZ01mtjmeNxstKZQJLJE5mB2gonBpL1vAIcodHkjsqmpyRUWQOC8fTP4CEgQG4+8/E2W8G8QMDSBgUiNFvajcAdqtbf0eKFQTBKAjCZEEQpIIgXBE6Ae81QRBsgiD87x95z3VBEBa/uN4gCMLJP7v/z0LnP4HYv/C5/yh0/pPo8kDhRQUwebSIpBGRJA6PwDOyEwgz3pKRPl7K7GALK9VZNCWW886GjXx4sI0vTh3g64tvc+fKYW5e2MPdC/u4dWIHV9Yu49SCatYajLSoVBzQarmYYON6uoP2yjSe1Gb/KAA+aarkdy0L+F3LfH7fWs0fdszhjzsr+L6lgu+ba3i2YQFn0lLYKIlj/uQgknsHk9pfQuZIFckjFMQPlWIbJiG25yysQ2NIGhtH/IhYrH4RJAyJRdczBMdgGbaBEpLH6kgZpydhRBzuYQrfY+p4A2lvGbEMjkXxRjiFQSnkzEhE6ycm7s1IVL2iMA2MxThAxlxxPmustThH6DAOkKPpLcU8UIW6jxTvJBdL9fPZmr4R53grcj8JTRkb2DN7N/OVZSRPsKLvJ8HQX4qqVxRpkx3UKstpdCxhTnQunvFmPOPNRP7DFGS/mIG6RyALxNmUBCaxP7eJ+dICVL2iUPYW4RxtoiAsm0pZOYt081lsnEd2kBfT8Di0A8SYBkvQ+IWj7x+FoV84ut5BWAdGou8ZgLtvKIl+oXh6B+DpM5PkXtPI6PkWFUNmsXhMIPUTw2jyj2J3uIy2yFiOxyo5IY/jlFLNebWWixoNlzVarmg0XNPGcUOr4oZWxfu6OD40638U/LrO9HVN+Xad9ft1vO2Val9X+HPXSrgu+PtNgv0V0HvZXZXAlzMCuyJhugZEusKj29M9PwsAO4pyuZOfxa3cDNoLc+goyu0Ew58AwLuF6b7K380cL7fzU7lbmM7dvFTuF2VyvyiT2/mpvhzAOyWZ3CrN5Nbs+EeZngAAIABJREFUbN8ZwDtz8rkzp5Dbcwq5U1nE3bnF3JlX+lcB4N3tDbTvbuLe3s107N/CnQPN3D28rbMNfHovj8/s59GZ/Tw6f4BH5w/w+N3DPLnyNk/fO8bT907w9L1TPH7vOI/fO87D60d4/uExvv/gOH+8cZo/XjnF3R0tlEwLIWfMNBaExbIgQk5tlJLlUp2vDbxWY/cB4GZLkg8ANzu9bHansNOTwR5vKm2JHg4lJHLQ7eKow8Jxq5mTFh0nzBpOG7W8ozPxjt7MO3ozxzUG3lYZ2CtVs0eiYkeMilaxmlaxmh0SLce0Rk7qjLxjsHPSYOOYxs5+hYXmKDWNwXHUz4xj5QwFK2dpWBmopS7SRIPE4Wv51ottrIwyU+PfGfBcPiGKsrciKZ/QCXtd1b/iCZEUvRVBxTQJNQFKFofr2aD2sFmfyg57LrvjC9jtLWR/RgmtidlscWawwZzKyjgXS6UOFkabqQrVUzBFRs4EMWkjI0gZHoZ3aAhJg4PwDAkmdWgoacPCSB0aindAIJ7+AXj6B5A4MKAbALvVrb9jvSF0tm+ThP+7AFgl/HD4BMfQEJJGRBI/NAzHwCCcg4JJHi0ibZyElDFiygJNrFRnsSlpNuc3b+KzY4f58txhbl06TPu1w3x9cTf33t3P/XP7+KS5gct1tWy0mdimVnNQp+NSop3r6Q465qbzdFHOTwLg77fU8Iet1fyxpZI/tlbwhx1z+F3rPL7ZVMP9hvkcT0mlMUbLgunRpPeLJH2gjJQhsbgHirH1j8I8WIT8zQAMAyJxj4zFNUyKoWcwVr+oVwDQO0ZL8lgdCSPiSBgRR9IoNQkj4kifYCJzkgXbUAWqXlEkT7BSEZVD4lijDwC1fmISxxpZoa9mrX0xnvFWzIOU6PvKcQ43YBigJGVKPKttS2lKbsQzNR7dEBVLrIvYM3s3TZ5VzI7Mxj1Kh76fBFWvKOJH61kUN5s6Qw010iK8b1lIn+Ik/L9NQvtGCJJ/mExNRDr50xzsTG1gX9YGUsZbkL0Whr6vnOwZyRSGZFMeVcimtEbmqcrxTLGjHdCZB6joGYTGLxydXyjaXoHYBkXh6BdGol8w3j6BpPaeSVrvaWT2mkJur3HUjgmiYUoYW2ZGsTNUwmGRnLfFcs4oVZxTqjmnVHNRpeaiSsW7ajXv6VTc0Cp5Xyv3+SOLwQd/n9qsPvj7qQrgr+Nt/Mpt5QuXxVfx+yrJ+comkC8THb7p3x9zF+S9XAX8800hXZXBrkrgfxYA7xXn+aqAHUW53CvO6zwL+BMA2FGcya28FB8A3i1Mp6M4k46CdB4UZ/GgOMsHgHdKMrlbmsXtsixuV+S8gL9c7lYWcGdOIbcqCv4EgfPLfjYAtm9bw53WNdzZuYH23U107N/C7bat3HmxI/jh6b08emcfD9/Zx8NzbZ0QeLmzCvjk2lEfAD66doxH147x8PoRnn1wlO/eP8bvrp3gf117h++OHqI6JIa8cf7MD5UxPzyWhZEKlkm01MUaWKUw/cQZwAQ2ORLZHO9lV3I6+1LTaEtM5GC8m4NuB0cdJo7bjJy0aDlhVnHaqOGsTscZvZEzeiOntEaOawzsk8axTxrHHomKXVINu2VaDsh1nDWYuGjQc9Fo4YzBwkmNmTa5idZoLetD1awN1LAqUEV9kJ41IWbqxTZf5W+t1MmqaAsrIoxUTZNSMUlE6fgIyid0TvgWT4ikdFI0ZZNFvnbw4nA9taFaVogsbNan0mzKYJczn72JRez2FrI3rYhmdwab7GmsMyZTp3RSK7JQHaajfFYcuRNjyBofTfKoCDwjwvAMDSFxcBBJQ4LJGBFBxogIskZEkjE0jNRBwaQPCSVnVHQ3AHarW3/nuiEIQq3wf7cF/KMVQOewUDwjo0gYFo6tfwC2/gEkjxaRMkaMd1Q0ZYEmVmmy2eKdzeWWrXx15ig3Lxzk60v7uXvtIF+ea+X+lX08vXKQOwe38unmenYmJ9KqUXFIr+dykoMbGU7uVWXwbHHujwLgs6ZK/rBhLn9oquAPTeX8vrmM3zXP5rut1TxorOZewyI+XbCU42llbDdnUT5eR/FYA95BUmx+EZ2BxkPEFIUlYhoUjXlgFLZBIsy9w7D1jcYxMIbEkSocg2XED1fiGirH3E9E8lgdqeMNeMdoyZpsJXuKDcvgWOzDVMT2CGWxqoKKqBwk/xKE1k+M4o1wysIz2Zy0igXyUjzjrZgGKtD5xeIeacIwQEnyZDeN7pUsUFeREZBCZmAqWaEZtM3dz7HKvay1LyZzmhtlzwgfWGZOc1MalkGNtAh9PwmukVqMfiK0PYIxvBZEwWQbeZNtVIams9ZQQ6t3Dca+MvR9ZOTNTCV/VjrZM1Kody+nWllKXmgqReGppEw2o+sXiXlwDKYBkUj+aRLyX05D/YtJON+YiveNKeT1m0HxkAAqRwSxaHQA9RPDaJ4Vyd7QGA5FSjgu6vRJqZR3ZDLOKRRc0+m4YdDwvlHLB3oVH+qVfKiT86FOzkeaWD61GH3hzi9X/n5qCKQLAH/ltvoqfl0TvV3Vwa57XVO+f+6uNm9XO/hl2Hu5RfzXAmB7YQ638zK5V5zH/ZL8zrOAPwGA90uzuZWXwlfZHr7K9tBelMH90mzuF2XyqDSHhyXZPgC8W5rF3dIs7pRnvwR/ebTPLeRuZRE3y/P4enY+dyqLaF9Q/lcB4K2W1Xzd2sjdXRtp37eZ221buf1iRdyDU3t4eHovD07v5cHZ/Tw818bDSwd5/O5hHl89wpNrx3ly7SQPrx7l4dWjPHjvbZ6+f4Rvbxzlu8tH+Lerp+HKRdaoLBRPCmReiJR5YTIWRipYGqNhhUzPSrnxB5XAdTona/UONlidNLnc7EpOYW9KMvsSXOx32TjqdXEqwcqZeCtnnQbOunSct+s5p9VwXqflgl7HWa2B01o9x9SdPqI2clRr5bjezlmznXeNWq4ZNVw1Grig13FapeWAVMOeGD1bIg1sDDPSGGZiXYSdddFu1svjWRfrfqX6Vxdponq6jDmTxZ2Vv8liqqfLqJ6loHqWgjnTpZRPETNnupTF4XrWxLrYoPaw21XA3vgiDnrLOZxWwRZ7Olucaaw1xLNGF88qlZvFEjM14XpmBygpnColY2wk6WMicAyahXt4MCljo8iaICFjTDSegYG4/fzx9g8ga0gYuUMjKBkjoTbA1A2A3erW37F+KQjCt4IgZAt/GgLRv3R/rPDjQyB+L/1MstBZRfzHn/G5PQRBwDIwBPeQSOKHRuEeEolrcATJo6UkjRCTPFpK0QwT9bpC2vKXcuv4PtrPvc3Ns210vHuUu+8e5v61t7n5zi5un93J53sb+HznanZlJrBZo2K/zsxFTyLXs5O4U5XOw0XZPFmRx/N1hTxvKuHZ1jIeNpfzcHMpz1u6YmBK+W5nEd/vKuab1tk82lTOo43zuFSYw7uF5VzKm8PCYBe5Y3WkjVCSPDQW65uhxA+W4BmpQN8nFMuAKKyDRZgGRGIfIiVjspmMyRbyZ7o7q4Cj1CSNiCN9tA5bn2iKJtnJGKmldIqTjLEmXIOUyH4RyGJFOXXaKlS9ojAOikXeM5zy6Bx2FWwhK9hL+jQXzoEKzL3EmPpKMPjFUByewfqEFTQlrSR+rIGk0QbmhmSyWlnJsTl72JrRSHlMHqIewSj7itAOkhHbO5JSUQ71riXU6iqRvhlOjbwMzxgzht4SHINllIV4KAq0ET8yhlWGYnKnm5H+Yjo1onzmiYpwDtGzzLyUxeZFZAZnsNS5jFWeOlRDZIh6BCP+l1mofxmIWHgL12uBeP55Mnm9/Snu58/sQTNYPDactVMi2ThTxPbgaPZFiDkYHcMxSQwnJBLOSmI4J5VwIVbGZaWCd+OUvBun5H2D/gf+2Nrplyd6u6Z5/9y/cpj5zGrgV3YTv3Fa+DrBwa1EJ7eTXNxKdPJ1goOb8Xa+ctv40mXl64RO34y38JXb7PNdr5OOFDd3PA7fvfZkN+3pia+cAeyKjOl6/rLvpCf54mBe9v2CDO7lp7+yF/h+QQbtRZ1t4Ft5KdzKS+FuYbrvtfaiDDqKM7lfms2Dshweluf6Jn5f9s2CVN8gSHtZNvdm53K/Io/2inxuVxT4KoB35xZzd34ZdxaU07GkkvvLqri/oroTAJfP4/ayKu6uXMC9+kU8bqrj8eZVPGmup2NLHe0tq+jY2cD93Y082Le+Mxj60CY6Dm/m/tFtPDjWORH8+J0DPDlzkKfnj/D04gmevXuK51dO8vTqEZ69d4bn713i6Y1rPLlxnqc3TvK/vjjOv392mD9eP8Se3BxKgsQUTRUx219KTYiC1Uoz63QONlmcrNVYaNTaWat2U69wU69IYoMunWZLGq22FNriszmQmMlhh5cjtiQOmx2ctbu45Ijnss3BJbOZCwYzZ/VWzugsvKM1c0pj4KRazSmt6oXjOGNQcc6k4YrdyPtuB+87bFwwGjml0fG2UsNumZ6N4bE0RmpZG2WiUWJlgzKRJlUq9ZJkVoqSWBbhZlGojdoQM7UhZuYHaaiepaDSX0rVzFhqAhSUjg+lclIk8/0lzJshpTZQQb3EwlZTCtus6ez1FLI/rZS29DL2p5azy1vCFnsuTZYs1uoyWCFPYrE4nqoQC2Uz9ORPUuIdGkXCwDCS/IJJ7RdGysAIPINDSB4aRt4EKYmDZpA6JICyMZHMmyBi+TQ5y/yV3QDYrW79HWmZIAgRgiAMEwQhWOiMc3kmCEKfF/cbhc6KX5TQGQNz5YW71BUDc1IQhClC5znCp8JfGQNjHhD8AwD0jpKQOFyEd5SEgukGVmny2Ze7mNsn9tNx/gg3z7bRfvkIty8d5N7Vw3x1eie3z+7kV/sb+dXuNezJTvqLAPisseAVAHy0pYznLXNeAGA53+0s4ftdnVD4YEM5DzfM42xOBmcyCzidVsSySA954/QkDZKQNEiC9c1QEofKSBgmQ9c7BOvAaOxDYzAPjMI+RErSGDWesVoyp1ixD5LiHaUmZYyW7PEm3AOklE+PJ3ecicqZSRROdZMy2ojytVAqwrNYIC3GOUKDZagSaY8QFsSVs7e4hbRZCWT6x+MeHIe1jwTbQDmWAbEUh2ewLn45DY7F2IarcA/XUDYzmZrQbE7XHKCtbDt1toUo/KJR+EWjHSRD4RdNqSiHOttCFmrnoBscS9ZMD/kzvCSNNOIepqBgpovCACvecXKqRF5yp5vRvBlC3vQEyoMzSZvgYn1SA/UJqymJKWZ10iqa8zeT5O/EOEyJ/PUQFP/TH9X/8CexZzCJ/zSBvN7TKO3nT8XgmSwZG8rqCaFsmhHNjhAR+8PFHBJJOCGRcDJGwnmZlAuxMi4p5Lwbp+SqWsVVtepvAoBf2E382mHmN04LN+PtfJ3g8IHgnwPgHY/D59tJdp9/CgDvpiW8Cnn/BQDYUZxJR3Em90qyuFeS1Vn9K83+UQDs8u3iDNrLsukoz/EB4Mst4P8IAO8sr/YB4KONK3i8eRWPt67+mwDgkytv8/TaOz8AwH/7/Bj/9vEB/nj9EEfKy6gIj2VOoILqoDjmh3VGwSyXalkh01AfZ6RBbaVB5aJe6aJekUCTIZ0Wazrb7ansd2fSlpDGIUcSb1sTOWJ1cc7h5rIznss2G5ctFi4aLZwz2DhrsHBGb+a0Vs9prZYzhi5rOG/WctGq55rTzA2XlRt2K+cNBk6qtRxWqNkl1dEUIX8FANcrEtgYl8JKURLLI+NZEuakNsTqA8AFwVpqApTMnSGjepacmgAFFZMiqZkmZnGggsXBcayI0LEhzk2rLYOdzmz2Jxd3wl9aKftSytgWn++LfKlTeKgVOagJszJ7lp6iqWqyx8tIGhxB/IBQkvqEktovgpSBESQNCsY7JJS8cTGkDQ8iZ2QYNZMlLPOPZc0sFfWzugGwW936e9IuoXMC+H8LgnD/xfORL93vCoL+VuicFm4TOrMCX9ZQQRCOCZ1B0M+ETqj8q4KgTf2DcA2OwDU4AuegcJyDwvGOkhA/NIrE4SKyJqpYEptBa2o1d062cf/iMW6ebeP2hUN8eXYv7e8e5MtTO7h9die/ObCer/av41BR+k8C4KNlOTxdm8/zphKeN5fzeFsFT7bO4XlzNd9sq+Tb1jl8t2M23++s4MmWCtrXlnG/cQEH3PG0aBw0q1wsCfeQOVJFwgAxKcPkuPtF4+gfjdkvHF3vEFzDpCSOUWIZFI11UAyu4XIcQ2OJH9l55i9pRBx5U+0UTnGQOlJDVWAyxZMd1IZnUj7LS/EMD7aBcpxDVXjHmigNyyB1igPJa8Hsyd/CnqJm7OP0ZM1IIHWMCXtfGcljTXjHmigISaXBuYRG11IMA2WY+8uoDM6gdLqH1daFbMvewJ6iZrxTHcT2jkTSMwzbaC1l4lzWJixnlWMRtbpKlL1FuIZpcQ7ujKfJnGymWpzMAlk66ZPUeMcq8Y7VoHo9HGt/BdlTkyiLyKEytoS80HQygzws0M1mR/56WtJWUxubi+Yfp2PvEYz9f04io8ckZg+cxaJRoSwZG8qaSZGseSuQrTMj2BMSxaHwKI6KRLwjEfOORMy7cUquqOK4qlZxXaflhl73Stbfy/65APil2+YDvN84LT7/GAC2J7voSHHTkeLmXmo891LjuZ+W8JMAeCvZ9cqauB8Dv781AD4sz+VBWQ73S7PpKM70/VxX6POPuessYBcEPqgqpqOqhDuVRb4hkP8MAHasruXB+mU82LiCB5vqaN+8gjtb62jfsYZ7u9Zyb0/jTwLgo9NtPDrdxpNzb/P4/DGeXj7J08vHO4dCrp7m2bWLPH7vCo/eO8uT6yf4/Sdv8921nfzhvYP8qmkjDeZESqcrmT09jjkzOyFwsUjFcqmWJTFylkvVrFKYWCW3sCbOzRZLOtvsyWx3eNnj9LLHlcghh5u3bS5OxcdzOTGBa4nxXHXZuGIzc9li4oLZ7PN5s4HzZj1XXRauua28l2DhfY+V9z1WPkyycsNl5brNwlmdjmNKFW1SBdui49gqUrEuSkdDpJH6aCOrxTbqY9wsCLQwP8DMvFkm5geaWBBkZGGwiUVhBmpDtcwPimNeoJJ5gUqqpompnRVLfbSRBomVprh49rpyOZhcwuHUMt7OrOBQVgV7U4rZ7Slme2IhjfpUVsUlskjspDrMREWAnsyxYlJHRuMZGo67fwiufsEk9A3F0y+C5EFRJA0KxTs0hLyx4ZRMjKJmmpiNkVpaRQZ2ifRsDpJ1A2C3utWtn61OAOwXiHNQuA8AHQPD8I6S+KqCaePkLIxJYUtSBbdP7OfehaN8fe4Aty8c4tfv7Obu5QP85uR2bp3Zwa/b1vHlvkYOFqb9JAA+XJr9CgA+aZ3D0+ZKnjfX8E1LDd+2zuW7HXP4fmclTzZX0t4wmwfrFrHX7mKtWEej2MJcfyspQ2JJG6Eka4yG+P4iTL1CO+NN/MJIHKUg+S0NpgGRGPtF4RmrwTVcgXOYnJRxetxDYima4SZ/ko3UkRoqZiSSN97MvOBU8iY5KJ7hIWGEFutAOY4hcZRHZJEX6EXtJ+JkdRtbMxqxjNaQNtVJziQnNj8pqeMtpE2wkRvopd6+iPXxy1H7iVD2CGNuSCaVgenkByWz2FBFS9Z65sqLcYzVE9dPjGWkmoxZiWxMXs1Key1r3EuRvh6OskcEujfFnUMqE41URCRQE5NCYYAV93AJqW/piesRhqpHJAnDjWRMdTFHnEe1rIikyRbyw73szFnDgYL1NCcsJHlgNMn9Ikn6l2kU953JolHhrJ4YTf2kaJr8xTRNDmLbzHD2h4bzdkQkx8VRnJVGcVYq8lX9rmnUPvjrinr5rwTAW4k2bifZueNxcNfr9AHhTwHgTY/jlcng/78B4J2STJ+7ALC9LJtHNaXcrynrBL8XvjOv9D8FgPfXLeXe+mXc27icu5uWc3vLCu5ur6djZwMdu9f+JAA+PLWfh6f28/jsYR6dO8qTSyd4cukYjy4f4vGVUzy9esEHgI/fO84fPj3Ct1d38PtrB3iwdw/bU/KZE6CnKsBIdaCR2kgdyyWdUTC10VKWShTUxepZKTdQr7Sx2eyl2ZbINlsCO23x7Ha6Oexycczl5ExSIleT47nhTeC9eBvXnEau2I1cspl9vmw3c9lu5EaSjfc9dj5KsfFJup2P02x85LVw3Wnhus3COxoNR+RK9sXEsjVCzlaRisZILfXheurCtSwLN7A8wkqVv54qfz3VMwzMDzRRG2JmUaiFJREmlkQYqA3VsCBYxbxAJdXTY1gUIGeNyESjzM5mdSJtCQW8nVbO0YwKjmZXciirgj3JRexMLKQ1oYB6tYelUgfVYSZmB2gonhZH8vBwkoaEkTAoBGffIJx9g4jvE4qnbxTJgzq3fqQNC6N4QiRV08QsnhlDS7SKPRId+0VqWgLF3QDYrW5162erhyAIGPsG4BgY5oM/+4BQvKMkvqpg8mgpNVFJbHSXcvPoHjrOH+Hrcwe4c/GwDwB/faKVr9/Zzhf71vKr3WvYl+v9SQC8vziTJw15PNtYzPPmcp5ur+RZy1yeN8/nm5Z5fNtazXfbK/l+x1yebqmiY20ljzcsZ4/VTV2okvoIE4XjVHgGSsgdrydnnA6nXySmXqFo3wjE1C+C5HFq0ibp0fcNQ9MrFO84LY6hsVgHSciYaMY5SEp5kIe8iVZSRqgpmeIkfYSGCv8EMseZKZ7hIWWcGftgJfbBSiqiciiPysY5SsuFxcdY5ViEeZSahHFGivyTML0pInmsidS3rGTPSqLevoi1ziXIe4YT9Q/TKZuZTGVgOp4JFgrC01lpr2WDdxUV0gISJlrQDpJhHqFic1oDC7VzWGaeh/iXIcS9Hom+VwyuoXISR8WRNVVH3gwTlVFJJIyUkTHJhK5XNMpfhmPpJ8c9QkVZRCrLdLNxjI7DOVbBamsFTa55NNkqqZ5pZ/YEHfn9Qpk3LIzVE8WsmyZhw7RommdJ2DYjjO2zwmgLDeVYZCSnxJFckEVyQRr9kxXArqDnl/1zAfDXTgtfuqw+f/UCCH8MAL9ym7kZb+HrBKuv9due7PpJAPwy0fan3cD/RQDY1fLtagF3tYRfhr2Xoe/H/HheGQ/mldNeVeLLAvxLAHh3RQ13Vy6gfdVCOtYupr1xCe3rl3KnaRm3t6zgTutq2nes+YsA+ODkPh6e2s+jM4d4dO4ojy8e58mlYzy8dJBH757kyZXzPLr2Lg+vneHRtWP82+fH+O7aTn53tY3vjx3lSHE1K2PTqItJZZkogcVRZpaKTSyX6lgYJWFJjJwVsSpWyDSsUhhpMsWz2exki9lOq8XBLoeDowluTiXGcyHVw/W0RD5MTeJGko33XAauOgxctpt512HhXYeFK04zV90mPvBa+CjFxqcZDj7PcvBpho2Pk61cd5p4z2rmtFrNYZmcPSIpm8NkbImOY02YirpgNUuClCwIiGNBgJbKaZ2u8tezMNjC4jArSyPsLIuysCzKxOJwHQtD1J1VwBlSlgQpaRCbWRfrYIsm6RUAPJI1h4OZs9ntLWRHQgGb7VkskdipDtNRPF1B3iQJmWNFeIaGkjg4FPeAIBx+gTj8AnH2CSGpXxTewdFkDI8md7SIudOkLAmIZXWwnJ2iONrEKg6LlOwO7p4C7la3uvXz1UMQBDR9/DH1C8TUPwhTv0CMfQNwj4jGPCAYU/8gHEMjKA60sNyYyfUdG/n08E4+ObaTz0/u4YO3m/ns5Hau79vAhwc2cHnTYi5vWMiGRDMNili2xek47vr/2rvz4CjLOw7gX9RRq6jAVEWiSBEVkHMCJuHIxea+r80diLlIDCHhkACiIQQQpKAcAhFpoSJUBWS0chgQHEQRjSGHSWCGeFRrdbSt9qJj++0fz8Ysm7Cjf2yi2e9n5pl5r2RevmTf/e3zPu+zGTxWkMn68ly2VhTwg4o8nn+8kBfWz2bblrm8sK2cbdWL2Lb5EbZtXcIPqxfzo6fL+fG2hWzbuoTNaxez7anV3GnNYtXEUK6aFMfCocHMvt3CgmGRzLgtgBHXjuP0IcGMvGkCkwb5MW9kDPNHxzGs/wRarhvP+IF+DO/vzeAbJrBwjJXJg6bxYb8CzhplZe7QKBYPT2TmbRaWjEhiyZg0PuSVx/yRVqYNiWTWXbFcFrGADweXscQ7h4er9rHMbyatd0czeuA0LvDOZ8T1Pky7M4JZd8Uyd2wqV1sruDFrFeM8ghh4jSeLR6WxbGwWc0YnM3FoBDNGJnLH7K3cnLeWcwOKmDQ0kqG3+HP3/O2cF/ggS30LGNzflymDI5lwSxBDb5jIqAE+nHFPMPPui+C8SWks8bSycKyVCbdamHhrMDOGxNDqYeHsiRl8wrqEiXcEMKjfeC4LL+Ks8fEsGh7OrVGlfHzyDOb3G8uqu325bkwg146YxF8P9+KWcVO43XMSt3t6cY+3N/dP8eHL/pN5yDKFhyxTeSg4iIdDgnkkNIRHI8J5NDKCx6IieTIhvnNLjObJxGiessbylDWWb1nj+HZyfJftHWs830qM4TvWOL6bnMD3062sy0jm2cwU1mUk8/10K2vTrKxNTeJ7KYmsTY1nbVoC309PZMP0ZDZlp7I5J/375fosK2vTElibGs/GGak8k5bA9zKsrM1KYd2MNDbkZLIxN4sNOZmdWn1uJpuKcjq15uI8fvBgLhsLH2DDzGw2Fj7A5uI8NpbksWFWLuuKsllXlM2GWbnfb2ssyWPT7Hw2lxWwZc5Mts4tZENZQafWOKejNZQVsL40n/Wl+bzwyHyeWzKfTQvL2FheysbyUtYvLmP9krlsqlzA5qpyNq9YyJaVi9i8fDEbVixi/cqH2fDYEjauqWD9mgrWr13Ks+uXsW7Tcp6tXsWGp1ezcfsaNu3awMbdG9m0ZxObX6hmy4vb2Lr3N2zeu4Mt+3ay9cBzbH35eZ579UXqXVT+AAAHMElEQVSeP/gCWw7u4rkj+3j+yCtsrTnMlpoDbK15gV+9u5+fndjJT47s5OcHXuKRR1dxU/wcro8o5ZrgAlb6JnHp1FhW+ofzUd9prAywcLkliFXTgrjCEsJ10XFcFxXDJyKjuCU2ls9YE7k/O5MHc2fwSH4WT+Rn8mReOk9MT+Lr6TE8mhzN15LjWZMax6Np8TyWEc/XM+P4RnYC38y18nRBMs8UJvPtgiS+kRXHo9ZYHk2I477QUD4XaOH2qQFcf38AN0wO4mMTg7h0vIWLxwZw3kg/zh0RyPmjwvnQ6AiWj4vmUh8rV/im8DH/NK70t3KlfyKrpsaywieSiyeEcJl3OFdNjeGG4BRuDEtndUw2d2fN5q7ps7k7u4x78ubx2dw53J5VzG3pxdySUsjKQCvLvSJYPMrCgnvNVC/TB/sww8ObqQMnMmmAJ5MGeNLa34tpN/tyxu3+LBpmYdnIYFb5RPHJwFhuDoziswEhfD4gmPsDLdzr568CUER+NA90MS+gmpqamtrPrnlAROQH6oOOKWY8cOkcgWp2cyUqH+WjfJTPTzgfD5jruYjID3YjzAXmxp4+kZ8o5eOc8nFO+TinfJxTPiLiMrrAOKd8nFM+zikf55SPc8pHRFxGFxjnlI9zysc55eOc8nFO+YiIy1wDoAI/7ivk3InycU75OKd8nFM+zikfERERERERERERERERERERERERERERERERERF39SCADwH8G8BpAPf36Nl0H18ALwP4DGaKhViH/X0AVAL4E4B/AagBcLfDMQMA7ALwDYC/AngGQF/XnXK3WgjgDIBvAXwB4CWYb4yxdy2ATQC+AvB3AHsB3OpwzGAAfwDwT9vveRzAVS476+5TCKAe5v/+GwBvAQiz2+/O2XSlHOZ19oTdNnfOqAKdv8atxW6/O2cjIt0gGcBFANkARgKoBvAXALf05El1kzAAVQDi0HUBuACmqIsBMAbAAQAXYC7M7Q4CqAPgBWAKgPMAnnPpWXefQwBmALgPwFiYN5qPAFxvd8xmAB8DCATgCVMEvWm3/0oADQBeAzAOJvMvAaxw7al3iygA4TAfCu4BsBzAf2DyAtw7G0cTAbQBOItLC0B3zqgCQCOAgXbtl3b73TkbEekGpwFstFu/AsCnMJ/W3YljAdgHpudvnt22m2B6SVNs6yNsPzfB7phQAP8DMMhlZ9pzbob59/ra1m+CKXgS7Y4ZbjvG27YeBuC/uLTnYiaAvwG42pUn20O+BpADZWOvL4BzACwAjqOjAHT3jCpgPjx2xd2zEREXuxrAd+jc87UDprfLnTgWgENt28Y5HHcCwJO25QdgekvtXQWTaZwLzrGnDYPJZJRtPdC23s/huI8AlNmWK9H5Te5Xtp8b75rT7BFXwnwwuAjTk65sOuwAsM62fBwdBaC7Z1QB4B8wQ1AuwAwlGWzb5+7ZiIiLDYK5WPg4bF8N0zPoThwLwEm2bbc5HPc8gN/blhcBaO3id30BMz6sN7kCwCsATtptS4MpeBy9A2CVbbkawGGH/dfBZBuGn7/RMOOzvoMZLhBu265sjBSY25TtwyaOo6MAdPeMwgAkwQwvCQFwCqbAuwHKRkRcTAVgBxWAzm2GeVDodrttepMyvejDYMZorYQZgzUSygYA7gDwZ5gCp91xqAC8nH4wt29zoGxExMV0C7iDbgFf3kYAn8DcXrKn21Sd1QDYCmUDmNcTYV4P7Y0wY2S/AzANysjRGZgPEvr7ERGXOw1gg936FQD+CD0E0v4QyFy7bTei64dAPO2OCUbveQikD0zx9yk6T38DdAxUT7Dbdi+6Hqhu/1R5PkxPR2/8YvtjAH4LZQOYW5mjHNoZAL+zLSujS/WFeYioBMpGRLpBMkxRMx2moNkK06vlON9Ub9QXpodvHMyFtcy23D4QewFMFtEwY71eQtfTwNTCzJ04GeZpx94yDcxTMOPa/HDpVBW/sDtmM0yvRABMIXzK1tq1T1VxGGYqmRCYW+S9YaqKlTBPRA+B+ftYCVP8B9n2u3M2l3McnaeBcdeM1sC8tobADDl5DWYIwc22/e6cjYh0k2KYC81FmB5Br549nW7jj84TsRKmBwfomAj6c5giuQZmvjd7A2AKvm9hPnlvR++ZCLqrbAgzN2C79slqv4Z5onEfTJFo704Ar8JMVvslzBtfb5is9hmYcZEXYd54a9BR/AHunc3lHEfXE0G7Y0Z7YJ4Avghz12UPgLvs9rtzNiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIr3S/wGmjiml4fUpKwAAAABJRU5ErkJggg==" width="640">
+
+
+
+
+.. parsed-literal::
+
+ <matplotlib.image.AxesImage at 0x7f0805b03e80>
+
+
+
+.. 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', '<f4'), ('y', '<f4'), ('scale', '<f4'), ('angle', '<f4'), ('desc', 'u1', (128,))])
+ x: 275.483 y: 302.585 sigma: 36.518 angle: -0.194
+ descriptor:
+ [ 11 5 0 1 5 20 22 8 88 20 3 0 0 4 40 120 41 9
+ 13 52 32 36 15 81 1 8 14 25 89 84 7 1 12 0 0 0
+ 22 94 29 9 120 32 0 0 1 21 43 69 81 20 0 0 22 120
+ 43 49 48 120 13 2 16 79 17 3 24 6 0 0 30 76 16 9
+ 120 64 7 5 5 10 7 38 64 75 36 37 38 54 5 8 109 120
+ 9 1 2 4 12 21 39 22 0 0 18 19 5 4 120 120 10 5
+ 1 0 0 0 27 42 44 52 37 20 6 2 24 10 3 2 7 42
+ 81 25]
+
+
+.. code:: python
+
+ #Overlay keypoints on the image:
+ fig, ax = subplots()
+ ax.imshow(image)
+ ax.plot(keypoints[:].x, keypoints[:].y,".g")
+
+
+
+.. parsed-literal::
+
+ <IPython.core.display.Javascript object>
+
+
+
+.. raw:: html
+
+ <img src="data:image/png;base64,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" width="640">
+
+
+
+
+.. parsed-literal::
+
+ [<matplotlib.lines.Line2D at 0x7f07fc026278>]
+
+
+
+.. code:: python
+
+ #Diplaying keypoints by scale:
+ fig, ax = subplots()
+ ax.hist(keypoints[:].scale, 100)
+ ax.set_xlabel("scale")
+
+
+
+.. parsed-literal::
+
+ <IPython.core.display.Javascript object>
+
+
+
+.. raw:: html
+
+ <img src="data:image/png;base64,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RQButs+sxr+p/n71Ay2f83veavqTWjb+g7bd77XVb5/iMY+t7nPSOJsBKAgBYHcE4Ga7q7p5222/UL119fVeAvCcOwIoAAFgdwTgZru1+vfbbnt+9f7V13t5C3i7s/4ZQAEIALsjADfbf+yeJ4G8vBNHBbdOAnnh2vSLm+wkEAEIALsjADfbE6q/q15SPax6bvWp6rvW5rm++lj1zOqK6g1NdhkYAQgAuyMAN98/brn482eq/9nJZwHXiQtBf2g1z43VI3bx+AIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgJwsx1r2bjr451r0y+sXl3dVn2yel31gF0+hwAEgMkIwM12rPrz6oFr44vXpt9Qvbe6qnp89dbqLbt8DgEIAJMRgJvtWPUnp5h2SXVXdfXabY9q2RmeuIvnEIAAMBkBuNmOVZ+qPlC9q/rN6iGraVe1bPhLt93n1uq6XTyHAASAyQjAzfaM6juqx1bfUt3cEnj3q55b3bnDfd5Wvew0j3lBy86yNS5LAALAVATg0XJpdUf1fe09AI91zxNLBCAATEQAHj1vr17a3t8CdgQQACYnAI+Wi6rbqxd04iSQ56xNf2ROAgGAjScAN9vPV0+pLq+eVP1h9ZHq/qvpN7Qc8buy5TIwN6/GbghAAJiMANxsv9VyBvCd1ftW33/l2vStC0Hf3nK28OtbrhW4GwIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjAI+OH2vZ0K9Yu+3C6tXVbdUnq9dVD9jl4wpAAJiMADwanlC9u/rTTg7AG6r3VldVj6/eWr1ll48tAAFgMgJw811U/VX1tOqmTgTgJdVd1dVr8z6qZWd44i4eXwACwGQE4Ob7terlq69v6kQAXtWy4S/dNv+t1XWnebwLWnaWrXFZAhAApiIAN9s11TtaPutXJwfgc6s7d7jP26qXneYxj7XsMCcNAQgA8xCAm+vB1d9Uj1277abGA9ARQACYnADcXM9u2bCfXRt3V59bff1N7e0t4O18BhAAJiMAN9f9qq/eNt5e/frq662TQJ6zdp9H5iQQANh4AvBoual7Xgbm1urKlsvA3LwauyEAAWAyAvBouamdLwR9e/Wp6vXVA3f5mAIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUedcAIpCADg9AcgoAQgAkxGAjBKAADAZAcgoAQgAkxGAjBKAADAZAcgoAQgAkxGAjBKAADAZAcgoAQgAkxGAm+351Z9Vf7sab62esTb9wurV1W3VJ6vXVQ/Y5XMIQACYjADcbN9WfWv18OoR1c9Ud1WPWU2/oXpvdVX1+JZAfMsun0MAAsBkBODRc3v1fdUlLTF49dq0R7XsDE/cxeMJQACYjAA8Ou5TXVPdWX1Vy1G/u6tLt813a3XdLh5XAALAZATg5rui5fN9n60+3vKWcNVzW2Jwu7dVLzvN413QsrNsjcsSgAAwFQG4+e5bPazlM34vrT7ScgRwrwF4rGWHOWkIQACYhwA8em6sfrm9vwXsCCAATE4AHj1/VL2mEyeBPGdt2iNzEggAbDwBuNleWj25urzls4AvrT5XPX01/YaWI35XtrxFfPNq7IYABIDJCMDN9qvVe1o+6/fhlrd/n742fetC0LdXn6peXz1wl88hAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgKQUQIQACYjABklAAFgMgJws724env1ierD1RuqR26b58Lq1dVt1Ser11UP2MVzbEwAikYAjgoBuNl+v7q2ekz1NdXvVbdWX7g2zw3Ve6urqsdXb63esovnEIAAMBkBeLTcv2VjP3n1/SXVXdXVa/M8ajXPE8/wMQUgAExGAB4tD2vZ2F+9+v6q1feXbpvv1uq6UzzGBS07y9a4LAEIAFMRgEfH+dWbqj9eu+251Z07zPu26mWneJxjLTvMSeNcD8AziTsBCMBRIQCPjhuq91RftnbbXgJwyiOAAhAAThCAR8OrquPVV2y7fS9vAW83xWcABSAAnCAAN9t5LfH3/urhO0zfOgnkOWu3PbINPAlEAALACQJws/1S9fHqKdUD18bnr81zQ8sRvytbLgNz82qcKQEIAJMRgJvtHidrrMa1a/NsXQj69upT1etbIvFMHakAFIkAbAIByCgBCACTEYCMEoAAMBkByCgBCACTEYCMEoAAMBkByCgBCACTEYCMEoAAMBkByCgBCACTEYCMmjIADzISAeBcJwAZJQABYDICkFECEAAmIwAZJQABYDICkFECEAAmIwAZJQABYDICkFECEAAmIwAZJQABYDICkFECEAAmIwAZJQABYDICkFECEAAmIwAZJQABYDICkFECEAAmIwAZtbEBuNdIBIBznQBklAAEgMkIQEYJQACYjABklAAEgMkIQEYJQACYjABklAAEgMkIQEYJQACYjABklAAEgMkIQEYJQACYjABklAAEgMkIQEYJQACYjABklAAEgMkIQEYJQACYjADcbE+ufrf6QMtGfva26edVP1V9sPp0dWP18F0+hwAEgMkIwM32jOqnq29v5wC8vvp49azqsdUbq3dVF+7iOQQgAExGAB4d2wPwvJYjfy9au+2S6jPVNbt4XAEIAJMRgEfH9gB86Oq2x22b783VK3fxuAIQACYjAI+O7QH4pNVtD9o232ur3z7N41zQsrNsjcsSgAAwFQF4dOxXAB5b3e+kIQABYB4C8OjYr7eAHQEUgABMTgAeHac6CeSFa7ddnJNABCAAG08AbraLWo7wPa5lI1+3+vohq+nXVx+rnlldUb0hl4ERgABsPAG42Z7aDp/Xq16zmr51IegPtRz5u7F6xC6fQwACwGQEIKMEIABMRgAySgACwGQEIKMEIABMRgAy6kgHoCgEYEYCkFECUAACMBkByCgBKAABmIwAZJQAFIAATEYAMkoACkAAJiMAGSUABSAAkxGAjBKAAhCAyQhARglAAQjAZAQgowSgAARgMgKQUQLwgAJQWAJwUAQgowSgAARgMgKQUQJQAAIwGQHIKAEoAAGYjABklAC8l1DbazTu1zwAsJ0AZJQAFIAATEYAMkoACkAAJiMAGSUABSAAkxGAjBKAAhCAyQhARgnAcygAD3KZAdgcApBRAlAAAjAZAcgoASgAAZiMAGSUABSAAExGADJKAJ6lsNzP1+dMHvdsOteWB2B2ApBRAlAAHrhzbXkAZicAGSUABeCBO9eWB2B2ApBRAlAAHrhzbXkAZicAGSUABeCBO9eWB2B2ApBRAnADxl5e94O0X89/VKLxsF+fo/K6snv2jXkIQEYJwA0Ye3ndD9J+Pf9R+WF02K/PUXld2T37xjwEIKME4AaMvbzuB2m/nv+o/DA67NfnqLyu7J59Yx4CkFECcAPGXl73g7Rfz39Ufhgd9utzVF5Xds++MQ8BSNUPVe+pPlPdUn3dLu4rADdg7OV1P9e210Euz7luv16fvT7fDPZrmTdhfzlIM74W59oyH9byCEC+s7qz+p7qq6pfqT5WfckZ3l8AbsDYy+t+rm2vg1yec91+vT57fb4Z7Ncyb8L+cpBmfC3OtWU+rOURgNxSvWrt+/Or91c/dob3F4AbMPbyup9r2+sgl+dct1+vz16fbwb7tcybsL8cpBlfi3NtmQ9reQTg0Xbf6rPVs7fd/mvVG09xnwtadpatcVl19/Hjx+++44479n08+EdfaxzC2Mvrfq5tr4NcnoPYtw/7/5Mzud9en+9sr/9hLvMm7C8zvM5HeZkPa3mOHz8uAI+wL23Z+N+w7fafazkyuJNjq/sYhmEYhjH/uCyOnL0E4PYjgBdXl7d2NHD13+3zbNqwrps5rOtmDuu6eeOorOdBr+tl1Xlx5OzlLeDTubhlJ714cLlmYF03k3XdTNZ18xyV9ayjta4coluqX1z7/vzqfZ35SSDrjtJOal03k3XdTNZ18xyV9ayjta4cou9suf7f86pHV7/cchmYB+zhsY7STmpdN5N13UzWdfMclfWso7WuHLIfrm5tuR7gLdXX7/FxLmg5SeSC/Vmsc5p13UzWdTNZ181zVNazjta6AgAAAAAAAAAAAAAAAAfhh6r3tFxS5pbq687q0hycY93zz+i882wu0D56cvW71Qda1mv7BcLPq36q+mD16erG6uGHuYD76N7W9TXdczv//iEu3355cfX26hPVh6s3VI/cNs+F1aur26pPVq9rb5eBOtvOZF1v6p7b9d8d3iLum+dXf1b97Wq8tXrG2vRN2aZ17+t6U5uxTbf7sZZ1ecXabZu0XdkQ39lyCZnvqb6q+pWWawl+ydlcqANyrPrz6oFr44vP5gLto2dUP119eztH0fXVx6tnVY9t+Wsx72r5R2k297aur6n+Uydv5y86xOXbL79fXVs9pvqa6vdaLvn0hWvz3FC9t7qqenzLD9i3HOpS7o8zWdebWv59Wt+uM15b7duqb235BewR1c9Ud7Wse23ONq17X9eb2oxtuu4J1burP+3kANyk7cqGuKV61dr351fvb29/TeRcd6z6k7O9EIdgexSd13Lk70Vrt13ScsT3mkNcroNwqgB8w+EvyoG7f8v6Pnn1/SUtP0yvXpvnUat5nni4i7bvtq9rLbHwih3nnt/t1fe12dt0y9a61uZt04uqv6qe1snrdhS2K5PZ778nfK47Vn2q5a3Dd1W/WT3kbC7QAdkeRQ9d3fa4bfO9uXrlYS3UATlVAH685a3Ev2z5zfvvHe5iHYiHtazvV6++v2r1/aXb5ru1uu4Ql+sgbF/XWn6gfqT6aMuR/JdWX3DoS7a/7tPyS9idLe/AbPI23b6utXnb9Neql6++vqkTAbjJ25VJfWnLTvkN227/uZYjg5vmGdV3tLwF+i3VzS3/A97vbC7UAdgeRU9a3fagbfO9tvrtw1qoA7JTAF5TPbO6YjXtL6q3tfwAmtX51ZuqP1677bktP0y3e1v1ssNYqAOy07pW/UDL/7dXVN/V8nfPX3+4i7Zvrmj5HNhnW35Z+dbV7Zu4TU+1rrVZ2/Sa6h2d+FjNTZ0IwE3crkzuqAXgdpdWd3Ti7YhNcdQDcLutI6DfdPCLc2BuaDlR68vWbtvUHyo7retOto6qfOVBL9ABuG/LUc7Htxz1+kjLUbFN3KanWtedzLpNH1z9TcvBhS03JQA5hx21t4B38vaWf5Q2yVF/C3gnH6l+8ICX5aC8qjpefcW22zfxbaVTretOvrBl/b/lQJfocNxY/XKbuU2321rXncy6TZ/dstyfXRt3V59bff1Nbf52ZUK3VL+49v35LYfhN/EkkO0uavlA8gvO9oLss1OdBPLCtdsubnNPAtnuy1r+IX7mwS/OvjqvJYje386X7Nn6YPlz1m57ZHN+sPze1nUn39iyro+9txkn8Ectn13dpG16KlvrupNZt+n9Wj6vuj7eXv366uujsF2Z0He2hMDzqke3/Gb2sTbz+kQ/Xz2lurzlbdE/bDkydP+zuEz75aKWI3yPa/lH5brV11snuVzfsl23Phv3hua9DMzp1vWi6t+2/KN6ectv3v+15cy8C87Cso74pZbPTD2lky+T8flr89zQchThypa32G5ejdnc27p+ZfUTLet4ect+/NctR7Fn89KWs5svb/l/8aUtv6A8fTV9U7ZpnX5dN2mb7uSm7nkZmE3ZrmyQH27ZMe9sOSL49Wd3cQ7Mb7WcAXxny1HO32q+z5qcylO75wVV7+7Eb9pbF4L+UEvw39hyXa4ZPbVTr+vnV3/QcgbwXS2fJfuV5vyFZqd1vLvlenlbti4ue3vLGe6vbwmn2dzbuj64JQxua9l//1fLZ5VnvGbcr7bsl3e27Kc3diL+anO2aZ1+XTdpm+7kpna+EPQmbFcAAAAAAAAAAAAAAAAAAAAAAAAAAADuxbUtf3kDAIAj4toEIADAkXJtAhAA4Jx0dfWO6tMtfzP1xuoLV9O+t/ofLX9n9YPVq9bu9y9W9/tUdbz6peqitenXds8AfFb131r+Luu7qp+sPm/f1gQAgHv1oOrvquuqy6srqn/WEnLPb4nCH6keUT2h+tG1+/5odeXqfldV72yJwC3XdnIA/sPqjup51UOrp1fvbolAAAAOyT+o7q6+fIdp769+ehePdXX10bXvr+3kALyxevG2+/zT6gO7eA4AAAbdpyXM/rb6ner7qy+qvqQlDK88zX2fVv3nllD8RMvRwrurL1hNv7aTA/Ajq3k+uTa23wcAgENwXvWN1b+q/qz6cMtbwacLwMtbPsf38uqJLW8Rf+/qPpeu5rm2kwPw09W/rB62wzh/n9YFAIBduk/1vpYTPN7dqd8Cfk51VyeH2493+gB8S/Wr+7isAADswddXL6m+tnpI9R0tZ/w+o+VkjU9XL6ge3vJ5wX++ut/XtMTej7Sc0PHdLeF4ugD8lpYTTn6yekz16Oqadvc5QwAABj26+v2Wt30/U/1l9cNr03+w5ezeu1pO1viFtWnXrW77P6vH+O5OH4C1ROBbVve5o7ql5XOHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnMv+H625rciQ7INuAAAAAElFTkSuQmCC" width="640">
+
+
+
+
+.. parsed-literal::
+
+ <matplotlib.text.Text at 0x7f07fc042128>
+
+
+
+.. 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]
+ small = keypoints[numpy.logical_and(keypoints[:].scale<L,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::
+
+ <IPython.core.display.Javascript object>
+
+
+
+.. raw:: html
+
+ <img src="data:image/png;base64,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" width="640">
+
+
+
+
+.. parsed-literal::
+
+ <matplotlib.legend.Legend at 0x7f07f47bf710>
+
+
+
+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::
+
+ <IPython.core.display.Javascript object>
+
+
+
+.. raw:: html
+
+ <img src="data:image/png;base64,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" width="1200">
+
+
+
+
+.. parsed-literal::
+
+ <matplotlib.image.AxesImage at 0x7f076c299240>
+
+
+
+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 <http://pymca.sourceforge.net/stripbackground.html>`_
+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
--- /dev/null
+++ b/doc/source/Tutorials/img/arraywidget3D_0.png
Binary files 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
--- /dev/null
+++ b/doc/source/Tutorials/img/arraywidget3D_1.png
Binary files 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
--- /dev/null
+++ b/doc/source/Tutorials/img/arraywidget5D_0.png
Binary files 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
--- /dev/null
+++ b/doc/source/Tutorials/img/arraywidget5D_1.png
Binary files 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
--- /dev/null
+++ b/doc/source/Tutorials/img/custom_config_scale0.5.png
Binary files 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
--- /dev/null
+++ b/doc/source/Tutorials/img/custom_config_scale1.0.png
Binary files 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
--- /dev/null
+++ b/doc/source/Tutorials/img/custom_config_scale2.1.png
Binary files differ
diff --git a/doc/source/Tutorials/img/fitwidget1.png b/doc/source/Tutorials/img/fitwidget1.png
new file mode 100644
index 0000000..be371ac
--- /dev/null
+++ b/doc/source/Tutorials/img/fitwidget1.png
Binary files differ
diff --git a/doc/source/Tutorials/img/fitwidget2.png b/doc/source/Tutorials/img/fitwidget2.png
new file mode 100644
index 0000000..5ee43bb
--- /dev/null
+++ b/doc/source/Tutorials/img/fitwidget2.png
Binary files differ
diff --git a/doc/source/Tutorials/img/fitwidget3.png b/doc/source/Tutorials/img/fitwidget3.png
new file mode 100644
index 0000000..5da223c
--- /dev/null
+++ b/doc/source/Tutorials/img/fitwidget3.png
Binary files differ
diff --git a/doc/source/Tutorials/img/fitwidget4.png b/doc/source/Tutorials/img/fitwidget4.png
new file mode 100644
index 0000000..feff3a2
--- /dev/null
+++ b/doc/source/Tutorials/img/fitwidget4.png
Binary files differ
diff --git a/doc/source/Tutorials/img/fitwidget5.png b/doc/source/Tutorials/img/fitwidget5.png
new file mode 100644
index 0000000..1e1278f
--- /dev/null
+++ b/doc/source/Tutorials/img/fitwidget5.png
Binary files 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
--- /dev/null
+++ b/doc/source/Tutorials/img/stripbg_plot1.png
Binary files 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
--- /dev/null
+++ b/doc/source/Tutorials/img/stripbg_plot2.png
Binary files 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
+# "<project> v<release> 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 <link> 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
--- /dev/null
+++ b/doc/source/description/img/sift_bench_cpu0.png
Binary files 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
--- /dev/null
+++ b/doc/source/description/img/sift_bench_cpu_kp.png
Binary files 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
--- /dev/null
+++ b/doc/source/description/img/sift_bench_cpu_res.png
Binary files 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
--- /dev/null
+++ b/doc/source/description/img/sift_bench_gpu0.png
Binary files 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
--- /dev/null
+++ b/doc/source/description/img/sift_bench_gpu_kp.png
Binary files 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
--- /dev/null
+++ b/doc/source/description/img/sift_bench_gpu_res.png
Binary files 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
--- /dev/null
+++ b/doc/source/description/img/sift_dog1.png
Binary files 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
--- /dev/null
+++ b/doc/source/description/img/sift_match1.png
Binary files 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
--- /dev/null
+++ b/doc/source/description/img/sift_orientation.png
Binary files 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
--- /dev/null
+++ b/doc/source/img/silx.ico
Binary files differ
diff --git a/doc/source/img/silx_large.png b/doc/source/img/silx_large.png
new file mode 100644
index 0000000..56fcfd3
--- /dev/null
+++ b/doc/source/img/silx_large.png
Binary files differ
diff --git a/doc/source/img/silx_small.png b/doc/source/img/silx_small.png
new file mode 100755
index 0000000..32aba21
--- /dev/null
+++ b/doc/source/img/silx_small.png
Binary files 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 <https://certif.com/spec.html>`_ 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 <https://www.python.org/>`_ 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 <http://www.numpy.org/>`_.
+
+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 <https://riverbankcomputing.com/software/pyqt/intro>`_ or `PySide <https://pypi.python.org/pypi/PySide/>`_
+* `matplotlib <http://matplotlib.org/>`_
+* `PyOpenGL <http://pyopengl.sourceforge.net/>`_
+* `IPython <https://ipython.org/>`_ and `qt_console <https://pypi.python.org/pypi/qtconsole>`_ for the ``silx.gui.console`` widget.
+
+Tools for reading and writing files depend on the following packages:
+
+* `h5py <http://docs.h5py.org/en/latest/build.html>`_ for HDF5 files
+* `fabio <https://github.com/silx-kit/fabio>`_ for multiple image formats
+
+*silx.opencl* and *silx.image.sift* further depends on OpenCL and the following packages to :
+
+* `pyopencl <https://mathema.tician.de/software/pyopencl/>`_
+* `Mako <http://www.makotemplates.org/>`_
+
+Build dependencies
+++++++++++++++++++
+
+In addition to run-time dependencies, building *silx* requires a C/C++ compiler, `numpy <http://www.numpy.org/>`_ and `cython <http://cython.org>`_ (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 <https://www.python.org/downloads/>`_.
+
+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
+<https://docs.python.org/3/using/windows.html#configuring-python>`_ to add
+the python installation directory to your PATH environment variable.
+
+Alternative Scientific Python stacks exists, such as `WinPython <http://winpython.github.io/>`_.
+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 <https://www.riverbankcomputing.com/software/pyqt/download5>`_.
+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 <https://pypi.python.org/pypi/silx>`_.
+
+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>`_: 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 <http://www.sphinx-doc.org/>`_), 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 <https://opensource.org/licenses/MIT>`_ and `LGPL 2.1 <https://opensource.org/licenses/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
--- /dev/null
+++ b/doc/source/modules/gui/data/img/DataViewer.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/data/img/DataViewerFrame.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/data/img/NumpyAxesSelector.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/fit/img/bgwidget.png
Binary files 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 <files>
+
+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
--- /dev/null
+++ b/doc/source/modules/gui/hdf5/img/Hdf5Example.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/hdf5/img/Hdf5TreeView.png
Binary files 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 <http://matplotlib.org/>`_ 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 <http://pyopengl.sourceforge.net/>`_ 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 <http://ipython.org/>`_, 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 <http://matplotlib.org/>`_, the safest way to use *silx* from IPython is to import :mod:`silx.gui.plot` first and then run either `%gui <http://ipython.org/ipython-doc/stable/interactive/magics.html#magic-gui>`_ qt or `%pylab <http://ipython.org/ipython-doc/stable/interactive/magics.html#magic-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 <http://ipython.org/ipython-doc/stable/interactive/reference.html#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 <http://matplotlib.org/>`_ (see `Choosing Colormaps <http://matplotlib.org/users/colormaps.html>`_) 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/ImageView.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/LimitsToolBar.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/Plot1D.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/Plot2D.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/PlotWidget.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/PlotWindow.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/PositionInfo.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/StackView.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/StackViewMainWindow.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/colorScale.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/colorScaleBar.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/fftAction0.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/fftAction1.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/linearColorbar.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/logColorbar.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/netCounts.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/plot_and_backend.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/rawCounts.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/roiwidget.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/shiftAction0.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/shiftAction3.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot/img/tickbar.png
Binary files 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 <http://pymca.sourceforge.net/>`_.
+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
--- /dev/null
+++ b/doc/source/modules/gui/plot3d/img/Plot3DWidget.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot3d/img/Plot3DWindow.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot3d/img/SFViewParamTree.png
Binary files 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
--- /dev/null
+++ b/doc/source/modules/gui/plot3d/img/ScalarFieldView.png
Binary files 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 <https://pypi.python.org/pypi/silx>`_
+- `Debian 8 packages <http://www.silx.org/pub/debian/>`_
+- `Documentation on PythonHosted <http://pythonhosted.org/silx/>`_
+- :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 <http://www.silx.org/pub/debian/>`_
+- `Documentation <http://www.silx.org/doc/silx/>`_
+
+Project
+-------
+
+- `Homepage <http://www.silx.org/>`_
+- `Source repository <https://github.com/silx-kit/silx>`_
+- `Issue tracker <https://github.com/silx-kit/silx/issues>`_
+- Mailing list: silx@esrf.fr (`Archive <http://www.silx.org/lurker/list/silx.en.html>`_)
+- Continuous integration
+
+ - Linux and MacOS X: `Travis <https://travis-ci.org/silx-kit/silx>`_
+ - Windows: `AppVeyor <https://ci.appveyor.com/project/ESRF/silx>`_
+
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()
+
+
+
+
+
+
diff --git a/examples/animatedicons.py b/examples/animatedicons.py
new file mode 100644
index 0000000..5a5cad6
--- /dev/null
+++ b/examples/animatedicons.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""
+Display available project icons using Qt.
+"""
+from silx.gui import qt
+import silx.gui.icons
+import functools
+
+
+class AnimatedToolButton(qt.QToolButton):
+ """ToolButton which support animated icons"""
+
+ def __init__(self, parent=None):
+ super(AnimatedToolButton, self).__init__(parent)
+ self.__animatedIcon = None
+
+ def setIcon(self, icon):
+ if isinstance(icon, silx.gui.icons.AbstractAnimatedIcon):
+ self._setAnimatedIcon(icon)
+ else:
+ self._setAnimatedIcon(None)
+ super(AnimatedToolButton, self).setIcon(icon)
+
+ def _setAnimatedIcon(self, icon):
+ if self.__animatedIcon is not None:
+ self.__animatedIcon.unregister(self)
+ self.__animatedIcon.iconChanged.disconnect(self.__updateIcon)
+ self.__animatedIcon = icon
+ if self.__animatedIcon is not None:
+ self.__animatedIcon.register(self)
+ self.__animatedIcon.iconChanged.connect(self.__updateIcon)
+ i = self.__animatedIcon.currentIcon()
+ else:
+ i = qt.QIcon()
+ super(AnimatedToolButton, self).setIcon(i)
+
+ def __updateIcon(self, icon):
+ super(AnimatedToolButton, self).setIcon(icon)
+
+ def icon(self):
+ if self.__animatedIcon is not None:
+ return self.__animatedIcon
+ else:
+ return super(AnimatedToolButton, self).icon()
+
+
+class AnimatedIconPreview(qt.QMainWindow):
+
+ def __init__(self, *args, **kwargs):
+ qt.QMainWindow.__init__(self, *args, **kwargs)
+
+ widget = qt.QWidget(self)
+ self.iconPanel = self.createIconPanel(widget)
+ self.sizePanel = self.createSizePanel(widget)
+
+ layout = qt.QVBoxLayout(widget)
+ layout.addWidget(self.sizePanel)
+ layout.addWidget(self.iconPanel)
+ layout.addStretch()
+ self.setCentralWidget(widget)
+
+ def createSizePanel(self, parent):
+ group = qt.QButtonGroup()
+ group.setExclusive(True)
+ panel = qt.QWidget(parent)
+ panel.setLayout(qt.QHBoxLayout())
+
+ buttons = {}
+ for size in [16, 24, 32]:
+ button = qt.QPushButton("%spx" % size, panel)
+ button.clicked.connect(functools.partial(self.setIconSize, size))
+ button.setCheckable(True)
+ panel.layout().addWidget(button)
+ group.addButton(button)
+ buttons[size] = button
+
+ self.__sizeGroup = group
+ buttons[24].setChecked(True)
+ return panel
+
+ def createIconPanel(self, parent):
+ panel = qt.QWidget(parent)
+ layout = qt.QVBoxLayout()
+ panel.setLayout(layout)
+
+ self.tools = []
+
+ # wait icon
+ icon = silx.gui.icons.getWaitIcon()
+ tool = AnimatedToolButton(panel)
+ tool.setIcon(icon)
+ tool.setText("getWaitIcon")
+ tool.setToolButtonStyle(qt.Qt.ToolButtonTextBesideIcon)
+ self.tools.append(tool)
+
+ icon = silx.gui.icons.getAnimatedIcon("process-working")
+ tool = AnimatedToolButton(panel)
+ tool.setIcon(icon)
+ tool.setText("getAnimatedIcon")
+ tool.setToolButtonStyle(qt.Qt.ToolButtonTextBesideIcon)
+ self.tools.append(tool)
+
+ icon = silx.gui.icons.MovieAnimatedIcon("process-working", self)
+ tool = AnimatedToolButton(panel)
+ tool.setIcon(icon)
+ tool.setText("MovieAnimatedIcon")
+ tool.setToolButtonStyle(qt.Qt.ToolButtonTextBesideIcon)
+ self.tools.append(tool)
+
+ icon = silx.gui.icons.MultiImageAnimatedIcon("process-working", self)
+ tool = AnimatedToolButton(panel)
+ tool.setIcon(icon)
+ tool.setText("MultiImageAnimatedIcon")
+ tool.setToolButtonStyle(qt.Qt.ToolButtonTextBesideIcon)
+ self.tools.append(tool)
+
+ for t in self.tools:
+ layout.addWidget(t)
+
+ return panel
+
+ def setIconSize(self, size):
+ for tool in self.tools:
+ tool.setIconSize(qt.QSize(size, size))
+
+
+if __name__ == "__main__":
+ app = qt.QApplication([])
+ window = AnimatedIconPreview()
+ window.setVisible(True)
+ app.exec_()
diff --git a/examples/colorbar.py b/examples/colorbar.py
new file mode 100644
index 0000000..a4dc2d8
--- /dev/null
+++ b/examples/colorbar.py
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""
+Example to show the use of `ColorBarWidget` widget.
+It can be associated to a plot.
+
+In this exqmple the `ColorBarWidget` widget will display the colormap of the
+active image.
+
+To change the active image slick on the image you want to set active.
+"""
+
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "03/05/2017"
+
+
+from silx.gui import qt
+import numpy
+from silx.gui.plot import Plot2D
+from silx.gui.plot.ColorBar import ColorBarWidget
+
+image = numpy.exp(numpy.random.rand(100, 100) * 10)
+
+app = qt.QApplication([])
+
+plot = Plot2D()
+colorbar = ColorBarWidget(parent=None, plot=plot)
+colorbar.setLegend('my colormap')
+colorbar.show()
+plot.show()
+
+clm = plot.getDefaultColormap()
+clm['normalization'] = 'log'
+clm['name'] = 'viridis'
+plot.addImage(data=image, colormap=clm, legend='image')
+plot.setActiveImage('image')
+
+app.exec_()
diff --git a/examples/fft.png b/examples/fft.png
new file mode 100644
index 0000000..2464580
--- /dev/null
+++ b/examples/fft.png
Binary files differ
diff --git a/examples/fftPlotAction.py b/examples/fftPlotAction.py
new file mode 100755
index 0000000..e4d4081
--- /dev/null
+++ b/examples/fftPlotAction.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This script is a simple example of how to create a PlotWindow with a custom
+PlotAction added to the toolbar.
+
+The action computes the FFT of all curves and plots their amplitude spectrum.
+It also performs the reverse transform.
+
+This example illustrates:
+ - how to create a checkable action
+ - how to store user info with a curve in a PlotWindow
+ - how to modify the graph title and axes labels
+ - how to add your own icon as a PNG file
+
+See shiftPlotAction.py for a simpler example with more basic comments.
+
+"""
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "12/01/2017"
+
+import numpy
+import os
+import sys
+
+from silx.gui import qt
+from silx.gui.plot import PlotWindow
+from silx.gui.plot.PlotActions import PlotAction
+
+# Custom icon
+# make sure there is a "fft.png" file saved in the same folder as this script
+scriptdir = os.path.dirname(os.path.realpath(__file__))
+my_icon = os.path.join(scriptdir, "fft.png")
+
+
+class FftAction(PlotAction):
+ """QAction performing a Fourier transform on all curves when checked,
+ and reverse transform when unchecked.
+
+ :param plot: PlotWindow on which to operate
+ :param parent: See documentation of :class:`QAction`
+ """
+ def __init__(self, plot, parent=None):
+ PlotAction.__init__(
+ self,
+ plot,
+ icon=qt.QIcon(my_icon),
+ text='FFT',
+ tooltip='Perform Fast Fourier Transform on all curves',
+ triggered=self.fftAllCurves,
+ checkable=True,
+ parent=parent)
+
+ def _rememberGraphLabels(self):
+ """Store labels and title as attributes"""
+ self.original_title = self.plot.getGraphTitle()
+ self.original_xlabel = self.plot.getGraphXLabel()
+ self.original_ylabel = self.plot.getGraphYLabel()
+
+ def fftAllCurves(self, checked=False):
+ """Get all curves from our PlotWindow, compute the amplitude spectrum
+ using a Fast Fourier Transform, replace all curves with their
+ amplitude spectra.
+
+ When un-checking the button, do the reverse transform.
+
+ :param checked: Boolean parameter signaling whether the action
+ has been checked or unchecked.
+ """
+ allCurves = self.plot.getAllCurves(withhidden=True)
+
+ if checked:
+ # remember original labels
+ self._rememberGraphLabels()
+ # change them
+ self.plot.setGraphTitle("Amplitude spectrum")
+ self.plot.setGraphXLabel("Frequency")
+ self.plot.setGraphYLabel("Amplitude")
+ else:
+ # restore original labels
+ self.plot.setGraphTitle(self.original_title)
+ self.plot.setGraphXLabel(self.original_xlabel)
+ self.plot.setGraphYLabel(self.original_ylabel)
+
+ self.plot.clearCurves()
+
+ for curve in allCurves:
+ x = curve.getXData()
+ y = curve.getYData()
+ legend = curve.getLegend()
+ info = curve.getInfo()
+ if info is None:
+ info = {}
+
+ if checked:
+ # FAST FOURIER TRANSFORM
+ fft_y = numpy.fft.fft(y)
+ # amplitude spectrum
+ A = numpy.abs(fft_y)
+
+ # sampling frequency (samples per X unit)
+ Fs = len(x) / (max(x) - min(x))
+ # frequency array (abscissa of new curve)
+ F = [k * Fs / len(x) for k in range(len(A))]
+
+ # we need to store the complete transform (complex data) to be
+ # able to perform the reverse transform.
+ info["complex fft"] = fft_y
+ info["original x"] = x
+
+ # plot the amplitude spectrum
+ self.plot.addCurve(F, A, legend="FFT of " + legend,
+ info=info)
+
+ else:
+ # INVERSE FFT
+ fft_y = info["complex fft"]
+ # we keep only the real part because we know the imaginary
+ # part is 0 (our original data was real numbers)
+ y1 = numpy.real(numpy.fft.ifft(fft_y))
+
+ # recover original info
+ x1 = info["original x"]
+ legend1 = legend[7:] # remove "FFT of "
+
+ # remove restored data from info dict
+ for key in ["complex fft", "original x"]:
+ del info[key]
+
+ # plot the original data
+ self.plot.addCurve(x1, y1, legend=legend1,
+ info=info)
+
+ self.plot.resetZoom()
+
+
+app = qt.QApplication([])
+
+sys.excepthook = qt.exceptionHandler
+
+plotwin = PlotWindow(control=True)
+toolbar = qt.QToolBar("My toolbar")
+plotwin.addToolBar(toolbar)
+
+myaction = FftAction(plotwin)
+toolbar.addAction(myaction)
+
+# x range: 0 -- 10 (1000 points)
+x = numpy.arange(1000) * 0.01
+
+twopi = 2 * numpy.pi
+# Sum of sine functions with frequencies 3, 20 and 42 Hz
+y1 = numpy.sin(twopi * 3 * x) + 1.5 * numpy.sin(twopi * 20 * x) + 2 * numpy.sin(twopi * 42 * x)
+# Cosine with frequency 7 Hz and phase pi / 3
+y2 = numpy.cos(twopi * 7 * (x - numpy.pi / 3))
+# 5 periods of square wave, amplitude 2
+y3 = numpy.zeros_like(x)
+for i in [0, 2, 4, 6, 8]:
+ y3[i * len(x) / 10:(i + 1) * len(x) / 10] = 2
+
+plotwin.addCurve(x, y1, legend="sin")
+plotwin.addCurve(x, y2, legend="cos")
+plotwin.addCurve(x, y3, legend="square wave")
+
+plotwin.setGraphTitle("Original data")
+plotwin.setGraphYLabel("amplitude")
+plotwin.setGraphXLabel("time")
+
+plotwin.show()
+app.exec_()
+sys.excepthook = sys.__excepthook__
diff --git a/examples/hdf5widget.py b/examples/hdf5widget.py
new file mode 100755
index 0000000..95607ff
--- /dev/null
+++ b/examples/hdf5widget.py
@@ -0,0 +1,753 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Qt Hdf5 widget examples
+
+.. note:: This module has a dependency on the `h5py <http://www.h5py.org/>`_
+ library, which is not a mandatory dependency for `silx`. You might need
+ to install it if you don't already have it.
+"""
+
+import logging
+import sys
+import tempfile
+import numpy
+
+logging.basicConfig()
+_logger = logging.getLogger("hdf5widget")
+"""Module logger"""
+
+try:
+ # it should be loaded before h5py
+ import hdf5plugin # noqa
+except ImportError:
+ message = "Module 'hdf5plugin' is not installed. It supports some hdf5"\
+ + " compressions. You can install it using \"pip install hdf5plugin\"."
+ _logger.warning(message)
+import h5py
+
+import silx.gui.hdf5
+import silx.utils.html
+from silx.gui import qt
+from silx.gui.data.DataViewerFrame import DataViewerFrame
+from silx.gui.widgets.ThreadPoolPushButton import ThreadPoolPushButton
+
+try:
+ import fabio
+except ImportError:
+ fabio = None
+
+_file_cache = {}
+
+
+def get_hdf5_with_all_types():
+ global _file_cache
+ ID = "alltypes"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+
+ g = h5.create_group("arrays")
+ g.create_dataset("scalar", data=10)
+ g.create_dataset("list", data=numpy.arange(10))
+ base_image = numpy.arange(10**2).reshape(10, 10)
+ images = [ base_image,
+ base_image.T,
+ base_image.size - 1 - base_image,
+ base_image.size - 1 - base_image.T]
+ dtype = images[0].dtype
+ data = numpy.empty((10 * 10, 10, 10), dtype=dtype)
+ for i in range(10 * 10):
+ data[i] = images[i % 4]
+ data.shape = 10, 10, 10, 10
+ g.create_dataset("image", data=data[0, 0])
+ g.create_dataset("cube", data=data[0])
+ g.create_dataset("hypercube", data=data)
+ g = h5.create_group("dtypes")
+ g.create_dataset("int32", data=numpy.int32(10))
+ g.create_dataset("int64", data=numpy.int64(10))
+ g.create_dataset("float32", data=numpy.float32(10))
+ g.create_dataset("float64", data=numpy.float64(10))
+ g.create_dataset("string_", data=numpy.string_("Hi!"))
+ # g.create_dataset("string0",data=numpy.string0("Hi!\x00"))
+
+ g.create_dataset("bool", data=True)
+ g.create_dataset("bool2", data=False)
+ h5.close()
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+def get_hdf5_with_all_links():
+ global _file_cache
+ ID = "alllinks"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+
+ g = h5.create_group("group")
+ g.create_dataset("dataset", data=numpy.int64(10))
+ h5.create_dataset("dataset", data=numpy.int64(10))
+
+ h5["hard_link_to_group"] = h5["/group"]
+ h5["hard_link_to_dataset"] = h5["/dataset"]
+
+ h5["soft_link_to_group"] = h5py.SoftLink("/group")
+ h5["soft_link_to_dataset"] = h5py.SoftLink("/dataset")
+ h5["soft_link_to_nothing"] = h5py.SoftLink("/foo/bar/2000")
+
+ alltypes_filename = get_hdf5_with_all_types()
+
+ h5["external_link_to_group"] = h5py.ExternalLink(alltypes_filename, "/arrays")
+ h5["external_link_to_dataset"] = h5py.ExternalLink(alltypes_filename, "/arrays/cube")
+ h5["external_link_to_nothing"] = h5py.ExternalLink(alltypes_filename, "/foo/bar/2000")
+ h5["external_link_to_missing_file"] = h5py.ExternalLink("missing_file.h5", "/")
+ h5.close()
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+def get_hdf5_with_1000_datasets():
+ global _file_cache
+ ID = "dataset1000"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+
+ g = h5.create_group("group")
+ for i in range(1000):
+ g.create_dataset("dataset%i" % i, data=numpy.int64(10))
+ h5.close()
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+def get_hdf5_with_10000_datasets():
+ global _file_cache
+ ID = "dataset10000"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+
+ g = h5.create_group("group")
+ for i in range(10000):
+ g.create_dataset("dataset%i" % i, data=numpy.int64(10))
+ h5.close()
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+def get_hdf5_with_100000_datasets():
+ global _file_cache
+ ID = "dataset100000"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+
+ g = h5.create_group("group")
+ for i in range(100000):
+ g.create_dataset("dataset%i" % i, data=numpy.int64(10))
+ h5.close()
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+def get_hdf5_with_recursive_links():
+ global _file_cache
+ ID = "recursive_links"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+
+ g = h5.create_group("group")
+ g.create_dataset("dataset", data=numpy.int64(10))
+ h5.create_dataset("dataset", data=numpy.int64(10))
+
+ h5["hard_recursive_link"] = h5["/group"]
+ g["recursive"] = h5["hard_recursive_link"]
+ h5["hard_link_to_dataset"] = h5["/dataset"]
+
+ h5["soft_link_to_group"] = h5py.SoftLink("/group")
+ h5["soft_link_to_link"] = h5py.SoftLink("/soft_link_to_group")
+ h5["soft_link_to_itself"] = h5py.SoftLink("/soft_link_to_itself")
+ h5.close()
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+def get_hdf5_with_external_recursive_links():
+ global _file_cache
+ ID = "external_recursive_links"
+ if ID in _file_cache:
+ return _file_cache[ID][0].name
+
+ tmp1 = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp1.file.close()
+ h5_1 = h5py.File(tmp1.name, "w")
+
+ tmp2 = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp2.file.close()
+ h5_2 = h5py.File(tmp2.name, "w")
+
+ g = h5_1.create_group("group")
+ g.create_dataset("dataset", data=numpy.int64(10))
+ h5_1["soft_link_to_group"] = h5py.SoftLink("/group")
+ h5_1["external_link_to_link"] = h5py.ExternalLink(tmp2.name, "/soft_link_to_group")
+ h5_1["external_link_to_recursive_link"] = h5py.ExternalLink(tmp2.name, "/external_link_to_recursive_link")
+ h5_1.close()
+
+ g = h5_2.create_group("group")
+ g.create_dataset("dataset", data=numpy.int64(10))
+ h5_2["soft_link_to_group"] = h5py.SoftLink("/group")
+ h5_2["external_link_to_link"] = h5py.ExternalLink(tmp1.name, "/soft_link_to_group")
+ h5_2["external_link_to_recursive_link"] = h5py.ExternalLink(tmp1.name, "/external_link_to_recursive_link")
+ h5_2.close()
+
+ _file_cache[ID] = (tmp1, tmp2)
+ return tmp1.name
+
+
+def get_hdf5_with_nxdata():
+ global _file_cache
+ ID = "nxdata"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+
+ # SCALARS
+ g0d = h5.create_group("scalars")
+
+ g0d0 = g0d.create_group("0D_scalar")
+ g0d0.attrs["NX_class"] = "NXdata"
+ g0d0.attrs["signal"] = "scalar"
+ g0d0.create_dataset("scalar", data=10)
+
+ g0d1 = g0d.create_group("2D_scalars")
+ g0d1.attrs["NX_class"] = "NXdata"
+ g0d1.attrs["signal"] = "scalars"
+ ds = g0d1.create_dataset("scalars", data=numpy.arange(3*10).reshape((3, 10)))
+ ds.attrs["interpretation"] = "scalar"
+
+ g0d1 = g0d.create_group("4D_scalars")
+ g0d1.attrs["NX_class"] = "NXdata"
+ g0d1.attrs["signal"] = "scalars"
+ ds = g0d1.create_dataset("scalars", data=numpy.arange(2*2*3*10).reshape((2, 2, 3, 10)))
+ ds.attrs["interpretation"] = "scalar"
+
+ # SPECTRA
+ g1d = h5.create_group("spectra")
+
+ g1d0 = g1d.create_group("1D_spectrum")
+ g1d0.attrs["NX_class"] = "NXdata"
+ g1d0.attrs["signal"] = "count"
+ g1d0.attrs["axes"] = "energy_calib"
+ g1d0.attrs["uncertainties"] = b"energy_errors",
+ g1d0.create_dataset("count", data=numpy.arange(10))
+ g1d0.create_dataset("energy_calib", data=(10, 5)) # 10 * idx + 5
+ g1d0.create_dataset("energy_errors", data=3.14*numpy.random.rand(10))
+
+ g1d1 = g1d.create_group("2D_spectra")
+ g1d1.attrs["NX_class"] = "NXdata"
+ g1d1.attrs["signal"] = "counts"
+ ds = g1d1.create_dataset("counts", data=numpy.arange(3*10).reshape((3, 10)))
+ ds.attrs["interpretation"] = "spectrum"
+
+ g1d2 = g1d.create_group("4D_spectra")
+ g1d2.attrs["NX_class"] = "NXdata"
+ g1d2.attrs["signal"] = "counts"
+ g1d2.attrs["axes"] = b"energy",
+ ds = g1d2.create_dataset("counts", data=numpy.arange(2*2*3*10).reshape((2, 2, 3, 10)))
+ ds.attrs["interpretation"] = "spectrum"
+ ds = g1d2.create_dataset("errors", data=4.5*numpy.random.rand(2, 2, 3, 10))
+ ds = g1d2.create_dataset("energy", data=5+10*numpy.arange(15),
+ shuffle=True, compression="gzip")
+ ds.attrs["long_name"] = "Calibrated energy"
+ ds.attrs["first_good"] = 3
+ ds.attrs["last_good"] = 12
+ g1d2.create_dataset("energy_errors", data=10*numpy.random.rand(15))
+
+ # IMAGES
+ g2d = h5.create_group("images")
+
+ g2d0 = g2d.create_group("2D_regular_image")
+ g2d0.attrs["NX_class"] = "NXdata"
+ g2d0.attrs["signal"] = "image"
+ g2d0.attrs["axes"] = b"rows_calib", b"columns_coordinates"
+ g2d0.create_dataset("image", data=numpy.arange(4*6).reshape((4, 6)))
+ ds = g2d0.create_dataset("rows_calib", data=(10, 5))
+ ds.attrs["long_name"] = "Calibrated Y"
+ g2d0.create_dataset("columns_coordinates", data=0.5+0.02*numpy.arange(6))
+
+ g2d1 = g2d.create_group("2D_irregular_data")
+ g2d1.attrs["NX_class"] = "NXdata"
+ g2d1.attrs["signal"] = "data"
+ g2d1.attrs["axes"] = b"rows_coordinates", b"columns_coordinates"
+ g2d1.create_dataset("data", data=numpy.arange(64*128).reshape((64, 128)))
+ g2d1.create_dataset("rows_coordinates", data=numpy.arange(64) + numpy.random.rand(64))
+ g2d1.create_dataset("columns_coordinates", data=numpy.arange(128) + 2.5 * numpy.random.rand(128))
+
+ g2d2 = g2d.create_group("3D_images")
+ g2d2.attrs["NX_class"] = "NXdata"
+ g2d2.attrs["signal"] = "images"
+ ds = g2d2.create_dataset("images", data=numpy.arange(2*4*6).reshape((2, 4, 6)))
+ ds.attrs["interpretation"] = "image"
+
+ g2d3 = g2d.create_group("5D_images")
+ g2d3.attrs["NX_class"] = "NXdata"
+ g2d3.attrs["signal"] = "images"
+ g2d3.attrs["axes"] = b"rows_coordinates", b"columns_coordinates"
+ ds = g2d3.create_dataset("images", data=numpy.arange(2*2*2*4*6).reshape((2, 2, 2, 4, 6)))
+ ds.attrs["interpretation"] = "image"
+ g2d3.create_dataset("rows_coordinates", data=5+10*numpy.arange(4))
+ g2d3.create_dataset("columns_coordinates", data=0.5+0.02*numpy.arange(6))
+
+ # SCATTER
+ g = h5.create_group("scatters")
+
+ gd0 = g.create_group("x_y_scatter")
+ gd0.attrs["NX_class"] = "NXdata"
+ gd0.attrs["signal"] = "y"
+ gd0.attrs["axes"] = b"x",
+ gd0.create_dataset("y", data=numpy.random.rand(128) - 0.5)
+ gd0.create_dataset("x", data=2*numpy.random.rand(128))
+ gd0.create_dataset("x_errors", data=0.05*numpy.random.rand(128))
+ gd0.create_dataset("errors", data=0.05*numpy.random.rand(128))
+
+ gd1 = g.create_group("x_y_value_scatter")
+ gd1.attrs["NX_class"] = "NXdata"
+ gd1.attrs["signal"] = "values"
+ gd1.attrs["axes"] = b"x", b"y"
+ gd1.create_dataset("values", data=3.14*numpy.random.rand(128))
+ gd1.create_dataset("y", data=numpy.random.rand(128))
+ gd1.create_dataset("y_errors", data=0.02*numpy.random.rand(128))
+ gd1.create_dataset("x", data=numpy.random.rand(128))
+ gd1.create_dataset("x_errors", data=0.02*numpy.random.rand(128))
+
+ # NDIM > 3
+ g = h5.create_group("cubes")
+
+ gd0 = g.create_group("3D_cube")
+ gd0.attrs["NX_class"] = "NXdata"
+ gd0.attrs["signal"] = "cube"
+ gd0.attrs["axes"] = b"img_idx", b"rows_coordinates", b"cols_coordinates"
+ gd0.create_dataset("cube", data=numpy.arange(4*5*6).reshape((4, 5, 6)))
+ gd0.create_dataset("img_idx", data=numpy.arange(4))
+ gd0.create_dataset("rows_coordinates", data=0.1*numpy.arange(5))
+ gd0.create_dataset("cols_coordinates", data=[0.2, 0.3]) # linear calibration
+
+ gd1 = g.create_group("5D")
+ gd1.attrs["NX_class"] = "NXdata"
+ gd1.attrs["signal"] = "hypercube"
+ gd1.create_dataset("hypercube",
+ data=numpy.arange(2*3*4*5*6).reshape((2, 3, 4, 5, 6)))
+
+ h5.close()
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+def get_edf_with_all_types():
+ global _file_cache
+ ID = "alltypesedf"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".edf", delete=True)
+
+ header = fabio.fabioimage.OrderedDict()
+ header["integer"] = "10"
+ header["float"] = "10.5"
+ header["string"] = "Hi!"
+ header["integer_list"] = "10 20 50"
+ header["float_list"] = "1.1 3.14 500.12"
+ header["motor_pos"] = "10 2.5 a1"
+ header["motor_mne"] = "integer_position float_position named_position"
+
+ data = numpy.array([[10, 50], [50, 10]])
+ fabiofile = fabio.edfimage.EdfImage(data, header)
+ fabiofile.write(tmp.name)
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+def get_edf_with_100000_frames():
+ global _file_cache
+ ID = "frame100000"
+ if ID in _file_cache:
+ return _file_cache[ID].name
+
+ tmp = tempfile.NamedTemporaryFile(prefix=ID + "_", suffix=".edf", delete=True)
+
+ fabiofile = None
+ for framre_id in range(100000):
+ data = numpy.array([[framre_id, 50], [50, 10]])
+ if fabiofile is None:
+ header = fabio.fabioimage.OrderedDict()
+ header["nb_frames"] = "100000"
+ fabiofile = fabio.edfimage.EdfImage(data, header)
+ else:
+ header = fabio.fabioimage.OrderedDict()
+ header["frame_nb"] = framre_id
+ fabiofile.appendFrame(fabio.edfimage.Frame(data, header, framre_id))
+ fabiofile.write(tmp.name)
+
+ _file_cache[ID] = tmp
+ return tmp.name
+
+
+class Hdf5TreeViewExample(qt.QMainWindow):
+ """
+ This window show an example of use of a Hdf5TreeView.
+
+ The tree is initialized with a list of filenames. A panel allow to play
+ with internal property configuration of the widget, and a text screen
+ allow to display events.
+ """
+
+ def __init__(self, filenames=None):
+ """
+ :param files_: List of HDF5 or Spec files (pathes or
+ :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
+ instances)
+ """
+ qt.QMainWindow.__init__(self)
+ self.setWindowTitle("Silx HDF5 widget example")
+
+ self.__asyncload = False
+ self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
+ """Silx HDF5 TreeView"""
+ self.__text = qt.QTextEdit(self)
+ """Widget displaying information"""
+
+ self.__dataViewer = DataViewerFrame(self)
+ vSpliter = qt.QSplitter(qt.Qt.Vertical)
+ vSpliter.addWidget(self.__dataViewer)
+ vSpliter.addWidget(self.__text)
+ vSpliter.setSizes([10, 0])
+
+ spliter = qt.QSplitter(self)
+ spliter.addWidget(self.__treeview)
+ spliter.addWidget(vSpliter)
+ spliter.setStretchFactor(1, 1)
+
+ main_panel = qt.QWidget(self)
+ layout = qt.QVBoxLayout()
+ layout.addWidget(spliter)
+ layout.addWidget(self.createTreeViewConfigurationPanel(self, self.__treeview))
+ layout.setStretchFactor(spliter, 1)
+ main_panel.setLayout(layout)
+
+ self.setCentralWidget(main_panel)
+
+ # append all files to the tree
+ for file_name in filenames:
+ self.__treeview.findHdf5TreeModel().appendFile(file_name)
+
+ self.__treeview.activated.connect(self.displayData)
+ self.__treeview.activated.connect(lambda index: self.displayEvent("activated", index))
+ self.__treeview.clicked.connect(lambda index: self.displayEvent("clicked", index))
+ self.__treeview.doubleClicked.connect(lambda index: self.displayEvent("doubleClicked", index))
+ self.__treeview.entered.connect(lambda index: self.displayEvent("entered", index))
+ self.__treeview.pressed.connect(lambda index: self.displayEvent("pressed", index))
+
+ self.__treeview.addContextMenuCallback(self.customContextMenu)
+ # lambda function will never be called cause we store it as weakref
+ self.__treeview.addContextMenuCallback(lambda event: None)
+ # you have to store it first
+ self.__store_lambda = lambda event: self.closeAndSyncCustomContextMenu(event)
+ self.__treeview.addContextMenuCallback(self.__store_lambda)
+
+ def displayData(self):
+ """Called to update the dataviewer with the selected data.
+ """
+ selected = list(self.__treeview.selectedH5Nodes())
+ if len(selected) == 1:
+ # Update the viewer for a single selection
+ data = selected[0]
+ # data is a hdf5.H5Node object
+ # data.h5py_object is a Group/Dataset object (from h5py, spech5, fabioh5)
+ # The dataviewer can display both
+ self.__dataViewer.setData(data)
+
+ def displayEvent(self, eventName, index):
+ """Called to log event in widget
+ """
+ def formatKey(name, value):
+ name, value = silx.utils.html.escape(str(name)), silx.utils.html.escape(str(value))
+ return "<li><b>%s</b>: %s</li>" % (name, value)
+
+ text = "<html>"
+ text += "<h1>Event</h1>"
+ text += "<ul>"
+ text += formatKey("name", eventName)
+ text += formatKey("index", type(index))
+ text += "</ul>"
+
+ text += "<h1>Selected HDF5 objects</h1>"
+
+ for h5_obj in self.__treeview.selectedH5Nodes():
+ text += "<h2>HDF5 object</h2>"
+ text += "<ul>"
+ text += formatKey("local_filename", h5_obj.local_file.filename)
+ text += formatKey("local_basename", h5_obj.local_basename)
+ text += formatKey("local_name", h5_obj.local_name)
+ text += formatKey("real_filename", h5_obj.file.filename)
+ text += formatKey("real_basename", h5_obj.basename)
+ text += formatKey("real_name", h5_obj.name)
+
+ text += formatKey("obj", h5_obj.ntype)
+ text += formatKey("dtype", getattr(h5_obj, "dtype", None))
+ text += formatKey("shape", getattr(h5_obj, "shape", None))
+ text += formatKey("attrs", getattr(h5_obj, "attrs", None))
+ if hasattr(h5_obj, "attrs"):
+ text += "<ul>"
+ if len(h5_obj.attrs) == 0:
+ text += "<li>empty</li>"
+ for key, value in h5_obj.attrs.items():
+ text += formatKey(key, value)
+ text += "</ul>"
+ text += "</ul>"
+
+ text += "</html>"
+ self.__text.setHtml(text)
+
+ def useAsyncLoad(self, useAsync):
+ self.__asyncload = useAsync
+
+ def __fileCreated(self, filename):
+ if self.__asyncload:
+ self.__treeview.findHdf5TreeModel().insertFileAsync(filename)
+ else:
+ self.__treeview.findHdf5TreeModel().insertFile(filename)
+
+ def customContextMenu(self, event):
+ """Called to populate the context menu
+
+ :param silx.gui.hdf5.Hdf5ContextMenuEvent event: Event
+ containing expected information to populate the context menu
+ """
+ selectedObjects = event.source().selectedH5Nodes()
+ menu = event.menu()
+
+ hasDataset = False
+ for obj in selectedObjects:
+ if obj.ntype is h5py.Dataset:
+ hasDataset = True
+ break
+
+ if len(menu.children()):
+ menu.addSeparator()
+
+ if hasDataset:
+ action = qt.QAction("Do something on the datasets", event.source())
+ menu.addAction(action)
+
+ def closeAndSyncCustomContextMenu(self, event):
+ """Called to populate the context menu
+
+ :param silx.gui.hdf5.Hdf5ContextMenuEvent event: Event
+ containing expected information to populate the context menu
+ """
+ selectedObjects = event.source().selectedH5Nodes()
+ menu = event.menu()
+
+ if len(menu.children()):
+ menu.addSeparator()
+
+ for obj in selectedObjects:
+ if obj.ntype is h5py.File:
+ action = qt.QAction("Remove %s" % obj.local_filename, event.source())
+ action.triggered.connect(lambda: self.__treeview.findHdf5TreeModel().removeH5pyObject(obj.h5py_object))
+ menu.addAction(action)
+ action = qt.QAction("Synchronize %s" % obj.local_filename, event.source())
+ action.triggered.connect(lambda: self.__treeview.findHdf5TreeModel().synchronizeH5pyObject(obj.h5py_object))
+ menu.addAction(action)
+
+ def __hdf5ComboChanged(self, index):
+ function = self.__hdf5Combo.itemData(index)
+ self.__createHdf5Button.setCallable(function)
+
+ def __edfComboChanged(self, index):
+ function = self.__edfCombo.itemData(index)
+ self.__createEdfButton.setCallable(function)
+
+ def createTreeViewConfigurationPanel(self, parent, treeview):
+ """Create a configuration panel to allow to play with widget states"""
+ panel = qt.QWidget(parent)
+ panel.setLayout(qt.QHBoxLayout())
+
+ content = qt.QGroupBox("Create HDF5", panel)
+ content.setLayout(qt.QVBoxLayout())
+ panel.layout().addWidget(content)
+
+ combo = qt.QComboBox()
+ combo.addItem("Containing all types", get_hdf5_with_all_types)
+ combo.addItem("Containing all links", get_hdf5_with_all_links)
+ combo.addItem("Containing 1000 datasets", get_hdf5_with_1000_datasets)
+ combo.addItem("Containing 10000 datasets", get_hdf5_with_10000_datasets)
+ combo.addItem("Containing 100000 datasets", get_hdf5_with_100000_datasets)
+ combo.addItem("Containing recursive links", get_hdf5_with_recursive_links)
+ combo.addItem("Containing external recursive links", get_hdf5_with_external_recursive_links)
+ combo.addItem("Containing NXdata groups", get_hdf5_with_nxdata)
+ combo.activated.connect(self.__hdf5ComboChanged)
+ content.layout().addWidget(combo)
+
+ button = ThreadPoolPushButton(content, text="Create")
+ button.setCallable(combo.itemData(combo.currentIndex()))
+ button.succeeded.connect(self.__fileCreated)
+ content.layout().addWidget(button)
+
+ self.__hdf5Combo = combo
+ self.__createHdf5Button = button
+
+ asyncload = qt.QCheckBox("Async load", content)
+ asyncload.setChecked(self.__asyncload)
+ asyncload.toggled.connect(lambda: self.useAsyncLoad(asyncload.isChecked()))
+ content.layout().addWidget(asyncload)
+
+ content.layout().addStretch(1)
+
+ if fabio is not None:
+ content = qt.QGroupBox("Create EDF", panel)
+ content.setLayout(qt.QVBoxLayout())
+ panel.layout().addWidget(content)
+
+ combo = qt.QComboBox()
+ combo.addItem("Containing all types", get_edf_with_all_types)
+ combo.addItem("Containing 100000 datasets", get_edf_with_100000_frames)
+ combo.activated.connect(self.__edfComboChanged)
+ content.layout().addWidget(combo)
+
+ button = ThreadPoolPushButton(content, text="Create")
+ button.setCallable(combo.itemData(combo.currentIndex()))
+ button.succeeded.connect(self.__fileCreated)
+ content.layout().addWidget(button)
+
+ self.__edfCombo = combo
+ self.__createEdfButton = button
+
+ content.layout().addStretch(1)
+
+ option = qt.QGroupBox("Tree options", panel)
+ option.setLayout(qt.QVBoxLayout())
+ panel.layout().addWidget(option)
+
+ sorting = qt.QCheckBox("Enable sorting", option)
+ sorting.setChecked(treeview.selectionMode() == qt.QAbstractItemView.MultiSelection)
+ sorting.toggled.connect(lambda: treeview.setSortingEnabled(sorting.isChecked()))
+ option.layout().addWidget(sorting)
+
+ multiselection = qt.QCheckBox("Multi-selection", option)
+ multiselection.setChecked(treeview.selectionMode() == qt.QAbstractItemView.MultiSelection)
+ switch_selection = lambda: treeview.setSelectionMode(
+ qt.QAbstractItemView.MultiSelection if multiselection.isChecked()
+ else qt.QAbstractItemView.SingleSelection)
+ multiselection.toggled.connect(switch_selection)
+ option.layout().addWidget(multiselection)
+
+ filedrop = qt.QCheckBox("Drop external file", option)
+ filedrop.setChecked(treeview.findHdf5TreeModel().isFileDropEnabled())
+ filedrop.toggled.connect(lambda: treeview.findHdf5TreeModel().setFileDropEnabled(filedrop.isChecked()))
+ option.layout().addWidget(filedrop)
+
+ filemove = qt.QCheckBox("Reorder files", option)
+ filemove.setChecked(treeview.findHdf5TreeModel().isFileMoveEnabled())
+ filemove.toggled.connect(lambda: treeview.findHdf5TreeModel().setFileMoveEnabled(filedrop.isChecked()))
+ option.layout().addWidget(filemove)
+
+ option.layout().addStretch(1)
+
+ option = qt.QGroupBox("Header options", panel)
+ option.setLayout(qt.QVBoxLayout())
+ panel.layout().addWidget(option)
+
+ autosize = qt.QCheckBox("Auto-size headers", option)
+ autosize.setChecked(treeview.header().hasAutoResizeColumns())
+ autosize.toggled.connect(lambda: treeview.header().setAutoResizeColumns(autosize.isChecked()))
+ option.layout().addWidget(autosize)
+
+ columnpopup = qt.QCheckBox("Popup to hide/show columns", option)
+ columnpopup.setChecked(treeview.header().hasHideColumnsPopup())
+ columnpopup.toggled.connect(lambda: treeview.header().setEnableHideColumnsPopup(columnpopup.isChecked()))
+ option.layout().addWidget(columnpopup)
+
+ define_columns = qt.QComboBox()
+ define_columns.addItem("Default columns", treeview.findHdf5TreeModel().COLUMN_IDS)
+ define_columns.addItem("Only name and Value", [treeview.findHdf5TreeModel().NAME_COLUMN, treeview.findHdf5TreeModel().VALUE_COLUMN])
+ define_columns.activated.connect(lambda index: treeview.header().setSections(define_columns.itemData(index)))
+ option.layout().addWidget(define_columns)
+
+ option.layout().addStretch(1)
+
+ panel.layout().addStretch(1)
+
+ return panel
+
+
+def main(filenames):
+ """
+ :param filenames: list of file paths
+ """
+ app = qt.QApplication([])
+ sys.excepthook = qt.exceptionHandler
+ window = Hdf5TreeViewExample(filenames)
+ window.show()
+ result = app.exec_()
+ # remove ending warnings relative to QTimer
+ app.deleteLater()
+ sys.exit(result)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/examples/icons.py b/examples/icons.py
new file mode 100644
index 0000000..0992cf4
--- /dev/null
+++ b/examples/icons.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""
+Display available project icons using Qt.
+"""
+from silx.gui import qt
+import silx.gui.icons
+import pkg_resources
+import functools
+
+
+class IconPreview(qt.QMainWindow):
+
+ def __init__(self, *args, **kwargs):
+ qt.QMainWindow.__init__(self, *args, **kwargs)
+
+ widget = qt.QWidget(self)
+ self.iconPanel = self.createIconPanel(widget)
+ self.sizePanel = self.createSizePanel(widget)
+
+ layout = qt.QVBoxLayout()
+ widget.setLayout(layout)
+ # layout.setSizeConstraint(qt.QLayout.SetMinAndMaxSize)
+ layout.addWidget(self.sizePanel)
+ layout.addWidget(self.iconPanel)
+ layout.addStretch()
+ self.setCentralWidget(widget)
+
+ def createSizePanel(self, parent):
+ group = qt.QButtonGroup()
+ group.setExclusive(True)
+ panel = qt.QWidget(parent)
+ panel.setLayout(qt.QHBoxLayout())
+
+ for size in [16, 24, 32]:
+ button = qt.QPushButton("%spx" % size, panel)
+ button.clicked.connect(functools.partial(self.setIconSize, size))
+ button.setCheckable(True)
+ panel.layout().addWidget(button)
+ group.addButton(button)
+
+ self.__sizeGroup = group
+ button.setChecked(True)
+ return panel
+
+ def createIconPanel(self, parent):
+ panel = qt.QWidget(parent)
+ layout = qt.QGridLayout()
+ # layout.setSizeConstraint(qt.QLayout.SetMinAndMaxSize)
+ panel.setLayout(layout)
+
+ self.tools = []
+
+ icons = pkg_resources.resource_listdir("silx.resources", "gui/icons")
+ # filter out sub-directories
+ icons = filter(lambda x: not pkg_resources.resource_isdir("silx.resources", "gui/icons/" + x), icons)
+ # remove extension
+ icons = [i.split(".")[0] for i in icons]
+ # remove duplicated names
+ icons = set(icons)
+ # sort by names
+ icons = sorted(icons)
+
+ for i, icon_name in enumerate(icons):
+ col, line = i / 10, i % 10
+ icon = silx.gui.icons.getQIcon(icon_name)
+ tool = qt.QToolButton(panel)
+ tool.setIcon(icon)
+ tool.setIconSize(qt.QSize(32, 32))
+ tool.setToolTip(icon_name)
+ layout.addWidget(tool, col, line)
+ self.tools.append(tool)
+
+ return panel
+
+ def setIconSize(self, size):
+ for tool in self.tools:
+ tool.setIconSize(qt.QSize(size, size))
+
+
+if __name__ == "__main__":
+ app = qt.QApplication([])
+ window = IconPreview()
+ window.setVisible(True)
+ app.exec_()
diff --git a/examples/imageview.py b/examples/imageview.py
new file mode 100755
index 0000000..34595e2
--- /dev/null
+++ b/examples/imageview.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""
+Example to show the use of `ImageView` widget. It can be used to open an EDF
+or TIFF file from the shell command line.
+
+To view an image file with the current installed silx library:
+``python examples/imageview.py <file to open>``
+To get help:
+``python examples/imageview.py -h``
+
+For developers with a git clone you can use it with the bootstrap
+To view an image file with the current installed silx library:
+
+``./bootstrap.py python examples/imageview.py <file to open>``
+"""
+from __future__ import division
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/10/2016"
+
+import logging
+from silx.gui.plot.ImageView import ImageViewMainWindow
+from silx.gui import qt
+import numpy
+
+logger = logging.getLogger(__name__)
+
+
+def main(argv=None):
+ """Display an image from a file in an :class:`ImageView` widget.
+
+ :param argv: list of command line arguments or None (the default)
+ to use sys.argv.
+ :type argv: list of str
+ :return: Exit status code
+ :rtype: int
+ :raises IOError: if no image can be loaded from the file
+ """
+ import argparse
+ import os.path
+
+ from silx.third_party.EdfFile import EdfFile
+
+ # Command-line arguments
+ parser = argparse.ArgumentParser(
+ description='Browse the images of an EDF file.')
+ parser.add_argument(
+ '-o', '--origin', nargs=2,
+ type=float, default=(0., 0.),
+ help="""Coordinates of the origin of the image: (x, y).
+ Default: 0., 0.""")
+ parser.add_argument(
+ '-s', '--scale', nargs=2,
+ type=float, default=(1., 1.),
+ help="""Scale factors applied to the image: (sx, sy).
+ Default: 1., 1.""")
+ parser.add_argument(
+ '-l', '--log', action="store_true",
+ help="Use logarithm normalization for colormap, default: Linear.")
+ parser.add_argument(
+ 'filename', nargs='?',
+ help='EDF filename of the image to open')
+ args = parser.parse_args(args=argv)
+
+ # Open the input file
+ if not args.filename:
+ logger.warning('No image file provided, displaying dummy data')
+ edfFile = None
+ data = numpy.arange(1024 * 1024.).reshape(1024, 1024)
+ nbFrames = 1
+
+ else:
+ if not os.path.isfile(args.filename):
+ raise IOError('No input file: %s' % args.filename)
+
+ else:
+ edfFile = EdfFile(args.filename)
+ data = edfFile.GetData(0)
+
+ nbFrames = edfFile.GetNumImages()
+ if nbFrames == 0:
+ raise IOError(
+ 'Cannot read image(s) from file: %s' % args.filename)
+
+ global app # QApplication must be global to avoid seg fault on quit
+ app = qt.QApplication([])
+ sys.excepthook = qt.exceptionHandler
+
+ mainWindow = ImageViewMainWindow()
+ mainWindow.setAttribute(qt.Qt.WA_DeleteOnClose)
+
+ if args.log: # Use log normalization by default
+ colormap = mainWindow.getDefaultColormap()
+ colormap['normalization'] = 'log'
+ mainWindow.setColormap(colormap)
+
+ mainWindow.setImage(data,
+ origin=args.origin,
+ scale=args.scale)
+
+ if edfFile is not None and nbFrames > 1:
+ # Add a toolbar for multi-frame EDF support
+ multiFrameToolbar = qt.QToolBar('Multi-frame')
+ multiFrameToolbar.addWidget(qt.QLabel(
+ 'Frame [0-%d]:' % (nbFrames - 1)))
+
+ spinBox = qt.QSpinBox()
+ spinBox.setRange(0, nbFrames - 1)
+
+ def updateImage(index):
+ mainWindow.setImage(edfFile.GetData(index),
+ origin=args.origin,
+ scale=args.scale,
+ reset=False)
+ spinBox.valueChanged[int].connect(updateImage)
+ multiFrameToolbar.addWidget(spinBox)
+
+ mainWindow.addToolBar(multiFrameToolbar)
+
+ mainWindow.show()
+ mainWindow.setFocus(qt.Qt.OtherFocusReason)
+
+ return app.exec_()
+
+
+if __name__ == "__main__":
+ import sys
+ sys.exit(main(argv=sys.argv[1:]))
diff --git a/examples/periodicTable.py b/examples/periodicTable.py
new file mode 100644
index 0000000..e329ef7
--- /dev/null
+++ b/examples/periodicTable.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""This script is a simple example of how to use the periodic table widgets,
+select elements and connect signals.
+"""
+import sys
+from silx.gui import qt
+from silx.gui.widgets import PeriodicTable
+
+a = qt.QApplication(sys.argv)
+sys.excepthook = qt.exceptionHandler
+a.lastWindowClosed.connect(a.quit)
+
+w = qt.QTabWidget()
+
+pt = PeriodicTable.PeriodicTable(w, selectable=True)
+pc = PeriodicTable.PeriodicCombo(w)
+pl = PeriodicTable.PeriodicList(w)
+
+pt.setSelection(['Fe', 'Si', 'Mt'])
+pl.setSelectedElements(['H', 'Be', 'F'])
+pc.setSelection("Li")
+
+
+def change_list(items):
+ print("New list selection:", [item.symbol for item in items])
+
+
+def change_combo(item):
+ print("New combo selection:", item.symbol)
+
+
+def click_table(item):
+ print("New table click: %s (%s)" % (item.name, item.subcategory))
+
+
+def change_table(items):
+ print("New table selection:", [item.symbol for item in items])
+
+
+pt.sigElementClicked.connect(click_table)
+pt.sigSelectionChanged.connect(change_table)
+pl.sigSelectionChanged.connect(change_list)
+pc.sigSelectionChanged.connect(change_combo)
+
+# move combo into container widget to preventing it from filling
+# the tab inside TabWidget
+comboContainer = qt.QWidget(w)
+comboContainer.setLayout(qt.QVBoxLayout())
+comboContainer.layout().addWidget(pc)
+
+w.addTab(pt, "PeriodicTable")
+w.addTab(pl, "PeriodicList")
+w.addTab(comboContainer, "PeriodicCombo")
+w.show()
+
+a.exec_()
+
diff --git a/examples/scatterMask.py b/examples/scatterMask.py
new file mode 100644
index 0000000..45b1bac
--- /dev/null
+++ b/examples/scatterMask.py
@@ -0,0 +1,153 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""
+This example demonstrates how to use ScatterMaskToolsWidget
+and NamedScatterAlphaSlider with a PlotWidget.
+"""
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.plot import PlotWidget
+
+from silx.gui.plot.AlphaSlider import NamedScatterAlphaSlider
+
+from silx.gui.plot import ScatterMaskToolsWidget
+
+
+class MaskScatterWidget(qt.QMainWindow):
+ """Simple plot widget designed to display a scatter plot on top
+ of a background image.
+
+ A transparency slider is provided to adjust the transparency of the
+ scatter points.
+
+ A mask tools widget is provided to select/mask points of the scatter
+ plot.
+ """
+ def __init__(self, parent=None):
+ super(MaskScatterWidget, self).__init__(parent=parent)
+ self._activeScatterLegend = "active scatter"
+ self._bgImageLegend = "background image"
+
+ # widgets
+ centralWidget = qt.QWidget(self)
+
+ self._plot = PlotWidget(parent=centralWidget)
+
+ self._maskToolsWidget = ScatterMaskToolsWidget.ScatterMaskToolsWidget(
+ plot=self._plot, parent=centralWidget)
+
+ self._alphaSlider = NamedScatterAlphaSlider(parent=self, plot=self._plot)
+ self._alphaSlider.setOrientation(qt.Qt.Horizontal)
+ self._alphaSlider.setToolTip("Adjust scatter opacity")
+
+ # layout
+ layout = qt.QVBoxLayout(centralWidget)
+ layout.addWidget(self._plot)
+ layout.addWidget(self._alphaSlider)
+ layout.addWidget(self._maskToolsWidget)
+ centralWidget.setLayout(layout)
+
+ self.setCentralWidget(centralWidget)
+
+ def setSelectionMask(self, mask, copy=True):
+ """Set the mask to a new array.
+
+ :param numpy.ndarray mask: The array to use for the mask.
+ Mask type: array of uint8 of dimension 1,
+ Array of other types are converted.
+ :param bool copy: True (the default) to copy the array,
+ False to use it as is if possible.
+ :return: None if failed, shape of mask as 1-tuple if successful.
+ """
+ return self._maskToolsWidget.setSelectionMask(mask,
+ copy=copy)
+
+ def getSelectionMask(self, copy=True):
+ """Get the current mask as a 1D array.
+
+ :param bool copy: True (default) to get a copy of the mask.
+ If False, the returned array MUST not be modified.
+ :return: The array of the mask with dimension of the scatter data.
+ If there is no scatter data, an empty array is returned.
+ :rtype: 1D numpy.ndarray of uint8
+ """
+ return self._maskToolsWidget.getSelectionMask(copy=copy)
+
+ def setBackgroundImage(self, image, xscale=(0, 1.), yscale=(0, 1.),
+ colormap=None):
+ """Set a background image
+
+ :param image: 2D image, array of shape (nrows, ncolumns)
+ or (nrows, ncolumns, 3) or (nrows, ncolumns, 4) RGB(A) pixmap
+ :param xscale: Factors for polynomial scaling for x-axis,
+ *(a, b)* such as :math:`x \mapsto a + bx`
+ :param yscale: Factors for polynomial scaling for y-axis
+ """
+ self._plot.addImage(image, legend=self._bgImageLegend,
+ origin=(xscale[0], yscale[0]),
+ scale=(xscale[1], yscale[1]),
+ z=0, replace=False,
+ colormap=colormap)
+
+ def setScatter(self, x, y, v=None, info=None, colormap=None):
+ """Set the scatter data, by providing its data as a 1D
+ array or as a pixmap.
+
+ The scatter plot set through this method is associated
+ with the transparency slider.
+
+ :param x: 1D array of x coordinates
+ :param y: 1D array of y coordinates
+ :param v: Array of values for each point, represented as the color
+ of the point on the plot.
+ """
+ self._plot.addScatter(x, y, v, legend=self._activeScatterLegend,
+ info=info, colormap=colormap)
+ # the mask is associated with the active scatter
+ self._plot._setActiveItem(kind="scatter",
+ legend=self._activeScatterLegend)
+
+ self._alphaSlider.setLegend(self._activeScatterLegend)
+
+
+if __name__ == "__main__":
+ app = qt.QApplication([])
+ msw = MaskScatterWidget()
+
+ # create a synthetic bg image
+ bg_img = numpy.arange(200*150).reshape((200, 150))
+ bg_img[75:125, 80:120] = 1000
+
+ # create synthetic data for a scatter plot
+ twopi = numpy.pi * 2
+ x = 50 + 80 * numpy.linspace(0, twopi, num=100) / twopi * numpy.cos(numpy.linspace(0, twopi, num=100))
+ y = 150 + 150 * numpy.linspace(0, twopi, num=100) / twopi * numpy.sin(numpy.linspace(0, twopi, num=100))
+ v = numpy.arange(100) / 3.14
+
+ msw.setScatter(x, y, v=v)
+ msw.setBackgroundImage(bg_img)
+ msw.show()
+ app.exec_()
diff --git a/examples/shiftPlotAction.py b/examples/shiftPlotAction.py
new file mode 100755
index 0000000..ca48300
--- /dev/null
+++ b/examples/shiftPlotAction.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This script is a simple (trivial) example of how to create a PlotWindow,
+create a custom :class:`PlotAction` and add it to the toolbar.
+
+The action simply shifts the selected curve up by 1 unit by adding 1 to each
+value of y.
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "12/01/2017"
+
+import sys
+from silx.gui import qt
+from silx.gui.plot import PlotWindow
+from silx.gui.plot.PlotActions import PlotAction
+
+
+class ShiftUpAction(PlotAction):
+ """QAction shifting up a curve by one unit
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+ def __init__(self, plot, parent=None):
+ PlotAction.__init__(self,
+ plot,
+ icon='shape-circle',
+ text='Shift up',
+ tooltip='Shift active curve up by one unit',
+ triggered=self.shiftActiveCurveUp,
+ parent=parent)
+
+ def shiftActiveCurveUp(self):
+ """Get the active curve, add 1 to all y values, use this new y
+ array to replace the original curve"""
+ # By inheriting from PlotAction, we get access to attribute self.plot
+ # which is a reference to the PlotWindow
+ activeCurve = self.plot.getActiveCurve()
+
+ if activeCurve is None:
+ qt.QMessageBox.information(self.plot,
+ 'Shift Curve',
+ 'Please select a curve.')
+ else:
+ # Unpack curve data.
+ # Each curve is represented by an object with methods to access:
+ # the curve data, its legend, associated information and curve style
+ # Here we retrieve the x and y data of the curve
+ x0 = activeCurve.getXData()
+ y0 = activeCurve.getYData()
+
+ # Add 1 to all values in the y array
+ # and assign the result to a new array y1
+ y1 = y0 + 1.0
+
+ # Set the active curve data with the shifted y values
+ activeCurve.setData(x0, y1)
+
+
+# creating QApplication is mandatory in order to use qt widget
+app = qt.QApplication([])
+
+sys.excepthook = qt.exceptionHandler
+
+# create a PlotWindow
+plotwin = PlotWindow()
+# Add a new toolbar
+toolbar = qt.QToolBar("My toolbar")
+plotwin.addToolBar(toolbar)
+# Get a reference to the PlotWindow's menu bar, add a menu
+menubar = plotwin.menuBar()
+actions_menu = menubar.addMenu("Custom actions")
+
+# Initialize our action, give it plotwin as a parameter
+myaction = ShiftUpAction(plotwin)
+# Add action to the menubar and toolbar
+toolbar.addAction(myaction)
+actions_menu.addAction(myaction)
+
+# Plot a couple of curves with synthetic data
+x = [0, 1, 2, 3, 4, 5, 6]
+y1 = [0, 1, 0, 1, 0, 1, 0]
+y2 = [0, 1, 2, 3, 4, 5, 6]
+plotwin.addCurve(x, y1, legend="triangle shaped curve")
+plotwin.addCurve(x, y2, legend="oblique line")
+
+plotwin.show()
+app.exec_()
diff --git a/examples/simplewidget.py b/examples/simplewidget.py
new file mode 100755
index 0000000..605beb3
--- /dev/null
+++ b/examples/simplewidget.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This script shows a gallery of simple widgets provided by silx.
+
+It shows the following widgets:
+
+- :class:WaitingPushButton: A button with a progress-like waiting animated icon
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "12/01/2017"
+
+import sys
+from silx.gui import qt
+from silx.gui.widgets.WaitingPushButton import WaitingPushButton
+from silx.gui.widgets.ThreadPoolPushButton import ThreadPoolPushButton
+
+
+class SimpleWidgetExample(qt.QMainWindow):
+ """This windows shows simple widget provided by silx."""
+
+ def __init__(self):
+ """Constructor"""
+ qt.QMainWindow.__init__(self)
+ self.setWindowTitle("Silx simple widget example")
+
+ main_panel = qt.QWidget(self)
+ main_panel.setLayout(qt.QVBoxLayout())
+
+ main_panel.layout().addWidget(qt.QLabel("WaitingPushButton"))
+ main_panel.layout().addWidget(self.createWaitingPushButton())
+ main_panel.layout().addWidget(self.createWaitingPushButton2())
+
+ main_panel.layout().addWidget(qt.QLabel("ThreadPoolPushButton"))
+ main_panel.layout().addWidget(self.createThreadPoolPushButton())
+
+ self.setCentralWidget(main_panel)
+
+ def createWaitingPushButton(self):
+ widget = WaitingPushButton(text="Push me and wait for ever")
+ widget.clicked.connect(widget.swapWaiting)
+ return widget
+
+ def createWaitingPushButton2(self):
+ widget = WaitingPushButton(text="Push me")
+ widget.setDisabledWhenWaiting(False)
+ widget.clicked.connect(widget.swapWaiting)
+ return widget
+
+ def printResult(self, result):
+ print(result)
+
+ def printError(self, result):
+ print("Error")
+ print(result)
+
+ def takesTimeToComputePow(self, a, b):
+ qt.QThread.sleep(2)
+ return a ** b
+
+ def createThreadPoolPushButton(self):
+ widget = ThreadPoolPushButton(text="Compute 2^16")
+ widget.setCallable(self.takesTimeToComputePow, 2, 16)
+ widget.succeeded.connect(self.printResult)
+ widget.failed.connect(self.printError)
+ return widget
+
+
+def main():
+ """
+ Main function
+ """
+ app = qt.QApplication([])
+ sys.excepthook = qt.exceptionHandler
+ window = SimpleWidgetExample()
+ window.show()
+ result = app.exec_()
+ # remove ending warnings relative to QTimer
+ app.deleteLater()
+ sys.excepthook = sys.__excepthook__
+ sys.exit(result)
+
+
+main()
diff --git a/examples/spectoh5.py b/examples/spectoh5.py
new file mode 100755
index 0000000..f2f796b
--- /dev/null
+++ b/examples/spectoh5.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+# ###########################################################################*/
+"""This script converts SPEC data files to HDF5 files.
+
+By default, it creates a new output file or fails if the output file given
+on the command line already exist, but the user can choose to overwrite
+existing files, or append SPEC data to existing HDF5 files.
+
+In case of appending data to HDF5 files, the user can choose between ignoring
+input data if a corresponding dataset already exists in the output file, or
+overwriting existing datasets.
+
+By default, new scans are written to the root (/) of the HDF5 file, but it is
+possible to specify a different target path.
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "18/10/2016"
+
+import argparse
+from silx.io.spectoh5 import write_spec_to_h5
+
+parser = argparse.ArgumentParser(description=__doc__)
+parser.add_argument('spec_path',
+ help='Path to input SPEC data file')
+parser.add_argument('h5_path',
+ help='Path to output HDF5 file')
+parser.add_argument('-t', '--target-path', default="/",
+ help='Name of the group in which to save the scans ' +
+ 'in the output file')
+
+mode_group = parser.add_mutually_exclusive_group()
+mode_group.add_argument('-o', '--overwrite', action="store_true",
+ help='Overwrite output file if it exists, ' +
+ 'else create new file.')
+mode_group.add_argument('-a', '--append', action="store_true",
+ help='Append data to existing file if it exists, ' +
+ 'else create new file.')
+
+parser.add_argument('--overwrite-data', action="store_true",
+ help='In append mode, overwrite existing groups and ' +
+ 'datasets in the output file, if they exist with ' +
+ 'the same name as input data. By default, existing' +
+ ' data is not touched, corresponding input data is' +
+ ' ignored.')
+
+args = parser.parse_args()
+
+if args.overwrite_data and not args.append:
+ print("Option --overwrite-data ignored " +
+ "(only relevant combined with option -a)")
+
+if args.overwrite:
+ mode = "w"
+elif args.append:
+ mode = "a"
+else:
+ # by default, use "write" mode and fail if file already exists
+ mode = "w-"
+
+write_spec_to_h5(args.spec_path, args.h5_path,
+ h5path=args.target_path,
+ mode=mode,
+ overwrite_data=args.overwrite_data)
diff --git a/examples/stackView.py b/examples/stackView.py
new file mode 100644
index 0000000..0447cea
--- /dev/null
+++ b/examples/stackView.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This script is a simple example to illustrate how to use the StackView
+widget.
+"""
+import numpy
+import sys
+from silx.gui import qt
+from silx.gui.plot.StackView import StackViewMainWindow
+
+app = qt.QApplication(sys.argv[1:])
+
+a, b, c = numpy.meshgrid(numpy.linspace(-10, 10, 200),
+ numpy.linspace(-10, 5, 150),
+ numpy.linspace(-5, 10, 120),
+ indexing="ij")
+mystack = numpy.asarray(numpy.sin(a * b * c) / (a * b * c),
+ dtype='float32')
+
+# linear calibrations (a, b), x -> a + bx
+dim0_calib = (-10., 20. / 200.)
+dim1_calib = (-10., 15. / 150.)
+dim2_calib = (-5., 15. / 120.)
+
+# sv = StackView()
+sv = StackViewMainWindow()
+sv.setColormap("jet", autoscale=True)
+sv.setStack(mystack,
+ calibrations=[dim0_calib, dim1_calib, dim2_calib])
+sv.setLabels(["dim0: -10 to 10 (200 samples)",
+ "dim1: -10 to 5 (150 samples)",
+ "dim2: -5 to 10 (120 samples)"])
+sv.show()
+
+app.exec_()
diff --git a/examples/viewer3DVolume.py b/examples/viewer3DVolume.py
new file mode 100644
index 0000000..7a95d8a
--- /dev/null
+++ b/examples/viewer3DVolume.py
@@ -0,0 +1,209 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This script illustrates the use of silx.gui.plot3d.ScalarFieldView.
+
+It loads a 3D scalar data set from a file and displays iso-surfaces and
+an interactive cutting plane.
+It can also be started without providing a file.
+"""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/01/2017"
+
+
+import argparse
+import logging
+import os.path
+
+import numpy
+
+from silx.gui import qt
+
+from silx.gui.plot3d.ScalarFieldView import ScalarFieldView
+from silx.gui.plot3d import SFViewParamTree
+
+logging.basicConfig()
+
+_logger = logging.getLogger(__name__)
+
+
+try:
+ import h5py
+except ImportError:
+ _logger.warning('h5py is not installed: HDF5 not supported')
+ h5py = None
+
+
+def load(filename):
+ """Load 3D scalar field from file.
+
+ It supports 3D stack HDF5 files and numpy files.
+
+ :param str filename: Name of the file to open
+ and path in file for hdf5 file
+ :return: numpy.ndarray with 3 dimensions.
+ """
+ if not os.path.isfile(filename.split('::')[0]):
+ raise IOError('No input file: %s' % filename)
+
+ if h5py is not None and h5py.is_hdf5(filename.split('::')[0]):
+ if '::' not in filename:
+ raise ValueError(
+ 'HDF5 path not provided: Use <filename>::<path> format')
+
+ filename, path = filename.split('::')
+ path, indices = path.split('#')[0], path.split('#')[1:]
+
+ with h5py.File(filename) as f:
+ data = f[path]
+
+ # Loop through indices along first dimensions
+ for index in indices:
+ data = data[int(index)]
+
+ data = numpy.array(data, order='C', dtype='float32')
+
+ else: # Try with numpy
+ try:
+ data = numpy.load(filename)
+ except IOError:
+ raise IOError('Unsupported file format: %s' % filename)
+
+ if data.ndim != 3:
+ raise RuntimeError(
+ 'Unsupported data set dimensions, only supports 3D datasets')
+
+ return data
+
+
+def main(argv=None):
+ # Parse input arguments
+ parser = argparse.ArgumentParser(
+ description=__doc__)
+ parser.add_argument(
+ '-l', '--level', nargs='?', type=float, default=float('nan'),
+ help="The value at which to generate the iso-surface")
+ parser.add_argument(
+ '-sx', '--xscale', nargs='?', type=float, default=1.,
+ help="The scale of the data on the X axis")
+ parser.add_argument(
+ '-sy', '--yscale', nargs='?', type=float, default=1.,
+ help="The scale of the data on the Y axis")
+ parser.add_argument(
+ '-sz', '--zscale', nargs='?', type=float, default=1.,
+ help="The scale of the data on the Z axis")
+ parser.add_argument(
+ '-ox', '--xoffset', nargs='?', type=float, default=0.,
+ help="The offset of the data on the X axis")
+ parser.add_argument(
+ '-oy', '--yoffset', nargs='?', type=float, default=0.,
+ help="The offset of the data on the Y axis")
+ parser.add_argument(
+ '-oz', '--zoffset', nargs='?', type=float, default=0.,
+ help="The offset of the data on the Z axis")
+ parser.add_argument(
+ 'filename',
+ nargs='?',
+ default=None,
+ help="""Filename to open.
+
+ It supports 3D volume saved as .npy or in .h5 files.
+
+ It also support nD data set (n>=3) stored in a HDF5 file.
+ For HDF5, provide the filename and path as: <filename>::<path_in_file>.
+ If the data set has more than 3 dimensions, it is possible to choose a
+ 3D data set as a subset by providing the indices along the first n-3
+ dimensions with '#':
+ <filename>::<path_in_file>#<1st_dim_index>...#<n-3th_dim_index>
+
+ E.g.: data.h5::/data_5D#1#1
+ """)
+ args = parser.parse_args(args=argv)
+
+ # Start GUI
+ global app # QApplication must be global to avoid seg fault on quit
+ app = qt.QApplication([])
+
+ # Create the viewer main window
+ window = ScalarFieldView()
+ window.setAttribute(qt.Qt.WA_DeleteOnClose)
+
+ # Create a parameter tree for the scalar field view
+ treeView = SFViewParamTree.TreeView(window)
+ treeView.setSfView(window) # Attach the parameter tree to the view
+
+ # Add the parameter tree to the main window in a dock widget
+ dock = qt.QDockWidget()
+ dock.setWindowTitle('Parameters')
+ dock.setWidget(treeView)
+ window.addDockWidget(qt.Qt.RightDockWidgetArea, dock)
+
+ # Load data from file
+ if args.filename is not None:
+ data = load(args.filename)
+ _logger.info('Data:\n\tShape: %s\n\tRange: [%f, %f]',
+ str(data.shape), data.min(), data.max())
+ else:
+ # Create dummy data
+ _logger.warning('Not data file provided, creating dummy data')
+ size = 128
+ z, y, x = numpy.mgrid[0:size, 0:size, 0:size]
+ data = numpy.asarray(
+ size**2 - ((x-size/2)**2 + (y-size/2)**2 + (z-size/2)**2),
+ dtype='float32')
+
+ # Set ScalarFieldView data
+ window.setData(data)
+
+ # Set scale of the data
+ window.setScale(args.xscale, args.yscale, args.zscale)
+
+ # Set offset of the data
+ window.setTranslation(args.xoffset, args.yoffset, args.zoffset)
+
+ # Set axes labels
+ window.setAxesLabels('X', 'Y', 'Z')
+
+ # Add an iso-surface
+ if not numpy.isnan(args.level):
+ # Add an iso-surface at the given iso-level
+ window.addIsosurface(args.level, '#FF0000FF')
+ else:
+ # Add an iso-surface from a function
+ window.addIsosurface(
+ lambda data: numpy.mean(data) + numpy.std(data),
+ '#FF0000FF')
+
+ window.show()
+ return app.exec_()
+
+
+if __name__ == '__main__':
+ import sys
+
+ sys.exit(main(argv=sys.argv[1:]))
diff --git a/qtdesigner_plugins/README.rst b/qtdesigner_plugins/README.rst
new file mode 100644
index 0000000..d647ea3
--- /dev/null
+++ b/qtdesigner_plugins/README.rst
@@ -0,0 +1,40 @@
+Using silx widgets in Qt Designer
+=================================
+
+With PyQt_, it is possible to use ``silx.gui`` widgets (and widgets written with PyQt in general) from the `Qt Designer`_.
+
+The following ``silx.gui`` widgets are available in the Qt Designer:
+
+- :class:`silx.gui.plot.Plot1D`
+- :class:`silx.gui.plot.Plot2D`
+- :class:`silx.gui.plot.PlotWidget`
+- :class:`silx.gui.plot.PlotWindow`
+
+Pre-requisite
+-------------
+
+The following software must be installed:
+
+- Qt_ with the `Qt Designer`_.
+- Python_.
+- PyQt_ with the designer plugin.
+- The ``silx`` Python package and its dependencies.
+ :mod:`silx.gui.plot` widgets requires matplotlib_.
+
+Usage
+-----
+
+The **PYQTDESIGNERPATH** environment variable defines the search paths for plugins enabling use of PyQt widgets in the designer.
+
+To start the Qt Designer with ``silx.gui`` widgets available, on Linux, run the following from the command line::
+
+ PYQTDESIGNERPATH=<silx_designer_plugin_dir> designer
+
+
+See `Using Qt Designer <http://pyqt.sourceforge.net/Docs/PyQt5/designer.html>`_ in PyQt_ documentation.
+
+.. _Qt: http://www.qt.io/
+.. _Python: https://www.python.org/
+.. _PyQt: https://riverbankcomputing.com/software/pyqt/intro
+.. _Qt Designer: http://doc.qt.io/qt-5/qtdesigner-manual.html
+.. _matplotlib: http://matplotlib.org/
diff --git a/qtdesigner_plugins/plot1dplugin.py b/qtdesigner_plugins/plot1dplugin.py
new file mode 100644
index 0000000..86982af
--- /dev/null
+++ b/qtdesigner_plugins/plot1dplugin.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+# 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.
+#
+# ###########################################################################*/
+"""silx.gui.plot Plot1D Qt designer plugin."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "30/05/2016"
+
+
+from silx.gui import icons, qt
+
+if qt.BINDING == 'PyQt4':
+ from PyQt4 import QtDesigner
+elif qt.BINDING == 'PyQt5':
+ from PyQt5 import QtDesigner
+else:
+ raise RuntimeError("Unsupport Qt BINDING: %s" % qt.BINDING)
+
+from silx.gui.plot import Plot1D
+
+
+class Plot1DPlugin(QtDesigner.QPyDesignerCustomWidgetPlugin):
+
+ def __init__(self, parent=None):
+ super(Plot1DPlugin, self).__init__(parent)
+ self.initialized = False
+
+ def initialize(self, core):
+ if self.initialized:
+ return
+
+ self.initialized = True
+
+ def isInitialized(self):
+ return self.initialized
+
+ def createWidget(self, parent):
+ plot = Plot1D(parent=parent)
+ plot.setAutoReplot(False)
+ return plot
+
+ def name(self):
+ return "Plot1D"
+
+ def group(self):
+ return "silx"
+
+ def icon(self):
+ return icons.getQIcon('plot-window')
+
+ def toolTip(self):
+ return ""
+
+ def whatsThis(self):
+ return ""
+
+ def isContainer(self):
+ return False
+
+ def includeFile(self):
+ return "silx.gui.plot.PlotWindow"
diff --git a/qtdesigner_plugins/plot2dplugin.py b/qtdesigner_plugins/plot2dplugin.py
new file mode 100644
index 0000000..1a07510
--- /dev/null
+++ b/qtdesigner_plugins/plot2dplugin.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+# 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.
+#
+# ###########################################################################*/
+"""silx.gui.plot Plot2D Qt designer plugin."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "30/05/2016"
+
+
+from silx.gui import icons, qt
+
+if qt.BINDING == 'PyQt4':
+ from PyQt4 import QtDesigner
+elif qt.BINDING == 'PyQt5':
+ from PyQt5 import QtDesigner
+else:
+ raise RuntimeError("Unsupport Qt BINDING: %s" % qt.BINDING)
+
+from silx.gui.plot import Plot2D
+
+
+class Plot2DPlugin(QtDesigner.QPyDesignerCustomWidgetPlugin):
+
+ def __init__(self, parent=None):
+ super(Plot2DPlugin, self).__init__(parent)
+ self.initialized = False
+
+ def initialize(self, core):
+ if self.initialized:
+ return
+
+ self.initialized = True
+
+ def isInitialized(self):
+ return self.initialized
+
+ def createWidget(self, parent):
+ plot = Plot2D(parent=parent)
+ plot.setAutoReplot(False)
+ return plot
+
+ def name(self):
+ return "Plot2D"
+
+ def group(self):
+ return "silx"
+
+ def icon(self):
+ return icons.getQIcon('plot-window-image')
+
+ def toolTip(self):
+ return ""
+
+ def whatsThis(self):
+ return ""
+
+ def isContainer(self):
+ return False
+
+ def includeFile(self):
+ return "silx.gui.plot.PlotWindow"
diff --git a/qtdesigner_plugins/plotwidgetplugin.py b/qtdesigner_plugins/plotwidgetplugin.py
new file mode 100644
index 0000000..6cc97a5
--- /dev/null
+++ b/qtdesigner_plugins/plotwidgetplugin.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+"""silx.gui.plot PlotWidget Qt designer plugin."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "30/05/2016"
+
+
+from silx.gui import qt, icons
+
+if qt.BINDING == 'PyQt4':
+ from PyQt4 import QtDesigner
+elif qt.BINDING == 'PyQt5':
+ from PyQt5 import QtDesigner
+else:
+ raise RuntimeError("Unsupport Qt BINDING: %s" % qt.BINDING)
+
+from silx.gui.plot import PlotWidget
+
+
+class PlotWidgetPlugin(QtDesigner.QPyDesignerCustomWidgetPlugin):
+
+ def __init__(self, parent=None):
+ super(PlotWidgetPlugin, self).__init__(parent)
+ self.initialized = False
+
+ def initialize(self, core):
+ if self.initialized:
+ return
+
+ self.initialized = True
+
+ def isInitialized(self):
+ return self.initialized
+
+ def createWidget(self, parent):
+ plot = PlotWidget(parent)
+ plot.setAutoReplot(False)
+ return plot
+
+ def name(self):
+ return "PlotWidget"
+
+ def group(self):
+ return "silx"
+
+ def icon(self):
+ return icons.getQIcon('plot-widget')
+
+ def toolTip(self):
+ return ""
+
+ def whatsThis(self):
+ return ""
+
+ def isContainer(self):
+ return False
+
+ def includeFile(self):
+ return "silx.gui.plot.PlotWidget"
diff --git a/qtdesigner_plugins/plotwindowplugin.py b/qtdesigner_plugins/plotwindowplugin.py
new file mode 100644
index 0000000..b666399
--- /dev/null
+++ b/qtdesigner_plugins/plotwindowplugin.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+"""silx.gui.plot PlotWindow Qt designer plugin."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "30/05/2016"
+
+
+from silx.gui import icons, qt
+
+if qt.BINDING == 'PyQt4':
+ from PyQt4 import QtDesigner
+elif qt.BINDING == 'PyQt5':
+ from PyQt5 import QtDesigner
+else:
+ raise RuntimeError("Unsupport Qt BINDING: %s" % qt.BINDING)
+
+from silx.gui.plot import PlotWindow
+
+
+class PlotWindowPlugin(QtDesigner.QPyDesignerCustomWidgetPlugin):
+
+ def __init__(self, parent=None):
+ super(PlotWindowPlugin, self).__init__(parent)
+ self.initialized = False
+
+ def initialize(self, core):
+ if self.initialized:
+ return
+
+ self.initialized = True
+
+ def isInitialized(self):
+ return self.initialized
+
+ def createWidget(self, parent):
+ plot = PlotWindow(parent)
+ plot.setAutoReplot(False)
+ return plot
+
+ def name(self):
+ return "PlotWindow"
+
+ def group(self):
+ return "silx"
+
+ def icon(self):
+ return icons.getQIcon('plot-window')
+
+ def toolTip(self):
+ return ""
+
+ def whatsThis(self):
+ return ""
+
+ def isContainer(self):
+ return False
+
+ def includeFile(self):
+ return "silx.gui.plot.PlotWindow"
diff --git a/run_tests.py b/run_tests.py
new file mode 100755
index 0000000..f314e6a
--- /dev/null
+++ b/run_tests.py
@@ -0,0 +1,391 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""Run the tests of the project.
+
+This script expects a suite function in <project_package>.test,
+which returns a unittest.TestSuite.
+
+Test coverage dependencies: coverage, lxml.
+"""
+
+__authors__ = ["Jérôme Kieffer", "Thomas Vincent"]
+__date__ = "19/04/2017"
+__license__ = "MIT"
+
+import distutils.util
+import logging
+import os
+import subprocess
+import sys
+import time
+import unittest
+
+
+logging.basicConfig(level=logging.WARNING)
+logger = logging.getLogger("run_tests")
+logger.setLevel(logging.WARNING)
+
+logger.info("Python %s %s", sys.version, tuple.__itemsize__ * 8)
+
+
+try:
+ import resource
+except ImportError:
+ resource = None
+ logger.warning("resource module missing")
+
+try:
+ import importlib
+except:
+ importer = __import__
+else:
+ importer = importlib.import_module
+
+
+try:
+ import numpy
+except Exception as error:
+ logger.warning("Numpy missing: %s", error)
+else:
+ logger.info("Numpy %s", numpy.version.version)
+
+
+try:
+ import h5py
+except Exception as error:
+ logger.warning("h5py missing: %s", error)
+else:
+ logger.info("h5py %s", h5py.version.version)
+
+
+def get_project_name(root_dir):
+ """Retrieve project name by running python setup.py --name in root_dir.
+
+ :param str root_dir: Directory where to run the command.
+ :return: The name of the project stored in root_dir
+ """
+ logger.debug("Getting project name in %s", root_dir)
+ p = subprocess.Popen([sys.executable, "setup.py", "--name"],
+ shell=False, cwd=root_dir, stdout=subprocess.PIPE)
+ name, _stderr_data = p.communicate()
+ logger.debug("subprocess ended with rc= %s", p.returncode)
+ return name.split()[-1].decode('ascii')
+
+
+PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
+PROJECT_NAME = get_project_name(PROJECT_DIR)
+logger.info("Project name: %s", PROJECT_NAME)
+
+
+class ProfileTextTestResult(unittest.TextTestRunner.resultclass):
+
+ def __init__(self, *arg, **kwarg):
+ unittest.TextTestRunner.resultclass.__init__(self, *arg, **kwarg)
+ self.logger = logging.getLogger("memProf")
+ self.logger.setLevel(min(logging.INFO, logging.root.level))
+ self.logger.handlers.append(logging.FileHandler("profile.log"))
+
+ def startTest(self, test):
+ unittest.TextTestRunner.resultclass.startTest(self, test)
+ if resource:
+ self.__mem_start = \
+ resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
+ self.__time_start = time.time()
+
+ def stopTest(self, test):
+ unittest.TextTestRunner.resultclass.stopTest(self, test)
+ # see issue 311. For other platform, get size of ru_maxrss in "man getrusage"
+ if sys.platform == "darwin":
+ ratio = 1e-6
+ else:
+ ratio = 1e-3
+ if resource:
+ memusage = (resource.getrusage(resource.RUSAGE_SELF).ru_maxrss -
+ self.__mem_start) * ratio
+ else:
+ memusage = 0
+ self.logger.info("Time: %.3fs \t RAM: %.3f Mb\t%s",
+ time.time() - self.__time_start, memusage, test.id())
+
+
+def report_rst(cov, package, version="0.0.0", base=""):
+ """
+ Generate a report of test coverage in RST (for Sphinx inclusion)
+
+ :param cov: test coverage instance
+ :param str package: Name of the package
+ :param str base: base directory of modules to include in the report
+ :return: RST string
+ """
+ import tempfile
+ fd, fn = tempfile.mkstemp(suffix=".xml")
+ os.close(fd)
+ cov.xml_report(outfile=fn)
+
+ from lxml import etree
+ xml = etree.parse(fn)
+ classes = xml.xpath("//class")
+
+ line0 = "Test coverage report for %s" % package
+ res = [line0, "=" * len(line0), ""]
+ res.append("Measured on *%s* version %s, %s" %
+ (package, version, time.strftime("%d/%m/%Y")))
+ res += ["",
+ ".. csv-table:: Test suite coverage",
+ ' :header: "Name", "Stmts", "Exec", "Cover"',
+ ' :widths: 35, 8, 8, 8',
+ '']
+ tot_sum_lines = 0
+ tot_sum_hits = 0
+
+ for cl in classes:
+ name = cl.get("name")
+ fname = cl.get("filename")
+ if not os.path.abspath(fname).startswith(base):
+ continue
+ lines = cl.find("lines").getchildren()
+ hits = [int(i.get("hits")) for i in lines]
+
+ sum_hits = sum(hits)
+ sum_lines = len(lines)
+
+ cover = 100.0 * sum_hits / sum_lines if sum_lines else 0
+
+ if base:
+ name = os.path.relpath(fname, base)
+
+ res.append(' "%s", "%s", "%s", "%.1f %%"' %
+ (name, sum_lines, sum_hits, cover))
+ tot_sum_lines += sum_lines
+ tot_sum_hits += sum_hits
+ res.append("")
+ res.append(' "%s total", "%s", "%s", "%.1f %%"' %
+ (package, tot_sum_lines, tot_sum_hits,
+ 100.0 * tot_sum_hits / tot_sum_lines if tot_sum_lines else 0))
+ res.append("")
+ return os.linesep.join(res)
+
+
+def build_project(name, root_dir):
+ """Run python setup.py build for the project.
+
+ Build directory can be modified by environment variables.
+
+ :param str name: Name of the project.
+ :param str root_dir: Root directory of the project
+ :return: The path to the directory were build was performed
+ """
+ platform = distutils.util.get_platform()
+ architecture = "lib.%s-%i.%i" % (platform,
+ sys.version_info[0], sys.version_info[1])
+
+ if os.environ.get("PYBUILD_NAME") == name:
+ # we are in the debian packaging way
+ home = os.environ.get("PYTHONPATH", "").split(os.pathsep)[-1]
+ elif os.environ.get("BUILDPYTHONPATH"):
+ home = os.path.abspath(os.environ.get("BUILDPYTHONPATH", ""))
+ else:
+ home = os.path.join(root_dir, "build", architecture)
+
+ logger.warning("Building %s to %s", name, home)
+ p = subprocess.Popen([sys.executable, "setup.py", "build"],
+ shell=False, cwd=root_dir)
+ logger.debug("subprocess ended with rc= %s", p.wait())
+ return home
+
+
+from argparse import ArgumentParser
+epilog = """Environment variables:
+WITH_QT_TEST=False to disable graphical tests
+SILX_OPENCL=False to disable OpenCL tests
+SILX_TEST_LOW_MEM=True to disable tests taking large amount of memory
+GPU=False to disable the use of a GPU with OpenCL test
+WITH_GL_TEST=False to disable tests using OpenGL
+"""
+parser = ArgumentParser(description='Run the tests.',
+ epilog=epilog)
+
+parser.add_argument("-i", "--insource",
+ action="store_true", dest="insource", default=False,
+ help="Use the build source and not the installed version")
+parser.add_argument("-c", "--coverage", dest="coverage",
+ action="store_true", default=False,
+ help=("Report code coverage" +
+ "(requires 'coverage' and 'lxml' module)"))
+parser.add_argument("-m", "--memprofile", dest="memprofile",
+ action="store_true", default=False,
+ help="Report memory profiling")
+parser.add_argument("-v", "--verbose", default=0,
+ action="count", dest="verbose",
+ help="Increase verbosity. Option -v prints additional " +
+ "INFO messages. Use -vv for full verbosity, " +
+ "including debug messages and test help strings.")
+parser.add_argument("-x", "--no-gui", dest="gui", default=True,
+ action="store_false",
+ help="Disable the test of the graphical use interface")
+parser.add_argument("-g", "--no-opengl", dest="opengl", default=True,
+ action="store_false",
+ help="Disable tests using OpenGL")
+parser.add_argument("-o", "--no-opencl", dest="opencl", default=True,
+ action="store_false",
+ help="Disable the test of the OpenCL part")
+parser.add_argument("-l", "--low-mem", dest="low_mem", default=False,
+ action="store_true",
+ help="Disable test with large memory consumption (>100Mbyte")
+parser.add_argument("--qt-binding", dest="qt_binding", default=None,
+ help="Force using a Qt binding, from 'PyQt4', 'PyQt5', or 'PySide'")
+
+default_test_name = "%s.test.suite" % PROJECT_NAME
+parser.add_argument("test_name", nargs='*',
+ default=(default_test_name,),
+ help="Test names to run (Default: %s)" % default_test_name)
+options = parser.parse_args()
+sys.argv = [sys.argv[0]]
+
+
+test_verbosity = 1
+if options.verbose == 1:
+ logging.root.setLevel(logging.INFO)
+ logger.info("Set log level: INFO")
+ test_verbosity = 2
+elif options.verbose > 1:
+ logging.root.setLevel(logging.DEBUG)
+ logger.info("Set log level: DEBUG")
+ test_verbosity = 2
+
+if not options.gui:
+ os.environ["WITH_QT_TEST"] = "False"
+
+if not options.opencl:
+ os.environ["SILX_OPENCL"] = "False"
+
+if not options.opengl:
+ os.environ["WITH_GL_TEST"] = "False"
+
+if options.low_mem:
+ os.environ["SILX_TEST_LOW_MEM"] = "True"
+
+if options.coverage:
+ logger.info("Running test-coverage")
+ import coverage
+ omits = ["*test*", "*third_party*", "*/setup.py",
+ # temporary test modules (silx.math.fit.test.test_fitmanager)
+ "*customfun.py", ]
+ try:
+ cov = coverage.Coverage(omit=omits)
+ except AttributeError:
+ cov = coverage.coverage(omit=omits)
+ cov.start()
+
+if options.qt_binding:
+ binding = options.qt_binding.lower()
+ if binding == "pyqt4":
+ logger.info("Force using PyQt4")
+ import PyQt4.QtCore # noqa
+ elif binding == "pyqt5":
+ logger.info("Force using PyQt5")
+ import PyQt5.QtCore # noqa
+ elif binding == "pyside":
+ logger.info("Force using PySide")
+ import PySide.QtCore # noqa
+ else:
+ raise ValueError("Qt binding '%s' is unknown" % options.qt_binding)
+
+# Prevent importing from source directory
+if (os.path.dirname(os.path.abspath(__file__)) ==
+ os.path.abspath(sys.path[0])):
+ removed_from_sys_path = sys.path.pop(0)
+ logger.info("Patched sys.path, removed: '%s'", removed_from_sys_path)
+
+
+# import module
+if not options.insource:
+ try:
+ module = importer(PROJECT_NAME)
+ except:
+ logger.warning(
+ "%s missing, using built (i.e. not installed) version",
+ PROJECT_NAME)
+ options.insource = True
+
+if options.insource:
+ build_dir = build_project(PROJECT_NAME, PROJECT_DIR)
+
+ sys.path.insert(0, build_dir)
+ logger.warning("Patched sys.path, added: '%s'", build_dir)
+ module = importer(PROJECT_NAME)
+
+
+PROJECT_VERSION = getattr(module, 'version', '')
+PROJECT_PATH = module.__path__[0]
+
+
+# Run the tests
+runnerArgs = {}
+runnerArgs["verbosity"] = test_verbosity
+if options.memprofile:
+ runnerArgs["resultclass"] = ProfileTextTestResult
+runner = unittest.TextTestRunner(**runnerArgs)
+
+logger.warning("Test %s %s from %s",
+ PROJECT_NAME, PROJECT_VERSION, PROJECT_PATH)
+
+test_module_name = PROJECT_NAME + '.test'
+logger.info('Import %s', test_module_name)
+test_module = importer(test_module_name)
+
+test_suite = unittest.TestSuite()
+
+if not options.test_name:
+ # Do not use test loader to avoid cryptic exception
+ # when an error occur during import
+ project_test_suite = getattr(test_module, 'suite')
+ test_suite.addTest(project_test_suite())
+else:
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromNames(options.test_name))
+
+
+result = runner.run(test_suite)
+for test, reason in result.skipped:
+ logger.warning('Skipped %s (%s): %s',
+ test.id(), test.shortDescription() or '', reason)
+
+if result.wasSuccessful():
+ logger.info("Test suite succeeded")
+ exit_status = 0
+else:
+ logger.warning("Test suite failed")
+ exit_status = 1
+
+
+if options.coverage:
+ cov.stop()
+ cov.save()
+ with open("coverage.rst", "w") as fn:
+ fn.write(report_rst(cov, PROJECT_NAME, PROJECT_VERSION, PROJECT_PATH))
+
+sys.exit(exit_status)
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..861a9f5
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build =
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..852c48d
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,745 @@
+#!/usr/bin/python
+# coding: utf8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["Jérôme Kieffer", "Thomas Vincent"]
+__date__ = "04/05/2017"
+__license__ = "MIT"
+
+
+# This import is here only to fix a bug on Debian 7 with python2.7
+# Without this, the system io module is not loaded from numpy.distutils
+# the silx.io module seems to be loaded instead
+import io
+
+import sys
+import os
+import platform
+import shutil
+import logging
+import glob
+
+logging.basicConfig(level=logging.INFO)
+
+logger = logging.getLogger("silx.setup")
+
+
+from distutils.command.clean import clean as Clean
+from distutils.command.build import build as _build
+try:
+ from setuptools import Command
+ from setuptools.command.build_py import build_py as _build_py
+ from setuptools.command.build_ext import build_ext
+ from setuptools.command.sdist import sdist
+ logger.info("Use setuptools")
+except ImportError:
+ try:
+ from numpy.distutils.core import Command
+ except ImportError:
+ from distutils.core import Command
+ from distutils.command.build_py import build_py as _build_py
+ from distutils.command.build_ext import build_ext
+ from distutils.command.sdist import sdist
+ logger.info("Use distutils")
+
+try:
+ import sphinx
+ import sphinx.util.console
+ sphinx.util.console.color_terminal = lambda: False
+ from sphinx.setup_command import BuildDoc
+except ImportError:
+ sphinx = None
+
+
+PROJECT = "silx"
+
+if "LANG" not in os.environ and sys.platform == "darwin" and sys.version_info[0] > 2:
+ print("""WARNING: the LANG environment variable is not defined,
+an utf-8 LANG is mandatory to use setup.py, you may face unexpected UnicodeError.
+export LANG=en_US.utf-8
+export LC_ALL=en_US.utf-8
+""")
+
+
+def get_version():
+ """Returns current version number from version.py file"""
+ import version
+ return version.strictversion
+
+
+def get_readme():
+ """Returns content of README.rst file"""
+ dirname = os.path.dirname(os.path.abspath(__file__))
+ filename = os.path.join(dirname, "README.rst")
+ with io.open(filename, "r", encoding="utf-8") as fp:
+ long_description = fp.read()
+ return long_description
+
+
+classifiers = ["Development Status :: 4 - Beta",
+ "Environment :: Console",
+ "Environment :: MacOS X",
+ "Environment :: Win32 (MS Windows)",
+ "Environment :: X11 Applications :: Qt",
+ "Intended Audience :: Education",
+ "Intended Audience :: Science/Research",
+ "License :: OSI Approved :: MIT License",
+ "License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
+ "Natural Language :: English",
+ "Operating System :: MacOS",
+ "Operating System :: Microsoft :: Windows",
+ "Operating System :: POSIX",
+ "Programming Language :: Cython",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3.4",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: Implementation :: CPython",
+ "Topic :: Scientific/Engineering :: Physics",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ ]
+
+
+# ########## #
+# version.py #
+# ########## #
+
+class build_py(_build_py):
+ """
+ Enhanced build_py which copies version.py to <PROJECT>._version.py
+ """
+ def find_package_modules(self, package, package_dir):
+ modules = _build_py.find_package_modules(self, package, package_dir)
+ if package == PROJECT:
+ modules.append((PROJECT, '_version', 'version.py'))
+ return modules
+
+
+########
+# Test #
+########
+
+class PyTest(Command):
+ """Command to start tests running the script: run_tests.py -i"""
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ import subprocess
+ errno = subprocess.call([sys.executable, 'run_tests.py', '-i'])
+ if errno != 0:
+ raise SystemExit(errno)
+
+
+# ################### #
+# build_doc command #
+# ################### #
+
+if sphinx is None:
+ class SphinxExpectedCommand(Command):
+ """Command to inform that sphinx is missing"""
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ raise RuntimeError(
+ 'Sphinx is required to build or test the documentation.\n'
+ 'Please install Sphinx (http://www.sphinx-doc.org).')
+
+
+class BuildMan(Command):
+ """Command to build man pages"""
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ build = self.get_finalized_command('build')
+ path = sys.path
+ path.insert(0, os.path.abspath(build.build_lib))
+
+ env = dict((str(k), str(v)) for k, v in os.environ.items())
+ env["PYTHONPATH"] = os.pathsep.join(path)
+
+ import subprocess
+
+ status = subprocess.call(["mkdir", "-p", "build/man"])
+ if status != 0:
+ raise RuntimeError("Fail to create build/man directory")
+
+ try:
+ import tempfile
+ import stat
+ script_name = None
+
+ # help2man expect a single executable file to extract the help
+ # we create it, execute it, and delete it at the end
+
+ # create a launcher using the right python interpreter
+ script_fid, script_name = tempfile.mkstemp(prefix="%s_" % PROJECT, text=True)
+ script = os.fdopen(script_fid, 'wt')
+ script.write("#!%s\n" % sys.executable)
+ script.write("import runpy\n")
+ script.write("runpy.run_module('%s', run_name='__main__')\n" % PROJECT)
+ script.close()
+
+ # make it executable
+ mode = os.stat(script_name).st_mode
+ os.chmod(script_name, mode + stat.S_IEXEC)
+
+ # execute help2man
+ p = subprocess.Popen(["help2man", script_name, "-o", "build/man/silx.1"], env=env)
+ status = p.wait()
+ if status != 0:
+ raise RuntimeError("Fail to generate man documentation")
+ finally:
+ # clean up the script
+ if script_name is not None:
+ os.remove(script_name)
+
+
+if sphinx is not None:
+ class BuildDocCommand(BuildDoc):
+ """Command to build documentation using sphinx.
+
+ Project should have already be built.
+ """
+
+ def run(self):
+ # make sure the python path is pointing to the newly built
+ # code so that the documentation is built on this and not a
+ # previously installed version
+
+ build = self.get_finalized_command('build')
+ sys.path.insert(0, os.path.abspath(build.build_lib))
+
+ # # Copy .ui files to the path:
+ # dst = os.path.join(
+ # os.path.abspath(build.build_lib), "silx", "gui")
+ # if not os.path.isdir(dst):
+ # os.makedirs(dst)
+ # for i in os.listdir("gui"):
+ # if i.endswith(".ui"):
+ # src = os.path.join("gui", i)
+ # idst = os.path.join(dst, i)
+ # if not os.path.exists(idst):
+ # shutil.copy(src, idst)
+
+ # Build the Users Guide in HTML and TeX format
+ for builder in ['html', 'latex']:
+ self.builder = builder
+ self.builder_target_dir = os.path.join(self.build_dir, builder)
+ self.mkpath(self.builder_target_dir)
+ BuildDoc.run(self)
+ sys.path.pop(0)
+else:
+ BuildDocCommand = SphinxExpectedCommand
+
+
+# ################### #
+# test_doc command #
+# ################### #
+
+if sphinx is not None:
+ class TestDocCommand(BuildDoc):
+ """Command to test the documentation using sphynx doctest.
+
+ http://www.sphinx-doc.org/en/1.4.8/ext/doctest.html
+ """
+ def run(self):
+ # make sure the python path is pointing to the newly built
+ # code so that the documentation is built on this and not a
+ # previously installed version
+
+ build = self.get_finalized_command('build')
+ sys.path.insert(0, os.path.abspath(build.build_lib))
+
+ # Build the Users Guide in HTML and TeX format
+ for builder in ['doctest']:
+ self.builder = builder
+ self.builder_target_dir = os.path.join(self.build_dir, builder)
+ self.mkpath(self.builder_target_dir)
+ BuildDoc.run(self)
+ sys.path.pop(0)
+
+else:
+ TestDocCommand = SphinxExpectedCommand
+
+# ############################# #
+# numpy.distutils Configuration #
+# ############################# #
+
+def configuration(parent_package='', top_path=None):
+ """Recursive construction of package info to be used in setup().
+
+ See http://docs.scipy.org/doc/numpy/reference/distutils.html#numpy.distutils.misc_util.Configuration
+ """
+ try:
+ from numpy.distutils.misc_util import Configuration
+ except ImportError:
+ raise ImportError(
+ "To install this package, you must install numpy first\n"
+ "(See https://pypi.python.org/pypi/numpy)")
+ config = Configuration(None, parent_package, top_path)
+ config.set_options(
+ ignore_setup_xxx_py=True,
+ assume_default_configuration=True,
+ delegate_options_to_subpackages=True,
+ quiet=True)
+ config.add_subpackage(PROJECT)
+ return config
+
+# ############## #
+# Compiler flags #
+# ############## #
+
+
+class Build(_build):
+ """Command to support more user options for the build."""
+
+ user_options = [
+ ('no-openmp', None,
+ "do not use OpenMP for compiled extension modules"),
+ ('openmp', None,
+ "use OpenMP for the compiled extension modules"),
+ ('no-cython', None,
+ "do not compile Cython extension modules (use default compiled c-files)"),
+ ('force-cython', None,
+ "recompile all Cython extension modules"),
+ ]
+ user_options.extend(_build.user_options)
+
+ boolean_options = ['no-openmp', 'openmp', 'no-cython', 'force-cython']
+ boolean_options.extend(_build.boolean_options)
+
+ def initialize_options(self):
+ _build.initialize_options(self)
+ self.no_openmp = None
+ self.openmp = None
+ self.no_cython = None
+ self.force_cython = None
+
+ def finalize_options(self):
+ _build.finalize_options(self)
+ self.finalize_cython_options(min_version='0.21.1')
+ self.finalize_openmp_options()
+
+ def _parse_env_as_bool(self, key):
+ content = os.environ.get(key, "")
+ value = content.lower()
+ if value in ["1", "true", "yes", "y"]:
+ return True
+ if value in ["0", "false", "no", "n"]:
+ return False
+ if value in ["none", ""]:
+ return None
+ msg = "Env variable '%s' contains '%s'. But a boolean or an empty \
+ string was expected. Variable ignored."
+ logger.warning(msg, key, content)
+ return None
+
+ def finalize_openmp_options(self):
+ """Check if extensions must be compiled with OpenMP.
+
+ The result is stored into the object.
+ """
+ if self.openmp:
+ use_openmp = True
+ elif self.no_openmp:
+ use_openmp = False
+ else:
+ env_force_cython = self._parse_env_as_bool("WITH_OPENMP")
+ if env_force_cython is not None:
+ use_openmp = env_force_cython
+ else:
+ # Use it by default
+ use_openmp = True
+
+ if use_openmp:
+ if platform.system() == "Darwin":
+ # By default Xcode5 & XCode6 do not support OpenMP, Xcode4 is OK.
+ osx = tuple([int(i) for i in platform.mac_ver()[0].split(".")])
+ if osx >= (10, 8):
+ logger.warning("OpenMP support ignored. Your platform do not support it")
+ use_openmp = False
+
+ # Remove attributes used by distutils parsing
+ # use 'use_openmp' instead
+ del self.no_openmp
+ del self.openmp
+ self.use_openmp = use_openmp
+
+ def finalize_cython_options(self, min_version=None):
+ """
+ Check if cythonization must be used for the extensions.
+
+ The result is stored into the object.
+ """
+
+ if self.force_cython:
+ use_cython = "force"
+ elif self.no_cython:
+ use_cython = "no"
+ else:
+ env_force_cython = self._parse_env_as_bool("FORCE_CYTHON")
+ env_with_cython = self._parse_env_as_bool("WITH_CYTHON")
+ if env_force_cython is True:
+ use_cython = "force"
+ elif env_with_cython is True:
+ use_cython = "yes"
+ elif env_with_cython is False:
+ use_cython = "no"
+ else:
+ # Use it by default
+ use_cython = "yes"
+
+ if use_cython in ["force", "yes"]:
+ try:
+ import Cython.Compiler.Version
+ if min_version and Cython.Compiler.Version.version < min_version:
+ msg = "Cython version is too old. At least version is %s \
+ expected. Cythonization is skipped."
+ logger.warning(msg, str(min_version))
+ use_cython = "no"
+ except ImportError:
+ msg = "Cython is not available. Cythonization is skipped."
+ logger.warning(msg)
+ use_cython = "no"
+
+
+ # Remove attribute used by distutils parsing
+ # use 'use_cython' and 'force_cython' instead
+ del self.no_cython
+ self.force_cython = use_cython == "force"
+ self.use_cython = use_cython in ["force", "yes"]
+
+
+class BuildExt(build_ext):
+ """Handle extension compilation.
+
+ Command-line argument and environment can custom:
+
+ - The use of cython to cythonize files, else a default version is used
+ - Build extension with support of OpenMP (by default it is enabled)
+ - If building with MSVC, compiler flags are converted from gcc flags.
+ """
+
+ COMPILE_ARGS_CONVERTER = {'-fopenmp': '/openmp'}
+
+ LINK_ARGS_CONVERTER = {'-fopenmp': ' '}
+
+ description = 'Build silx extensions'
+
+ def finalize_options(self):
+ build_ext.finalize_options(self)
+ build_obj = self.distribution.get_command_obj("build")
+ self.use_openmp = build_obj.use_openmp
+ self.use_cython = build_obj.use_cython
+ self.force_cython = build_obj.force_cython
+
+ def patch_with_default_cythonized_files(self, ext):
+ """Replace cython files by .c or .cpp files in extension's sources.
+
+ It replaces the *.pyx and *.py source files of the extensions
+ to either *.cpp or *.c source files.
+ No compilation is performed.
+
+ :param Extension ext: An extension to patch.
+ """
+ new_sources = []
+ for source in ext.sources:
+ base, file_ext = os.path.splitext(source)
+ if file_ext in ('.pyx', '.py'):
+ if ext.language == 'c++':
+ cythonized = base + '.cpp'
+ else:
+ cythonized = base + '.c'
+ if not os.path.isfile(cythonized):
+ raise RuntimeError("Source file not found: %s. Cython is needed" % cythonized)
+ print("Use default cythonized file for %s" % source)
+ new_sources.append(cythonized)
+ else:
+ new_sources.append(source)
+ ext.sources = new_sources
+
+ def patch_extension(self, ext):
+ """
+ Patch an extension according to requested Cython and OpenMP usage.
+
+ :param Extension ext: An extension
+ """
+ # Cytonize
+ if not self.use_cython:
+ self.patch_with_default_cythonized_files(ext)
+ else:
+ from Cython.Build import cythonize
+ patched_exts = cythonize(
+ [ext],
+ compiler_directives={'embedsignature': True},
+ force=self.force_cython,
+ compile_time_env={"HAVE_OPENMP": self.use_openmp}
+ )
+ ext.sources = patched_exts[0].sources
+
+ # Remove OpenMP flags if OpenMP is disabled
+ if not self.use_openmp:
+ ext.extra_compile_args = [
+ f for f in ext.extra_compile_args if f != '-fopenmp']
+ ext.extra_link_args = [
+ f for f in ext.extra_link_args if f != '-fopenmp']
+
+ # Convert flags from gcc to MSVC if required
+ if self.compiler.compiler_type == 'msvc':
+ ext.extra_compile_args = [self.COMPILE_ARGS_CONVERTER.get(f, f)
+ for f in ext.extra_compile_args]
+ ext.extra_link_args = [self.LINK_ARGS_CONVERTER.get(f, f)
+ for f in ext.extra_link_args]
+
+ def build_extensions(self):
+ for ext in self.extensions:
+ self.patch_extension(ext)
+ build_ext.build_extensions(self)
+
+
+################################################################################
+# Clean command
+################################################################################
+
+
+class CleanCommand(Clean):
+ description = "Remove build artifacts from the source tree"
+
+ def expand(self, path_list):
+ """Expand a list of path using glob magic.
+
+ :param list[str] path_list: A list of path which may contains magic
+ :rtype: list[str]
+ :returns: A list of path without magic
+ """
+ path_list2 = []
+ for path in path_list:
+ if glob.has_magic(path):
+ iterator = glob.iglob(path)
+ path_list2.extend(iterator)
+ else:
+ path_list2.append(path)
+ return path_list2
+
+ def run(self):
+ Clean.run(self)
+ # really remove the directories
+ # and not only if they are empty
+ to_remove = [self.build_base]
+ to_remove = self.expand(to_remove)
+
+ if not self.dry_run:
+ for path in to_remove:
+ try:
+ if os.path.isdir(path):
+ shutil.rmtree(path)
+ else:
+ os.remove(path)
+ logger.info("removing '%s'", path)
+ except OSError:
+ pass
+
+################################################################################
+# Debian source tree
+################################################################################
+
+
+class sdist_debian(sdist):
+ """
+ Tailor made sdist for debian
+ * remove auto-generated doc
+ * remove cython generated .c files
+ * remove cython generated .c files
+ * remove .bat files
+ * include .l man files
+ """
+ @staticmethod
+ def get_debian_name():
+ import version
+ name = "%s_%s" % (PROJECT, version.debianversion)
+ return name
+
+ def prune_file_list(self):
+ sdist.prune_file_list(self)
+ to_remove = ["doc/build", "doc/pdf", "doc/html", "pylint", "epydoc"]
+ print("Removing files for debian")
+ for rm in to_remove:
+ self.filelist.exclude_pattern(pattern="*", anchor=False, prefix=rm)
+
+ # this is for Cython files specifically: remove C & html files
+ search_root = os.path.dirname(os.path.abspath(__file__))
+ for root, _, files in os.walk(search_root):
+ for afile in files:
+ if os.path.splitext(afile)[1].lower() == ".pyx":
+ base_file = os.path.join(root, afile)[len(search_root) + 1:-4]
+ self.filelist.exclude_pattern(pattern=base_file + ".c")
+ self.filelist.exclude_pattern(pattern=base_file + ".cpp")
+ self.filelist.exclude_pattern(pattern=base_file + ".html")
+
+ # do not include third_party/_local files
+ self.filelist.exclude_pattern(pattern="*", prefix="silx/third_party/_local")
+
+ def make_distribution(self):
+ self.prune_file_list()
+ sdist.make_distribution(self)
+ dest = self.archive_files[0]
+ dirname, basename = os.path.split(dest)
+ base, ext = os.path.splitext(basename)
+ while ext in [".zip", ".tar", ".bz2", ".gz", ".Z", ".lz", ".orig"]:
+ base, ext = os.path.splitext(base)
+ if ext:
+ dest = "".join((base, ext))
+ else:
+ dest = base
+ # sp = dest.split("-")
+ # base = sp[:-1]
+ # nr = sp[-1]
+ debian_arch = os.path.join(dirname, self.get_debian_name() + ".orig.tar.gz")
+ os.rename(self.archive_files[0], debian_arch)
+ self.archive_files = [debian_arch]
+ print("Building debian .orig.tar.gz in %s" % self.archive_files[0])
+
+
+# ##### #
+# setup #
+# ##### #
+
+def get_project_configuration(dry_run):
+ """Returns project arguments for setup"""
+ install_requires = [
+ # for most of the computation
+ "numpy",
+ # for the script launcher
+ "setuptools"]
+
+ setup_requires = ["setuptools", "numpy"]
+
+ package_data = {
+ 'silx.resources': [
+ # Add here all resources files
+ 'gui/icons/*.png',
+ 'gui/icons/*.svg',
+ 'gui/icons/*.mng',
+ 'gui/icons/*.gif',
+ 'gui/icons/animated/*.png',
+ 'opencl/*.cl',
+ 'opencl/sift/*.cl']
+ }
+
+ entry_points = {
+ 'console_scripts': ['silx = silx.__main__:main'],
+ # 'gui_scripts': [],
+ }
+
+ cmdclass = dict(
+ build=Build,
+ build_py=build_py,
+ test=PyTest,
+ build_doc=BuildDocCommand,
+ test_doc=TestDocCommand,
+ build_ext=BuildExt,
+ build_man=BuildMan,
+ clean=CleanCommand,
+ debian_src=sdist_debian)
+
+ if dry_run:
+ # DRY_RUN implies actions which do not require NumPy
+ #
+ # And they are required to succeed without Numpy for example when
+ # pip is used to install silx when Numpy is not yet present in
+ # the system.
+ setup_kwargs = {}
+ else:
+ config = configuration()
+ setup_kwargs = config.todict()
+
+ setup_kwargs.update(name=PROJECT,
+ version=get_version(),
+ url="https://github.com/silx-kit/silx",
+ author="data analysis unit",
+ author_email="silx@esrf.fr",
+ classifiers=classifiers,
+ description="Software library for X-Ray data analysis",
+ long_description=get_readme(),
+ install_requires=install_requires,
+ setup_requires=setup_requires,
+ cmdclass=cmdclass,
+ package_data=package_data,
+ zip_safe=False,
+ entry_points=entry_points,
+ )
+ return setup_kwargs
+
+
+def setup_package():
+ """Run setup(**kwargs)
+
+ Depending on the command, it either runs the complete setup which depends on numpy,
+ or a *dry run* setup with no dependency on numpy.
+ """
+
+ # Check if action requires build/install
+ dry_run = len(sys.argv) == 1 or (len(sys.argv) >= 2 and (
+ '--help' in sys.argv[1:] or
+ sys.argv[1] in ('--help-commands', 'egg_info', '--version',
+ 'clean', '--name')))
+
+ if dry_run:
+ # DRY_RUN implies actions which do not require dependancies, like NumPy
+ try:
+ from setuptools import setup
+ logger.info("Use setuptools.setup")
+ except ImportError:
+ from distutils.core import setup
+ logger.info("Use distutils.core.setup")
+ else:
+ try:
+ from setuptools import setup
+ except ImportError:
+ from numpy.distutils.core import setup
+ logger.info("Use numpydistutils.setup")
+
+ setup_kwargs = get_project_configuration(dry_run)
+ setup(**setup_kwargs)
+
+if __name__ == "__main__":
+ setup_package()
diff --git a/silx.egg-info/PKG-INFO b/silx.egg-info/PKG-INFO
new file mode 100644
index 0000000..7a6c11c
--- /dev/null
+++ b/silx.egg-info/PKG-INFO
@@ -0,0 +1,140 @@
+Metadata-Version: 1.1
+Name: silx
+Version: 0.5.0
+Summary: Software library for X-Ray data analysis
+Home-page: https://github.com/silx-kit/silx
+Author: data analysis unit
+Author-email: silx@esrf.fr
+License: UNKNOWN
+Description:
+ silx toolkit
+ ============
+
+ 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 `HDF5 <https://www.hdfgroup.org/HDF5/>`_ file format (with support of `SPEC <https://certif.com/spec.html>`_ file format)
+ * histogramming
+ * fitting
+ * 1D and 2D visualization using multiple backends (matplotlib or OpenGL)
+ * image plot widget with a set of associated tools (See `changelog file <https://github.com/silx-kit/silx/blob/master/CHANGELOG.rst>`_).
+ * Unified browser for HDF5, SPEC and image file formats supporting inspection and visualization of n-dimensional datasets.
+ * Unified viewer (silx view filename) for HDF5, SPEC and image file formats
+ * OpenGL-based widget to display 3D scalar field with isosurface and cutting plane.
+ * image alignement (sift - OpenCL implementation)
+
+ Installation
+ ------------
+
+ To install silx, run::
+
+ pip install silx
+
+ To install silx locally, run::
+
+ pip install silx --user
+
+ On Linux, to install silx with pip, you must install numpy first. Unofficial packages for different distributions are available :
+
+ - Unofficial Debian8 packages are available at http://www.silx.org/pub/debian/
+ - 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/
+ - Arch Linux (AUR) packages are also available: https://aur.archlinux.org/packages/python-silx
+
+ On Windows, pre-compiled binaries (aka Python wheels) are available for Python 2.7, 3.5 and 3.6.
+
+ On Mac OS X, pre-compiled binaries (aka Python wheels) are available for Python 2.7.
+
+ The latest development version can be obtained from the git repository::
+
+ git clone https://github.com/silx-kit/silx.git
+ cd silx
+ pip install . [--user]
+
+ Dependencies
+ ------------
+
+ * `Python <https://www.python.org/>`_ 2.7, 3.4 or above.
+ * `numpy <http://www.numpy.org>`_
+
+ The GUI widgets of the silx package depend on the following extra packages:
+
+ * A Qt binding: `PyQt5, PyQt4 <https://riverbankcomputing.com/software/pyqt/intro>`_ (using API version 2) or `PySide <https://pypi.python.org/pypi/PySide/>`_
+ * `matplotlib <http://matplotlib.org/>`_ for the silx.gui.plot package
+ * `PyOpenGL <http://pyopengl.sourceforge.net/>`_ for the silx.gui.plot3d package
+
+ Most modules and functions dealing with `HDF5 <https://www.hdfgroup.org/HDF5/>`_ input/output depend on the following extra package:
+ * `h5py <http://www.h5py.org/>`_
+
+ * `ipython <https://ipython.org/>`_ and `qtconsole <https://pypi.python.org/pypi/qtconsole>`_ is required by silx.gui.console.py
+
+ Supported platforms: Linux, Windows, Mac OS X.
+
+ Documentation
+ -------------
+
+ Documentation of releases is available at https://pythonhosted.org/silx/
+
+ Latest documentation (nightly build) is available at http://www.silx.org/doc/silx/
+
+ To build the documentation from the source (requires `Sphinx <http://www.sphinx-doc.org>`_), run::
+
+ python setup.py build build_doc
+
+ Testing
+ -------
+
+ - Travis CI status: |Travis Status|
+ - Appveyor CI status: |Appveyor Status|
+
+ To run the tests from the python interpreter, run:
+
+ >>> import silx.test
+ >>> silx.test.run_tests()
+
+ To run the tests, from the source directory, run::
+
+ python run_tests.py
+
+ Examples
+ --------
+
+ Some examples are available in the source code repository. For example::
+
+ python examples/{exampleName.py}
+
+
+ License
+ -------
+
+ The source code of silx is licensed under the MIT and LGPL licenses.
+ See the `copyright file <https://github.com/silx-kit/silx/blob/master/copyright>`_ for details.
+
+ .. |Travis Status| image:: https://travis-ci.org/silx-kit/silx.svg?branch=master
+ :target: https://travis-ci.org/silx-kit/silx
+ .. |Appveyor Status| image:: https://ci.appveyor.com/api/projects/status/qgox9ei0wxwfagrb/branch/master?svg=true
+ :target: https://ci.appveyor.com/project/ESRF/silx
+
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Environment :: Console
+Classifier: Environment :: MacOS X
+Classifier: Environment :: Win32 (MS Windows)
+Classifier: Environment :: X11 Applications :: Qt
+Classifier: Intended Audience :: Education
+Classifier: Intended Audience :: Science/Research
+Classifier: License :: OSI Approved :: MIT License
+Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
+Classifier: Natural Language :: English
+Classifier: Operating System :: MacOS
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: POSIX
+Classifier: Programming Language :: Cython
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Topic :: Scientific/Engineering :: Physics
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
diff --git a/silx.egg-info/SOURCES.txt b/silx.egg-info/SOURCES.txt
new file mode 100644
index 0000000..6c9b73a
--- /dev/null
+++ b/silx.egg-info/SOURCES.txt
@@ -0,0 +1,848 @@
+CHANGELOG.rst
+MANIFEST.in
+README.rst
+copyright
+run_tests.py
+setup.py
+stdeb.cfg
+version.py
+doc/source/changelog.rst
+doc/source/conf.py
+doc/source/index.rst
+doc/source/install.rst
+doc/source/license.rst
+doc/source/overview.rst
+doc/source/tutorials.rst
+doc/source/virtualenv.rst
+doc/source/Tutorials/array_widget.rst
+doc/source/Tutorials/fit.rst
+doc/source/Tutorials/fitconfig.rst
+doc/source/Tutorials/specfile_to_hdf5.rst
+doc/source/Tutorials/Sift/sift.rst
+doc/source/Tutorials/img/arraywidget3D_0.png
+doc/source/Tutorials/img/arraywidget3D_1.png
+doc/source/Tutorials/img/arraywidget5D_0.png
+doc/source/Tutorials/img/arraywidget5D_1.png
+doc/source/Tutorials/img/custom_config_scale0.5.png
+doc/source/Tutorials/img/custom_config_scale1.0.png
+doc/source/Tutorials/img/custom_config_scale2.1.png
+doc/source/Tutorials/img/fitwidget1.png
+doc/source/Tutorials/img/fitwidget2.png
+doc/source/Tutorials/img/fitwidget3.png
+doc/source/Tutorials/img/fitwidget4.png
+doc/source/Tutorials/img/fitwidget5.png
+doc/source/Tutorials/img/stripbg_plot1.png
+doc/source/Tutorials/img/stripbg_plot2.png
+doc/source/description/index.rst
+doc/source/description/sift.rst
+doc/source/description/img/sift_bench_cpu0.png
+doc/source/description/img/sift_bench_cpu_kp.png
+doc/source/description/img/sift_bench_cpu_res.png
+doc/source/description/img/sift_bench_gpu0.png
+doc/source/description/img/sift_bench_gpu_kp.png
+doc/source/description/img/sift_bench_gpu_res.png
+doc/source/description/img/sift_dog1.png
+doc/source/description/img/sift_match1.png
+doc/source/description/img/sift_orientation.png
+doc/source/img/silx.ico
+doc/source/img/silx_large.png
+doc/source/img/silx_small.png
+doc/source/modules/index.rst
+doc/source/modules/resources.rst
+doc/source/modules/gui/console.rst
+doc/source/modules/gui/designer.rst
+doc/source/modules/gui/icons.rst
+doc/source/modules/gui/index.rst
+doc/source/modules/gui/qt.rst
+doc/source/modules/gui/update_icons_rst.py
+doc/source/modules/gui/data/arraytable.rst
+doc/source/modules/gui/data/dataviewer.rst
+doc/source/modules/gui/data/dataviewerframe.rst
+doc/source/modules/gui/data/index.rst
+doc/source/modules/gui/data/numpyaxesselector.rst
+doc/source/modules/gui/data/textformatter.rst
+doc/source/modules/gui/data/img/DataViewer.png
+doc/source/modules/gui/data/img/DataViewerFrame.png
+doc/source/modules/gui/data/img/NumpyAxesSelector.png
+doc/source/modules/gui/fit/backgroundwidget.rst
+doc/source/modules/gui/fit/fitwidget.rst
+doc/source/modules/gui/fit/index.rst
+doc/source/modules/gui/fit/img/bgwidget.png
+doc/source/modules/gui/hdf5/examples_hdf5widget.rst
+doc/source/modules/gui/hdf5/getting_started.rst
+doc/source/modules/gui/hdf5/h5node.rst
+doc/source/modules/gui/hdf5/hdf5contextmenuevent.rst
+doc/source/modules/gui/hdf5/hdf5treemodel.rst
+doc/source/modules/gui/hdf5/hdf5treeview.rst
+doc/source/modules/gui/hdf5/index.rst
+doc/source/modules/gui/hdf5/nexussortfilterproxymodel.rst
+doc/source/modules/gui/hdf5/img/Hdf5Example.png
+doc/source/modules/gui/hdf5/img/Hdf5TreeView.png
+doc/source/modules/gui/plot/dev.rst
+doc/source/modules/gui/plot/getting_started.rst
+doc/source/modules/gui/plot/imageview.rst
+doc/source/modules/gui/plot/index.rst
+doc/source/modules/gui/plot/items.rst
+doc/source/modules/gui/plot/plot.rst
+doc/source/modules/gui/plot/plotactions.rst
+doc/source/modules/gui/plot/plotactions_examples.rst
+doc/source/modules/gui/plot/plottools.rst
+doc/source/modules/gui/plot/plotwidget.rst
+doc/source/modules/gui/plot/plotwindow.rst
+doc/source/modules/gui/plot/profile.rst
+doc/source/modules/gui/plot/roi.rst
+doc/source/modules/gui/plot/stackview.rst
+doc/source/modules/gui/plot/img/ImageView.png
+doc/source/modules/gui/plot/img/LimitsToolBar.png
+doc/source/modules/gui/plot/img/Plot1D.png
+doc/source/modules/gui/plot/img/Plot2D.png
+doc/source/modules/gui/plot/img/PlotWidget.png
+doc/source/modules/gui/plot/img/PlotWindow.png
+doc/source/modules/gui/plot/img/PositionInfo.png
+doc/source/modules/gui/plot/img/StackView.png
+doc/source/modules/gui/plot/img/StackViewMainWindow.png
+doc/source/modules/gui/plot/img/colorScale.png
+doc/source/modules/gui/plot/img/colorScaleBar.png
+doc/source/modules/gui/plot/img/fftAction0.png
+doc/source/modules/gui/plot/img/fftAction1.png
+doc/source/modules/gui/plot/img/linearColorbar.png
+doc/source/modules/gui/plot/img/logColorbar.png
+doc/source/modules/gui/plot/img/netCounts.png
+doc/source/modules/gui/plot/img/plot_and_backend.png
+doc/source/modules/gui/plot/img/rawCounts.png
+doc/source/modules/gui/plot/img/roiwidget.png
+doc/source/modules/gui/plot/img/shiftAction0.png
+doc/source/modules/gui/plot/img/shiftAction3.png
+doc/source/modules/gui/plot/img/tickbar.png
+doc/source/modules/gui/plot3d/actions.rst
+doc/source/modules/gui/plot3d/dev.rst
+doc/source/modules/gui/plot3d/glutils.rst
+doc/source/modules/gui/plot3d/index.rst
+doc/source/modules/gui/plot3d/plot3dwidget.rst
+doc/source/modules/gui/plot3d/plot3dwindow.rst
+doc/source/modules/gui/plot3d/scalarfieldview.rst
+doc/source/modules/gui/plot3d/scene.rst
+doc/source/modules/gui/plot3d/sfviewparamtree.rst
+doc/source/modules/gui/plot3d/toolbars.rst
+doc/source/modules/gui/plot3d/utils.rst
+doc/source/modules/gui/plot3d/viewer3dvolume_example.rst
+doc/source/modules/gui/plot3d/img/Plot3DWidget.png
+doc/source/modules/gui/plot3d/img/Plot3DWindow.png
+doc/source/modules/gui/plot3d/img/SFViewParamTree.png
+doc/source/modules/gui/plot3d/img/ScalarFieldView.png
+doc/source/modules/gui/widgets/framebrowser.rst
+doc/source/modules/gui/widgets/index.rst
+doc/source/modules/gui/widgets/periodictable.rst
+doc/source/modules/gui/widgets/tablewidget.rst
+doc/source/modules/gui/widgets/threadpoolpushbutton.rst
+doc/source/modules/gui/widgets/waitingpushbutton.rst
+doc/source/modules/image/bilinear.rst
+doc/source/modules/image/index.rst
+doc/source/modules/image/medianfilter.rst
+doc/source/modules/image/shapes.rst
+doc/source/modules/image/sift.rst
+doc/source/modules/io/configdict.rst
+doc/source/modules/io/dictdump.rst
+doc/source/modules/io/index.rst
+doc/source/modules/io/nxdata.rst
+doc/source/modules/io/octaveh5.rst
+doc/source/modules/io/specfile.rst
+doc/source/modules/io/specfilewrapper.rst
+doc/source/modules/io/spech5.rst
+doc/source/modules/io/spectoh5.rst
+doc/source/modules/io/utils.rst
+doc/source/modules/math/combo.rst
+doc/source/modules/math/histogram.rst
+doc/source/modules/math/index.rst
+doc/source/modules/math/medianfilter.rst
+doc/source/modules/math/fit/bgtheories.rst
+doc/source/modules/math/fit/filters.rst
+doc/source/modules/math/fit/fitmanager.rst
+doc/source/modules/math/fit/fittheories.rst
+doc/source/modules/math/fit/fittheory.rst
+doc/source/modules/math/fit/functions.rst
+doc/source/modules/math/fit/index.rst
+doc/source/modules/math/fit/leastsq.rst
+doc/source/modules/math/fit/peaksearch.rst
+doc/source/modules/test/index.rst
+doc/source/modules/utils/array_like.rst
+doc/source/modules/utils/decorators.rst
+doc/source/modules/utils/html.rst
+doc/source/modules/utils/index.rst
+doc/source/modules/utils/weakref.rst
+examples/animatedicons.py
+examples/colorbar.py
+examples/fft.png
+examples/fftPlotAction.py
+examples/hdf5widget.py
+examples/icons.py
+examples/imageview.py
+examples/periodicTable.py
+examples/scatterMask.py
+examples/shiftPlotAction.py
+examples/simplewidget.py
+examples/spectoh5.py
+examples/stackView.py
+examples/viewer3DVolume.py
+qtdesigner_plugins/README.rst
+qtdesigner_plugins/plot1dplugin.py
+qtdesigner_plugins/plot2dplugin.py
+qtdesigner_plugins/plotwidgetplugin.py
+qtdesigner_plugins/plotwindowplugin.py
+silx/__init__.py
+silx/__main__.py
+silx/setup.py
+silx.egg-info/PKG-INFO
+silx.egg-info/SOURCES.txt
+silx.egg-info/dependency_links.txt
+silx.egg-info/entry_points.txt
+silx.egg-info/not-zip-safe
+silx.egg-info/requires.txt
+silx.egg-info/top_level.txt
+silx/app/__init__.py
+silx/app/setup.py
+silx/app/view.py
+silx/app/test/__init__.py
+silx/app/test/test_view.py
+silx/gui/__init__.py
+silx/gui/_utils.py
+silx/gui/console.py
+silx/gui/icons.py
+silx/gui/setup.py
+silx/gui/_glutils/Context.py
+silx/gui/_glutils/FramebufferTexture.py
+silx/gui/_glutils/Program.py
+silx/gui/_glutils/Texture.py
+silx/gui/_glutils/VertexBuffer.py
+silx/gui/_glutils/__init__.py
+silx/gui/_glutils/font.py
+silx/gui/_glutils/gl.py
+silx/gui/_glutils/utils.py
+silx/gui/data/ArrayTableModel.py
+silx/gui/data/ArrayTableWidget.py
+silx/gui/data/DataViewer.py
+silx/gui/data/DataViewerFrame.py
+silx/gui/data/DataViewerSelector.py
+silx/gui/data/DataViews.py
+silx/gui/data/Hdf5TableView.py
+silx/gui/data/NXdataWidgets.py
+silx/gui/data/NumpyAxesSelector.py
+silx/gui/data/RecordTableView.py
+silx/gui/data/TextFormatter.py
+silx/gui/data/__init__.py
+silx/gui/data/setup.py
+silx/gui/data/test/__init__.py
+silx/gui/data/test/test_arraywidget.py
+silx/gui/data/test/test_dataviewer.py
+silx/gui/data/test/test_numpyaxesselector.py
+silx/gui/data/test/test_textformatter.py
+silx/gui/fit/BackgroundWidget.py
+silx/gui/fit/FitConfig.py
+silx/gui/fit/FitWidget.py
+silx/gui/fit/FitWidgets.py
+silx/gui/fit/Parameters.py
+silx/gui/fit/__init__.py
+silx/gui/fit/setup.py
+silx/gui/fit/test/__init__.py
+silx/gui/fit/test/testBackgroundWidget.py
+silx/gui/fit/test/testFitConfig.py
+silx/gui/fit/test/testFitWidget.py
+silx/gui/hdf5/Hdf5HeaderView.py
+silx/gui/hdf5/Hdf5Item.py
+silx/gui/hdf5/Hdf5LoadingItem.py
+silx/gui/hdf5/Hdf5Node.py
+silx/gui/hdf5/Hdf5TreeModel.py
+silx/gui/hdf5/Hdf5TreeView.py
+silx/gui/hdf5/NexusSortFilterProxyModel.py
+silx/gui/hdf5/__init__.py
+silx/gui/hdf5/_utils.py
+silx/gui/hdf5/setup.py
+silx/gui/hdf5/test/__init__.py
+silx/gui/hdf5/test/_mock.py
+silx/gui/hdf5/test/test_hdf5.py
+silx/gui/plot/AlphaSlider.py
+silx/gui/plot/ColorBar.py
+silx/gui/plot/ColormapDialog.py
+silx/gui/plot/Colors.py
+silx/gui/plot/CurvesROIWidget.py
+silx/gui/plot/ImageView.py
+silx/gui/plot/Interaction.py
+silx/gui/plot/LegendSelector.py
+silx/gui/plot/MPLColormap.py
+silx/gui/plot/MaskToolsWidget.py
+silx/gui/plot/Plot.py
+silx/gui/plot/PlotActions.py
+silx/gui/plot/PlotEvents.py
+silx/gui/plot/PlotInteraction.py
+silx/gui/plot/PlotToolButtons.py
+silx/gui/plot/PlotTools.py
+silx/gui/plot/PlotWidget.py
+silx/gui/plot/PlotWindow.py
+silx/gui/plot/Profile.py
+silx/gui/plot/ProfileMainWindow.py
+silx/gui/plot/ScatterMaskToolsWidget.py
+silx/gui/plot/StackView.py
+silx/gui/plot/_BaseMaskToolsWidget.py
+silx/gui/plot/__init__.py
+silx/gui/plot/setup.py
+silx/gui/plot/_utils/__init__.py
+silx/gui/plot/_utils/panzoom.py
+silx/gui/plot/_utils/setup.py
+silx/gui/plot/_utils/ticklayout.py
+silx/gui/plot/_utils/test/__init__.py
+silx/gui/plot/_utils/test/test_ticklayout.py
+silx/gui/plot/backends/BackendBase.py
+silx/gui/plot/backends/BackendMatplotlib.py
+silx/gui/plot/backends/BackendOpenGL.py
+silx/gui/plot/backends/ModestImage.py
+silx/gui/plot/backends/__init__.py
+silx/gui/plot/backends/_matplotlib.py
+silx/gui/plot/backends/glutils/GLPlotCurve.py
+silx/gui/plot/backends/glutils/GLPlotFrame.py
+silx/gui/plot/backends/glutils/GLPlotImage.py
+silx/gui/plot/backends/glutils/GLSupport.py
+silx/gui/plot/backends/glutils/GLText.py
+silx/gui/plot/backends/glutils/GLTexture.py
+silx/gui/plot/backends/glutils/PlotImageFile.py
+silx/gui/plot/backends/glutils/__init__.py
+silx/gui/plot/items/__init__.py
+silx/gui/plot/items/core.py
+silx/gui/plot/items/curve.py
+silx/gui/plot/items/histogram.py
+silx/gui/plot/items/image.py
+silx/gui/plot/items/marker.py
+silx/gui/plot/items/scatter.py
+silx/gui/plot/items/shape.py
+silx/gui/plot/test/__init__.py
+silx/gui/plot/test/testAlphaSlider.py
+silx/gui/plot/test/testColorBar.py
+silx/gui/plot/test/testColormapDialog.py
+silx/gui/plot/test/testColors.py
+silx/gui/plot/test/testCurvesROIWidget.py
+silx/gui/plot/test/testInteraction.py
+silx/gui/plot/test/testLegendSelector.py
+silx/gui/plot/test/testMaskToolsWidget.py
+silx/gui/plot/test/testPlot.py
+silx/gui/plot/test/testPlotInteraction.py
+silx/gui/plot/test/testPlotTools.py
+silx/gui/plot/test/testPlotWidget.py
+silx/gui/plot/test/testPlotWindow.py
+silx/gui/plot/test/testProfile.py
+silx/gui/plot/test/testScatterMaskToolsWidget.py
+silx/gui/plot/test/testStackView.py
+silx/gui/plot3d/Plot3DActions.py
+silx/gui/plot3d/Plot3DToolBar.py
+silx/gui/plot3d/Plot3DWidget.py
+silx/gui/plot3d/Plot3DWindow.py
+silx/gui/plot3d/SFViewParamTree.py
+silx/gui/plot3d/ScalarFieldView.py
+silx/gui/plot3d/ViewpointToolBar.py
+silx/gui/plot3d/__init__.py
+silx/gui/plot3d/setup.py
+silx/gui/plot3d/scene/__init__.py
+silx/gui/plot3d/scene/axes.py
+silx/gui/plot3d/scene/camera.py
+silx/gui/plot3d/scene/core.py
+silx/gui/plot3d/scene/cutplane.py
+silx/gui/plot3d/scene/event.py
+silx/gui/plot3d/scene/function.py
+silx/gui/plot3d/scene/interaction.py
+silx/gui/plot3d/scene/primitives.py
+silx/gui/plot3d/scene/setup.py
+silx/gui/plot3d/scene/text.py
+silx/gui/plot3d/scene/transform.py
+silx/gui/plot3d/scene/utils.py
+silx/gui/plot3d/scene/viewport.py
+silx/gui/plot3d/scene/window.py
+silx/gui/plot3d/scene/test/__init__.py
+silx/gui/plot3d/scene/test/test_transform.py
+silx/gui/plot3d/scene/test/test_utils.py
+silx/gui/plot3d/test/__init__.py
+silx/gui/plot3d/utils/__init__.py
+silx/gui/plot3d/utils/mng.py
+silx/gui/qt/__init__.py
+silx/gui/qt/_macosx.py
+silx/gui/qt/_pyside_dynamic.py
+silx/gui/qt/_pyside_missing.py
+silx/gui/qt/_qt.py
+silx/gui/qt/_utils.py
+silx/gui/test/__init__.py
+silx/gui/test/test_console.py
+silx/gui/test/test_icons.py
+silx/gui/test/test_qt.py
+silx/gui/test/test_utils.py
+silx/gui/test/utils.py
+silx/gui/widgets/FrameBrowser.py
+silx/gui/widgets/HierarchicalTableView.py
+silx/gui/widgets/MedianFilterDialog.py
+silx/gui/widgets/PeriodicTable.py
+silx/gui/widgets/TableWidget.py
+silx/gui/widgets/ThreadPoolPushButton.py
+silx/gui/widgets/WaitingPushButton.py
+silx/gui/widgets/__init__.py
+silx/gui/widgets/setup.py
+silx/gui/widgets/test/__init__.py
+silx/gui/widgets/test/test_hierarchicaltableview.py
+silx/gui/widgets/test/test_periodictable.py
+silx/gui/widgets/test/test_tablewidget.py
+silx/gui/widgets/test/test_threadpoolpushbutton.py
+silx/image/__init__.py
+silx/image/bilinear.c
+silx/image/bilinear.pyx
+silx/image/medianfilter.py
+silx/image/setup.py
+silx/image/shapes.c
+silx/image/shapes.pyx
+silx/image/sift.py
+silx/image/test/__init__.py
+silx/image/test/test_bilinear.py
+silx/image/test/test_medianfilter.py
+silx/image/test/test_shapes.py
+silx/io/__init__.py
+silx/io/configdict.py
+silx/io/dictdump.py
+silx/io/fabioh5.py
+silx/io/nxdata.py
+silx/io/octaveh5.py
+silx/io/setup.py
+silx/io/specfilewrapper.py
+silx/io/spech5.py
+silx/io/spectoh5.py
+silx/io/utils.py
+silx/io/specfile/specfile.c
+silx/io/specfile/specfile.pyx
+silx/io/specfile/specfile_wrapper.pxd
+silx/io/specfile/include/Lists.h
+silx/io/specfile/include/SpecFile.h
+silx/io/specfile/include/SpecFileCython.h
+silx/io/specfile/include/SpecFileP.h
+silx/io/specfile/include/locale_management.h
+silx/io/specfile/src/locale_management.c
+silx/io/specfile/src/sfdata.c
+silx/io/specfile/src/sfheader.c
+silx/io/specfile/src/sfindex.c
+silx/io/specfile/src/sfinit.c
+silx/io/specfile/src/sflabel.c
+silx/io/specfile/src/sflists.c
+silx/io/specfile/src/sfmca.c
+silx/io/specfile/src/sftools.c
+silx/io/specfile/src/sfwrite.c
+silx/io/test/__init__.py
+silx/io/test/test_dictdump.py
+silx/io/test/test_fabioh5.py
+silx/io/test/test_nxdata.py
+silx/io/test/test_octaveh5.py
+silx/io/test/test_specfile.py
+silx/io/test/test_specfilewrapper.py
+silx/io/test/test_spech5.py
+silx/io/test/test_spectoh5.py
+silx/io/test/test_utils.py
+silx/math/__init__.py
+silx/math/calibration.py
+silx/math/histogram.py
+silx/math/setup.py
+silx/math/combo/combo.c
+silx/math/combo/combo.pyx
+silx/math/combo/isnan.h
+silx/math/fit/__init__.py
+silx/math/fit/bgtheories.py
+silx/math/fit/fitmanager.py
+silx/math/fit/fittheories.py
+silx/math/fit/fittheory.py
+silx/math/fit/leastsq.py
+silx/math/fit/setup.py
+silx/math/fit/filters/filters.c
+silx/math/fit/filters/filters.pyx
+silx/math/fit/filters/filters_wrapper.pxd
+silx/math/fit/filters/include/filters.h
+silx/math/fit/filters/src/smoothnd.c
+silx/math/fit/filters/src/snip1d.c
+silx/math/fit/filters/src/snip2d.c
+silx/math/fit/filters/src/snip3d.c
+silx/math/fit/filters/src/strip.c
+silx/math/fit/functions/functions.c
+silx/math/fit/functions/functions.pyx
+silx/math/fit/functions/functions_wrapper.pxd
+silx/math/fit/functions/include/functions.h
+silx/math/fit/functions/src/funs.c
+silx/math/fit/peaks/peaks.c
+silx/math/fit/peaks/peaks.pyx
+silx/math/fit/peaks/peaks_wrapper.pxd
+silx/math/fit/peaks/include/peaks.h
+silx/math/fit/peaks/src/peaks.c
+silx/math/fit/test/__init__.py
+silx/math/fit/test/test_bgtheories.py
+silx/math/fit/test/test_filters.py
+silx/math/fit/test/test_fit.py
+silx/math/fit/test/test_fitmanager.py
+silx/math/fit/test/test_functions.py
+silx/math/fit/test/test_peaks.py
+silx/math/histogramnd/chistogramnd.c
+silx/math/histogramnd/chistogramnd.pyx
+silx/math/histogramnd/chistogramnd_lut.c
+silx/math/histogramnd/chistogramnd_lut.pyx
+silx/math/histogramnd/histogramnd_c.pxd
+silx/math/histogramnd/include/histogramnd_c.h
+silx/math/histogramnd/include/templates.h
+silx/math/histogramnd/include/msvc/stdint.h
+silx/math/histogramnd/src/histogramnd_c.c
+silx/math/histogramnd/src/histogramnd_template.c
+silx/math/marchingcubes/marchingcubes.cpp
+silx/math/marchingcubes/marchingcubes.pyx
+silx/math/marchingcubes/mc.hpp
+silx/math/marchingcubes/mc.pxd
+silx/math/marchingcubes/mc_lut.cpp
+silx/math/medianfilter/__init__.py
+silx/math/medianfilter/median_filter.pxd
+silx/math/medianfilter/medianfilter.cpp
+silx/math/medianfilter/medianfilter.pyx
+silx/math/medianfilter/setup.py
+silx/math/medianfilter/include/median_filter.hpp
+silx/math/medianfilter/test/__init__.py
+silx/math/medianfilter/test/benchmark.py
+silx/math/medianfilter/test/test_medianfilter.py
+silx/math/test/__init__.py
+silx/math/test/benchmark_combo.py
+silx/math/test/histo_benchmarks.py
+silx/math/test/test_HistogramndLut_nominal.py
+silx/math/test/test_combo.py
+silx/math/test/test_histogramnd_error.py
+silx/math/test/test_histogramnd_nominal.py
+silx/math/test/test_histogramnd_vs_np.py
+silx/math/test/test_marchingcubes.py
+silx/opencl/__init__.py
+silx/opencl/common.py
+silx/opencl/medfilt.py
+silx/opencl/processing.py
+silx/opencl/setup.py
+silx/opencl/utils.py
+silx/opencl/sift/__init__.py
+silx/opencl/sift/alignment.py
+silx/opencl/sift/match.py
+silx/opencl/sift/param.py
+silx/opencl/sift/plan.py
+silx/opencl/sift/setup.py
+silx/opencl/sift/sift.py
+silx/opencl/sift/utils.py
+silx/opencl/sift/test/__init__.py
+silx/opencl/sift/test/test_algebra.py
+silx/opencl/sift/test/test_align.py
+silx/opencl/sift/test/test_convol.py
+silx/opencl/sift/test/test_gaussian.py
+silx/opencl/sift/test/test_image.py
+silx/opencl/sift/test/test_image_functions.py
+silx/opencl/sift/test/test_image_setup.py
+silx/opencl/sift/test/test_keypoints.py
+silx/opencl/sift/test/test_matching.py
+silx/opencl/sift/test/test_preproc.py
+silx/opencl/sift/test/test_reductions.py
+silx/opencl/sift/test/test_transform.py
+silx/opencl/sift/test/utilstest.py
+silx/opencl/test/__init__.py
+silx/opencl/test/test_addition.py
+silx/opencl/test/test_medfilt.py
+silx/resources/__init__.py
+silx/resources/gui/icons/3d-plane-normal-x.png
+silx/resources/gui/icons/3d-plane-normal-x.svg
+silx/resources/gui/icons/3d-plane-normal-y.png
+silx/resources/gui/icons/3d-plane-normal-y.svg
+silx/resources/gui/icons/3d-plane-normal-z.png
+silx/resources/gui/icons/3d-plane-normal-z.svg
+silx/resources/gui/icons/3d-plane.png
+silx/resources/gui/icons/3d-plane.svg
+silx/resources/gui/icons/arrow-keys.png
+silx/resources/gui/icons/arrow-keys.svg
+silx/resources/gui/icons/camera.png
+silx/resources/gui/icons/camera.svg
+silx/resources/gui/icons/clipboard.png
+silx/resources/gui/icons/clipboard.svg
+silx/resources/gui/icons/close.png
+silx/resources/gui/icons/close.svg
+silx/resources/gui/icons/colormap.png
+silx/resources/gui/icons/colormap.svg
+silx/resources/gui/icons/crop.png
+silx/resources/gui/icons/crop.svg
+silx/resources/gui/icons/crosshair.png
+silx/resources/gui/icons/crosshair.svg
+silx/resources/gui/icons/cube-back.png
+silx/resources/gui/icons/cube-back.svg
+silx/resources/gui/icons/cube-bottom.png
+silx/resources/gui/icons/cube-bottom.svg
+silx/resources/gui/icons/cube-front.png
+silx/resources/gui/icons/cube-front.svg
+silx/resources/gui/icons/cube-left.png
+silx/resources/gui/icons/cube-left.svg
+silx/resources/gui/icons/cube-right.png
+silx/resources/gui/icons/cube-right.svg
+silx/resources/gui/icons/cube-top.png
+silx/resources/gui/icons/cube-top.svg
+silx/resources/gui/icons/cube.png
+silx/resources/gui/icons/cube.svg
+silx/resources/gui/icons/document-open.png
+silx/resources/gui/icons/document-open.svg
+silx/resources/gui/icons/document-print.png
+silx/resources/gui/icons/document-print.svg
+silx/resources/gui/icons/document-save.png
+silx/resources/gui/icons/document-save.svg
+silx/resources/gui/icons/draw-brush.png
+silx/resources/gui/icons/draw-brush.svg
+silx/resources/gui/icons/draw-pencil.png
+silx/resources/gui/icons/draw-pencil.svg
+silx/resources/gui/icons/draw-rubber.png
+silx/resources/gui/icons/draw-rubber.svg
+silx/resources/gui/icons/edit-copy.png
+silx/resources/gui/icons/edit-copy.svg
+silx/resources/gui/icons/first.png
+silx/resources/gui/icons/first.svg
+silx/resources/gui/icons/folder.png
+silx/resources/gui/icons/folder.svg
+silx/resources/gui/icons/image-mask.png
+silx/resources/gui/icons/image-mask.svg
+silx/resources/gui/icons/image-select-add.png
+silx/resources/gui/icons/image-select-add.svg
+silx/resources/gui/icons/image-select-box.png
+silx/resources/gui/icons/image-select-box.svg
+silx/resources/gui/icons/image-select-brush.png
+silx/resources/gui/icons/image-select-brush.svg
+silx/resources/gui/icons/image-select-erase-rubber.png
+silx/resources/gui/icons/image-select-erase-rubber.svg
+silx/resources/gui/icons/image-select-erase.png
+silx/resources/gui/icons/image-select-erase.svg
+silx/resources/gui/icons/image.png
+silx/resources/gui/icons/image.svg
+silx/resources/gui/icons/item-0dim.png
+silx/resources/gui/icons/item-0dim.svg
+silx/resources/gui/icons/item-1dim.png
+silx/resources/gui/icons/item-1dim.svg
+silx/resources/gui/icons/item-2dim.png
+silx/resources/gui/icons/item-2dim.svg
+silx/resources/gui/icons/item-3dim.png
+silx/resources/gui/icons/item-3dim.svg
+silx/resources/gui/icons/item-ndim.png
+silx/resources/gui/icons/item-ndim.svg
+silx/resources/gui/icons/item-object.png
+silx/resources/gui/icons/item-object.svg
+silx/resources/gui/icons/last.png
+silx/resources/gui/icons/last.svg
+silx/resources/gui/icons/math-average.png
+silx/resources/gui/icons/math-average.svg
+silx/resources/gui/icons/math-derive.png
+silx/resources/gui/icons/math-derive.svg
+silx/resources/gui/icons/math-energy.png
+silx/resources/gui/icons/math-energy.svg
+silx/resources/gui/icons/math-fit.png
+silx/resources/gui/icons/math-fit.svg
+silx/resources/gui/icons/math-normalize.png
+silx/resources/gui/icons/math-normalize.svg
+silx/resources/gui/icons/math-peak-reset.png
+silx/resources/gui/icons/math-peak-reset.svg
+silx/resources/gui/icons/math-peak-search.png
+silx/resources/gui/icons/math-peak-search.svg
+silx/resources/gui/icons/math-peak.png
+silx/resources/gui/icons/math-peak.svg
+silx/resources/gui/icons/math-sigma.png
+silx/resources/gui/icons/math-sigma.svg
+silx/resources/gui/icons/math-smooth.png
+silx/resources/gui/icons/math-smooth.svg
+silx/resources/gui/icons/math-substract.png
+silx/resources/gui/icons/math-substract.svg
+silx/resources/gui/icons/math-swap-sign.png
+silx/resources/gui/icons/math-swap-sign.svg
+silx/resources/gui/icons/math-ymin-to-zero.png
+silx/resources/gui/icons/math-ymin-to-zero.svg
+silx/resources/gui/icons/median-filter.png
+silx/resources/gui/icons/median-filter.svg
+silx/resources/gui/icons/next.png
+silx/resources/gui/icons/next.svg
+silx/resources/gui/icons/normal.png
+silx/resources/gui/icons/normal.svg
+silx/resources/gui/icons/pixel-intensities.png
+silx/resources/gui/icons/pixel-intensities.svg
+silx/resources/gui/icons/plot-grid.png
+silx/resources/gui/icons/plot-grid.svg
+silx/resources/gui/icons/plot-roi-above.png
+silx/resources/gui/icons/plot-roi-above.svg
+silx/resources/gui/icons/plot-roi-below.png
+silx/resources/gui/icons/plot-roi-below.svg
+silx/resources/gui/icons/plot-roi-between.png
+silx/resources/gui/icons/plot-roi-between.svg
+silx/resources/gui/icons/plot-roi-reset.png
+silx/resources/gui/icons/plot-roi-reset.svg
+silx/resources/gui/icons/plot-roi.png
+silx/resources/gui/icons/plot-roi.svg
+silx/resources/gui/icons/plot-toggle-points.png
+silx/resources/gui/icons/plot-toggle-points.svg
+silx/resources/gui/icons/plot-widget.png
+silx/resources/gui/icons/plot-widget.svg
+silx/resources/gui/icons/plot-window-image.png
+silx/resources/gui/icons/plot-window-image.svg
+silx/resources/gui/icons/plot-window.png
+silx/resources/gui/icons/plot-window.svg
+silx/resources/gui/icons/plot-xauto.png
+silx/resources/gui/icons/plot-xauto.svg
+silx/resources/gui/icons/plot-xlog.png
+silx/resources/gui/icons/plot-xlog.svg
+silx/resources/gui/icons/plot-yauto.png
+silx/resources/gui/icons/plot-yauto.svg
+silx/resources/gui/icons/plot-ydown.png
+silx/resources/gui/icons/plot-ydown.svg
+silx/resources/gui/icons/plot-ylog.png
+silx/resources/gui/icons/plot-ylog.svg
+silx/resources/gui/icons/plot-yup.png
+silx/resources/gui/icons/plot-yup.svg
+silx/resources/gui/icons/previous.png
+silx/resources/gui/icons/previous.svg
+silx/resources/gui/icons/process-working.mng
+silx/resources/gui/icons/profile-clear.png
+silx/resources/gui/icons/profile-clear.svg
+silx/resources/gui/icons/profile1D.png
+silx/resources/gui/icons/profile1D.svg
+silx/resources/gui/icons/profile2D.png
+silx/resources/gui/icons/profile2D.svg
+silx/resources/gui/icons/remove.png
+silx/resources/gui/icons/remove.svg
+silx/resources/gui/icons/rudder.png
+silx/resources/gui/icons/rudder.svg
+silx/resources/gui/icons/selected.png
+silx/resources/gui/icons/selected.svg
+silx/resources/gui/icons/shape-circle-solid.png
+silx/resources/gui/icons/shape-circle-solid.svg
+silx/resources/gui/icons/shape-circle.png
+silx/resources/gui/icons/shape-circle.svg
+silx/resources/gui/icons/shape-diagonal.png
+silx/resources/gui/icons/shape-diagonal.svg
+silx/resources/gui/icons/shape-ellipse-solid.png
+silx/resources/gui/icons/shape-ellipse-solid.svg
+silx/resources/gui/icons/shape-ellipse.png
+silx/resources/gui/icons/shape-ellipse.svg
+silx/resources/gui/icons/shape-horizontal.png
+silx/resources/gui/icons/shape-horizontal.svg
+silx/resources/gui/icons/shape-polygon.png
+silx/resources/gui/icons/shape-polygon.svg
+silx/resources/gui/icons/shape-rectangle.png
+silx/resources/gui/icons/shape-rectangle.svg
+silx/resources/gui/icons/shape-square.png
+silx/resources/gui/icons/shape-square.svg
+silx/resources/gui/icons/shape-vertical.png
+silx/resources/gui/icons/shape-vertical.svg
+silx/resources/gui/icons/silx.png
+silx/resources/gui/icons/silx.svg
+silx/resources/gui/icons/sliders-off.png
+silx/resources/gui/icons/sliders-off.svg
+silx/resources/gui/icons/sliders-on.png
+silx/resources/gui/icons/sliders-on.svg
+silx/resources/gui/icons/spec.png
+silx/resources/gui/icons/spec.svg
+silx/resources/gui/icons/test-png.png
+silx/resources/gui/icons/test-svg.svg
+silx/resources/gui/icons/view-1d.png
+silx/resources/gui/icons/view-1d.svg
+silx/resources/gui/icons/view-2d-stack.png
+silx/resources/gui/icons/view-2d-stack.svg
+silx/resources/gui/icons/view-2d.png
+silx/resources/gui/icons/view-2d.svg
+silx/resources/gui/icons/view-3d.png
+silx/resources/gui/icons/view-3d.svg
+silx/resources/gui/icons/view-fullscreen.png
+silx/resources/gui/icons/view-fullscreen.svg
+silx/resources/gui/icons/view-hdf5.png
+silx/resources/gui/icons/view-hdf5.svg
+silx/resources/gui/icons/view-nexus.png
+silx/resources/gui/icons/view-nexus.svg
+silx/resources/gui/icons/view-nofullscreen.png
+silx/resources/gui/icons/view-nofullscreen.svg
+silx/resources/gui/icons/view-raw.png
+silx/resources/gui/icons/view-raw.svg
+silx/resources/gui/icons/view-refresh.png
+silx/resources/gui/icons/view-refresh.svg
+silx/resources/gui/icons/view-text.png
+silx/resources/gui/icons/view-text.svg
+silx/resources/gui/icons/window-new.png
+silx/resources/gui/icons/window-new.svg
+silx/resources/gui/icons/zoom-in.png
+silx/resources/gui/icons/zoom-in.svg
+silx/resources/gui/icons/zoom-original.png
+silx/resources/gui/icons/zoom-original.svg
+silx/resources/gui/icons/zoom-out.png
+silx/resources/gui/icons/zoom-out.svg
+silx/resources/gui/icons/zoom.png
+silx/resources/gui/icons/zoom.svg
+silx/resources/gui/icons/animated/process-working-00.png
+silx/resources/gui/icons/animated/process-working-01.png
+silx/resources/gui/icons/animated/process-working-02.png
+silx/resources/gui/icons/animated/process-working-03.png
+silx/resources/gui/icons/animated/process-working-04.png
+silx/resources/gui/icons/animated/process-working-05.png
+silx/resources/gui/icons/animated/process-working-06.png
+silx/resources/gui/icons/animated/process-working-07.png
+silx/resources/gui/icons/animated/process-working-08.png
+silx/resources/gui/icons/animated/process-working-09.png
+silx/resources/gui/icons/animated/process-working-10.png
+silx/resources/gui/icons/animated/process-working-11.png
+silx/resources/gui/icons/animated/process-working-12.png
+silx/resources/gui/icons/animated/process-working-13.png
+silx/resources/gui/icons/animated/process-working-14.png
+silx/resources/gui/icons/animated/process-working-15.png
+silx/resources/gui/icons/animated/process-working-16.png
+silx/resources/gui/icons/animated/process-working-17.png
+silx/resources/gui/icons/animated/process-working-18.png
+silx/resources/gui/icons/animated/process-working-19.png
+silx/resources/gui/icons/animated/process-working-20.png
+silx/resources/gui/icons/animated/process-working-21.png
+silx/resources/gui/icons/animated/process-working-22.png
+silx/resources/gui/icons/animated/process-working-23.png
+silx/resources/gui/icons/animated/process-working-24.png
+silx/resources/gui/icons/animated/process-working-25.png
+silx/resources/gui/icons/animated/process-working-26.png
+silx/resources/gui/icons/animated/process-working-27.png
+silx/resources/gui/icons/animated/process-working-28.png
+silx/resources/gui/icons/animated/process-working-29.png
+silx/resources/gui/icons/animated/process-working-30.png
+silx/resources/opencl/addition.cl
+silx/resources/opencl/bitonic.cl
+silx/resources/opencl/medfilt.cl
+silx/resources/opencl/preprocess.cl
+silx/resources/opencl/sift/addition.cl
+silx/resources/opencl/sift/algebra.cl
+silx/resources/opencl/sift/convolution.cl
+silx/resources/opencl/sift/gaussian.cl
+silx/resources/opencl/sift/image.cl
+silx/resources/opencl/sift/interpolation.cl
+silx/resources/opencl/sift/keypoints_cpu.cl
+silx/resources/opencl/sift/keypoints_gpu1.cl
+silx/resources/opencl/sift/keypoints_gpu2.cl
+silx/resources/opencl/sift/matching_cpu.cl
+silx/resources/opencl/sift/matching_gpu.cl
+silx/resources/opencl/sift/memset.cl
+silx/resources/opencl/sift/orientation_cpu.cl
+silx/resources/opencl/sift/orientation_gpu.cl
+silx/resources/opencl/sift/preprocess.cl
+silx/resources/opencl/sift/reductions.cl
+silx/resources/opencl/sift/transform.cl
+silx/sx/__init__.py
+silx/sx/_plot.py
+silx/test/__init__.py
+silx/test/test_resources.py
+silx/test/test_sx.py
+silx/test/test_version.py
+silx/test/utils.py
+silx/third_party/EdfFile.py
+silx/third_party/TiffIO.py
+silx/third_party/__init__.py
+silx/third_party/setup.py
+silx/third_party/six.py
+silx/third_party/_local/__init__.py
+silx/third_party/_local/six.py
+silx/utils/__init__.py
+silx/utils/array_like.py
+silx/utils/decorators.py
+silx/utils/html.py
+silx/utils/launcher.py
+silx/utils/setup.py
+silx/utils/weakref.py
+silx/utils/test/__init__.py
+silx/utils/test/test_array_like.py
+silx/utils/test/test_html.py
+silx/utils/test/test_launcher.py
+silx/utils/test/test_launcher_command.py
+silx/utils/test/test_weakref.py \ No newline at end of file
diff --git a/silx.egg-info/dependency_links.txt b/silx.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/silx.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/silx.egg-info/entry_points.txt b/silx.egg-info/entry_points.txt
new file mode 100644
index 0000000..898d662
--- /dev/null
+++ b/silx.egg-info/entry_points.txt
@@ -0,0 +1,3 @@
+[console_scripts]
+silx = silx.__main__:main
+
diff --git a/silx.egg-info/not-zip-safe b/silx.egg-info/not-zip-safe
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/silx.egg-info/not-zip-safe
@@ -0,0 +1 @@
+
diff --git a/silx.egg-info/requires.txt b/silx.egg-info/requires.txt
new file mode 100644
index 0000000..e18e48e
--- /dev/null
+++ b/silx.egg-info/requires.txt
@@ -0,0 +1,2 @@
+numpy
+setuptools
diff --git a/silx.egg-info/top_level.txt b/silx.egg-info/top_level.txt
new file mode 100644
index 0000000..dbcf435
--- /dev/null
+++ b/silx.egg-info/top_level.txt
@@ -0,0 +1 @@
+silx
diff --git a/silx/__init__.py b/silx/__init__.py
new file mode 100644
index 0000000..cfb306b
--- /dev/null
+++ b/silx/__init__.py
@@ -0,0 +1,43 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+
+from __future__ import absolute_import, print_function, division
+
+__authors__ = ["Jérôme Kieffer"]
+__license__ = "MIT"
+__date__ = "23/05/2016"
+
+import os as _os
+import logging as _logging
+
+_logging.basicConfig() # Make sure logging is initialised
+
+project = _os.path.basename(_os.path.dirname(_os.path.abspath(__file__)))
+
+try:
+ from ._version import __date__ as date # noqa
+ from ._version import version, version_info, hexversion, strictversion # noqa
+except ImportError:
+ raise RuntimeError("Do NOT use %s from its sources: build it and use the built version" % project)
diff --git a/silx/__main__.py b/silx/__main__.py
new file mode 100644
index 0000000..4c05ef3
--- /dev/null
+++ b/silx/__main__.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+# ###########################################################################*/
+"""This module describe silx applications which are available through
+the silx launcher.
+
+Your environment should provide a command `silx`. You can reach help with
+`silx --help`, and check the version with `silx --version`.
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "18/04/2017"
+
+
+import logging
+logging.basicConfig()
+
+import sys
+from silx.utils.launcher import Launcher
+import silx._version
+
+
+def main():
+ """Main function of the launcher
+
+ This function is referenced in the setup.py file.
+ Thisfor it is executed by a launcher script generated by setuptools.
+
+ :rtype: int
+ :returns: The execution status
+ """
+ launcher = Launcher(prog="silx", version=silx._version.version)
+ launcher.add_command("view",
+ module_name="silx.app.view",
+ description="Browse a data file with a GUI")
+ status = launcher.execute(sys.argv)
+ return status
+
+
+if __name__ == "__main__":
+ # executed when using python -m PROJECT_NAME
+ status = main()
+ sys.exit(status)
diff --git a/silx/app/__init__.py b/silx/app/__init__.py
new file mode 100644
index 0000000..9cbb8bb
--- /dev/null
+++ b/silx/app/__init__.py
@@ -0,0 +1,29 @@
+# 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.
+#
+# ###########################################################################*/
+"""Application provided by the launcher"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "30/03/2017"
diff --git a/silx/app/setup.py b/silx/app/setup.py
new file mode 100644
index 0000000..bf6f3af
--- /dev/null
+++ b/silx/app/setup.py
@@ -0,0 +1,40 @@
+# 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.
+#
+# ############################################################################*/
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "30/03/2017"
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('app', parent_package, top_path)
+ config.add_subpackage('test')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
diff --git a/silx/app/test/__init__.py b/silx/app/test/__init__.py
new file mode 100644
index 0000000..54241dc
--- /dev/null
+++ b/silx/app/test/__init__.py
@@ -0,0 +1,41 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "30/03/2017"
+
+
+import logging
+import os
+import sys
+import unittest
+
+
+_logger = logging.getLogger(__name__)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ return test_suite
diff --git a/silx/app/test/test_view.py b/silx/app/test/test_view.py
new file mode 100644
index 0000000..774bc01
--- /dev/null
+++ b/silx/app/test/test_view.py
@@ -0,0 +1,135 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Module testing silx.app.view"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "12/04/2017"
+
+
+import unittest
+from silx.gui.test.utils import TestCaseQt
+from .. import view
+import sys
+
+
+class QApplicationMock(object):
+
+ def __init__(self, args):
+ pass
+
+ def exec_(self):
+ return 0
+
+ def deleteLater(self):
+ pass
+
+
+class ViewerMock(object):
+
+ def __init__(self):
+ super(ViewerMock, self).__init__()
+ self.__class__._instance = self
+ self.appendFileCalls = []
+
+ def appendFile(self, filename):
+ self.appendFileCalls.append(filename)
+
+ def resize(self, size):
+ pass
+
+ def show(self):
+ pass
+
+
+class TestLauncher(unittest.TestCase):
+ """Test command line parsing"""
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestLauncher, cls).setUpClass()
+ cls._Viewer = view.Viewer
+ view.Viewer = ViewerMock
+ cls._QApplication = view.qt.QApplication
+ view.qt.QApplication = QApplicationMock
+
+ @classmethod
+ def tearDownClass(cls):
+ view.Viewer = cls._Viewer
+ view.qt.QApplication = cls._QApplication
+ cls._Viewer = None
+ super(TestLauncher, cls).tearDownClass()
+
+ def testHelp(self):
+ try:
+ result = view.main(["view", "--help"])
+ self.assertNotEqual(result, 0)
+ except SystemExit as e:
+ result = e.args[0]
+ self.assertEqual(result, 0)
+
+ def testWrongOption(self):
+ try:
+ result = view.main(["view", "--foo"])
+ self.assertNotEqual(result, 0)
+ except SystemExit as e:
+ result = e.args[0]
+ self.assertNotEqual(result, 0)
+
+ def testWrongFile(self):
+ try:
+ result = view.main(["view", "__file.not.found__"])
+ self.assertNotEqual(result, 0)
+ except SystemExit as e:
+ result = e.args[0]
+ self.assertNotEqual(result, 0)
+
+ def testFile(self):
+ # sys.executable is an existing readable file
+ result = view.main(["view", sys.executable])
+ self.assertEqual(result, 0)
+ viewer = ViewerMock._instance
+ self.assertEqual(viewer.appendFileCalls, [sys.executable])
+ ViewerMock._instance = None
+
+
+class TestViewer(TestCaseQt):
+ """Test for Viewer class"""
+
+ def testConstruct(self):
+ widget = view.Viewer()
+ self.qWaitForWindowExposed(widget)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ loader = unittest.defaultTestLoader.loadTestsFromTestCase
+ test_suite.addTest(loader(TestViewer))
+ test_suite.addTest(loader(TestLauncher))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/app/view.py b/silx/app/view.py
new file mode 100644
index 0000000..8fdabde
--- /dev/null
+++ b/silx/app/view.py
@@ -0,0 +1,326 @@
+# 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.
+#
+# ############################################################################*/
+"""Browse a data file with a GUI"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "12/04/2017"
+
+import sys
+import os
+import argparse
+import logging
+import collections
+
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+"""Module logger"""
+
+try:
+ # it should be loaded before h5py
+ import hdf5plugin # noqa
+except ImportError:
+ hdf5plugin = None
+
+try:
+ import h5py
+ import silx.gui.hdf5
+except ImportError:
+ h5py = None
+
+try:
+ import fabio
+except ImportError:
+ fabio = None
+
+from silx.gui import qt
+from silx.gui.data.DataViewerFrame import DataViewerFrame
+
+
+class Viewer(qt.QMainWindow):
+ """
+ This window allows to browse a data file like images or HDF5 and it's
+ content.
+ """
+
+ def __init__(self):
+ """
+ :param files_: List of HDF5 or Spec files (pathes or
+ :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
+ instances)
+ """
+ qt.QMainWindow.__init__(self)
+ self.setWindowTitle("Silx viewer")
+
+ self.__asyncload = False
+ self.__dialogState = None
+ self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
+ """Silx HDF5 TreeView"""
+
+ self.__dataViewer = DataViewerFrame(self)
+ vSpliter = qt.QSplitter(qt.Qt.Vertical)
+ vSpliter.addWidget(self.__dataViewer)
+ vSpliter.setSizes([10, 0])
+
+ spliter = qt.QSplitter(self)
+ spliter.addWidget(self.__treeview)
+ spliter.addWidget(vSpliter)
+ spliter.setStretchFactor(1, 1)
+
+ main_panel = qt.QWidget(self)
+ layout = qt.QVBoxLayout()
+ layout.addWidget(spliter)
+ layout.setStretchFactor(spliter, 1)
+ main_panel.setLayout(layout)
+
+ self.setCentralWidget(main_panel)
+
+ self.__treeview.selectionModel().selectionChanged.connect(self.displayData)
+
+ self.__treeview.addContextMenuCallback(self.customContextMenu)
+ # lambda function will never be called cause we store it as weakref
+ self.__treeview.addContextMenuCallback(lambda event: None)
+ # you have to store it first
+ self.__store_lambda = lambda event: self.closeAndSyncCustomContextMenu(event)
+ self.__treeview.addContextMenuCallback(self.__store_lambda)
+
+ self.createActions()
+ self.createMenus()
+
+ def createActions(self):
+ action = qt.QAction("E&xit", self)
+ action.setShortcuts(qt.QKeySequence.Quit)
+ action.setStatusTip("Exit the application")
+ action.triggered.connect(self.close)
+ self._exitAction = action
+
+ action = qt.QAction("&Open", self)
+ action.setStatusTip("Open a file")
+ action.triggered.connect(self.open)
+ self._openAction = action
+
+ action = qt.QAction("&About", self)
+ action.setStatusTip("Show the application's About box")
+ action.triggered.connect(self.about)
+ self._aboutAction = action
+
+ def createMenus(self):
+ fileMenu = self.menuBar().addMenu("&File")
+ fileMenu.addAction(self._openAction)
+ fileMenu.addSeparator()
+ fileMenu.addAction(self._exitAction)
+ helpMenu = self.menuBar().addMenu("&Help")
+ helpMenu.addAction(self._aboutAction)
+
+ def open(self):
+ dialog = self.createFileDialog()
+ if self.__dialogState is None:
+ currentDirectory = os.getcwd()
+ dialog.setDirectory(currentDirectory)
+ else:
+ dialog.restoreState(self.__dialogState)
+
+ result = dialog.exec_()
+ if not result:
+ return
+
+ self.__dialogState = dialog.saveState()
+
+ filenames = dialog.selectedFiles()
+ for filename in filenames:
+ self.appendFile(filename)
+
+ def createFileDialog(self):
+ dialog = qt.QFileDialog(self)
+ dialog.setWindowTitle("Open")
+ dialog.setModal(True)
+
+ extensions = collections.OrderedDict()
+ # expect h5py
+ extensions["HDF5 files"] = "*.h5"
+ # no dependancy
+ extensions["Spec files"] = "*.dat *.spec *.mca"
+ # expect fabio
+ extensions["EDF files"] = "*.edf"
+ extensions["TIFF image files"] = "*.tif *.tiff"
+ extensions["NumPy binary files"] = "*.npy"
+ extensions["CBF files"] = "*.cbf"
+ extensions["MarCCD image files"] = "*.mccd"
+
+ filters = []
+ filters.append("All supported files (%s)" % " ".join(extensions.values()))
+ for name, extension in extensions.items():
+ filters.append("%s (%s)" % (name, extension))
+ filters.append("All files (*)")
+
+ dialog.setNameFilters(filters)
+ dialog.setFileMode(qt.QFileDialog.ExistingFiles)
+ return dialog
+
+ def about(self):
+ import silx._version
+ message = """<p align="center"><b>Silx viewer</b>
+ <br />
+ <br />{silx_version}
+ <br />
+ <br /><a href="{project_url}">Upstream project on GitHub</a>
+ </p>
+ <p align="left">
+ <dl>
+ <dt><b>Silx version</b></dt><dd>{silx_version}</dd>
+ <dt><b>Qt version</b></dt><dd>{qt_version}</dd>
+ <dt><b>Qt binding</b></dt><dd>{qt_binding}</dd>
+ <dt><b>Python version</b></dt><dd>{python_version}</dd>
+ <dt><b>Optional libraries</b></dt><dd>{optional_lib}</dd>
+ </dl>
+ </p>
+ <p>
+ Copyright (C) <a href="{esrf_url}">European Synchrotron Radiation Facility</a>
+ </p>
+ """
+ def format_optional_lib(name, isAvailable):
+ if isAvailable:
+ template = '<b>%s</b> is <font color="green">installed</font>'
+ else:
+ template = '<b>%s</b> is <font color="red">not installed</font>'
+ return template % name
+
+ optional_lib = []
+ optional_lib.append(format_optional_lib("FabIO", fabio is not None))
+ optional_lib.append(format_optional_lib("H5py", h5py is not None))
+ optional_lib.append(format_optional_lib("hdf5plugin", hdf5plugin is not None))
+
+ info = dict(
+ esrf_url="http://www.esrf.eu",
+ project_url="https://github.com/silx-kit/silx",
+ silx_version=silx._version.version,
+ qt_binding=qt.BINDING,
+ qt_version=qt.qVersion(),
+ python_version=sys.version.replace("\n", "<br />"),
+ optional_lib="<br />".join(optional_lib)
+ )
+ qt.QMessageBox.about(self, "About Menu", message.format(**info))
+
+ def appendFile(self, filename):
+ self.__treeview.findHdf5TreeModel().appendFile(filename)
+
+ def displayData(self):
+ """Called to update the dataviewer with the selected data.
+ """
+ selected = list(self.__treeview.selectedH5Nodes())
+ if len(selected) == 1:
+ # Update the viewer for a single selection
+ data = selected[0]
+ self.__dataViewer.setData(data)
+
+ def useAsyncLoad(self, useAsync):
+ self.__asyncload = useAsync
+
+ def customContextMenu(self, event):
+ """Called to populate the context menu
+
+ :param silx.gui.hdf5.Hdf5ContextMenuEvent event: Event
+ containing expected information to populate the context menu
+ """
+ selectedObjects = event.source().selectedH5Nodes()
+ menu = event.menu()
+
+ hasDataset = False
+ for obj in selectedObjects:
+ if obj.ntype is h5py.Dataset:
+ hasDataset = True
+ break
+
+ if len(menu.children()):
+ menu.addSeparator()
+
+ if hasDataset:
+ action = qt.QAction("Do something on the datasets", event.source())
+ menu.addAction(action)
+
+ def closeAndSyncCustomContextMenu(self, event):
+ """Called to populate the context menu
+
+ :param silx.gui.hdf5.Hdf5ContextMenuEvent event: Event
+ containing expected information to populate the context menu
+ """
+ selectedObjects = event.source().selectedH5Nodes()
+ menu = event.menu()
+
+ if len(menu.children()):
+ menu.addSeparator()
+
+ for obj in selectedObjects:
+ if obj.ntype is h5py.File:
+ action = qt.QAction("Remove %s" % obj.local_filename, event.source())
+ action.triggered.connect(lambda: self.__treeview.findHdf5TreeModel().removeH5pyObject(obj.h5py_object))
+ menu.addAction(action)
+ action = qt.QAction("Synchronize %s" % obj.local_filename, event.source())
+ action.triggered.connect(lambda: self.__treeview.findHdf5TreeModel().synchronizeH5pyObject(obj.h5py_object))
+ menu.addAction(action)
+
+
+def main(argv):
+ """
+ Main function to launch the viewer as an application
+
+ :param argv: Command line arguments
+ :returns: exit status
+ """
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ 'files',
+ type=argparse.FileType('rb'),
+ nargs=argparse.ZERO_OR_MORE,
+ help='Data file to show (h5 file, edf files, spec files)')
+
+ options = parser.parse_args(argv[1:])
+
+ if h5py is None:
+ message = "Module 'h5py' is not installed but is mandatory."\
+ + " You can install it using \"pip install h5py\"."
+ _logger.error(message)
+ return -1
+
+ if hdf5plugin is None:
+ message = "Module 'hdf5plugin' is not installed. It supports some hdf5"\
+ + " compressions. You can install it using \"pip install hdf5plugin\"."
+ _logger.warning(message)
+
+ app = qt.QApplication([])
+ sys.excepthook = qt.exceptionHandler
+ window = Viewer()
+ window.resize(qt.QSize(640, 480))
+
+ for f in options.files:
+ filename = f.name
+ f.close()
+ window.appendFile(filename)
+
+ window.show()
+ result = app.exec_()
+ # remove ending warnings relative to QTimer
+ app.deleteLater()
+ return result
diff --git a/silx/gui/__init__.py b/silx/gui/__init__.py
new file mode 100644
index 0000000..6baf238
--- /dev/null
+++ b/silx/gui/__init__.py
@@ -0,0 +1,29 @@
+# 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.
+#
+# ###########################################################################*/
+"""Set of Qt widgets"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "23/05/2016"
diff --git a/silx/gui/_glutils/Context.py b/silx/gui/_glutils/Context.py
new file mode 100644
index 0000000..7600992
--- /dev/null
+++ b/silx/gui/_glutils/Context.py
@@ -0,0 +1,63 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""Abstraction of OpenGL context.
+
+It defines a way to get current OpenGL context to support multiple
+OpenGL contexts.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+# context #####################################################################
+
+
+def _defaultGLContextGetter():
+ return None
+
+_glContextGetter = _defaultGLContextGetter
+
+
+def getGLContext():
+ """Returns platform dependent object of current OpenGL context.
+
+ This is useful to associate OpenGL resources with the context they are
+ created in.
+
+ :return: Platform specific OpenGL context
+ :rtype: None by default or a platform dependent object"""
+ return _glContextGetter()
+
+
+def setGLContextGetter(getter=_defaultGLContextGetter):
+ """Set a platform dependent function to retrieve the current OpenGL context
+
+ :param getter: Platform dependent GL context getter
+ :type getter: Function with no args returning the current OpenGL context
+ """
+ global _glContextGetter
+ _glContextGetter = getter
diff --git a/silx/gui/_glutils/FramebufferTexture.py b/silx/gui/_glutils/FramebufferTexture.py
new file mode 100644
index 0000000..b01eb41
--- /dev/null
+++ b/silx/gui/_glutils/FramebufferTexture.py
@@ -0,0 +1,164 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""Association of a texture and a framebuffer object for off-screen rendering.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import logging
+
+from . import gl
+from .Texture import Texture
+
+
+_logger = logging.getLogger(__name__)
+
+
+class FramebufferTexture(object):
+ """Framebuffer with a texture.
+
+ Aimed at off-screen rendering to texture.
+
+ :param internalFormat: OpenGL texture internal format
+ :param shape: Shape (height, width) of the framebuffer and texture
+ :type shape: 2-tuple of int
+ :param stencilFormat: Stencil renderbuffer format
+ :param depthFormat: Depth renderbuffer format
+ :param kwargs: Extra arguments for :class:`Texture` constructor
+ """
+
+ _PACKED_FORMAT = gl.GL_DEPTH24_STENCIL8, gl.GL_DEPTH_STENCIL
+
+ def __init__(self,
+ internalFormat,
+ shape,
+ stencilFormat=gl.GL_DEPTH24_STENCIL8,
+ depthFormat=gl.GL_DEPTH24_STENCIL8,
+ **kwargs):
+
+ self._texture = Texture(internalFormat, shape=shape, **kwargs)
+
+ self._previousFramebuffer = 0 # Used by with statement
+
+ self._name = gl.glGenFramebuffers(1)
+ gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self._name)
+
+ # Attachments
+ gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER,
+ gl.GL_COLOR_ATTACHMENT0,
+ gl.GL_TEXTURE_2D,
+ self._texture.name,
+ 0)
+
+ height, width = self._texture.shape
+
+ if stencilFormat is not None:
+ self._stencilId = gl.glGenRenderbuffers(1)
+ gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self._stencilId)
+ gl.glRenderbufferStorage(gl.GL_RENDERBUFFER,
+ stencilFormat,
+ width, height)
+ gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER,
+ gl.GL_STENCIL_ATTACHMENT,
+ gl.GL_RENDERBUFFER,
+ self._stencilId)
+ else:
+ self._stencilId = None
+
+ if depthFormat is not None:
+ if self._stencilId and depthFormat in self._PACKED_FORMAT:
+ self._depthId = self._stencilId
+ else:
+ self._depthId = gl.glGenRenderbuffers(1)
+ gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self._depthId)
+ gl.glRenderbufferStorage(gl.GL_RENDERBUFFER,
+ depthFormat,
+ width, height)
+ gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER,
+ gl.GL_DEPTH_ATTACHMENT,
+ gl.GL_RENDERBUFFER,
+ self._depthId)
+ else:
+ self._depthId = None
+
+ assert gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == \
+ gl.GL_FRAMEBUFFER_COMPLETE
+ gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
+
+ @property
+ def shape(self):
+ """Shape of the framebuffer (height, width)"""
+ return self._texture.shape
+
+ @property
+ def texture(self):
+ """The texture this framebuffer is rendering to.
+
+ The life-cycle of the texture is managed by this object"""
+ return self._texture
+
+ @property
+ def name(self):
+ """OpenGL name of the framebuffer"""
+ if self._name is not None:
+ return self._name
+ else:
+ raise RuntimeError("No OpenGL framebuffer resource, \
+ discard has already been called")
+
+ def bind(self):
+ """Bind this framebuffer for rendering"""
+ gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.name)
+
+ # with statement
+
+ def __enter__(self):
+ self._previousFramebuffer = gl.glGetInteger(gl.GL_FRAMEBUFFER_BINDING)
+ self.bind()
+
+ def __exit__(self, exctype, excvalue, traceback):
+ gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self._previousFramebuffer)
+
+ def discard(self):
+ """Delete associated OpenGL resources including texture"""
+ if self._name is not None:
+ gl.glDeleteFramebuffers(self._name)
+ self._name = None
+
+ if self._stencilId is not None:
+ gl.glDeleteRenderbuffers(self._stencilId)
+ if self._stencilId == self._depthId:
+ self._depthId = None
+ self._stencilId = None
+ if self._depthId is not None:
+ gl.glDeleteRenderbuffers(self._depthId)
+ self._depthId = None
+
+ self._texture.discard() # Also discard the texture
+ else:
+ _logger.warning("Discard has already been called")
diff --git a/silx/gui/_glutils/Program.py b/silx/gui/_glutils/Program.py
new file mode 100644
index 0000000..48c12f5
--- /dev/null
+++ b/silx/gui/_glutils/Program.py
@@ -0,0 +1,202 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a class to handle shader program compilation."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import logging
+
+import numpy
+
+from . import gl
+from .Context import getGLContext
+
+_logger = logging.getLogger(__name__)
+
+
+class Program(object):
+ """Wrap OpenGL shader program.
+
+ The program is compiled lazily (i.e., at first program :meth:`use`).
+ When the program is compiled, it stores attributes and uniforms locations.
+ So, attributes and uniforms must be used after :meth:`use`.
+
+ This object supports multiple OpenGL contexts.
+
+ :param str vertexShader: The source of the vertex shader.
+ :param str fragmentShader: The source of the fragment shader.
+ :param str attrib0:
+ Attribute's name to bind to position 0 (default: 'position').
+ On certain platform, this attribute MUST be active and with an
+ array attached to it in order for the rendering to occur....
+ """
+
+ def __init__(self, vertexShader, fragmentShader,
+ attrib0='position'):
+ self._vertexShader = vertexShader
+ self._fragmentShader = fragmentShader
+ self._attrib0 = attrib0
+ self._programs = {}
+
+ @staticmethod
+ def _compileGL(vertexShader, fragmentShader, attrib0):
+ program = gl.glCreateProgram()
+
+ gl.glBindAttribLocation(program, 0, attrib0.encode('ascii'))
+
+ vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER)
+ gl.glShaderSource(vertex, vertexShader)
+ gl.glCompileShader(vertex)
+ if gl.glGetShaderiv(vertex, gl.GL_COMPILE_STATUS) != gl.GL_TRUE:
+ raise RuntimeError(gl.glGetShaderInfoLog(vertex))
+ gl.glAttachShader(program, vertex)
+ gl.glDeleteShader(vertex)
+
+ fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)
+ gl.glShaderSource(fragment, fragmentShader)
+ gl.glCompileShader(fragment)
+ if gl.glGetShaderiv(fragment,
+ gl.GL_COMPILE_STATUS) != gl.GL_TRUE:
+ raise RuntimeError(gl.glGetShaderInfoLog(fragment))
+ gl.glAttachShader(program, fragment)
+ gl.glDeleteShader(fragment)
+
+ gl.glLinkProgram(program)
+ if gl.glGetProgramiv(program, gl.GL_LINK_STATUS) != gl.GL_TRUE:
+ raise RuntimeError(gl.glGetProgramInfoLog(program))
+
+ attributes = {}
+ for index in range(gl.glGetProgramiv(program,
+ gl.GL_ACTIVE_ATTRIBUTES)):
+ name = gl.glGetActiveAttrib(program, index)[0]
+ namestr = name.decode('ascii')
+ attributes[namestr] = gl.glGetAttribLocation(program, name)
+
+ uniforms = {}
+ for index in range(gl.glGetProgramiv(program, gl.GL_ACTIVE_UNIFORMS)):
+ name = gl.glGetActiveUniform(program, index)[0]
+ namestr = name.decode('ascii')
+ uniforms[namestr] = gl.glGetUniformLocation(program, name)
+
+ return program, attributes, uniforms
+
+ def _getProgramInfo(self):
+ glcontext = getGLContext()
+ if glcontext not in self._programs:
+ raise RuntimeError(
+ "Program was not compiled for current OpenGL context.")
+ return self._programs[glcontext]
+
+ @property
+ def attributes(self):
+ """Vertex attributes names and locations as a dict of {str: int}.
+
+ WARNING:
+ Read-only usage.
+ To use only with a valid OpenGL context and after :meth:`use`
+ has been called for this context.
+ """
+ return self._getProgramInfo()[1]
+
+ @property
+ def uniforms(self):
+ """Program uniforms names and locations as a dict of {str: int}.
+
+ WARNING:
+ Read-only usage.
+ To use only with a valid OpenGL context and after :meth:`use`
+ has been called for this context.
+ """
+ return self._getProgramInfo()[2]
+
+ @property
+ def program(self):
+ """OpenGL id of the program.
+
+ WARNING:
+ To use only with a valid OpenGL context and after :meth:`use`
+ has been called for this context.
+ """
+ return self._getProgramInfo()[0]
+
+ # def discard(self):
+ # pass # Not implemented yet
+
+ def use(self):
+ """Make use of the program, compiling it if necessary"""
+ glcontext = getGLContext()
+
+ if glcontext not in self._programs:
+ self._programs[glcontext] = self._compileGL(
+ self._vertexShader,
+ self._fragmentShader,
+ self._attrib0)
+
+ if _logger.getEffectiveLevel() <= logging.DEBUG:
+ gl.glValidateProgram(self.program)
+ if gl.glGetProgramiv(
+ self.program, gl.GL_VALIDATE_STATUS) != gl.GL_TRUE:
+ _logger.debug('Cannot validate program: %s',
+ gl.glGetProgramInfoLog(self.program))
+
+ gl.glUseProgram(self.program)
+
+ def setUniformMatrix(self, name, value, transpose=True, safe=False):
+ """Wrap glUniformMatrix[2|3|4]fv
+
+ :param str name: The name of the uniform.
+ :param value: The 2D matrix (or the array of matrices, 3D).
+ Matrices are 2x2, 3x3 or 4x4.
+ :type value: numpy.ndarray with 2 or 3 dimensions of float32
+ :param bool transpose: Whether to transpose (True, default) or not.
+ :param bool safe: False: raise an error if no uniform with this name;
+ True: silently ignores it.
+
+ :raises KeyError: if no uniform corresponds to name.
+ """
+ assert value.dtype == numpy.float32
+
+ shape = value.shape
+ assert len(shape) in (2, 3)
+ assert shape[-1] in (2, 3, 4)
+ assert shape[-1] == shape[-2] # As in OpenGL|ES 2.0
+
+ location = self.uniforms.get(name)
+ if location is not None:
+ count = 1 if len(shape) == 2 else shape[0]
+ transpose = gl.GL_TRUE if transpose else gl.GL_FALSE
+
+ if shape[-1] == 2:
+ gl.glUniformMatrix2fv(location, count, transpose, value)
+ elif shape[-1] == 3:
+ gl.glUniformMatrix3fv(location, count, transpose, value)
+ elif shape[-1] == 4:
+ gl.glUniformMatrix4fv(location, count, transpose, value)
+
+ elif not safe:
+ raise KeyError('No uniform: %s' % name)
diff --git a/silx/gui/_glutils/Texture.py b/silx/gui/_glutils/Texture.py
new file mode 100644
index 0000000..9f09a86
--- /dev/null
+++ b/silx/gui/_glutils/Texture.py
@@ -0,0 +1,308 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a class wrapping OpenGL 2D and 3D texture."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "04/10/2016"
+
+
+import collections
+from ctypes import c_void_p
+import logging
+
+import numpy
+
+from . import gl, utils
+
+
+_logger = logging.getLogger(__name__)
+
+
+class Texture(object):
+ """Base class to wrap OpenGL 2D and 3D texture
+
+ :param internalFormat: OpenGL texture internal format
+ :param data: The data to copy to the texture or None for an empty texture
+ :type data: numpy.ndarray or None
+ :param format_: Input data format if different from internalFormat
+ :param shape: If data is None, shape of the texture
+ :type shape: 2 or 3-tuple of int (height, width) or (depth, height, width)
+ :param int texUnit: The texture unit to use
+ :param minFilter: OpenGL texture minimization filter (default: GL_NEAREST)
+ :param magFilter: OpenGL texture magnification filter (default: GL_LINEAR)
+ :param wrap: Texture wrap mode for dimensions: (t, s) or (r, t, s)
+ If a single value is provided, it used for all dimensions.
+ :type wrap: OpenGL wrap mode or 2 or 3-tuple of wrap mode
+ """
+
+ def __init__(self, internalFormat, data=None, format_=None,
+ shape=None, texUnit=0,
+ minFilter=None, magFilter=None, wrap=None):
+
+ self._internalFormat = internalFormat
+ if format_ is None:
+ format_ = self.internalFormat
+
+ if data is None:
+ assert shape is not None
+ else:
+ assert shape is None
+ data = numpy.array(data, copy=False, order='C')
+ if format_ != gl.GL_RED:
+ shape = data.shape[:-1] # Last dimension is channels
+ else:
+ shape = data.shape
+
+ assert len(shape) in (2, 3)
+ self._shape = tuple(shape)
+ self._ndim = len(shape)
+
+ self.texUnit = texUnit
+
+ self._name = gl.glGenTextures(1)
+ self.bind(self.texUnit)
+
+ self._minFilter = None
+ self.minFilter = minFilter if minFilter is not None else gl.GL_NEAREST
+
+ self._magFilter = None
+ self.magFilter = magFilter if magFilter is not None else gl.GL_LINEAR
+
+ if wrap is not None:
+ if not isinstance(wrap, collections.Iterable):
+ wrap = [wrap] * self.ndim
+
+ assert len(wrap) == self.ndim
+
+ gl.glTexParameter(self.target,
+ gl.GL_TEXTURE_WRAP_S,
+ wrap[-1])
+ gl.glTexParameter(self.target,
+ gl.GL_TEXTURE_WRAP_T,
+ wrap[-2])
+ if self.ndim == 3:
+ gl.glTexParameter(self.target,
+ gl.GL_TEXTURE_WRAP_R,
+ wrap[0])
+
+ gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1)
+
+ # This are the defaults, useless to set if not modified
+ # gl.glPixelStorei(gl.GL_UNPACK_ROW_LENGTH, 0)
+ # gl.glPixelStorei(gl.GL_UNPACK_SKIP_PIXELS, 0)
+ # gl.glPixelStorei(gl.GL_UNPACK_SKIP_ROWS, 0)
+ # gl.glPixelStorei(gl.GL_UNPACK_IMAGE_HEIGHT, 0)
+ # gl.glPixelStorei(gl.GL_UNPACK_SKIP_IMAGES, 0)
+
+ if data is None:
+ data = c_void_p(0)
+ type_ = gl.GL_UNSIGNED_BYTE
+ else:
+ type_ = utils.numpyToGLType(data.dtype)
+
+ if self.ndim == 2:
+ _logger.debug(
+ 'Creating 2D texture shape: (%d, %d),'
+ ' internal format: %s, format: %s, type: %s',
+ self.shape[0], self.shape[1],
+ str(self.internalFormat), str(format_), str(type_))
+
+ gl.glTexImage2D(
+ gl.GL_TEXTURE_2D,
+ 0,
+ self.internalFormat,
+ self.shape[1],
+ self.shape[0],
+ 0,
+ format_,
+ type_,
+ data)
+ else:
+ _logger.debug(
+ 'Creating 3D texture shape: (%d, %d, %d),'
+ ' internal format: %s, format: %s, type: %s',
+ self.shape[0], self.shape[1], self.shape[2],
+ str(self.internalFormat), str(format_), str(type_))
+
+ gl.glTexImage3D(
+ gl.GL_TEXTURE_3D,
+ 0,
+ self.internalFormat,
+ self.shape[2],
+ self.shape[1],
+ self.shape[0],
+ 0,
+ format_,
+ type_,
+ data)
+
+ gl.glBindTexture(self.target, 0)
+
+ @property
+ def target(self):
+ """OpenGL target type of this texture"""
+ return gl.GL_TEXTURE_2D if self.ndim == 2 else gl.GL_TEXTURE_3D
+
+ @property
+ def ndim(self):
+ """The number of dimensions: 2 or 3"""
+ return self._ndim
+
+ @property
+ def internalFormat(self):
+ """Texture internal format"""
+ return self._internalFormat
+
+ @property
+ def shape(self):
+ """Shape of the texture: (height, width) or (depth, height, width)"""
+ return self._shape
+
+ @property
+ def name(self):
+ """OpenGL texture name"""
+ if self._name is not None:
+ return self._name
+ else:
+ raise RuntimeError(
+ "No OpenGL texture resource, discard has already been called")
+
+ @property
+ def minFilter(self):
+ """Minifying function parameter (GL_TEXTURE_MIN_FILTER)"""
+ return self._minFilter
+
+ @minFilter.setter
+ def minFilter(self, minFilter):
+ if minFilter != self.minFilter:
+ self._minFilter = minFilter
+ self.bind()
+ gl.glTexParameter(self.target,
+ gl.GL_TEXTURE_MIN_FILTER,
+ self.minFilter)
+
+ @property
+ def magFilter(self):
+ """Magnification function parameter (GL_TEXTURE_MAG_FILTER)"""
+ return self._magFilter
+
+ @magFilter.setter
+ def magFilter(self, magFilter):
+ if magFilter != self.magFilter:
+ self._magFilter = magFilter
+ self.bind()
+ gl.glTexParameter(self.target,
+ gl.GL_TEXTURE_MAG_FILTER,
+ self.magFilter)
+
+ def discard(self):
+ """Delete associated OpenGL texture"""
+ if self._name is not None:
+ gl.glDeleteTextures(self._name)
+ self._name = None
+ else:
+ _logger.warning("Discard as already been called")
+
+ def bind(self, texUnit=None):
+ """Bind the texture to a texture unit.
+
+ :param int texUnit: The texture unit to use
+ """
+ if texUnit is None:
+ texUnit = self.texUnit
+ gl.glActiveTexture(gl.GL_TEXTURE0 + texUnit)
+ gl.glBindTexture(self.target, self.name)
+
+ # with statement
+
+ def __enter__(self):
+ self.bind()
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ gl.glActiveTexture(gl.GL_TEXTURE0 + self.texUnit)
+ gl.glBindTexture(self.target, 0)
+
+ def update(self,
+ format_,
+ data,
+ offset=(0, 0, 0),
+ texUnit=None):
+ """Update the content of the texture.
+
+ Texture is not resized, so data must fit into texture with the
+ given offset.
+
+ :param format_: The OpenGL format of the data
+ :param data: The data to use to update the texture
+ :param offset: The offset in the texture where to copy the data
+ :type offset: 2 or 3-tuple of int
+ :param int texUnit:
+ The texture unit to use (default: the one provided at init)
+ """
+ data = numpy.array(data, copy=False, order='C')
+
+ assert data.ndim == self.ndim
+ assert len(offset) >= self.ndim
+ for i in range(self.ndim):
+ assert offset[i] + data.shape[i] <= self.shape[i]
+
+ gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1)
+
+ # This are the defaults, useless to set if not modified
+ # gl.glPixelStorei(gl.GL_UNPACK_ROW_LENGTH, 0)
+ # gl.glPixelStorei(gl.GL_UNPACK_SKIP_PIXELS, 0)
+ # gl.glPixelStorei(gl.GL_UNPACK_SKIP_ROWS, 0)
+ # gl.glPixelStorei(gl.GL_UNPACK_IMAGE_HEIGHT, 0)
+ # gl.glPixelStorei(gl.GL_UNPACK_SKIP_IMAGES, 0)
+
+ self.bind(texUnit)
+
+ type_ = utils.numpyToGLType(data.dtype)
+
+ if self.ndim == 2:
+ gl.glTexSubImage2D(gl.GL_TEXTURE_2D,
+ 0,
+ offset[1],
+ offset[0],
+ data.shape[1],
+ data.shape[0],
+ format_,
+ type_,
+ data)
+ gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
+ else:
+ gl.glTexSubImage3D(gl.GL_TEXTURE_3D,
+ 0,
+ offset[2],
+ offset[1],
+ offset[0],
+ data.shape[2],
+ data.shape[1],
+ data.shape[0],
+ format_,
+ type_,
+ data)
+ gl.glBindTexture(gl.GL_TEXTURE_3D, 0)
diff --git a/silx/gui/_glutils/VertexBuffer.py b/silx/gui/_glutils/VertexBuffer.py
new file mode 100644
index 0000000..689b543
--- /dev/null
+++ b/silx/gui/_glutils/VertexBuffer.py
@@ -0,0 +1,266 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a class managing an OpenGL vertex buffer."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "10/01/2017"
+
+
+import logging
+from ctypes import c_void_p
+import numpy
+
+from . import gl
+from .utils import numpyToGLType, sizeofGLType
+
+
+_logger = logging.getLogger(__name__)
+
+
+class VertexBuffer(object):
+ """Object handling an OpenGL vertex buffer object
+
+ :param data: Data used to fill the vertex buffer
+ :type data: numpy.ndarray or None
+ :param int size: Size in bytes of the buffer or None for data size
+ :param usage: OpenGL vertex buffer expected usage pattern:
+ GL_STREAM_DRAW, GL_STATIC_DRAW (default) or GL_DYNAMIC_DRAW
+ :param target: Target buffer:
+ GL_ARRAY_BUFFER (default) or GL_ELEMENT_ARRAY_BUFFER
+ """
+ # OpenGL|ES 2.0 subset:
+ _USAGES = gl.GL_STREAM_DRAW, gl.GL_STATIC_DRAW, gl.GL_DYNAMIC_DRAW
+ _TARGETS = gl.GL_ARRAY_BUFFER, gl.GL_ELEMENT_ARRAY_BUFFER
+
+ def __init__(self,
+ data=None,
+ size=None,
+ usage=None,
+ target=None):
+ if usage is None:
+ usage = gl.GL_STATIC_DRAW
+ assert usage in self._USAGES
+
+ if target is None:
+ target = gl.GL_ARRAY_BUFFER
+ assert target in self._TARGETS
+
+ self._target = target
+ self._usage = usage
+
+ self._name = gl.glGenBuffers(1)
+ self.bind()
+
+ if data is None:
+ assert size is not None
+ self._size = size
+ gl.glBufferData(self._target,
+ self._size,
+ c_void_p(0),
+ self._usage)
+ else:
+ data = numpy.array(data, copy=False, order='C')
+ if size is not None:
+ assert size <= data.nbytes
+
+ self._size = size or data.nbytes
+ gl.glBufferData(self._target,
+ self._size,
+ data,
+ self._usage)
+
+ gl.glBindBuffer(self._target, 0)
+
+ @property
+ def target(self):
+ """The target buffer of the vertex buffer"""
+ return self._target
+
+ @property
+ def usage(self):
+ """The expected usage of the vertex buffer"""
+ return self._usage
+
+ @property
+ def name(self):
+ """OpenGL Vertex Buffer object name (int)"""
+ if self._name is not None:
+ return self._name
+ else:
+ raise RuntimeError("No OpenGL buffer resource, \
+ discard has already been called")
+
+ @property
+ def size(self):
+ """Size in bytes of the Vertex Buffer Object (int)"""
+ if self._size is not None:
+ return self._size
+ else:
+ raise RuntimeError("No OpenGL buffer resource, \
+ discard has already been called")
+
+ def bind(self):
+ """Bind the vertex buffer"""
+ gl.glBindBuffer(self._target, self.name)
+
+ def update(self, data, offset=0, size=None):
+ """Update vertex buffer content.
+
+ :param numpy.ndarray data: The data to put in the vertex buffer
+ :param int offset: Offset in bytes in the buffer where to put the data
+ :param int size: If provided, size of data to copy
+ """
+ data = numpy.array(data, copy=False, order='C')
+ if size is None:
+ size = data.nbytes
+ assert offset + size <= self.size
+ with self:
+ gl.glBufferSubData(self._target, offset, size, data)
+
+ def discard(self):
+ """Delete the vertex buffer"""
+ if self._name is not None:
+ gl.glDeleteBuffers(self._name)
+ self._name = None
+ self._size = None
+ else:
+ _logger.warning("Discard has already been called")
+
+ # with statement
+
+ def __enter__(self):
+ self.bind()
+
+ def __exit__(self, exctype, excvalue, traceback):
+ gl.glBindBuffer(self._target, 0)
+
+
+class VertexBufferAttrib(object):
+ """Describes data stored in a vertex buffer
+
+ Convenient class to store info for glVertexAttribPointer calls
+
+ :param VertexBuffer vbo: The vertex buffer storing the data
+ :param int type_: The OpenGL type of the data
+ :param int size: The number of data elements stored in the VBO
+ :param int dimension: The number of `type_` element(s) in [1, 4]
+ :param int offset: Start offset of data in the vertex buffer
+ :param int stride: Data stride in the vertex buffer
+ """
+
+ _GL_TYPES = gl.GL_UNSIGNED_BYTE, gl.GL_FLOAT, gl.GL_INT
+
+ def __init__(self,
+ vbo,
+ type_,
+ size,
+ dimension=1,
+ offset=0,
+ stride=0,
+ normalisation=False):
+ self.vbo = vbo
+ assert type_ in self._GL_TYPES
+ self.type_ = type_
+ self.size = size
+ assert 1 <= dimension <= 4
+ self.dimension = dimension
+ self.offset = offset
+ self.stride = stride
+ self.normalisation = bool(normalisation)
+
+ @property
+ def itemsize(self):
+ """Size in bytes of a vertex buffer element (int)"""
+ return self.dimension * sizeofGLType(self.type_)
+
+ itemSize = itemsize # Backward compatibility
+
+ def setVertexAttrib(self, attribute):
+ """Call glVertexAttribPointer with objects information"""
+ normalisation = gl.GL_TRUE if self.normalisation else gl.GL_FALSE
+ with self.vbo:
+ gl.glVertexAttribPointer(attribute,
+ self.dimension,
+ self.type_,
+ normalisation,
+ self.stride,
+ c_void_p(self.offset))
+
+ def copy(self):
+ return VertexBufferAttrib(self.vbo,
+ self.type_,
+ self.size,
+ self.dimension,
+ self.offset,
+ self.stride,
+ self.normalisation)
+
+
+def vertexBuffer(arrays, prefix=None, suffix=None, usage=None):
+ """Create a single vertex buffer from multiple 1D or 2D numpy arrays.
+
+ It is possible to reserve memory before and after each array in the VBO
+
+ :param arrays: Arrays of data to store
+ :type arrays: Iterable of numpy.ndarray
+ :param prefix: If given, number of elements to reserve before each array
+ :type prefix: Iterable of int or None
+ :param suffix: If given, number of elements to reserve after each array
+ :type suffix: Iterable of int or None
+ :param int usage: vertex buffer expected usage or None for default
+ :returns: List of VertexBufferAttrib objects sharing the same vertex buffer
+ """
+ info = []
+ vbosize = 0
+
+ if prefix is None:
+ prefix = (0,) * len(arrays)
+ if suffix is None:
+ suffix = (0,) * len(arrays)
+
+ for data, pre, post in zip(arrays, prefix, suffix):
+ data = numpy.array(data, copy=False, order='C')
+ shape = data.shape
+ assert len(shape) <= 2
+ type_ = numpyToGLType(data.dtype)
+ size = shape[0] + pre + post
+ dimension = 1 if len(shape) == 1 else shape[1]
+ sizeinbytes = size * dimension * sizeofGLType(type_)
+ sizeinbytes = 4 * ((sizeinbytes + 3) >> 2) # 4 bytes alignment
+ copyoffset = vbosize + pre * dimension * sizeofGLType(type_)
+ info.append((data, type_, size, dimension,
+ vbosize, sizeinbytes, copyoffset))
+ vbosize += sizeinbytes
+
+ vbo = VertexBuffer(size=vbosize, usage=usage)
+
+ result = []
+ for data, type_, size, dimension, offset, sizeinbytes, copyoffset in info:
+ copysize = data.shape[0] * dimension * sizeofGLType(type_)
+ vbo.update(data, offset=copyoffset, size=copysize)
+ result.append(
+ VertexBufferAttrib(vbo, type_, size, dimension, offset, 0))
+ return result
diff --git a/silx/gui/_glutils/__init__.py b/silx/gui/_glutils/__init__.py
new file mode 100644
index 0000000..e86a58f
--- /dev/null
+++ b/silx/gui/_glutils/__init__.py
@@ -0,0 +1,41 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""This package provides utility functions to handle OpenGL resources.
+
+The :mod:`gl` module provides a wrapper to OpenGL based on PyOpenGL.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+# OpenGL convenient functions
+from .Context import getGLContext, setGLContextGetter # noqa
+from .FramebufferTexture import FramebufferTexture # noqa
+from .Program import Program # noqa
+from .Texture import Texture # noqa
+from .VertexBuffer import VertexBuffer, VertexBufferAttrib, vertexBuffer # noqa
+from .utils import sizeofGLType, isSupportedGLType, numpyToGLType # noqa
diff --git a/silx/gui/_glutils/font.py b/silx/gui/_glutils/font.py
new file mode 100644
index 0000000..566ae49
--- /dev/null
+++ b/silx/gui/_glutils/font.py
@@ -0,0 +1,152 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Text rasterisation feature leveraging Qt font and text layout support."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "13/10/2016"
+
+
+import logging
+import sys
+import numpy
+from .. import qt
+from .._utils import convertQImageToArray
+
+
+_logger = logging.getLogger(__name__)
+
+
+def getDefaultFontFamily():
+ """Returns the default font family of the application"""
+ return qt.QApplication.instance().font().family()
+
+
+# Font weights
+ULTRA_LIGHT = 0
+"""Lightest characters: Minimum font weight"""
+
+LIGHT = 25
+"""Light characters"""
+
+NORMAL = 50
+"""Normal characters"""
+
+SEMI_BOLD = 63
+"""Between normal and bold characters"""
+
+BOLD = 74
+"""Thicker characters"""
+
+BLACK = 87
+"""Really thick characters"""
+
+ULTRA_BLACK = 99
+"""Thickest characters: Maximum font weight"""
+
+
+def rasterText(text, font,
+ size=-1,
+ weight=-1,
+ italic=False,
+ devicePixelRatio=1.0):
+ """Raster text using Qt.
+
+ It supports multiple lines.
+
+ :param str text: The text to raster
+ :param font: Font name or QFont to use
+ :type font: str or :class:`QFont`
+ :param int size:
+ Font size in points
+ Used only if font is given as name.
+ :param int weight:
+ Font weight in [0, 99], see QFont.Weight.
+ Used only if font is given as name.
+ :param bool italic:
+ True for italic font (default: False).
+ Used only if font is given as name.
+ :param float devicePixelRatio:
+ The current ratio between device and device-independent pixel
+ (default: 1.0)
+ :return: Corresponding image in gray scale and baseline offset from top
+ :rtype: (HxW numpy.ndarray of uint8, int)
+ """
+ if not text:
+ _logger.info("Trying to raster empty text, replaced by white space")
+ text = ' ' # Replace empty text by white space to produce an image
+
+ if not isinstance(font, qt.QFont):
+ font = qt.QFont(font, size, weight, italic)
+
+ metrics = qt.QFontMetrics(font)
+ size = metrics.size(qt.Qt.TextExpandTabs, text)
+ bounds = metrics.boundingRect(
+ qt.QRect(0, 0, size.width(), size.height()),
+ qt.Qt.TextExpandTabs,
+ text)
+
+ if (devicePixelRatio != 1.0 and
+ not hasattr(qt.QImage, 'setDevicePixelRatio')): # Qt 4
+ _logger.error('devicePixelRatio not supported')
+ devicePixelRatio = 1.0
+
+ # Add extra border and handle devicePixelRatio
+ width = bounds.width() * devicePixelRatio + 2
+ # align line size to 32 bits to ease conversion to numpy array
+ width = 4 * ((width + 3) // 4)
+ image = qt.QImage(width,
+ bounds.height() * devicePixelRatio,
+ qt.QImage.Format_RGB888)
+ if (devicePixelRatio != 1.0 and
+ hasattr(image, 'setDevicePixelRatio')): # Qt 5
+ image.setDevicePixelRatio(devicePixelRatio)
+
+ # TODO if Qt5 use Format_Grayscale8 instead
+ image.fill(0)
+
+ # Raster text
+ painter = qt.QPainter()
+ painter.begin(image)
+ painter.setPen(qt.Qt.white)
+ painter.setFont(font)
+ painter.drawText(bounds, qt.Qt.TextExpandTabs, text)
+ painter.end()
+
+ array = convertQImageToArray(image)
+
+ # RGB to R
+ array = numpy.ascontiguousarray(array[:, :, 0])
+
+ # Remove leading and trailing empty columns but one on each side
+ column_cumsum = numpy.cumsum(numpy.sum(array, axis=0))
+ array = array[:, column_cumsum.argmin():column_cumsum.argmax() + 2]
+
+ # Remove leading and trailing empty rows but one on each side
+ row_cumsum = numpy.cumsum(numpy.sum(array, axis=1))
+ min_row = row_cumsum.argmin()
+ array = array[min_row:row_cumsum.argmax() + 2, :]
+
+ return array, metrics.ascent() - min_row
diff --git a/silx/gui/_glutils/gl.py b/silx/gui/_glutils/gl.py
new file mode 100644
index 0000000..4b9a7bb
--- /dev/null
+++ b/silx/gui/_glutils/gl.py
@@ -0,0 +1,165 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""This module loads PyOpenGL and provides a namespace for OpenGL."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+from contextlib import contextmanager as _contextmanager
+from ctypes import c_uint
+import logging
+
+_logger = logging.getLogger(__name__)
+
+import OpenGL
+# Set the following to true for debugging
+if _logger.getEffectiveLevel() <= logging.DEBUG:
+ _logger.debug('Enabling PyOpenGL debug flags')
+ OpenGL.ERROR_LOGGING = True
+ OpenGL.ERROR_CHECKING = True
+ OpenGL.ERROR_ON_COPY = True
+else:
+ OpenGL.ERROR_LOGGING = False
+ OpenGL.ERROR_CHECKING = False
+ OpenGL.ERROR_ON_COPY = False
+
+import OpenGL.GL as _GL
+from OpenGL.GL import * # noqa
+
+# Extentions core in OpenGL 3
+from OpenGL.GL.ARB import framebuffer_object as _FBO
+from OpenGL.GL.ARB.framebuffer_object import * # noqa
+from OpenGL.GL.ARB.texture_rg import GL_R32F, GL_R16F # noqa
+from OpenGL.GL.ARB.texture_rg import GL_R16, GL_R8 # noqa
+
+# PyOpenGL 3.0.1 does not define it
+try:
+ GLchar
+except NameError:
+ from ctypes import c_char
+ GLchar = c_char
+
+
+def testGL():
+ """Test if required OpenGL version and extensions are available.
+
+ This MUST be run with an active OpenGL context.
+ """
+ version = glGetString(GL_VERSION).split()[0] # get version number
+ major, minor = int(version[0]), int(version[2])
+ if major < 2 or (major == 2 and minor < 1):
+ raise RuntimeError(
+ "Requires at least OpenGL version 2.1, running with %s" % version)
+
+ from OpenGL.GL.ARB.framebuffer_object import glInitFramebufferObjectARB
+ from OpenGL.GL.ARB.texture_rg import glInitTextureRgARB
+
+ if not glInitFramebufferObjectARB():
+ raise RuntimeError(
+ "OpenGL GL_ARB_framebuffer_object extension required !")
+
+ if not glInitTextureRgARB():
+ raise RuntimeError("OpenGL GL_ARB_texture_rg extension required !")
+
+
+# Additional setup
+if hasattr(glget, 'addGLGetConstant'):
+ glget.addGLGetConstant(GL_FRAMEBUFFER_BINDING, (1,))
+
+
+@_contextmanager
+def enabled(capacity, enable=True):
+ """Context manager enabling an OpenGL capacity.
+
+ This is not checking the current state of the capacity.
+
+ :param capacity: The OpenGL capacity enum to enable/disable
+ :param bool enable:
+ True (default) to enable during context, False to disable
+ """
+ if enable:
+ glEnable(capacity)
+ yield
+ glDisable(capacity)
+ else:
+ glDisable(capacity)
+ yield
+ glEnable(capacity)
+
+
+def disabled(capacity, disable=True):
+ """Context manager disabling an OpenGL capacity.
+
+ This is not checking the current state of the capacity.
+
+ :param capacity: The OpenGL capacity enum to disable/enable
+ :param bool disable:
+ True (default) to disable during context, False to enable
+ """
+ return enabled(capacity, not disable)
+
+
+# Additional OpenGL wrapping
+
+def glGetActiveAttrib(program, index):
+ """Wrap PyOpenGL glGetActiveAttrib"""
+ bufsize = glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH)
+ length = GLsizei()
+ size = GLint()
+ type_ = GLenum()
+ name = (GLchar * bufsize)()
+
+ _GL.glGetActiveAttrib(program, index, bufsize, length, size, type_, name)
+ return name.value, size.value, type_.value
+
+
+def glDeleteRenderbuffers(buffers):
+ if not hasattr(buffers, '__len__'): # Support single int argument
+ buffers = [buffers]
+ length = len(buffers)
+ _FBO.glDeleteRenderbuffers(length, (c_uint * length)(*buffers))
+
+
+def glDeleteFramebuffers(buffers):
+ if not hasattr(buffers, '__len__'): # Support single int argument
+ buffers = [buffers]
+ length = len(buffers)
+ _FBO.glDeleteFramebuffers(length, (c_uint * length)(*buffers))
+
+
+def glDeleteBuffers(buffers):
+ if not hasattr(buffers, '__len__'): # Support single int argument
+ buffers = [buffers]
+ length = len(buffers)
+ _GL.glDeleteBuffers(length, (c_uint * length)(*buffers))
+
+
+def glDeleteTextures(textures):
+ if not hasattr(textures, '__len__'): # Support single int argument
+ textures = [textures]
+ length = len(textures)
+ _GL.glDeleteTextures((c_uint * length)(*textures))
diff --git a/silx/gui/_glutils/utils.py b/silx/gui/_glutils/utils.py
new file mode 100644
index 0000000..73af338
--- /dev/null
+++ b/silx/gui/_glutils/utils.py
@@ -0,0 +1,70 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""This module provides conversion functions between OpenGL and numpy types.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "10/01/2017"
+
+from . import gl
+import numpy
+
+
+_GL_TYPE_SIZES = {
+ gl.GL_FLOAT: 4,
+ gl.GL_BYTE: 1,
+ gl.GL_SHORT: 2,
+ gl.GL_INT: 4,
+ gl.GL_UNSIGNED_BYTE: 1,
+ gl.GL_UNSIGNED_SHORT: 2,
+ gl.GL_UNSIGNED_INT: 4,
+}
+
+
+def sizeofGLType(type_):
+ """Returns the size in bytes of an element of type `type_`"""
+ return _GL_TYPE_SIZES[type_]
+
+
+_TYPE_CONVERTER = {
+ numpy.dtype(numpy.float32): gl.GL_FLOAT,
+ numpy.dtype(numpy.int8): gl.GL_BYTE,
+ numpy.dtype(numpy.int16): gl.GL_SHORT,
+ numpy.dtype(numpy.int32): gl.GL_INT,
+ numpy.dtype(numpy.uint8): gl.GL_UNSIGNED_BYTE,
+ numpy.dtype(numpy.uint16): gl.GL_UNSIGNED_SHORT,
+ numpy.dtype(numpy.uint32): gl.GL_UNSIGNED_INT,
+}
+
+
+def isSupportedGLType(type_):
+ """Test if a numpy type or dtype can be converted to a GL type."""
+ return numpy.dtype(type_) in _TYPE_CONVERTER
+
+
+def numpyToGLType(type_):
+ """Returns the GL type corresponding the provided numpy type or dtype."""
+ return _TYPE_CONVERTER[numpy.dtype(type_)]
diff --git a/silx/gui/_utils.py b/silx/gui/_utils.py
new file mode 100644
index 0000000..e29141f
--- /dev/null
+++ b/silx/gui/_utils.py
@@ -0,0 +1,102 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module provides convenient functions to use with Qt objects.
+
+It provides conversion between numpy and QImage.
+"""
+
+from __future__ import division
+
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+
+import sys
+import numpy
+
+from . import qt
+
+
+def convertArrayToQImage(image):
+ """Convert an array-like RGB888 image to a QImage.
+
+ The created QImage is using a copy of the array data.
+
+ Limitation: Only supports RGB888 format.
+
+ :param image: Array-like image data
+ :type image: numpy.ndarray of uint8 of dimension HxWx3
+ :return: Corresponding Qt image
+ :rtype: QImage
+ """
+ # Possible extension: add a format argument to support more formats
+
+ image = numpy.array(image, copy=False, order='C', dtype=numpy.uint8)
+
+ height, width, depth = image.shape
+ assert depth == 3
+
+ qimage = qt.QImage(
+ image.data,
+ width,
+ height,
+ image.strides[0], # bytesPerLine
+ qt.QImage.Format_RGB888)
+
+ return qimage.copy() # Making a copy of the image and its data
+
+
+def convertQImageToArray(image):
+ """Convert a RGB888 QImage to a numpy array.
+
+ Limitation: Only supports RGB888 format.
+ If QImage is not RGB888 it gets converted to this format.
+
+ :param QImage: The QImage to convert.
+ :return: The image array
+ :rtype: numpy.ndarray of uint8 of shape HxWx3
+ """
+ # Possible extension: avoid conversion to support more formats
+
+ if image.format() != qt.QImage.Format_RGB888:
+ # Convert to RGB888 if needed
+ image = image.convertToFormat(qt.QImage.Format_RGB888)
+
+ ptr = image.bits()
+ if qt.BINDING != 'PySide':
+ ptr.setsize(image.byteCount())
+ if qt.BINDING == 'PyQt4' and sys.version_info[0] == 2:
+ ptr = ptr.asstring()
+ elif sys.version_info[0] == 3: # PySide with Python3
+ ptr = ptr.tobytes()
+
+ array = numpy.fromstring(ptr, dtype=numpy.uint8)
+
+ # Lines are 32 bits aligned: remove padding bytes
+ array = array.reshape(image.height(), -1)[:, :image.width() * 3]
+ array.shape = image.height(), image.width(), 3
+ return array
diff --git a/silx/gui/console.py b/silx/gui/console.py
new file mode 100644
index 0000000..13760b4
--- /dev/null
+++ b/silx/gui/console.py
@@ -0,0 +1,214 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""This module provides an IPython console widget.
+
+You can push variables - any python object - to the
+console's interactive namespace. This provides users with an advanced way
+of interacting with your program. For instance, if your program has a
+:class:`PlotWidget` or a :class:`PlotWindow`, you can push a reference to
+these widgets to allow your users to add curves, save data to files… by using
+the widgets' methods from the console.
+
+.. note::
+
+ This module has a dependency on
+ `IPython <https://pypi.python.org/pypi/ipython>`_ and
+ `qtconsole <https://pypi.python.org/pypi/qtconsole>`_ (or *ipython.qt* for
+ older versions of *IPython*). An ``ImportError`` will be raised if it is
+ imported while the dependencies are not satisfied.
+
+Basic usage example::
+
+ from silx.gui import qt
+ from silx.gui.console import IPythonWidget
+
+ app = qt.QApplication([])
+
+ hello_button = qt.QPushButton("Hello World!", None)
+ hello_button.show()
+
+ console = IPythonWidget()
+ console.show()
+ console.pushVariables({"the_button": hello_button})
+
+ app.exec_()
+
+This program will display a console widget and a push button in two separate
+windows. You will be able to interact with the button from the console,
+for example change its text::
+
+ >>> the_button.setText("Spam spam")
+
+An IPython interactive console is a powerful tool that enables you to work
+with data and plot it.
+See `this tutorial <https://plot.ly/python/ipython-notebook-tutorial/>`_
+for more information on some of the rich features of IPython.
+"""
+__authors__ = ["Tim Rae", "V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "24/05/2016"
+
+import logging
+
+from . import qt
+
+_logger = logging.getLogger(__name__)
+
+try:
+ import IPython
+except ImportError as e:
+ raise ImportError("Failed to import IPython, required by " + __name__)
+
+# This widget cannot be used inside an interactive IPython shell.
+# It would raise MultipleInstanceError("Multiple incompatible subclass
+# instances of InProcessInteractiveShell are being created").
+try:
+ __IPYTHON__
+except NameError:
+ pass # Not in IPython
+else:
+ msg = "Module " + __name__ + " cannot be used within an IPython shell"
+ raise ImportError(msg)
+
+# qtconsole is a separate module in recent versions of IPython/Jupyter
+# http://blog.jupyter.org/2015/04/15/the-big-split/
+if IPython.__version__.startswith("2"):
+ qtconsole = None
+else:
+ try:
+ import qtconsole
+ except ImportError:
+ qtconsole = None
+
+if qtconsole is not None:
+ try:
+ from qtconsole.rich_ipython_widget import RichJupyterWidget as \
+ RichIPythonWidget
+ except ImportError:
+ try:
+ from qtconsole.rich_ipython_widget import RichIPythonWidget
+ except ImportError as e:
+ qtconsole = None
+ else:
+ from qtconsole.inprocess import QtInProcessKernelManager
+ else:
+ from qtconsole.inprocess import QtInProcessKernelManager
+
+
+if qtconsole is None:
+ # Import the console machinery from ipython
+
+ # The `has_binding` test of IPython does not find the Qt bindings
+ # in case silx is used in a frozen binary
+ import IPython.external.qt_loaders
+
+ def has_binding(*var, **kw):
+ return True
+
+ IPython.external.qt_loaders.has_binding = has_binding
+
+ from IPython.qt.console.rich_ipython_widget import RichIPythonWidget
+ from IPython.qt.inprocess import QtInProcessKernelManager
+
+
+class IPythonWidget(RichIPythonWidget):
+ """Live IPython console widget.
+
+ :param custom_banner: Custom welcome message to be printed at the top of
+ the console.
+ """
+
+ def __init__(self, parent=None, custom_banner=None, *args, **kwargs):
+ if parent is not None:
+ kwargs["parent"] = parent
+ super(IPythonWidget, self).__init__(*args, **kwargs)
+ if custom_banner is not None:
+ self.banner = custom_banner
+ self.setWindowTitle(self.banner)
+ self.kernel_manager = kernel_manager = QtInProcessKernelManager()
+ kernel_manager.start_kernel()
+ self.kernel_client = kernel_client = self._kernel_manager.client()
+ kernel_client.start_channels()
+
+ def stop():
+ kernel_client.stop_channels()
+ kernel_manager.shutdown_kernel()
+ self.exit_requested.connect(stop)
+
+ def sizeHint(self):
+ """Return a reasonable default size for usage in :class:`PlotWindow`"""
+ return qt.QSize(500, 300)
+
+ def pushVariables(self, variable_dict):
+ """ Given a dictionary containing name / value pairs, push those
+ variables to the IPython console widget.
+
+ :param variable_dict: Dictionary of variables to be pushed to the
+ console's interactive namespace (```{variable_name: object, …}```)
+ """
+ self.kernel_manager.kernel.shell.push(variable_dict)
+
+
+class IPythonDockWidget(qt.QDockWidget):
+ """Dock Widget including a :class:`IPythonWidget` inside
+ a vertical layout.
+
+ :param available_vars: Dictionary of variables to be pushed to the
+ console's interactive namespace: ``{"variable_name": object, …}``
+ :param custom_banner: Custom welcome message to be printed at the top of
+ the console
+ :param title: Dock widget title
+ :param parent: Parent :class:`qt.QMainWindow` containing this
+ :class:`qt.QDockWidget`
+ """
+ def __init__(self, parent=None, available_vars=None, custom_banner=None,
+ title="Console"):
+ super(IPythonDockWidget, self).__init__(title, parent)
+
+ self.ipyconsole = IPythonWidget(custom_banner=custom_banner)
+
+ self.layout().setContentsMargins(0, 0, 0, 0)
+ self.setWidget(self.ipyconsole)
+
+ if available_vars is not None:
+ self.ipyconsole.pushVariables(available_vars)
+
+ def showEvent(self, event):
+ """Make sure this widget is raised when it is shown
+ (when it is first created as a tab in PlotWindow or when it is shown
+ again after hiding).
+ """
+ self.raise_()
+
+
+def main():
+ """Run a Qt app with an IPython console"""
+ app = qt.QApplication([])
+ widget = IPythonDockWidget()
+ widget.show()
+ app.exec_()
+
+if __name__ == '__main__':
+ main()
diff --git a/silx/gui/data/ArrayTableModel.py b/silx/gui/data/ArrayTableModel.py
new file mode 100644
index 0000000..87a2fc1
--- /dev/null
+++ b/silx/gui/data/ArrayTableModel.py
@@ -0,0 +1,610 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""
+This module defines a data model for displaying and editing arrays of any
+number of dimensions in a table view.
+"""
+from __future__ import division
+import numpy
+import logging
+from silx.gui import qt
+from silx.gui.data.TextFormatter import TextFormatter
+
+__authors__ = ["V.A. Sole"]
+__license__ = "MIT"
+__date__ = "24/01/2017"
+
+
+_logger = logging.getLogger(__name__)
+
+
+def _is_array(data):
+ """Return True if object implements all necessary attributes to be used
+ as a numpy array.
+
+ :param object data: Array-like object (numpy array, h5py dataset...)
+ :return: boolean
+ """
+ # add more required attribute if necessary
+ for attr in ("shape", "dtype"):
+ if not hasattr(data, attr):
+ return False
+ return True
+
+
+class ArrayTableModel(qt.QAbstractTableModel):
+ """This data model provides access to 2D slices in a N-dimensional
+ array.
+
+ A slice for a 3-D array is characterized by a perspective (the number of
+ the axis orthogonal to the slice) and an index at which the slice
+ intersects the orthogonal axis.
+
+ In the n-D case, only slices parallel to the last two axes are handled. A
+ slice is therefore characterized by a list of indices locating the
+ slice on all the :math:`n - 2` orthogonal axes.
+
+ :param parent: Parent QObject
+ :param data: Numpy array, or object implementing a similar interface
+ (e.g. h5py dataset)
+ :param str fmt: Format string for representing numerical values.
+ Default is ``"%g"``.
+ :param sequence[int] perspective: See documentation
+ of :meth:`setPerspective`.
+ """
+ def __init__(self, parent=None, data=None, perspective=None):
+ qt.QAbstractTableModel.__init__(self, parent)
+
+ self._array = None
+ """n-dimensional numpy array"""
+
+ self._bgcolors = None
+ """(n+1)-dimensional numpy array containing RGB(A) color data
+ for the background color
+ """
+
+ self._fgcolors = None
+ """(n+1)-dimensional numpy array containing RGB(A) color data
+ for the foreground color
+ """
+
+ self._formatter = None
+ """Formatter for text representation of data"""
+
+ formatter = TextFormatter(self)
+ formatter.setUseQuoteForText(False)
+ self.setFormatter(formatter)
+
+ self._index = None
+ """This attribute stores the slice index, as a list of indices
+ where the frame intersects orthogonal axis."""
+
+ self._perspective = None
+ """Sequence of dimensions orthogonal to the frame to be viewed.
+ For an array with ``n`` dimensions, this is a sequence of ``n-2``
+ integers. the first dimension is numbered ``0``.
+ By default, the data frames use the last two dimensions as their axes
+ and therefore the perspective is a sequence of the first ``n-2``
+ dimensions.
+ For example, for a 5-D array, the default perspective is ``(0, 1, 2)``
+ and the default frames axes are ``(3, 4)``."""
+
+ # set _data and _perspective
+ self.setArrayData(data, perspective=perspective)
+
+ def _getRowDim(self):
+ """The row axis is the first axis parallel to the frames
+ (lowest dimension number)
+
+ Return None for 0-D (scalar) or 1-D arrays
+ """
+ n_dimensions = len(self._array.shape)
+ if n_dimensions < 2:
+ # scalar or 1D array: no row index
+ return None
+ # take all dimensions and remove the orthogonal ones
+ frame_axes = set(range(0, n_dimensions)) - set(self._perspective)
+ # sanity check
+ assert len(frame_axes) == 2
+ return min(frame_axes)
+
+ def _getColumnDim(self):
+ """The column axis is the second (highest dimension) axis parallel
+ to the frames
+
+ Return None for 0-D (scalar)
+ """
+ n_dimensions = len(self._array.shape)
+ if n_dimensions < 1:
+ # scalar: no column index
+ return None
+ frame_axes = set(range(0, n_dimensions)) - set(self._perspective)
+ # sanity check
+ assert (len(frame_axes) == 2) if n_dimensions > 1 else (len(frame_axes) == 1)
+ return max(frame_axes)
+
+ def _getIndexTuple(self, table_row, table_col):
+ """Return the n-dimensional index of a value in the original array,
+ based on its row and column indices in the table view
+
+ :param table_row: Row index (0-based) of a table cell
+ :param table_col: Column index (0-based) of a table cell
+ :return: Tuple of indices of the element in the numpy array
+ """
+ row_dim = self._getRowDim()
+ col_dim = self._getColumnDim()
+
+ # get indices on all orthogonal axes
+ selection = list(self._index)
+ # insert indices on parallel axes
+ if row_dim is not None:
+ selection.insert(row_dim, table_row)
+ if col_dim is not None:
+ selection.insert(col_dim, table_col)
+ return tuple(selection)
+
+ # Methods to be implemented to subclass QAbstractTableModel
+ def rowCount(self, parent_idx=None):
+ """QAbstractTableModel method
+ Return number of rows to be displayed in table"""
+ row_dim = self._getRowDim()
+ if row_dim is None:
+ # 0-D and 1-D arrays
+ return 1
+ return self._array.shape[row_dim]
+
+ def columnCount(self, parent_idx=None):
+ """QAbstractTableModel method
+ Return number of columns to be displayed in table"""
+ col_dim = self._getColumnDim()
+ if col_dim is None:
+ # 0-D array
+ return 1
+ return self._array.shape[col_dim]
+
+ def data(self, index, role=qt.Qt.DisplayRole):
+ """QAbstractTableModel method to access data values
+ in the format ready to be displayed"""
+ if index.isValid():
+ selection = self._getIndexTuple(index.row(),
+ index.column())
+ if role == qt.Qt.DisplayRole:
+ return self._formatter.toString(self._array[selection])
+
+ if role == qt.Qt.BackgroundRole and self._bgcolors is not None:
+ r, g, b = self._bgcolors[selection][0:3]
+ if self._bgcolors.shape[-1] == 3:
+ return qt.QColor(r, g, b)
+ if self._bgcolors.shape[-1] == 4:
+ a = self._bgcolors[selection][3]
+ return qt.QColor(r, g, b, a)
+
+ if role == qt.Qt.ForegroundRole:
+ if self._fgcolors is not None:
+ r, g, b = self._fgcolors[selection][0:3]
+ if self._fgcolors.shape[-1] == 3:
+ return qt.QColor(r, g, b)
+ if self._fgcolors.shape[-1] == 4:
+ a = self._fgcolors[selection][3]
+ return qt.QColor(r, g, b, a)
+
+ # no fg color given, use black or white
+ # based on luminosity threshold
+ elif self._bgcolors is not None:
+ r, g, b = self._bgcolors[selection][0:3]
+ lum = 0.21 * r + 0.72 * g + 0.07 * b
+ if lum < 128:
+ return qt.QColor(qt.Qt.white)
+ else:
+ return qt.QColor(qt.Qt.black)
+
+ def headerData(self, section, orientation, role=qt.Qt.DisplayRole):
+ """QAbstractTableModel method
+ Return the 0-based row or column index, for display in the
+ horizontal and vertical headers"""
+ if role == qt.Qt.DisplayRole:
+ if orientation == qt.Qt.Vertical:
+ return "%d" % section
+ if orientation == qt.Qt.Horizontal:
+ return "%d" % section
+ return None
+
+ def flags(self, index):
+ """QAbstractTableModel method to inform the view whether data
+ is editable or not."""
+ if not self._editable:
+ return qt.QAbstractTableModel.flags(self, index)
+ return qt.QAbstractTableModel.flags(self, index) | qt.Qt.ItemIsEditable
+
+ def setData(self, index, value, role=None):
+ """QAbstractTableModel method to handle editing data.
+ Cast the new value into the same format as the array before editing
+ the array value."""
+ if index.isValid() and role == qt.Qt.EditRole:
+ try:
+ # cast value to same type as array
+ v = numpy.asscalar(
+ numpy.array(value, dtype=self._array.dtype))
+ except ValueError:
+ return False
+
+ selection = self._getIndexTuple(index.row(),
+ index.column())
+ self._array[selection] = v
+ self.dataChanged.emit(index, index)
+ return True
+ else:
+ return False
+
+ # Public methods
+ def setArrayData(self, data, copy=True,
+ perspective=None, editable=False):
+ """Set the data array and the viewing perspective.
+
+ You can set ``copy=False`` if you need more performances, when dealing
+ with a large numpy array. In this case, a simple reference to the data
+ is used to access the data, rather than a copy of the array.
+
+ .. warning::
+
+ Any change to the data model will affect your original data
+ array, when using a reference rather than a copy..
+
+ :param data: n-dimensional numpy array, or any object that can be
+ converted to a numpy array using ``numpy.array(data)`` (e.g.
+ a nested sequence).
+ :param bool copy: If *True* (default), a copy of the array is stored
+ and the original array is not modified if the table is edited.
+ If *False*, then the behavior depends on the data type:
+ if possible (if the original array is a proper numpy array)
+ a reference to the original array is used.
+ :param perspective: See documentation of :meth:`setPerspective`.
+ If None, the default perspective is the list of the first ``n-2``
+ dimensions, to view frames parallel to the last two axes.
+ :param bool editable: Flag to enable editing data. Default *False*.
+ """
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+ else:
+ self.reset()
+
+ if data is None:
+ # empty array
+ self._array = numpy.array([])
+ elif copy:
+ # copy requested (default)
+ self._array = numpy.array(data, copy=True)
+ elif not _is_array(data):
+ raise TypeError("data is not a proper array. Try setting" +
+ " copy=True to convert it into a numpy array" +
+ " (this will cause the data to be copied!)")
+ # # copy not requested, but necessary
+ # _logger.warning(
+ # "data is not an array-like object. " +
+ # "Data must be copied.")
+ # self._array = numpy.array(data, copy=True)
+ else:
+ # Copy explicitly disabled & data implements required attributes.
+ # We can use a reference.
+ self._array = data
+
+ # reset colors to None if new data shape is inconsistent
+ valid_color_shapes = (self._array.shape + (3,),
+ self._array.shape + (4,))
+ if self._bgcolors is not None:
+ if self._bgcolors.shape not in valid_color_shapes:
+ self._bgcolors = None
+ if self._fgcolors is not None:
+ if self._fgcolors.shape not in valid_color_shapes:
+ self._fgcolors = None
+
+ self.setEditable(editable)
+
+ self._index = [0 for _i in range((len(self._array.shape) - 2))]
+ self._perspective = tuple(perspective) if perspective is not None else\
+ tuple(range(0, len(self._array.shape) - 2))
+
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+
+ def setArrayColors(self, bgcolors=None, fgcolors=None):
+ """Set the colors for all table cells by passing an array
+ of RGB or RGBA values (integers between 0 and 255).
+
+ The shape of the colors array must be consistent with the data shape.
+
+ If the data array is n-dimensional, the colors array must be
+ (n+1)-dimensional, with the first n-dimensions identical to the data
+ array dimensions, and the last dimension length-3 (RGB) or
+ length-4 (RGBA).
+
+ :param bgcolors: RGB or RGBA colors array, defining the background color
+ for each cell in the table.
+ :param fgcolors: RGB or RGBA colors array, defining the foreground color
+ (text color) for each cell in the table.
+ """
+ # array must be RGB or RGBA
+ valid_shapes = (self._array.shape + (3,), self._array.shape + (4,))
+ errmsg = "Inconsistent shape for color array, should be %s or %s" % valid_shapes
+
+ if bgcolors is not None:
+ if not _is_array(bgcolors):
+ bgcolors = numpy.array(bgcolors)
+ assert bgcolors.shape in valid_shapes, errmsg
+
+ self._bgcolors = bgcolors
+
+ if fgcolors is not None:
+ if not _is_array(fgcolors):
+ fgcolors = numpy.array(fgcolors)
+ assert fgcolors.shape in valid_shapes, errmsg
+
+ self._fgcolors = fgcolors
+
+ def setEditable(self, editable):
+ """Set flags to make the data editable.
+
+ .. warning::
+
+ If the data is a reference to a h5py dataset open in read-only
+ mode, setting *editable=True* will fail and print a warning.
+
+ .. warning::
+
+ Making the data editable means that the underlying data structure
+ in this data model will be modified.
+ If the data is a reference to a public object (open with
+ ``copy=False``), this could have side effects. If it is a
+ reference to an HDF5 dataset, this means the file will be
+ modified.
+
+ :param bool editable: Flag to enable editing data.
+ :return: True if setting desired flag succeeded, False if it failed.
+ """
+ self._editable = editable
+ if hasattr(self._array, "file"):
+ if hasattr(self._array.file, "mode"):
+ if editable and self._array.file.mode == "r":
+ _logger.warning(
+ "Data is a HDF5 dataset open in read-only " +
+ "mode. Editing must be disabled.")
+ self._editable = False
+ return False
+ return True
+
+ def getData(self, copy=True):
+ """Return a copy of the data array, or a reference to it
+ if *copy=False* is passed as parameter.
+
+ In case the shape was modified, to convert 0-D or 1-D data
+ into 2-D data, the original shape is restored in the returned data.
+
+ :param bool copy: If *True* (default), return a copy of the data. If
+ *False*, return a reference.
+ :return: numpy array of data, or reference to original data object
+ if *copy=False*
+ """
+ data = self._array if not copy else numpy.array(self._array, copy=True)
+ return data
+
+ def setFrameIndex(self, index):
+ """Set the active slice index.
+
+ This method is only relevant to arrays with at least 3 dimensions.
+
+ :param index: Index of the active slice in the array.
+ In the general n-D case, this is a sequence of :math:`n - 2`
+ indices where the slice intersects the respective orthogonal axes.
+ :raise IndexError: If any index in the index sequence is out of bound
+ on its respective axis.
+ """
+ shape = self._array.shape
+ if len(shape) < 3:
+ # index is ignored
+ return
+
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+ else:
+ self.reset()
+
+ if len(shape) == 3:
+ len_ = shape[self._perspective[0]]
+ # accept integers as index in the case of 3-D arrays
+ if not hasattr(index, "__len__"):
+ self._index = [index]
+ else:
+ self._index = index
+ if not 0 <= self._index[0] < len_:
+ raise ValueError("Index must be a positive integer " +
+ "lower than %d" % len_)
+ else:
+ # general n-D case
+ for i_, idx in enumerate(index):
+ if not 0 <= idx < shape[self._perspective[i_]]:
+ raise IndexError("Invalid index %d " % idx +
+ "not in range 0-%d" % (shape[i_] - 1))
+ self._index = index
+
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+
+ def setFormatter(self, formatter):
+ """Set the formatter object to be used to display data from the model
+
+ :param TextFormatter formatter: Formatter to use
+ """
+ if formatter is self._formatter:
+ return
+
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+
+ if self._formatter is not None:
+ self._formatter.formatChanged.disconnect(self.__formatChanged)
+
+ self._formatter = formatter
+ if self._formatter is not None:
+ self._formatter.formatChanged.connect(self.__formatChanged)
+
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+ else:
+ self.reset()
+
+ def getFormatter(self):
+ """Returns the text formatter used.
+
+ :rtype: TextFormatter
+ """
+ return self._formatter
+
+ def __formatChanged(self):
+ """Called when the format changed.
+ """
+ self.reset()
+
+ def setPerspective(self, perspective):
+ """Set the perspective by defining a sequence listing all axes
+ orthogonal to the frame or 2-D slice to be visualized.
+
+ Alternatively, you can use :meth:`setFrameAxes` for the complementary
+ approach of specifying the two axes parallel to the frame.
+
+ In the 1-D or 2-D case, this parameter is irrelevant.
+
+ In the 3-D case, if the unit vectors describing
+ your axes are :math:`\vec{x}, \vec{y}, \vec{z}`, a perspective of 0
+ means you slices are parallel to :math:`\vec{y}\vec{z}`, 1 means they
+ are parallel to :math:`\vec{x}\vec{z}` and 2 means they
+ are parallel to :math:`\vec{x}\vec{y}`.
+
+ In the n-D case, this parameter is a sequence of :math:`n-2` axes
+ numbers.
+ For instance if you want to display 2-D frames whose axes are the
+ second and third dimensions of a 5-D array, set the perspective to
+ ``(0, 3, 4)``.
+
+ :param perspective: Sequence of dimensions/axes orthogonal to the
+ frames.
+ :raise: IndexError if any value in perspective is higher than the
+ number of dimensions minus one (first dimension is 0), or
+ if the number of values is different from the number of dimensions
+ minus two.
+ """
+ n_dimensions = len(self._array.shape)
+ if n_dimensions < 3:
+ _logger.warning(
+ "perspective is not relevant for 1D and 2D arrays")
+ return
+
+ if not hasattr(perspective, "__len__"):
+ # we can tolerate an integer for 3-D array
+ if n_dimensions == 3:
+ perspective = [perspective]
+ else:
+ raise ValueError("perspective must be a sequence of integers")
+
+ # ensure unicity of dimensions in perspective
+ perspective = tuple(set(perspective))
+
+ if len(perspective) != n_dimensions - 2 or\
+ min(perspective) < 0 or max(perspective) >= n_dimensions:
+ raise IndexError(
+ "Invalid perspective " + str(perspective) +
+ " for %d-D array " % n_dimensions +
+ "with shape " + str(self._array.shape))
+
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+ else:
+ self.reset()
+
+ self._perspective = perspective
+
+ # reset index
+ self._index = [0 for _i in range(n_dimensions - 2)]
+
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+
+ def setFrameAxes(self, row_axis, col_axis):
+ """Set the perspective by specifying the two axes parallel to the frame
+ to be visualised.
+
+ The complementary approach of defining the orthogonal axes can be used
+ with :meth:`setPerspective`.
+
+ :param int row_axis: Index (0-based) of the first dimension used as a frame
+ axis
+ :param int col_axis: Index (0-based) of the 2nd dimension used as a frame
+ axis
+ :raise: IndexError if axes are invalid
+ """
+ if row_axis > col_axis:
+ _logger.warning("The dimension of the row axis must be lower " +
+ "than the dimension of the column axis. Swapping.")
+ row_axis, col_axis = min(row_axis, col_axis), max(row_axis, col_axis)
+
+ n_dimensions = len(self._array.shape)
+ if n_dimensions < 3:
+ _logger.warning(
+ "Frame axes cannot be changed for 1D and 2D arrays")
+ return
+
+ perspective = tuple(set(range(0, n_dimensions)) - {row_axis, col_axis})
+
+ if len(perspective) != n_dimensions - 2 or\
+ min(perspective) < 0 or max(perspective) >= n_dimensions:
+ raise IndexError(
+ "Invalid perspective " + str(perspective) +
+ " for %d-D array " % n_dimensions +
+ "with shape " + str(self._array.shape))
+
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+ else:
+ self.reset()
+
+ self._perspective = perspective
+ # reset index
+ self._index = [0 for _i in range(n_dimensions - 2)]
+
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+
+
+if __name__ == "__main__":
+ app = qt.QApplication([])
+ w = qt.QTableView()
+ d = numpy.random.normal(0, 1, (5, 1000, 1000))
+ for i in range(5):
+ d[i, :, :] += i * 10
+ m = ArrayTableModel(data=d)
+ w.setModel(m)
+ m.setFrameIndex(3)
+ # m.setArrayData(numpy.ones((100,)))
+ w.show()
+ app.exec_()
diff --git a/silx/gui/data/ArrayTableWidget.py b/silx/gui/data/ArrayTableWidget.py
new file mode 100644
index 0000000..ba3fa11
--- /dev/null
+++ b/silx/gui/data/ArrayTableWidget.py
@@ -0,0 +1,490 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module defines a widget designed to display data arrays with any
+number of dimensions as 2D frames (images, slices) in a table view.
+The dimensions not displayed in the table can be browsed using improved
+sliders.
+
+The widget uses a TableView that relies on a custom abstract item
+model: :class:`silx.gui.data.ArrayTableModel`.
+"""
+from __future__ import division
+import sys
+
+from silx.gui import qt
+from silx.gui.widgets.TableWidget import TableView
+from .ArrayTableModel import ArrayTableModel
+from silx.gui.widgets.FrameBrowser import HorizontalSliderWithBrowser
+
+__authors__ = ["V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "24/01/2017"
+
+
+class AxesSelector(qt.QWidget):
+ """Widget with two combo-boxes to select two dimensions among
+ all possible dimensions of an n-dimensional array.
+
+ The first combobox contains values from :math:`0` to :math:`n-2`.
+
+ The choices in the 2nd CB depend on the value selected in the first one.
+ If the value selected in the first CB is :math:`m`, the second one lets you
+ select values from :math:`m+1` to :math:`n-1`.
+
+ The two axes can be used to select the row axis and the column axis t
+ display a slice of the array data in a table view.
+ """
+ sigDimensionsChanged = qt.Signal(int, int)
+ """Signal emitted whenever one of the comboboxes is changed.
+ The signal carries the two selected dimensions."""
+
+ def __init__(self, parent=None, n=None):
+ qt.QWidget.__init__(self, parent)
+ self.layout = qt.QHBoxLayout(self)
+ self.layout.setContentsMargins(0, 2, 0, 2)
+ self.layout.setSpacing(10)
+
+ self.rowsCB = qt.QComboBox(self)
+ self.columnsCB = qt.QComboBox(self)
+
+ self.layout.addWidget(qt.QLabel("Rows dimension", self))
+ self.layout.addWidget(self.rowsCB)
+ self.layout.addWidget(qt.QLabel(" ", self))
+ self.layout.addWidget(qt.QLabel("Columns dimension", self))
+ self.layout.addWidget(self.columnsCB)
+ self.layout.addStretch(1)
+
+ self._slotsAreConnected = False
+ if n is not None:
+ self.setNDimensions(n)
+
+ def setNDimensions(self, n):
+ """Initialize combo-boxes depending on number of dimensions of array.
+ Initially, the rows dimension is the second-to-last one, and the
+ columns dimension is the last one.
+
+ Link the CBs together. MAke them emit a signal when their value is
+ changed.
+
+ :param int n: Number of dimensions of array
+ """
+ # remember the number of dimensions and the rows dimension
+ self.n = n
+ self._rowsDim = n - 2
+
+ # ensure slots are disconnected before (re)initializing widget
+ if self._slotsAreConnected:
+ self.rowsCB.currentIndexChanged.disconnect(self._rowDimChanged)
+ self.columnsCB.currentIndexChanged.disconnect(self._colDimChanged)
+
+ self._clear()
+ self.rowsCB.addItems([str(i) for i in range(n - 1)])
+ self.rowsCB.setCurrentIndex(n - 2)
+ if n >= 1:
+ self.columnsCB.addItem(str(n - 1))
+ self.columnsCB.setCurrentIndex(0)
+
+ # reconnect slots
+ self.rowsCB.currentIndexChanged.connect(self._rowDimChanged)
+ self.columnsCB.currentIndexChanged.connect(self._colDimChanged)
+ self._slotsAreConnected = True
+
+ # emit new dimensions
+ if n > 2:
+ self.sigDimensionsChanged.emit(n - 2, n - 1)
+
+ def setDimensions(self, row_dim, col_dim):
+ """Set the rows and columns dimensions.
+
+ The rows dimension must be lower than the columns dimension.
+
+ :param int row_dim: Rows dimension
+ :param int col_dim: Columns dimension
+ """
+ if row_dim >= col_dim:
+ raise IndexError("Row dimension must be lower than column dimension")
+ if not (0 <= row_dim < self.n - 1):
+ raise IndexError("Row dimension must be between 0 and %d" % (self.n - 2))
+ if not (row_dim < col_dim <= self.n - 1):
+ raise IndexError("Col dimension must be between %d and %d" % (row_dim + 1, self.n - 1))
+
+ # set the rows dimension; this triggers an update of columnsCB
+ self.rowsCB.setCurrentIndex(row_dim)
+ # columnsCB first item is "row_dim + 1". So index of "col_dim" is
+ # col_dim - (row_dim + 1)
+ self.columnsCB.setCurrentIndex(col_dim - row_dim - 1)
+
+ def getDimensions(self):
+ """Return a 2-tuple of the rows dimension and the columns dimension.
+
+ :return: 2-tuple of axes numbers (row_dimension, col_dimension)
+ """
+ return self._getRowDim(), self._getColDim()
+
+ def _clear(self):
+ """Empty the combo-boxes"""
+ self.rowsCB.clear()
+ self.columnsCB.clear()
+
+ def _getRowDim(self):
+ """Get rows dimension, selected in :attr:`rowsCB`
+ """
+ # rows combobox contains elements "0", ..."n-2",
+ # so the selected dim is always equal to the index
+ return self.rowsCB.currentIndex()
+
+ def _getColDim(self):
+ """Get columns dimension, selected in :attr:`columnsCB`"""
+ # columns combobox contains elements "row_dim+1", "row_dim+2", ..., "n-1"
+ # so the selected dim is equal to row_dim + 1 + index
+ return self._rowsDim + 1 + self.columnsCB.currentIndex()
+
+ def _rowDimChanged(self):
+ """Update columns combobox when the rows dimension is changed.
+
+ Emit :attr:`sigDimensionsChanged`"""
+ old_col_dim = self._getColDim()
+ new_row_dim = self._getRowDim()
+
+ # clear cols CB
+ self.columnsCB.currentIndexChanged.disconnect(self._colDimChanged)
+ self.columnsCB.clear()
+ # refill cols CB
+ for i in range(new_row_dim + 1, self.n):
+ self.columnsCB.addItem(str(i))
+
+ # keep previous col dimension if possible
+ new_col_cb_idx = old_col_dim - (new_row_dim + 1)
+ if new_col_cb_idx < 0:
+ # if row_dim is now greater than the previous col_dim,
+ # we select a new col_dim = row_dim + 1 (first element in cols CB)
+ new_col_cb_idx = 0
+ self.columnsCB.setCurrentIndex(new_col_cb_idx)
+
+ # reconnect slot
+ self.columnsCB.currentIndexChanged.connect(self._colDimChanged)
+
+ self._rowsDim = new_row_dim
+
+ self.sigDimensionsChanged.emit(self._getRowDim(), self._getColDim())
+
+ def _colDimChanged(self):
+ """Emit :attr:`sigDimensionsChanged`"""
+ self.sigDimensionsChanged.emit(self._getRowDim(), self._getColDim())
+
+
+def _get_shape(array_like):
+ """Return shape of an array like object.
+
+ In case the object is a nested sequence (list of lists, tuples...),
+ the size of each dimension is assumed to be uniform, and is deduced from
+ the length of the first sequence.
+
+ :param array_like: Array like object: numpy array, hdf5 dataset,
+ multi-dimensional sequence
+ :return: Shape of array, as a tuple of integers
+ """
+ if hasattr(array_like, "shape"):
+ return array_like.shape
+
+ shape = []
+ subsequence = array_like
+ while hasattr(subsequence, "__len__"):
+ shape.append(len(subsequence))
+ subsequence = subsequence[0]
+
+ return tuple(shape)
+
+
+class ArrayTableWidget(qt.QWidget):
+ """This widget is designed to display data of 2D frames (images, slices)
+ in a table view. The widget can load any n-dimensional array, and display
+ any 2-D frame/slice in the array.
+
+ The index of the dimensions orthogonal to the displayed frame can be set
+ interactively using a browser widget (sliders, buttons and text entries).
+
+ To set the data, use :meth:`setArrayData`.
+ To select the perspective, use :meth:`setPerspective` or
+ use :meth:`setFrameAxes`.
+ To select the frame, use :meth:`setFrameIndex`.
+ """
+ def __init__(self, parent=None):
+ """
+
+ :param parent: parent QWidget
+ :param labels: list of labels for each dimension of the array
+ """
+ qt.QWidget.__init__(self, parent)
+ self.mainLayout = qt.QVBoxLayout(self)
+ self.mainLayout.setContentsMargins(0, 0, 0, 0)
+ self.mainLayout.setSpacing(0)
+
+ self.browserContainer = qt.QWidget(self)
+ self.browserLayout = qt.QGridLayout(self.browserContainer)
+ self.browserLayout.setContentsMargins(0, 0, 0, 0)
+ self.browserLayout.setSpacing(0)
+
+ self._dimensionLabelsText = []
+ """List of text labels sorted in the increasing order of the dimension
+ they apply to."""
+ self._browserLabels = []
+ """List of QLabel widgets."""
+ self._browserWidgets = []
+ """List of HorizontalSliderWithBrowser widgets."""
+
+ self.axesSelector = AxesSelector(self)
+
+ self.view = TableView(self)
+
+ self.mainLayout.addWidget(self.browserContainer)
+ self.mainLayout.addWidget(self.axesSelector)
+ self.mainLayout.addWidget(self.view)
+
+ self.model = ArrayTableModel(self)
+ self.view.setModel(self.model)
+
+ def setArrayData(self, data, labels=None, copy=True, editable=False):
+ """Set the data array. Update frame browsers and labels.
+
+ :param data: Numpy array or similar object (e.g. nested sequence,
+ h5py dataset...)
+ :param labels: list of labels for each dimension of the array, or
+ boolean ``True`` to use default labels ("dimension 0",
+ "dimension 1", ...). `None` to disable labels (default).
+ :param bool copy: If *True*, store a copy of *data* in the model. If
+ *False*, store a reference to *data* if possible (only possible if
+ *data* is a proper numpy array or an object that implements the
+ same methods).
+ :param bool editable: Flag to enable editing data. Default is *False*
+ """
+ self._data_shape = _get_shape(data)
+
+ n_widgets = len(self._browserWidgets)
+ n_dimensions = len(self._data_shape)
+
+ # Reset text of labels
+ self._dimensionLabelsText = []
+ for i in range(n_dimensions):
+ if labels in [True, 1]:
+ label_text = "Dimension %d" % i
+ elif labels is None or i >= len(labels):
+ label_text = ""
+ else:
+ label_text = labels[i]
+ self._dimensionLabelsText.append(label_text)
+
+ # not enough widgets, create new ones (we need n_dim - 2)
+ for i in range(n_widgets, n_dimensions - 2):
+ browser = HorizontalSliderWithBrowser(self.browserContainer)
+ self.browserLayout.addWidget(browser, i, 1)
+ self._browserWidgets.append(browser)
+ browser.valueChanged.connect(self._browserSlot)
+ browser.setEnabled(False)
+ browser.hide()
+
+ label = qt.QLabel(self.browserContainer)
+ self._browserLabels.append(label)
+ self.browserLayout.addWidget(label, i, 0)
+ label.hide()
+
+ n_widgets = len(self._browserWidgets)
+ for i in range(n_widgets):
+ label = self._browserLabels[i]
+ browser = self._browserWidgets[i]
+
+ if (i + 2) < n_dimensions:
+ label.setText(self._dimensionLabelsText[i])
+ browser.setRange(0, self._data_shape[i] - 1)
+ browser.setEnabled(True)
+ browser.show()
+ if labels is not None:
+ label.show()
+ else:
+ label.hide()
+ else:
+ browser.setEnabled(False)
+ browser.hide()
+ label.hide()
+
+ # set model
+ self.model.setArrayData(data, copy=copy, editable=editable)
+ # some linux distributions need this call
+ self.view.setModel(self.model)
+ if editable:
+ self.view.enableCut()
+ self.view.enablePaste()
+
+ # initialize & connect axesSelector
+ self.axesSelector.setNDimensions(n_dimensions)
+ self.axesSelector.sigDimensionsChanged.connect(self.setFrameAxes)
+
+ def setArrayColors(self, bgcolors=None, fgcolors=None):
+ """Set the colors for all table cells by passing an array
+ of RGB or RGBA values (integers between 0 and 255).
+
+ The shape of the colors array must be consistent with the data shape.
+
+ If the data array is n-dimensional, the colors array must be
+ (n+1)-dimensional, with the first n-dimensions identical to the data
+ array dimensions, and the last dimension length-3 (RGB) or
+ length-4 (RGBA).
+
+ :param bgcolors: RGB or RGBA colors array, defining the background color
+ for each cell in the table.
+ :param fgcolors: RGB or RGBA colors array, defining the foreground color
+ (text color) for each cell in the table.
+ """
+ self.model.setArrayColors(bgcolors, fgcolors)
+
+ def displayAxesSelector(self, isVisible):
+ """Allow to display or hide the axes selector.
+
+ :param bool isVisible: True to display the axes selector.
+ """
+ self.axesSelector.setVisible(isVisible)
+
+ def setFrameIndex(self, index):
+ """Set the active slice/image index in the n-dimensional array.
+
+ A frame is a 2D array extracted from an array. This frame is
+ necessarily parallel to 2 axes, and orthogonal to all other axes.
+
+ The index of a frame is a sequence of indices along the orthogonal
+ axes, where the frame intersects the respective axis. The indices
+ are listed in the same order as the corresponding dimensions of the
+ data array.
+
+ For example, it the data array has 5 dimensions, and we are
+ considering frames whose parallel axes are the 2nd and 4th dimensions
+ of the array, the frame index will be a sequence of length 3
+ corresponding to the indices where the frame intersects the 1st, 3rd
+ and 5th axes.
+
+ :param index: Sequence of indices defining the active data slice in
+ a n-dimensional array. The sequence length is :math:`n-2`
+ :raise: IndexError if any index in the index sequence is out of bound
+ on its respective axis.
+ """
+ self.model.setFrameIndex(index)
+
+ def _resetBrowsers(self, perspective):
+ """Adjust limits for browsers based on the perspective and the
+ size of the corresponding dimensions. Reset the index to 0.
+ Update the dimension in the labels.
+
+ :param perspective: Sequence of axes/dimensions numbers (0-based)
+ defining the axes orthogonal to the frame.
+ """
+ # for 3D arrays we can accept an int rather than a 1-tuple
+ if not hasattr(perspective, "__len__"):
+ perspective = [perspective]
+
+ # perspective must be sorted
+ perspective = sorted(perspective)
+
+ n_dimensions = len(self._data_shape)
+ for i in range(n_dimensions - 2):
+ browser = self._browserWidgets[i]
+ label = self._browserLabels[i]
+ browser.setRange(0, self._data_shape[perspective[i]] - 1)
+ browser.setValue(0)
+ label.setText(self._dimensionLabelsText[perspective[i]])
+
+ def setPerspective(self, perspective):
+ """Set the *perspective* by specifying which axes are orthogonal
+ to the frame.
+
+ For the opposite approach (defining parallel axes), use
+ :meth:`setFrameAxes` instead.
+
+ :param perspective: Sequence of unique axes numbers (0-based) defining
+ the orthogonal axes. For a n-dimensional array, the sequence
+ length is :math:`n-2`. The order is of the sequence is not taken
+ into account (the dimensions are displayed in increasing order
+ in the widget).
+ """
+ self.model.setPerspective(perspective)
+ self._resetBrowsers(perspective)
+
+ def setFrameAxes(self, row_axis, col_axis):
+ """Set the *perspective* by specifying which axes are parallel
+ to the frame.
+
+ For the opposite approach (defining orthogonal axes), use
+ :meth:`setPerspective` instead.
+
+ :param int row_axis: Index (0-based) of the first dimension used as a frame
+ axis
+ :param int col_axis: Index (0-based) of the 2nd dimension used as a frame
+ axis
+ """
+ self.model.setFrameAxes(row_axis, col_axis)
+ n_dimensions = len(self._data_shape)
+ perspective = tuple(set(range(0, n_dimensions)) - {row_axis, col_axis})
+ self._resetBrowsers(perspective)
+
+ def _browserSlot(self, value):
+ index = []
+ for browser in self._browserWidgets:
+ if browser.isEnabled():
+ index.append(browser.value())
+ self.setFrameIndex(index)
+ self.view.reset()
+
+ def getData(self, copy=True):
+ """Return a copy of the data array, or a reference to it if
+ *copy=False* is passed as parameter.
+
+ :param bool copy: If *True* (default), return a copy of the data. If
+ *False*, return a reference.
+ :return: Numpy array of data, or reference to original data object
+ if *copy=False*
+ """
+ return self.model.getData(copy=copy)
+
+
+def main():
+ import numpy
+ a = qt.QApplication([])
+ d = numpy.random.normal(0, 1, (4, 5, 1000, 1000))
+ for j in range(4):
+ for i in range(5):
+ d[j, i, :, :] += i + 10 * j
+ w = ArrayTableWidget()
+ if "2" in sys.argv:
+ print("sending a single image")
+ w.setArrayData(d[0, 0])
+ elif "3" in sys.argv:
+ print("sending 5 images")
+ w.setArrayData(d[0])
+ else:
+ print("sending 4 * 5 images ")
+ w.setArrayData(d, labels=True)
+ w.show()
+ a.exec_()
+
+if __name__ == "__main__":
+ main()
diff --git a/silx/gui/data/DataViewer.py b/silx/gui/data/DataViewer.py
new file mode 100644
index 0000000..3a3ac64
--- /dev/null
+++ b/silx/gui/data/DataViewer.py
@@ -0,0 +1,464 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module defines a widget designed to display data using to most adapted
+view from available ones from silx.
+"""
+from __future__ import division
+
+from silx.gui.data import DataViews
+from silx.gui.data.DataViews import _normalizeData
+import logging
+from silx.gui import qt
+from silx.gui.data.NumpyAxesSelector import NumpyAxesSelector
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+
+_logger = logging.getLogger(__name__)
+
+
+class DataViewer(qt.QFrame):
+ """Widget to display any kind of data
+
+ .. image:: img/DataViewer.png
+
+ The method :meth:`setData` allows to set any data to the widget. Mostly
+ `numpy.array` and `h5py.Dataset` are supported with adapted views. Other
+ data types are displayed using a text viewer.
+
+ A default view is automatically selected when a data is set. The method
+ :meth:`setDisplayMode` allows to change the view. To have a graphical tool
+ to select the view, prefer using the widget :class:`DataViewerFrame`.
+
+ The dimension of the input data and the expected dimension of the selected
+ view can differ. For example you can display an image (2D) from 4D
+ data. In this case a :class:`NumpyAxesSelector` is displayed to allow the
+ user to select the axis mapping and the slicing of other axes.
+
+ .. code-block:: python
+
+ import numpy
+ data = numpy.random.rand(500,500)
+ viewer = DataViewer()
+ viewer.setData(data)
+ viewer.setVisible(True)
+ """
+
+ EMPTY_MODE = 0
+ PLOT1D_MODE = 10
+ PLOT2D_MODE = 20
+ PLOT3D_MODE = 30
+ RAW_MODE = 40
+ RAW_ARRAY_MODE = 41
+ RAW_RECORD_MODE = 42
+ RAW_SCALAR_MODE = 43
+ STACK_MODE = 50
+ HDF5_MODE = 60
+
+ displayedViewChanged = qt.Signal(object)
+ """Emitted when the displayed view changes"""
+
+ dataChanged = qt.Signal()
+ """Emitted when the data changes"""
+
+ currentAvailableViewsChanged = qt.Signal()
+ """Emitted when the current available views (which support the current
+ data) change"""
+
+ def __init__(self, parent=None):
+ """Constructor
+
+ :param QWidget parent: The parent of the widget
+ """
+ super(DataViewer, self).__init__(parent)
+
+ self.__stack = qt.QStackedWidget(self)
+ self.__numpySelection = NumpyAxesSelector(self)
+ self.__numpySelection.selectedAxisChanged.connect(self.__numpyAxisChanged)
+ self.__numpySelection.selectionChanged.connect(self.__numpySelectionChanged)
+ self.__numpySelection.customAxisChanged.connect(self.__numpyCustomAxisChanged)
+
+ self.setLayout(qt.QVBoxLayout(self))
+ self.layout().addWidget(self.__stack, 1)
+
+ group = qt.QGroupBox(self)
+ group.setLayout(qt.QVBoxLayout())
+ group.layout().addWidget(self.__numpySelection)
+ group.setTitle("Axis selection")
+ self.__axisSelection = group
+
+ self.layout().addWidget(self.__axisSelection)
+
+ self.__currentAvailableViews = []
+ self.__currentView = None
+ self.__data = None
+ self.__useAxisSelection = False
+ self.__userSelectedView = None
+
+ self.__views = []
+ self.__index = {}
+ """store stack index for each views"""
+
+ self._initializeViews()
+
+ def _initializeViews(self):
+ """Inisialize the available views"""
+ views = self.createDefaultViews(self.__stack)
+ self.__views = list(views)
+ self.setDisplayMode(self.EMPTY_MODE)
+
+ def createDefaultViews(self, parent=None):
+ """Create and returns available views which can be displayed by default
+ by the data viewer. It is called internally by the widget. It can be
+ overwriten to provide a different set of viewers.
+
+ :param QWidget parent: QWidget parent of the views
+ :rtype: list[silx.gui.data.DataViews.DataView]
+ """
+ viewClasses = [
+ DataViews._EmptyView,
+ DataViews._Hdf5View,
+ DataViews._NXdataView,
+ DataViews._Plot1dView,
+ DataViews._Plot2dView,
+ DataViews._Plot3dView,
+ DataViews._RawView,
+ DataViews._StackView,
+ ]
+ views = []
+ for viewClass in viewClasses:
+ try:
+ view = viewClass(parent)
+ views.append(view)
+ except Exception:
+ _logger.warning("%s instantiation failed. View is ignored" % viewClass.__name__)
+ _logger.debug("Backtrace", exc_info=True)
+
+ return views
+
+ def clear(self):
+ """Clear the widget"""
+ self.setData(None)
+
+ def normalizeData(self, data):
+ """Returns a normalized data if the embed a numpy or a dataset.
+ Else returns the data."""
+ return _normalizeData(data)
+
+ def __getStackIndex(self, view):
+ """Get the stack index containing the view.
+
+ :param silx.gui.data.DataViews.DataView view: The view
+ """
+ if view not in self.__index:
+ widget = view.getWidget()
+ index = self.__stack.addWidget(widget)
+ self.__index[view] = index
+ else:
+ index = self.__index[view]
+ return index
+
+ def __clearCurrentView(self):
+ """Clear the current selected view"""
+ view = self.__currentView
+ if view is not None:
+ view.clear()
+
+ def __numpyCustomAxisChanged(self, name, value):
+ view = self.__currentView
+ if view is not None:
+ view.setCustomAxisValue(name, value)
+
+ def __updateNumpySelectionAxis(self):
+ """
+ Update the numpy-selector according to the needed axis names
+ """
+ previous = self.__numpySelection.blockSignals(True)
+ self.__numpySelection.clear()
+ info = DataViews.DataInfo(self.__data)
+ axisNames = self.__currentView.axesNames(self.__data, info)
+ if info.isArray and self.__data is not None and len(axisNames) > 0:
+ self.__useAxisSelection = True
+ self.__numpySelection.setAxisNames(axisNames)
+ self.__numpySelection.setCustomAxis(self.__currentView.customAxisNames())
+ data = self.normalizeData(self.__data)
+ self.__numpySelection.setData(data)
+ if hasattr(data, "shape"):
+ isVisible = not (len(axisNames) == 1 and len(data.shape) == 1)
+ else:
+ isVisible = True
+ self.__axisSelection.setVisible(isVisible)
+ else:
+ self.__useAxisSelection = False
+ self.__axisSelection.setVisible(False)
+ self.__numpySelection.blockSignals(previous)
+
+ def __updateDataInView(self):
+ """
+ Update the views using the current data
+ """
+ if self.__useAxisSelection:
+ self.__displayedData = self.__numpySelection.selectedData()
+ else:
+ self.__displayedData = self.__data
+
+ qt.QTimer.singleShot(10, self.__setDataInView)
+
+ def __setDataInView(self):
+ self.__currentView.setData(self.__displayedData)
+
+ def setDisplayedView(self, view):
+ """Set the displayed view.
+
+ Change the displayed view according to the view itself.
+
+ :param silx.gui.data.DataViews.DataView view: The DataView to use to display the data
+ """
+ self.__userSelectedView = view
+ self._setDisplayedView(view)
+
+ def _setDisplayedView(self, view):
+ """Internal set of the displayed view.
+
+ Change the displayed view according to the view itself.
+
+ :param silx.gui.data.DataViews.DataView view: The DataView to use to display the data
+ """
+ if self.__currentView is view:
+ return
+ self.__clearCurrentView()
+ self.__currentView = view
+ self.__updateNumpySelectionAxis()
+ self.__updateDataInView()
+ stackIndex = self.__getStackIndex(self.__currentView)
+ if self.__currentView is not None:
+ self.__currentView.select()
+ self.__stack.setCurrentIndex(stackIndex)
+ self.displayedViewChanged.emit(view)
+
+ def getViewFromModeId(self, modeId):
+ """Returns the first available view which have the requested modeId.
+
+ :param int modeId: Requested mode id
+ :rtype: silx.gui.data.DataViews.DataView
+ """
+ for view in self.__views:
+ if view.modeId() == modeId:
+ return view
+ return view
+
+ def setDisplayMode(self, modeId):
+ """Set the displayed view using display mode.
+
+ Change the displayed view according to the requested mode.
+
+ :param int modeId: Display mode, one of
+
+ - `EMPTY_MODE`: display nothing
+ - `PLOT1D_MODE`: display the data as a curve
+ - `PLOT2D_MODE`: display the data as an image
+ - `PLOT3D_MODE`: display the data as an isosurface
+ - `RAW_MODE`: display the data as a table
+ - `STACK_MODE`: display the data as a stack of images
+ - `HDF5_MODE`: display the data as a table
+ """
+ try:
+ view = self.getViewFromModeId(modeId)
+ except KeyError:
+ raise ValueError("Display mode %s is unknown" % modeId)
+ self._setDisplayedView(view)
+
+ def displayedView(self):
+ """Returns the current displayed view.
+
+ :rtype: silx.gui.data.DataViews.DataView
+ """
+ return self.__currentView
+
+ def addView(self, view):
+ """Allow to add a view to the dataview.
+
+ If the current data support this view, it will be displayed.
+
+ :param DataView view: A dataview
+ """
+ self.__views.append(view)
+ # TODO It can be skipped if the view do not support the data
+ self.__updateAvailableViews()
+
+ def removeView(self, view):
+ """Allow to remove a view which was available from the dataview.
+
+ If the view was displayed, the widget will be updated.
+
+ :param DataView view: A dataview
+ """
+ self.__views.remove(view)
+ self.__stack.removeWidget(view.getWidget())
+ # invalidate the full index. It will be updated as expected
+ self.__index = {}
+
+ if self.__userSelectedView is view:
+ self.__userSelectedView = None
+
+ if view is self.__currentView:
+ self.__updateView()
+ else:
+ # TODO It can be skipped if the view is not part of the
+ # available views
+ self.__updateAvailableViews()
+
+ def __updateAvailableViews(self):
+ """
+ Update available views from the current data.
+ """
+ data = self.__data
+ # sort available views according to priority
+ info = DataViews.DataInfo(data)
+ priorities = [v.getDataPriority(data, info) for v in self.__views]
+ views = zip(priorities, self.__views)
+ views = filter(lambda t: t[0] > DataViews.DataView.UNSUPPORTED, views)
+ views = sorted(views, reverse=True)
+
+ # store available views
+ if len(views) == 0:
+ self.__setCurrentAvailableViews([])
+ available = []
+ else:
+ available = [v[1] for v in views]
+ self.__setCurrentAvailableViews(available)
+
+ def __updateView(self):
+ """Display the data using the widget which fit the best"""
+ data = self.__data
+
+ # update available views for this data
+ self.__updateAvailableViews()
+ available = self.__currentAvailableViews
+
+ # display the view with the most priority (the default view)
+ view = self.getDefaultViewFromAvailableViews(data, available)
+ self.__clearCurrentView()
+ try:
+ self._setDisplayedView(view)
+ except Exception as e:
+ # in case there is a problem to read the data, try to use a safe
+ # view
+ view = self.getSafeViewFromAvailableViews(data, available)
+ self._setDisplayedView(view)
+ raise e
+
+ def getSafeViewFromAvailableViews(self, data, available):
+ """Returns a view which is sure to display something without failing
+ on rendering.
+
+ :param object data: data which will be displayed
+ :param list[view] available: List of available views, from highest
+ priority to lowest.
+ :rtype: DataView
+ """
+ hdf5View = self.getViewFromModeId(DataViewer.HDF5_MODE)
+ if hdf5View in available:
+ return hdf5View
+ return self.getViewFromModeId(DataViewer.EMPTY_MODE)
+
+ def getDefaultViewFromAvailableViews(self, data, available):
+ """Returns the default view which will be used according to available
+ views.
+
+ :param object data: data which will be displayed
+ :param list[view] available: List of available views, from highest
+ priority to lowest.
+ :rtype: DataView
+ """
+ if len(available) > 0:
+ # returns the view with the highest priority
+ if self.__userSelectedView in available:
+ return self.__userSelectedView
+ self.__userSelectedView = None
+ view = available[0]
+ else:
+ # else returns the empty view
+ view = self.getViewFromModeId(DataViewer.EMPTY_MODE)
+ return view
+
+ def __setCurrentAvailableViews(self, availableViews):
+ """Set the current available viewa
+
+ :param List[DataView] availableViews: Current available viewa
+ """
+ self.__currentAvailableViews = availableViews
+ self.currentAvailableViewsChanged.emit()
+
+ def currentAvailableViews(self):
+ """Returns the list of available views for the current data
+
+ :rtype: List[DataView]
+ """
+ return self.__currentAvailableViews
+
+ def availableViews(self):
+ """Returns the list of registered views
+
+ :rtype: List[DataView]
+ """
+ return self.__views
+
+ def setData(self, data):
+ """Set the data to view.
+
+ It mostly can be a h5py.Dataset or a numpy.ndarray. Other kind of
+ objects will be displayed as text rendering.
+
+ :param numpy.ndarray data: The data.
+ """
+ self.__data = data
+ self.__displayedData = None
+ self.__updateView()
+ self.__updateNumpySelectionAxis()
+ self.__updateDataInView()
+ self.dataChanged.emit()
+
+ def __numpyAxisChanged(self):
+ """
+ Called when axis selection of the numpy-selector changed
+ """
+ self.__clearCurrentView()
+
+ def __numpySelectionChanged(self):
+ """
+ Called when data selection of the numpy-selector changed
+ """
+ self.__updateDataInView()
+
+ def data(self):
+ """Returns the data"""
+ return self.__data
+
+ def displayMode(self):
+ """Returns the current display mode"""
+ return self.__currentView.modeId()
diff --git a/silx/gui/data/DataViewerFrame.py b/silx/gui/data/DataViewerFrame.py
new file mode 100644
index 0000000..b48fa7b
--- /dev/null
+++ b/silx/gui/data/DataViewerFrame.py
@@ -0,0 +1,186 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module contains a DataViewer with a view selector.
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "10/04/2017"
+
+from silx.gui import qt
+from .DataViewer import DataViewer
+from .DataViewerSelector import DataViewerSelector
+
+
+class DataViewerFrame(qt.QWidget):
+ """
+ A :class:`DataViewer` with a view selector.
+
+ .. image:: img/DataViewerFrame.png
+
+ This widget provides the same API as :class:`DataViewer`. Therefore, for more
+ documentation, take a look at the documentation of the class
+ :class:`DataViewer`.
+
+ .. code-block:: python
+
+ import numpy
+ data = numpy.random.rand(500,500)
+ viewer = DataViewerFrame()
+ viewer.setData(data)
+ viewer.setVisible(True)
+
+ """
+
+ displayedViewChanged = qt.Signal(object)
+ """Emitted when the displayed view changes"""
+
+ dataChanged = qt.Signal()
+ """Emitted when the data changes"""
+
+ def __init__(self, parent=None):
+ """
+ Constructor
+
+ :param qt.QWidget parent:
+ """
+ super(DataViewerFrame, self).__init__(parent)
+
+ class _DataViewer(DataViewer):
+ """Overwrite methods to avoid to create views while the instance
+ is not created. `initializeViews` have to be called manually."""
+
+ def _initializeViews(self):
+ pass
+
+ def initializeViews(self):
+ """Avoid to create views while the instance is not created."""
+ super(_DataViewer, self)._initializeViews()
+
+ self.__dataViewer = _DataViewer(self)
+ # initialize views when `self.__dataViewer` is set
+ self.__dataViewer.initializeViews()
+ self.__dataViewer.setFrameShape(qt.QFrame.StyledPanel)
+ self.__dataViewer.setFrameShadow(qt.QFrame.Sunken)
+ self.__dataViewerSelector = DataViewerSelector(self, self.__dataViewer)
+ self.__dataViewerSelector.setFlat(True)
+
+ layout = qt.QVBoxLayout(self)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setSpacing(0)
+ layout.addWidget(self.__dataViewer, 1)
+ layout.addWidget(self.__dataViewerSelector)
+ self.setLayout(layout)
+
+ self.__dataViewer.dataChanged.connect(self.__dataChanged)
+ self.__dataViewer.displayedViewChanged.connect(self.__displayedViewChanged)
+
+ def __dataChanged(self):
+ """Called when the data is changed"""
+ self.dataChanged.emit()
+
+ def __displayedViewChanged(self, view):
+ """Called when the displayed view changes"""
+ self.displayedViewChanged.emit(view)
+
+ def availableViews(self):
+ """Returns the list of registered views
+
+ :rtype: List[DataView]
+ """
+ return self.__dataViewer.availableViews()
+
+ def currentAvailableViews(self):
+ """Returns the list of available views for the current data
+
+ :rtype: List[DataView]
+ """
+ return self.__dataViewer.currentAvailableViews()
+
+ def createDefaultViews(self, parent=None):
+ """Create and returns available views which can be displayed by default
+ by the data viewer. It is called internally by the widget. It can be
+ overwriten to provide a different set of viewers.
+
+ :param QWidget parent: QWidget parent of the views
+ :rtype: list[silx.gui.data.DataViews.DataView]
+ """
+ return self.__dataViewer.createDefaultViews(parent)
+
+ def addView(self, view):
+ """Allow to add a view to the dataview.
+
+ If the current data support this view, it will be displayed.
+
+ :param DataView view: A dataview
+ """
+ return self.__dataViewer.addView(view)
+
+ def removeView(self, view):
+ """Allow to remove a view which was available from the dataview.
+
+ If the view was displayed, the widget will be updated.
+
+ :param DataView view: A dataview
+ """
+ return self.__dataViewer.removeView(view)
+
+ def setData(self, data):
+ """Set the data to view.
+
+ It mostly can be a h5py.Dataset or a numpy.ndarray. Other kind of
+ objects will be displayed as text rendering.
+
+ :param numpy.ndarray data: The data.
+ """
+ self.__dataViewer.setData(data)
+
+ def data(self):
+ """Returns the data"""
+ return self.__dataViewer.data()
+
+ def setDisplayedView(self, view):
+ self.__dataViewer.setDisplayedView(view)
+
+ def displayedView(self):
+ return self.__dataViewer.displayedView()
+
+ def displayMode(self):
+ return self.__dataViewer.displayMode()
+
+ def setDisplayMode(self, modeId):
+ """Set the displayed view using display mode.
+
+ Change the displayed view according to the requested mode.
+
+ :param int modeId: Display mode, one of
+
+ - `EMPTY_MODE`: display nothing
+ - `PLOT1D_MODE`: display the data as a curve
+ - `PLOT2D_MODE`: display the data as an image
+ - `TEXT_MODE`: display the data as a text
+ - `ARRAY_MODE`: display the data as a table
+ """
+ return self.__dataViewer.setDisplayMode(modeId)
diff --git a/silx/gui/data/DataViewerSelector.py b/silx/gui/data/DataViewerSelector.py
new file mode 100644
index 0000000..32cc636
--- /dev/null
+++ b/silx/gui/data/DataViewerSelector.py
@@ -0,0 +1,153 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module defines a widget to be able to select the available view
+of the DataViewer.
+"""
+from __future__ import division
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "26/01/2017"
+
+import weakref
+import functools
+from silx.gui import qt
+from silx.gui.data.DataViewer import DataViewer
+import silx.utils.weakref
+
+
+class DataViewerSelector(qt.QWidget):
+ """Widget to be able to select a custom view from the DataViewer"""
+
+ def __init__(self, parent=None, dataViewer=None):
+ """Constructor
+
+ :param QWidget parent: The parent of the widget
+ :param DataViewer dataViewer: The connected `DataViewer`
+ """
+ super(DataViewerSelector, self).__init__(parent)
+
+ self.__group = None
+ self.__buttons = {}
+ self.__buttonDummy = None
+ self.__dataViewer = None
+
+ if dataViewer is not None:
+ self.setDataViewer(dataViewer)
+
+ def __updateButtons(self):
+ if self.__group is not None:
+ self.__group.deleteLater()
+ self.__buttons = {}
+ self.__buttonDummy = None
+
+ self.__group = qt.QButtonGroup(self)
+ self.setLayout(qt.QHBoxLayout())
+ self.layout().setContentsMargins(0, 0, 0, 0)
+ if self.__dataViewer is None:
+ return
+
+ iconSize = qt.QSize(16, 16)
+
+ for view in self.__dataViewer.availableViews():
+ label = view.label()
+ icon = view.icon()
+ button = qt.QPushButton(label)
+ button.setIcon(icon)
+ button.setIconSize(iconSize)
+ button.setCheckable(True)
+ # the weak objects are needed to be able to destroy the widget safely
+ weakView = weakref.ref(view)
+ weakMethod = silx.utils.weakref.WeakMethodProxy(self.__setDisplayedView)
+ callback = functools.partial(weakMethod, weakView)
+ button.clicked.connect(callback)
+ self.layout().addWidget(button)
+ self.__group.addButton(button)
+ self.__buttons[view] = button
+
+ button = qt.QPushButton("Dummy")
+ button.setCheckable(True)
+ button.setVisible(False)
+ self.layout().addWidget(button)
+ self.__group.addButton(button)
+ self.__buttonDummy = button
+
+ self.layout().addStretch(1)
+
+ self.__updateButtonsVisibility()
+ self.__displayedViewChanged(self.__dataViewer.displayedView())
+
+ def setDataViewer(self, dataViewer):
+ """Define the dataviewer connected to this status bar
+
+ :param DataViewer dataViewer: The connected `DataViewer`
+ """
+ if self.__dataViewer is dataViewer:
+ return
+ if self.__dataViewer is not None:
+ self.__dataViewer.dataChanged.disconnect(self.__updateButtonsVisibility)
+ self.__dataViewer.displayedViewChanged.disconnect(self.__displayedViewChanged)
+ self.__dataViewer = dataViewer
+ if self.__dataViewer is not None:
+ self.__dataViewer.dataChanged.connect(self.__updateButtonsVisibility)
+ self.__dataViewer.displayedViewChanged.connect(self.__displayedViewChanged)
+ self.__updateButtons()
+
+ def setFlat(self, isFlat):
+ """Set the flat state of all the buttons.
+
+ :param bool isFlat: True to display the buttons flatten.
+ """
+ for b in self.__buttons.values():
+ b.setFlat(isFlat)
+ self.__buttonDummy.setFlat(isFlat)
+
+ def __displayedViewChanged(self, view):
+ """Called on displayed view changeS"""
+ selectedButton = self.__buttons.get(view, self.__buttonDummy)
+ selectedButton.setChecked(True)
+
+ def __setDisplayedView(self, refView, clickEvent=None):
+ """Display a data using the requested view
+
+ :param DataView view: Requested view
+ :param clickEvent: Event sent by the clicked event
+ """
+ if self.__dataViewer is None:
+ return
+ view = refView()
+ if view is None:
+ return
+ self.__dataViewer.setDisplayedView(view)
+
+ def __updateButtonsVisibility(self):
+ """Called on data changed"""
+ if self.__dataViewer is None:
+ for b in self.__buttons.values():
+ b.setVisible(False)
+ else:
+ availableViews = set(self.__dataViewer.currentAvailableViews())
+ for view, button in self.__buttons.items():
+ button.setVisible(view in availableViews)
diff --git a/silx/gui/data/DataViews.py b/silx/gui/data/DataViews.py
new file mode 100644
index 0000000..d8d605a
--- /dev/null
+++ b/silx/gui/data/DataViews.py
@@ -0,0 +1,988 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module defines a views used by :class:`silx.gui.data.DataViewer`.
+"""
+
+import logging
+import numbers
+import numpy
+
+import silx.io
+from silx.gui import qt, icons
+from silx.gui.data.TextFormatter import TextFormatter
+from silx.io import nxdata
+from silx.gui.hdf5 import H5Node
+from silx.io.nxdata import NXdata
+
+__authors__ = ["V. Valls", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "07/04/2017"
+
+_logger = logging.getLogger(__name__)
+
+
+# DataViewer modes
+EMPTY_MODE = 0
+PLOT1D_MODE = 10
+PLOT2D_MODE = 20
+PLOT3D_MODE = 30
+RAW_MODE = 40
+RAW_ARRAY_MODE = 41
+RAW_RECORD_MODE = 42
+RAW_SCALAR_MODE = 43
+STACK_MODE = 50
+HDF5_MODE = 60
+
+
+def _normalizeData(data):
+ """Returns a normalized data.
+
+ If the data embed a numpy data or a dataset it is returned.
+ Else returns the input data."""
+ if isinstance(data, H5Node):
+ return data.h5py_object
+ return data
+
+
+def _normalizeComplex(data):
+ """Returns a normalized complex data.
+
+ If the data is a numpy data with complex, returns the
+ absolute value.
+ Else returns the input data."""
+ if hasattr(data, "dtype"):
+ isComplex = numpy.issubdtype(data.dtype, numpy.complex)
+ else:
+ isComplex = isinstance(data, numbers.Complex)
+ if isComplex:
+ data = numpy.absolute(data)
+ return data
+
+
+class DataInfo(object):
+ """Store extracted information from a data"""
+
+ def __init__(self, data):
+ data = self.normalizeData(data)
+ self.isArray = False
+ self.interpretation = None
+ self.isNumeric = False
+ self.isComplex = False
+ self.isRecord = False
+ self.isNXdata = False
+ self.shape = tuple()
+ self.dim = 0
+
+ if data is None:
+ return
+
+ if silx.io.is_group(data) and nxdata.is_valid_nxdata(data):
+ self.isNXdata = True
+ nxd = nxdata.NXdata(data)
+
+ if isinstance(data, numpy.ndarray):
+ self.isArray = True
+ elif silx.io.is_dataset(data) and data.shape != tuple():
+ self.isArray = True
+ else:
+ self.isArray = False
+
+ if silx.io.is_dataset(data):
+ self.interpretation = data.attrs.get("interpretation", None)
+ elif self.isNXdata:
+ self.interpretation = nxd.interpretation
+ else:
+ self.interpretation = None
+
+ if hasattr(data, "dtype"):
+ self.isNumeric = numpy.issubdtype(data.dtype, numpy.number)
+ self.isRecord = data.dtype.fields is not None
+ self.isComplex = numpy.issubdtype(data.dtype, numpy.complex)
+ elif self.isNXdata:
+ self.isNumeric = numpy.issubdtype(nxd.signal.dtype,
+ numpy.number)
+ self.isComplex = numpy.issubdtype(nxd.signal.dtype, numpy.complex)
+ else:
+ self.isNumeric = isinstance(data, numbers.Number)
+ self.isComplex = isinstance(data, numbers.Complex)
+ self.isRecord = False
+
+ if hasattr(data, "shape"):
+ self.shape = data.shape
+ elif self.isNXdata:
+ self.shape = nxd.signal.shape
+ else:
+ self.shape = tuple()
+ self.dim = len(self.shape)
+
+ def normalizeData(self, data):
+ """Returns a normalized data if the embed a numpy or a dataset.
+ Else returns the data."""
+ return _normalizeData(data)
+
+
+class DataView(object):
+ """Holder for the data view."""
+
+ UNSUPPORTED = -1
+ """Priority returned when the requested data can't be displayed by the
+ view."""
+
+ def __init__(self, parent, modeId=None, icon=None, label=None):
+ """Constructor
+
+ :param qt.QWidget parent: Parent of the hold widget
+ """
+ self.__parent = parent
+ self.__widget = None
+ self.__modeId = modeId
+ if label is None:
+ label = self.__class__.__name__
+ self.__label = label
+ if icon is None:
+ icon = qt.QIcon()
+ self.__icon = icon
+
+ def icon(self):
+ """Returns the default icon"""
+ return self.__icon
+
+ def label(self):
+ """Returns the default label"""
+ return self.__label
+
+ def modeId(self):
+ """Returns the mode id"""
+ return self.__modeId
+
+ def normalizeData(self, data):
+ """Returns a normalized data if the embed a numpy or a dataset.
+ Else returns the data."""
+ return _normalizeData(data)
+
+ def customAxisNames(self):
+ """Returns names of axes which can be custom by the user and provided
+ to the view."""
+ return []
+
+ def setCustomAxisValue(self, name, value):
+ """
+ Set the value of a custom axis
+
+ :param str name: Name of the custom axis
+ :param int value: Value of the custom axis
+ """
+ pass
+
+ def isWidgetInitialized(self):
+ """Returns true if the widget is already initialized.
+ """
+ return self.__widget is not None
+
+ def select(self):
+ """Called when the view is selected to display the data.
+ """
+ return
+
+ def getWidget(self):
+ """Returns the widget hold in the view and displaying the data.
+
+ :returns: qt.QWidget
+ """
+ if self.__widget is None:
+ self.__widget = self.createWidget(self.__parent)
+ return self.__widget
+
+ def createWidget(self, parent):
+ """Create the the widget displaying the data
+
+ :param qt.QWidget parent: Parent of the widget
+ :returns: qt.QWidget
+ """
+ raise NotImplementedError()
+
+ def clear(self):
+ """Clear the data from the view"""
+ return None
+
+ def setData(self, data):
+ """Set the data displayed by the view
+
+ :param data: Data to display
+ :type data: numpy.ndarray or h5py.Dataset
+ """
+ return None
+
+ def axesNames(self, data, info):
+ """Returns names of the expected axes of the view, according to the
+ input data.
+
+ :param data: Data to display
+ :type data: numpy.ndarray or h5py.Dataset
+ :param DataInfo info: Pre-computed information on the data
+ :rtype: list[str]
+ """
+ return []
+
+ def getDataPriority(self, data, info):
+ """
+ Returns the priority of using this view according to a data.
+
+ - `UNSUPPORTED` means this view can't display this data
+ - `1` means this view can display the data
+ - `100` means this view should be used for this data
+ - `1000` max value used by the views provided by silx
+ - ...
+
+ :param object data: The data to check
+ :param DataInfo info: Pre-computed information on the data
+ :rtype: int
+ """
+ return DataView.UNSUPPORTED
+
+ def __lt__(self, other):
+ return str(self) < str(other)
+
+
+class CompositeDataView(DataView):
+ """Data view which can display a data using different view according to
+ the kind of the data."""
+
+ def __init__(self, parent, modeId=None, icon=None, label=None):
+ """Constructor
+
+ :param qt.QWidget parent: Parent of the hold widget
+ """
+ super(CompositeDataView, self).__init__(parent, modeId, icon, label)
+ self.__views = {}
+ self.__currentView = None
+
+ def addView(self, dataView):
+ """Add a new dataview to the available list."""
+ self.__views[dataView] = None
+
+ def getBestView(self, data, info):
+ """Returns the best view according to priorities."""
+ info = DataInfo(data)
+ views = [(v.getDataPriority(data, info), v) for v in self.__views.keys()]
+ views = filter(lambda t: t[0] > DataView.UNSUPPORTED, views)
+ views = sorted(views, reverse=True)
+
+ if len(views) == 0:
+ return None
+ elif views[0][0] == DataView.UNSUPPORTED:
+ return None
+ else:
+ return views[0][1]
+
+ def customAxisNames(self):
+ if self.__currentView is None:
+ return
+ return self.__currentView.customAxisNames()
+
+ def setCustomAxisValue(self, name, value):
+ if self.__currentView is None:
+ return
+ self.__currentView.setCustomAxisValue(name, value)
+
+ def __updateDisplayedView(self):
+ widget = self.getWidget()
+ if self.__currentView is None:
+ return
+
+ # load the widget if it is not yet done
+ index = self.__views[self.__currentView]
+ if index is None:
+ w = self.__currentView.getWidget()
+ index = widget.addWidget(w)
+ self.__views[self.__currentView] = index
+ if widget.currentIndex() != index:
+ widget.setCurrentIndex(index)
+ self.__currentView.select()
+
+ def select(self):
+ self.__updateDisplayedView()
+ if self.__currentView is not None:
+ self.__currentView.select()
+
+ def createWidget(self, parent):
+ return qt.QStackedWidget()
+
+ def clear(self):
+ for v in self.__views.keys():
+ v.clear()
+
+ def setData(self, data):
+ if self.__currentView is None:
+ return
+ self.__updateDisplayedView()
+ self.__currentView.setData(data)
+
+ def axesNames(self, data, info):
+ view = self.getBestView(data, info)
+ self.__currentView = view
+ return view.axesNames(data, info)
+
+ def getDataPriority(self, data, info):
+ view = self.getBestView(data, info)
+ self.__currentView = view
+ if view is None:
+ return DataView.UNSUPPORTED
+ else:
+ return view.getDataPriority(data, info)
+
+
+class _EmptyView(DataView):
+ """Dummy view to display nothing"""
+
+ def __init__(self, parent):
+ DataView.__init__(self, parent, modeId=EMPTY_MODE)
+
+ def axesNames(self, data, info):
+ return []
+
+ def createWidget(self, parent):
+ return qt.QLabel(parent)
+
+ def getDataPriority(self, data, info):
+ return DataView.UNSUPPORTED
+
+
+class _Plot1dView(DataView):
+ """View displaying data using a 1d plot"""
+
+ def __init__(self, parent):
+ super(_Plot1dView, self).__init__(
+ parent=parent,
+ modeId=PLOT1D_MODE,
+ label="Curve",
+ icon=icons.getQIcon("view-1d"))
+ self.__resetZoomNextTime = True
+
+ def createWidget(self, parent):
+ from silx.gui import plot
+ return plot.Plot1D(parent=parent)
+
+ def clear(self):
+ self.getWidget().clear()
+ self.__resetZoomNextTime = True
+
+ def normalizeData(self, data):
+ data = DataView.normalizeData(self, data)
+ data = _normalizeComplex(data)
+ return data
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ self.getWidget().addCurve(legend="data",
+ x=range(len(data)),
+ y=data,
+ resetzoom=self.__resetZoomNextTime)
+ self.__resetZoomNextTime = True
+
+ def axesNames(self, data, info):
+ return ["y"]
+
+ def getDataPriority(self, data, info):
+ if data is None or not info.isArray or not info.isNumeric:
+ return DataView.UNSUPPORTED
+ if info.dim < 1:
+ return DataView.UNSUPPORTED
+ if info.interpretation == "spectrum":
+ return 1000
+ if info.dim == 2 and info.shape[0] == 1:
+ return 210
+ if info.dim == 1:
+ return 100
+ else:
+ return 10
+
+
+class _Plot2dView(DataView):
+ """View displaying data using a 2d plot"""
+
+ def __init__(self, parent):
+ super(_Plot2dView, self).__init__(
+ parent=parent,
+ modeId=PLOT2D_MODE,
+ label="Image",
+ icon=icons.getQIcon("view-2d"))
+ self.__resetZoomNextTime = True
+
+ def createWidget(self, parent):
+ from silx.gui import plot
+ widget = plot.Plot2D(parent=parent)
+ widget.setKeepDataAspectRatio(True)
+ widget.setGraphXLabel('X')
+ widget.setGraphYLabel('Y')
+ return widget
+
+ def clear(self):
+ self.getWidget().clear()
+ self.__resetZoomNextTime = True
+
+ def normalizeData(self, data):
+ data = DataView.normalizeData(self, data)
+ data = _normalizeComplex(data)
+ return data
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ self.getWidget().addImage(legend="data",
+ data=data,
+ resetzoom=self.__resetZoomNextTime)
+ self.__resetZoomNextTime = False
+
+ def axesNames(self, data, info):
+ return ["y", "x"]
+
+ def getDataPriority(self, data, info):
+ if data is None or not info.isArray or not info.isNumeric:
+ return DataView.UNSUPPORTED
+ if info.dim < 2:
+ return DataView.UNSUPPORTED
+ if info.interpretation == "image":
+ return 1000
+ if info.dim == 2:
+ return 200
+ else:
+ return 190
+
+
+class _Plot3dView(DataView):
+ """View displaying data using a 3d plot"""
+
+ def __init__(self, parent):
+ super(_Plot3dView, self).__init__(
+ parent=parent,
+ modeId=PLOT3D_MODE,
+ label="Cube",
+ icon=icons.getQIcon("view-3d"))
+ try:
+ import silx.gui.plot3d #noqa
+ except ImportError:
+ _logger.warning("Plot3dView is not available")
+ _logger.debug("Backtrace", exc_info=True)
+ raise
+ self.__resetZoomNextTime = True
+
+ def createWidget(self, parent):
+ from silx.gui.plot3d import ScalarFieldView
+ from silx.gui.plot3d import SFViewParamTree
+
+ plot = ScalarFieldView.ScalarFieldView(parent)
+ plot.setAxesLabels(*reversed(self.axesNames(None, None)))
+ plot.addIsosurface(
+ lambda data: numpy.mean(data) + numpy.std(data), '#FF0000FF')
+
+ # Create a parameter tree for the scalar field view
+ options = SFViewParamTree.TreeView(plot)
+ options.setSfView(plot)
+
+ # Add the parameter tree to the main window in a dock widget
+ dock = qt.QDockWidget()
+ dock.setWidget(options)
+ plot.addDockWidget(qt.Qt.RightDockWidgetArea, dock)
+
+ return plot
+
+ def clear(self):
+ self.getWidget().setData(None)
+ self.__resetZoomNextTime = True
+
+ def normalizeData(self, data):
+ data = DataView.normalizeData(self, data)
+ data = _normalizeComplex(data)
+ return data
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ plot = self.getWidget()
+ plot.setData(data)
+ self.__resetZoomNextTime = False
+
+ def axesNames(self, data, info):
+ return ["z", "y", "x"]
+
+ def getDataPriority(self, data, info):
+ if data is None or not info.isArray or not info.isNumeric:
+ return DataView.UNSUPPORTED
+ if info.dim < 3:
+ return DataView.UNSUPPORTED
+ if min(data.shape) < 2:
+ return DataView.UNSUPPORTED
+ if info.dim == 3:
+ return 100
+ else:
+ return 10
+
+
+class _ArrayView(DataView):
+ """View displaying data using a 2d table"""
+
+ def __init__(self, parent):
+ DataView.__init__(self, parent, modeId=RAW_ARRAY_MODE)
+
+ def createWidget(self, parent):
+ from silx.gui.data.ArrayTableWidget import ArrayTableWidget
+ widget = ArrayTableWidget(parent)
+ widget.displayAxesSelector(False)
+ return widget
+
+ def clear(self):
+ self.getWidget().setArrayData(numpy.array([[]]))
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ self.getWidget().setArrayData(data)
+
+ def axesNames(self, data, info):
+ return ["col", "row"]
+
+ def getDataPriority(self, data, info):
+ if data is None or not info.isArray or info.isRecord:
+ return DataView.UNSUPPORTED
+ if info.dim < 2:
+ return DataView.UNSUPPORTED
+ if info.interpretation in ["scalar", "scaler"]:
+ return 1000
+ return 500
+
+
+class _StackView(DataView):
+ """View displaying data using a stack of images"""
+
+ def __init__(self, parent):
+ super(_StackView, self).__init__(
+ parent=parent,
+ modeId=STACK_MODE,
+ label="Image stack",
+ icon=icons.getQIcon("view-2d-stack"))
+ self.__resetZoomNextTime = True
+
+ def customAxisNames(self):
+ return ["depth"]
+
+ def setCustomAxisValue(self, name, value):
+ if name == "depth":
+ self.getWidget().setFrameNumber(value)
+ else:
+ raise Exception("Unsupported axis")
+
+ def createWidget(self, parent):
+ from silx.gui import plot
+ widget = plot.StackView(parent=parent)
+ widget.setKeepDataAspectRatio(True)
+ widget.setLabels(self.axesNames(None, None))
+ # hide default option panel
+ widget.setOptionVisible(False)
+ return widget
+
+ def clear(self):
+ self.getWidget().clear()
+ self.__resetZoomNextTime = True
+
+ def normalizeData(self, data):
+ data = DataView.normalizeData(self, data)
+ data = _normalizeComplex(data)
+ return data
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ self.getWidget().setStack(stack=data, reset=self.__resetZoomNextTime)
+ self.__resetZoomNextTime = False
+
+ def axesNames(self, data, info):
+ return ["depth", "y", "x"]
+
+ def getDataPriority(self, data, info):
+ if data is None or not info.isArray or not info.isNumeric:
+ return DataView.UNSUPPORTED
+ if info.dim < 3:
+ return DataView.UNSUPPORTED
+ if info.interpretation == "image":
+ return 500
+ return 90
+
+
+class _ScalarView(DataView):
+ """View displaying data using text"""
+
+ def __init__(self, parent):
+ DataView.__init__(self, parent, modeId=RAW_SCALAR_MODE)
+
+ def createWidget(self, parent):
+ widget = qt.QTextEdit(parent)
+ widget.setTextInteractionFlags(qt.Qt.TextSelectableByMouse)
+ widget.setAlignment(qt.Qt.AlignLeft | qt.Qt.AlignTop)
+ self.__formatter = TextFormatter(parent)
+ return widget
+
+ def clear(self):
+ self.getWidget().setText("")
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ if silx.io.is_dataset(data):
+ data = data[()]
+ text = self.__formatter.toString(data)
+ self.getWidget().setText(text)
+
+ def axesNames(self, data, info):
+ return []
+
+ def getDataPriority(self, data, info):
+ data = self.normalizeData(data)
+ if data is None:
+ return DataView.UNSUPPORTED
+ if silx.io.is_group(data):
+ return DataView.UNSUPPORTED
+ return 2
+
+
+class _RecordView(DataView):
+ """View displaying data using text"""
+
+ def __init__(self, parent):
+ DataView.__init__(self, parent, modeId=RAW_RECORD_MODE)
+
+ def createWidget(self, parent):
+ from .RecordTableView import RecordTableView
+ widget = RecordTableView(parent)
+ widget.setWordWrap(False)
+ return widget
+
+ def clear(self):
+ self.getWidget().setArrayData(None)
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ widget = self.getWidget()
+ widget.setArrayData(data)
+ widget.resizeRowsToContents()
+ widget.resizeColumnsToContents()
+
+ def axesNames(self, data, info):
+ return ["data"]
+
+ def getDataPriority(self, data, info):
+ if info.isRecord:
+ return 40
+ if data is None or not info.isArray:
+ return DataView.UNSUPPORTED
+ if info.dim == 1:
+ if info.interpretation in ["scalar", "scaler"]:
+ return 1000
+ if info.shape[0] == 1:
+ return 510
+ return 500
+ elif info.isRecord:
+ return 40
+ return DataView.UNSUPPORTED
+
+
+class _Hdf5View(DataView):
+ """View displaying data using text"""
+
+ def __init__(self, parent):
+ super(_Hdf5View, self).__init__(
+ parent=parent,
+ modeId=HDF5_MODE,
+ label="HDF5",
+ icon=icons.getQIcon("view-hdf5"))
+
+ def createWidget(self, parent):
+ from .Hdf5TableView import Hdf5TableView
+ widget = Hdf5TableView(parent)
+ return widget
+
+ def clear(self):
+ widget = self.getWidget()
+ widget.setData(None)
+
+ def setData(self, data):
+ widget = self.getWidget()
+ widget.setData(data)
+
+ def axesNames(self, data, info):
+ return []
+
+ def getDataPriority(self, data, info):
+ widget = self.getWidget()
+ if widget.isSupportedData(data):
+ return 1
+ else:
+ return DataView.UNSUPPORTED
+
+
+class _RawView(CompositeDataView):
+ """View displaying data as raw data.
+
+ This implementation use a 2d-array view, or a record array view, or a
+ raw text output.
+ """
+
+ def __init__(self, parent):
+ super(_RawView, self).__init__(
+ parent=parent,
+ modeId=RAW_MODE,
+ label="Raw",
+ icon=icons.getQIcon("view-raw"))
+ self.addView(_ScalarView(parent))
+ self.addView(_ArrayView(parent))
+ self.addView(_RecordView(parent))
+
+
+class _NXdataScalarView(DataView):
+ """DataView using a table view for displaying NXdata scalars:
+ 0-D signal or n-D signal with *@interpretation=scalar*"""
+ def __init__(self, parent):
+ DataView.__init__(self, parent)
+
+ def createWidget(self, parent):
+ from silx.gui.data.ArrayTableWidget import ArrayTableWidget
+ widget = ArrayTableWidget(parent)
+ # widget.displayAxesSelector(False)
+ return widget
+
+ def axesNames(self, data, info):
+ return ["col", "row"]
+
+ def clear(self):
+ self.getWidget().setArrayData(numpy.array([[]]),
+ labels=True)
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ signal = NXdata(data).signal
+ self.getWidget().setArrayData(signal,
+ labels=True)
+
+ def getDataPriority(self, data, info):
+ data = self.normalizeData(data)
+ if info.isNXdata:
+ nxd = NXdata(data)
+ if nxd.signal_is_0d or nxd.interpretation in ["scalar", "scaler"]:
+ return 100
+ return DataView.UNSUPPORTED
+
+
+class _NXdataCurveView(DataView):
+ """DataView using a Plot1D for displaying NXdata curves:
+ 1-D signal or n-D signal with *@interpretation=spectrum*.
+
+ It also handles basic scatter plots:
+ a 1-D signal with one axis whose values are not monotonically increasing.
+ """
+ def __init__(self, parent):
+ DataView.__init__(self, parent)
+
+ def createWidget(self, parent):
+ from silx.gui.data.NXdataWidgets import ArrayCurvePlot
+ widget = ArrayCurvePlot(parent)
+ return widget
+
+ def axesNames(self, data, info):
+ # disabled (used by default axis selector widget in Hdf5Viewer)
+ return []
+
+ def clear(self):
+ self.getWidget().clear()
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ nxd = NXdata(data)
+ signal_name = data.attrs["signal"]
+ group_name = data.name
+ if nxd.axes_names[-1] is not None:
+ x_errors = nxd.get_axis_errors(nxd.axes_names[-1])
+ else:
+ x_errors = None
+
+ self.getWidget().setCurveData(nxd.signal, nxd.axes[-1],
+ yerror=nxd.errors, xerror=x_errors,
+ ylabel=signal_name, xlabel=nxd.axes_names[-1],
+ title="NXdata group " + group_name)
+
+ def getDataPriority(self, data, info):
+ data = self.normalizeData(data)
+ if info.isNXdata:
+ nxd = NXdata(data)
+ if nxd.is_x_y_value_scatter or nxd.is_unsupported_scatter:
+ return DataView.UNSUPPORTED
+ if nxd.signal_is_1d and \
+ not nxd.interpretation in ["scalar", "scaler"]:
+ return 100
+ if nxd.interpretation == "spectrum":
+ return 100
+ return DataView.UNSUPPORTED
+
+
+class _NXdataXYVScatterView(DataView):
+ """DataView using a Plot1D for displaying NXdata 3D scatters as
+ a scatter of coloured points (1-D signal with 2 axes)"""
+ def __init__(self, parent):
+ DataView.__init__(self, parent)
+
+ def createWidget(self, parent):
+ from silx.gui.data.NXdataWidgets import ArrayCurvePlot
+ widget = ArrayCurvePlot(parent)
+ return widget
+
+ def axesNames(self, data, info):
+ # disabled (used by default axis selector widget in Hdf5Viewer)
+ return []
+
+ def clear(self):
+ self.getWidget().clear()
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ nxd = NXdata(data)
+ signal_name = data.attrs["signal"]
+ # signal_errors = nx.errors # not supported
+ group_name = data.name
+ x_axis, y_axis = nxd.axes[-2:]
+
+ x_label, y_label = nxd.axes_names[-2:]
+ if x_label is not None:
+ x_errors = nxd.get_axis_errors(x_label)
+ else:
+ x_errors = None
+
+ if y_label is not None:
+ y_errors = nxd.get_axis_errors(y_label)
+ else:
+ y_errors = None
+
+ self.getWidget().setCurveData(y_axis, x_axis, values=nxd.signal,
+ yerror=y_errors, xerror=x_errors,
+ ylabel=signal_name, xlabel=x_label,
+ title="NXdata group " + group_name)
+
+ def getDataPriority(self, data, info):
+ data = self.normalizeData(data)
+ if info.isNXdata:
+ if NXdata(data).is_x_y_value_scatter:
+ return 100
+ return DataView.UNSUPPORTED
+
+
+class _NXdataImageView(DataView):
+ """DataView using a Plot2D for displaying NXdata images:
+ 2-D signal or n-D signals with *@interpretation=spectrum*."""
+ def __init__(self, parent):
+ DataView.__init__(self, parent)
+
+ def createWidget(self, parent):
+ from silx.gui.data.NXdataWidgets import ArrayImagePlot
+ widget = ArrayImagePlot(parent)
+ return widget
+
+ def axesNames(self, data, info):
+ return []
+
+ def clear(self):
+ self.getWidget().clear()
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ nxd = NXdata(data)
+ signal_name = data.attrs["signal"]
+ group_name = data.name
+ y_axis, x_axis = nxd.axes[-2:]
+ y_label, x_label = nxd.axes_names[-2:]
+
+ self.getWidget().setImageData(
+ nxd.signal, x_axis=x_axis, y_axis=y_axis,
+ signal_name=signal_name, xlabel=x_label, ylabel=y_label,
+ title="NXdata group %s: %s" % (group_name, signal_name))
+
+ def getDataPriority(self, data, info):
+ data = self.normalizeData(data)
+ if info.isNXdata:
+ nxd = NXdata(data)
+ if nxd.signal_is_2d:
+ if nxd.interpretation not in ["scalar", "spectrum", "scaler"]:
+ return 100
+ if nxd.interpretation == "image":
+ return 100
+ return DataView.UNSUPPORTED
+
+
+class _NXdataStackView(DataView):
+ def __init__(self, parent):
+ DataView.__init__(self, parent)
+
+ def createWidget(self, parent):
+ from silx.gui.data.NXdataWidgets import ArrayStackPlot
+ widget = ArrayStackPlot(parent)
+ return widget
+
+ def axesNames(self, data, info):
+ return []
+
+ def clear(self):
+ self.getWidget().clear()
+
+ def setData(self, data):
+ data = self.normalizeData(data)
+ nxd = NXdata(data)
+ signal_name = data.attrs["signal"]
+ group_name = data.name
+ z_axis, y_axis, x_axis = nxd.axes[-3:]
+ z_label, y_label, x_label = nxd.axes_names[-3:]
+
+ self.getWidget().setStackData(
+ nxd.signal, x_axis=x_axis, y_axis=y_axis, z_axis=z_axis,
+ signal_name=signal_name,
+ xlabel=x_label, ylabel=y_label, zlabel=z_label,
+ title="NXdata group %s: %s" % (group_name, signal_name))
+
+ def getDataPriority(self, data, info):
+ data = self.normalizeData(data)
+ if info.isNXdata:
+ nxd = NXdata(data)
+ if nxd.signal_ndim >= 3:
+ if nxd.interpretation not in ["scalar", "scaler",
+ "spectrum", "image"]:
+ return 100
+ return DataView.UNSUPPORTED
+
+
+class _NXdataView(CompositeDataView):
+ """Composite view displaying NXdata groups using the most adequate
+ widget depending on the dimensionality."""
+ def __init__(self, parent):
+ super(_NXdataView, self).__init__(
+ parent=parent,
+ label="NXdata",
+ icon=icons.getQIcon("view-nexus"))
+
+ self.addView(_NXdataScalarView(parent))
+ self.addView(_NXdataCurveView(parent))
+ self.addView(_NXdataXYVScatterView(parent))
+ self.addView(_NXdataImageView(parent))
+ self.addView(_NXdataStackView(parent))
diff --git a/silx/gui/data/Hdf5TableView.py b/silx/gui/data/Hdf5TableView.py
new file mode 100644
index 0000000..5d79907
--- /dev/null
+++ b/silx/gui/data/Hdf5TableView.py
@@ -0,0 +1,414 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""
+This module define model and widget to display 1D slices from numpy
+array using compound data types or hdf5 databases.
+"""
+from __future__ import division
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "07/04/2017"
+
+import functools
+import os.path
+import logging
+from silx.gui import qt
+import silx.io
+from .TextFormatter import TextFormatter
+import silx.gui.hdf5
+from silx.gui.widgets import HierarchicalTableView
+
+_logger = logging.getLogger(__name__)
+
+
+class _CellData(object):
+ """Store a table item
+ """
+ def __init__(self, value=None, isHeader=False, span=None):
+ """
+ Constructor
+
+ :param str value: Label of this property
+ :param bool isHeader: True if the cell is an header
+ :param tuple span: Tuple of row, column span
+ """
+ self.__value = value
+ self.__isHeader = isHeader
+ self.__span = span
+
+ def isHeader(self):
+ """Returns true if the property is a sub-header title.
+
+ :rtype: bool
+ """
+ return self.__isHeader
+
+ def value(self):
+ """Returns the value of the item.
+ """
+ return self.__value
+
+ def span(self):
+ """Returns the span size of the cell.
+
+ :rtype: tuple
+ """
+ return self.__span
+
+
+class _TableData(object):
+ """Modelize a table with header, row and column span.
+
+ It is mostly defined as a row based table.
+ """
+
+ def __init__(self, columnCount):
+ """Constructor.
+
+ :param int columnCount: Define the number of column of the table
+ """
+ self.__colCount = columnCount
+ self.__data = []
+
+ def rowCount(self):
+ """Returns the number of rows.
+
+ :rtype: int
+ """
+ return len(self.__data)
+
+ def columnCount(self):
+ """Returns the number of columns.
+
+ :rtype: int
+ """
+ return self.__colCount
+
+ def clear(self):
+ """Remove all the cells of the table"""
+ self.__data = []
+
+ def cellAt(self, row, column):
+ """Returns the cell at the row column location. Else None if there is
+ nothing.
+
+ :rtype: _CellData
+ """
+ if row < 0:
+ return None
+ if column < 0:
+ return None
+ if row >= len(self.__data):
+ return None
+ cells = self.__data[row]
+ if column >= len(cells):
+ return None
+ return cells[column]
+
+ def addHeaderRow(self, headerLabel):
+ """Append the table with header on the full row.
+
+ :param str headerLabel: label of the header.
+ """
+ item = _CellData(value=headerLabel, isHeader=True, span=(1, self.__colCount))
+ self.__data.append([item])
+
+ def addHeaderValueRow(self, headerLabel, value):
+ """Append the table with a row using the first column as an header and
+ other cells as a single cell for the value.
+
+ :param str headerLabel: label of the header.
+ :param object value: value to store.
+ """
+ header = _CellData(value=headerLabel, isHeader=True)
+ value = _CellData(value=value, span=(1, self.__colCount))
+ self.__data.append([header, value])
+
+ def addRow(self, *args):
+ """Append the table with a row using arguments for each cells
+
+ :param list[object] args: List of cell values for the row
+ """
+ row = []
+ for value in args:
+ if not isinstance(value, _CellData):
+ value = _CellData(value=value)
+ row.append(value)
+ self.__data.append(row)
+
+
+class Hdf5TableModel(HierarchicalTableView.HierarchicalTableModel):
+ """This data model provides access to HDF5 node content (File, Group,
+ Dataset). Main info, like name, file, attributes... are displayed
+ """
+
+ def __init__(self, parent=None, data=None):
+ """
+ Constructor
+
+ :param qt.QObject parent: Parent object
+ :param object data: An h5py-like object (file, group or dataset)
+ """
+ super(Hdf5TableModel, self).__init__(parent)
+
+ self.__obj = None
+ self.__data = _TableData(columnCount=4)
+ self.__formatter = None
+ formatter = TextFormatter(self)
+ self.setFormatter(formatter)
+ self.setObject(data)
+
+ def rowCount(self, parent_idx=None):
+ """Returns number of rows to be displayed in table"""
+ return self.__data.rowCount()
+
+ def columnCount(self, parent_idx=None):
+ """Returns number of columns to be displayed in table"""
+ return self.__data.columnCount()
+
+ def data(self, index, role=qt.Qt.DisplayRole):
+ """QAbstractTableModel method to access data values
+ in the format ready to be displayed"""
+ if not index.isValid():
+ return None
+
+ cell = self.__data.cellAt(index.row(), index.column())
+ if cell is None:
+ return None
+
+ if role == self.SpanRole:
+ return cell.span()
+ elif role == self.IsHeaderRole:
+ return cell.isHeader()
+ elif role == qt.Qt.DisplayRole:
+ value = cell.value()
+ if callable(value):
+ value = value(self.__obj)
+ return str(value)
+ return None
+
+ def flags(self, index):
+ """QAbstractTableModel method to inform the view whether data
+ is editable or not.
+ """
+ return qt.QAbstractTableModel.flags(self, index)
+
+ def isSupportedObject(self, h5pyObject):
+ """
+ Returns true if the provided object can be modelized using this model.
+ """
+ isSupported = False
+ isSupported = isSupported or silx.io.is_group(h5pyObject)
+ isSupported = isSupported or silx.io.is_dataset(h5pyObject)
+ isSupported = isSupported or isinstance(h5pyObject, silx.gui.hdf5.H5Node)
+ return isSupported
+
+ def setObject(self, h5pyObject):
+ """Set the h5py-like object exposed by the model
+
+ :param h5pyObject: A h5py-like object. It can be a `h5py.Dataset`,
+ a `h5py.File`, a `h5py.Group`. It also can be a,
+ `silx.gui.hdf5.H5Node` which is needed to display some local path
+ information.
+ """
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+
+ if h5pyObject is None or self.isSupportedObject(h5pyObject):
+ self.__obj = h5pyObject
+ else:
+ _logger.warning("Object class %s unsupported. Object ignored.", type(h5pyObject))
+ self.__initProperties()
+
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+ else:
+ self.reset()
+
+ def __initProperties(self):
+ """Initialize the list of available properties according to the defined
+ h5py-like object."""
+ self.__data.clear()
+ if self.__obj is None:
+ return
+
+ obj = self.__obj
+
+ hdf5obj = obj
+ if isinstance(obj, silx.gui.hdf5.H5Node):
+ hdf5obj = obj.h5py_object
+
+ if silx.io.is_file(hdf5obj):
+ objectType = "File"
+ elif silx.io.is_group(hdf5obj):
+ objectType = "Group"
+ elif silx.io.is_dataset(hdf5obj):
+ objectType = "Dataset"
+ else:
+ objectType = obj.__class__.__name__
+ self.__data.addHeaderRow(headerLabel="HDF5 %s" % objectType)
+ self.__data.addHeaderRow(headerLabel="Path info")
+
+ self.__data.addHeaderValueRow("basename", lambda x: os.path.basename(x.name))
+ self.__data.addHeaderValueRow("name", lambda x: x.name)
+ if silx.io.is_file(obj):
+ self.__data.addHeaderValueRow("filename", lambda x: x.filename)
+
+ if isinstance(obj, silx.gui.hdf5.H5Node):
+ # helpful informations if the object come from an HDF5 tree
+ self.__data.addHeaderValueRow("local_basename", lambda x: x.local_basename)
+ self.__data.addHeaderValueRow("local_name", lambda x: x.local_name)
+ self.__data.addHeaderValueRow("local_filename", lambda x: x.local_file.filename)
+
+ if hasattr(obj, "dtype"):
+ self.__data.addHeaderRow(headerLabel="Data info")
+ self.__data.addHeaderValueRow("dtype", lambda x: x.dtype)
+ if hasattr(obj, "shape"):
+ self.__data.addHeaderValueRow("shape", lambda x: x.shape)
+ if hasattr(obj, "size"):
+ self.__data.addHeaderValueRow("size", lambda x: x.size)
+ if hasattr(obj, "chunks") and obj.chunks is not None:
+ self.__data.addHeaderValueRow("chunks", lambda x: x.chunks)
+
+ # relative to compression
+ # h5py expose compression, compression_opts but are not initialized
+ # for external plugins, then we use id
+ # h5py also expose fletcher32 and shuffle attributes, but it is also
+ # part of the filters
+ if hasattr(obj, "shape") and hasattr(obj, "id"):
+ dcpl = obj.id.get_create_plist()
+ if dcpl.get_nfilters() > 0:
+ self.__data.addHeaderRow(headerLabel="Compression info")
+ pos = _CellData(value="Position", isHeader=True)
+ hdf5id = _CellData(value="HDF5 ID", isHeader=True)
+ name = _CellData(value="Name", isHeader=True)
+ options = _CellData(value="Options", isHeader=True)
+ self.__data.addRow(pos, hdf5id, name, options)
+ for index in range(dcpl.get_nfilters()):
+ callback = lambda index, dataIndex, x: self.__get_filter_info(x, index)[dataIndex]
+ pos = _CellData(value=functools.partial(callback, index, 0))
+ hdf5id = _CellData(value=functools.partial(callback, index, 1))
+ name = _CellData(value=functools.partial(callback, index, 2))
+ options = _CellData(value=functools.partial(callback, index, 3))
+ self.__data.addRow(pos, hdf5id, name, options)
+
+ if hasattr(obj, "attrs"):
+ if len(obj.attrs) > 0:
+ self.__data.addHeaderRow(headerLabel="Attributes")
+ for key in sorted(obj.attrs.keys()):
+ callback = lambda key, x: self.__formatter.toString(x.attrs[key])
+ self.__data.addHeaderValueRow(headerLabel=key, value=functools.partial(callback, key))
+
+ def __get_filter_info(self, dataset, filterIndex):
+ """Get a tuple of readable info from dataset filters
+
+ :param h5py.Dataset dataset: A h5py dataset
+ :param int filterId:
+ """
+ try:
+ dcpl = dataset.id.get_create_plist()
+ info = dcpl.get_filter(filterIndex)
+ filterId, _flags, cdValues, name = info
+ name = self.__formatter.toString(name)
+ options = " ".join([self.__formatter.toString(i) for i in cdValues])
+ return (filterIndex, filterId, name, options)
+ except Exception:
+ _logger.debug("Backtrace", exc_info=True)
+ return [filterIndex, None, None, None]
+
+ def object(self):
+ """Returns the internal object modelized.
+
+ :rtype: An h5py-like object
+ """
+ return self.__obj
+
+ def setFormatter(self, formatter):
+ """Set the formatter object to be used to display data from the model
+
+ :param TextFormatter formatter: Formatter to use
+ """
+ if formatter is self.__formatter:
+ return
+
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+
+ if self.__formatter is not None:
+ self.__formatter.formatChanged.disconnect(self.__formatChanged)
+
+ self.__formatter = formatter
+ if self.__formatter is not None:
+ self.__formatter.formatChanged.connect(self.__formatChanged)
+
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+ else:
+ self.reset()
+
+ def getFormatter(self):
+ """Returns the text formatter used.
+
+ :rtype: TextFormatter
+ """
+ return self.__formatter
+
+ def __formatChanged(self):
+ """Called when the format changed.
+ """
+ self.reset()
+
+
+class Hdf5TableView(HierarchicalTableView.HierarchicalTableView):
+ """A widget to display metadata about a HDF5 node using a table."""
+
+ def __init__(self, parent=None):
+ super(Hdf5TableView, self).__init__(parent)
+ self.setModel(Hdf5TableModel(self))
+
+ def isSupportedData(self, data):
+ """
+ Returns true if the provided object can be modelized using this model.
+ """
+ return self.model().isSupportedObject(data)
+
+ def setData(self, data):
+ """Set the h5py-like object exposed by the model
+
+ :param h5pyObject: A h5py-like object. It can be a `h5py.Dataset`,
+ a `h5py.File`, a `h5py.Group`. It also can be a,
+ `silx.gui.hdf5.H5Node` which is needed to display some local path
+ information.
+ """
+ self.model().setObject(data)
+ header = self.horizontalHeader()
+ if qt.qVersion() < "5.0":
+ setResizeMode = header.setResizeMode
+ else:
+ setResizeMode = header.setSectionResizeMode
+ setResizeMode(0, qt.QHeaderView.Fixed)
+ setResizeMode(1, qt.QHeaderView.Stretch)
+ header.setStretchLastSection(True)
diff --git a/silx/gui/data/NXdataWidgets.py b/silx/gui/data/NXdataWidgets.py
new file mode 100644
index 0000000..343c7f9
--- /dev/null
+++ b/silx/gui/data/NXdataWidgets.py
@@ -0,0 +1,523 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module defines widgets used by _NXdataView.
+"""
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "20/03/2017"
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.data.NumpyAxesSelector import NumpyAxesSelector
+from silx.gui.plot import Plot1D, Plot2D, StackView
+
+from silx.math.calibration import ArrayCalibration, NoCalibration, LinearCalibration
+
+
+class ArrayCurvePlot(qt.QWidget):
+ """
+ Widget for plotting a curve from a multi-dimensional signal array
+ and a 1D axis array.
+
+ The signal array can have an arbitrary number of dimensions, the only
+ limitation being that the last dimension must have the same length as
+ the axis array.
+
+ The widget provides sliders to select indices on the first (n - 1)
+ dimensions of the signal array, and buttons to add/replace selected
+ curves to the plot.
+
+ This widget also handles simple 2D or 3D scatter plots (third dimension
+ displayed as colour of points).
+ """
+ def __init__(self, parent=None):
+ """
+
+ :param parent: Parent QWidget
+ """
+ super(ArrayCurvePlot, self).__init__(parent)
+
+ self.__signal = None
+ self.__signal_name = None
+ self.__signal_errors = None
+ self.__axis = None
+ self.__axis_name = None
+ self.__axis_errors = None
+ self.__values = None
+
+ self.__first_curve_added = False
+
+ self._plot = Plot1D(self)
+ self._plot.setDefaultColormap( # for scatters
+ {"name": "viridis",
+ "vmin": 0., "vmax": 1., # ignored (autoscale) but mandatory
+ "normalization": "linear",
+ "autoscale": True})
+
+ self.selectorDock = qt.QDockWidget("Data selector", self._plot)
+ # not closable
+ self.selectorDock.setFeatures(qt.QDockWidget.DockWidgetMovable |
+ qt.QDockWidget.DockWidgetFloatable)
+ self._selector = NumpyAxesSelector(self.selectorDock)
+ self._selector.setNamedAxesSelectorVisibility(False)
+ self.__selector_is_connected = False
+ self.selectorDock.setWidget(self._selector)
+ self._plot.addTabbedDockWidget(self.selectorDock)
+
+ layout = qt.QGridLayout()
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.addWidget(self._plot, 0, 0)
+
+ self.setLayout(layout)
+
+ def setCurveData(self, y, x=None, values=None,
+ yerror=None, xerror=None,
+ ylabel=None, xlabel=None, title=None):
+ """
+
+ :param y: dataset to be represented by the y (vertical) axis.
+ For a scatter, this must be a 1D array and x and values must be
+ 1-D arrays of the same size.
+ In other cases, it can be a n-D array whose last dimension must
+ have the same length as x (and values must be None)
+ :param x: 1-D dataset used as the curve's x values. If provided,
+ its lengths must be equal to the length of the last dimension of
+ ``y`` (and equal to the length of ``value``, for a scatter plot).
+ :param values: Values, to be provided for a x-y-value scatter plot.
+ This will be used to compute the color map and assign colors
+ to the points.
+ :param yerror: 1-D dataset of errors for y, or None
+ :param xerror: 1-D dataset of errors for x, or None
+ :param ylabel: Label for Y axis
+ :param xlabel: Label for X axis
+ :param title: Graph title
+ """
+ self.__signal = y
+ self.__signal_name = ylabel
+ self.__signal_errors = yerror
+ self.__axis = x
+ self.__axis_name = xlabel
+ self.__axis_errors = xerror
+ self.__values = values
+
+ if self.__selector_is_connected:
+ self._selector.selectionChanged.disconnect(self._updateCurve)
+ self.__selector_is_connected = False
+ self._selector.setData(y)
+ self._selector.setAxisNames([ylabel or "Y"])
+
+ if len(y.shape) < 2:
+ self.selectorDock.hide()
+ else:
+ self.selectorDock.show()
+
+ self._plot.setGraphTitle(title or "")
+ self._plot.setGraphXLabel(self.__axis_name or "X")
+ self._plot.setGraphYLabel(self.__signal_name or "Y")
+ self._updateCurve()
+
+ if not self.__selector_is_connected:
+ self._selector.selectionChanged.connect(self._updateCurve)
+ self.__selector_is_connected = True
+
+ def _updateCurve(self):
+ y = self._selector.selectedData()
+ x = self.__axis
+ if x is None:
+ x = numpy.arange(len(y))
+ elif numpy.isscalar(x) or len(x) == 1:
+ # constant axis
+ x = x * numpy.ones_like(y)
+ elif len(x) == 2 and len(y) != 2:
+ # linear calibration a + b * x
+ x = x[0] + x[1] * numpy.arange(len(y))
+ legend = self.__signal_name + "["
+ for sl in self._selector.selection():
+ if sl == slice(None):
+ legend += ":, "
+ else:
+ legend += str(sl) + ", "
+ legend = legend[:-2] + "]"
+ if self.__signal_errors is not None:
+ y_errors = self.__signal_errors[self._selector.selection()]
+ else:
+ y_errors = None
+
+ self._plot.remove(kind=("curve", "scatter"))
+
+ # values: x-y-v scatter
+ if self.__values is not None:
+ self._plot.addScatter(x, y, self.__values,
+ legend=legend,
+ xerror=self.__axis_errors,
+ yerror=y_errors)
+
+ # x monotonically increasing: curve
+ elif numpy.all(numpy.diff(x) > 0):
+ self._plot.addCurve(x, y, legend=legend,
+ xerror=self.__axis_errors,
+ yerror=y_errors)
+
+ # scatter
+ else:
+ self._plot.addScatter(x, y, value=numpy.ones_like(y),
+ legend=legend,
+ xerror=self.__axis_errors,
+ yerror=y_errors)
+ self._plot.resetZoom()
+ self._plot.setGraphXLabel(self.__axis_name)
+ self._plot.setGraphYLabel(self.__signal_name)
+
+ def clear(self):
+ self._plot.clear()
+
+
+class ArrayImagePlot(qt.QWidget):
+ """
+ Widget for plotting an image from a multi-dimensional signal array
+ and two 1D axes array.
+
+ The signal array can have an arbitrary number of dimensions, the only
+ limitation being that the last two dimensions must have the same length as
+ the axes arrays.
+
+ Sliders are provided to select indices on the first (n - 2) dimensions of
+ the signal array, and the plot is updated to show the image corresponding
+ to the selection.
+
+ If one or both of the axes does not have regularly spaced values, the
+ the image is plotted as a coloured scatter plot.
+ """
+ def __init__(self, parent=None):
+ """
+
+ :param parent: Parent QWidget
+ """
+ super(ArrayImagePlot, self).__init__(parent)
+
+ self.__signal = None
+ self.__signal_name = None
+ self.__x_axis = None
+ self.__x_axis_name = None
+ self.__y_axis = None
+ self.__y_axis_name = None
+
+ self._plot = Plot2D(self)
+ self._plot.setDefaultColormap(
+ {"name": "viridis",
+ "vmin": 0., "vmax": 1., # ignored (autoscale) but mandatory
+ "normalization": "linear",
+ "autoscale": True})
+
+ self.selectorDock = qt.QDockWidget("Data selector", self._plot)
+ # not closable
+ self.selectorDock.setFeatures(qt.QDockWidget.DockWidgetMovable |
+ qt.QDockWidget.DockWidgetFloatable)
+ self._legend = qt.QLabel(self)
+ self._selector = NumpyAxesSelector(self.selectorDock)
+ self._selector.setNamedAxesSelectorVisibility(False)
+ self.__selector_is_connected = False
+
+ layout = qt.QVBoxLayout()
+ layout.addWidget(self._plot)
+ layout.addWidget(self._legend)
+ self.selectorDock.setWidget(self._selector)
+ self._plot.addTabbedDockWidget(self.selectorDock)
+
+ self.setLayout(layout)
+
+ def setImageData(self, signal,
+ x_axis=None, y_axis=None,
+ signal_name=None,
+ xlabel=None, ylabel=None,
+ title=None):
+ """
+
+ :param signal: n-D dataset, whose last 2 dimensions are used as the
+ image's values.
+ :param x_axis: 1-D dataset used as the image's x coordinates. If
+ provided, its lengths must be equal to the length of the last
+ dimension of ``signal``.
+ :param y_axis: 1-D dataset used as the image's y. If provided,
+ its lengths must be equal to the length of the 2nd to last
+ dimension of ``signal``.
+ :param signal_name: Label used in the legend
+ :param xlabel: Label for X axis
+ :param ylabel: Label for Y axis
+ :param title: Graph title
+ """
+ if self.__selector_is_connected:
+ self._selector.selectionChanged.disconnect(self._updateImage)
+ self.__selector_is_connected = False
+
+ self.__signal = signal
+ self.__signal_name = signal_name or ""
+ self.__x_axis = x_axis
+ self.__x_axis_name = xlabel
+ self.__y_axis = y_axis
+ self.__y_axis_name = ylabel
+
+ self._selector.setData(signal)
+ self._selector.setAxisNames([ylabel or "Y", xlabel or "X"])
+
+ if len(signal.shape) < 3:
+ self.selectorDock.hide()
+ else:
+ self.selectorDock.show()
+
+ self._plot.setGraphTitle(title or "")
+ self._plot.setGraphXLabel(self.__x_axis_name or "X")
+ self._plot.setGraphYLabel(self.__y_axis_name or "Y")
+
+ self._updateImage()
+
+ if not self.__selector_is_connected:
+ self._selector.selectionChanged.connect(self._updateImage)
+ self.__selector_is_connected = True
+
+ def _updateImage(self):
+ legend = self.__signal_name + "["
+ for sl in self._selector.selection():
+ if sl == slice(None):
+ legend += ":, "
+ else:
+ legend += str(sl) + ", "
+ legend = legend[:-2] + "]"
+ self._legend.setText("Displayed data: " + legend)
+
+ img = self._selector.selectedData()
+ x_axis = self.__x_axis
+ y_axis = self.__y_axis
+
+ if x_axis is None and y_axis is None:
+ xcalib = NoCalibration()
+ ycalib = NoCalibration()
+ else:
+ if x_axis is None:
+ # no calibration
+ x_axis = numpy.arange(img.shape[-1])
+ elif numpy.isscalar(x_axis) or len(x_axis) == 1:
+ # constant axis
+ x_axis = x_axis * numpy.ones((img.shape[-1], ))
+ elif len(x_axis) == 2:
+ # linear calibration
+ x_axis = x_axis[0] * numpy.arange(img.shape[-1]) + x_axis[1]
+
+ if y_axis is None:
+ y_axis = numpy.arange(img.shape[-2])
+ elif numpy.isscalar(y_axis) or len(y_axis) == 1:
+ y_axis = y_axis * numpy.ones((img.shape[-2], ))
+ elif len(y_axis) == 2:
+ y_axis = y_axis[0] * numpy.arange(img.shape[-2]) + y_axis[1]
+
+ xcalib = ArrayCalibration(x_axis)
+ ycalib = ArrayCalibration(y_axis)
+
+ self._plot.remove(kind=("scatter", "image"))
+ if xcalib.is_affine() and ycalib.is_affine():
+ # regular image
+ xorigin, xscale = xcalib(0), xcalib.get_slope()
+ yorigin, yscale = ycalib(0), ycalib.get_slope()
+ origin = (xorigin, yorigin)
+ scale = (xscale, yscale)
+
+ self._plot.addImage(img, legend=legend,
+ origin=origin, scale=scale)
+ else:
+ scatterx, scattery = numpy.meshgrid(x_axis, y_axis)
+ self._plot.addScatter(numpy.ravel(scatterx),
+ numpy.ravel(scattery),
+ numpy.ravel(img),
+ legend=legend)
+ self._plot.setGraphXLabel(self.__x_axis_name)
+ self._plot.setGraphYLabel(self.__y_axis_name)
+ self._plot.resetZoom()
+
+ def clear(self):
+ self._plot.clear()
+
+
+class ArrayStackPlot(qt.QWidget):
+ """
+ Widget for plotting a n-D array (n >= 3) as a stack of images.
+ Three axis arrays can be provided to calibrate the axes.
+
+ The signal array can have an arbitrary number of dimensions, the only
+ limitation being that the last 3 dimensions must have the same length as
+ the axes arrays.
+
+ Sliders are provided to select indices on the first (n - 3) dimensions of
+ the signal array, and the plot is updated to load the stack corresponding
+ to the selection.
+ """
+ def __init__(self, parent=None):
+ """
+
+ :param parent: Parent QWidget
+ """
+ super(ArrayStackPlot, self).__init__(parent)
+
+ self.__signal = None
+ self.__signal_name = None
+ # the Z, Y, X axes apply to the last three dimensions of the signal
+ # (in that order)
+ self.__z_axis = None
+ self.__z_axis_name = None
+ self.__y_axis = None
+ self.__y_axis_name = None
+ self.__x_axis = None
+ self.__x_axis_name = None
+
+ self._stack_view = StackView(self)
+ self._hline = qt.QFrame(self)
+ self._hline.setFrameStyle(qt.QFrame.HLine)
+ self._hline.setFrameShadow(qt.QFrame.Sunken)
+ self._legend = qt.QLabel(self)
+ self._selector = NumpyAxesSelector(self)
+ self._selector.setNamedAxesSelectorVisibility(False)
+ self.__selector_is_connected = False
+
+ layout = qt.QVBoxLayout()
+ layout.addWidget(self._stack_view)
+ layout.addWidget(self._hline)
+ layout.addWidget(self._legend)
+ layout.addWidget(self._selector)
+
+ self.setLayout(layout)
+
+ def setStackData(self, signal,
+ x_axis=None, y_axis=None, z_axis=None,
+ signal_name=None,
+ xlabel=None, ylabel=None, zlabel=None,
+ title=None):
+ """
+
+ :param signal: n-D dataset, whose last 3 dimensions are used as the
+ 3D stack values.
+ :param x_axis: 1-D dataset used as the image's x coordinates. If
+ provided, its lengths must be equal to the length of the last
+ dimension of ``signal``.
+ :param y_axis: 1-D dataset used as the image's y. If provided,
+ its lengths must be equal to the length of the 2nd to last
+ dimension of ``signal``.
+ :param z_axis: 1-D dataset used as the image's z. If provided,
+ its lengths must be equal to the length of the 3rd to last
+ dimension of ``signal``.
+ :param signal_name: Label used in the legend
+ :param xlabel: Label for X axis
+ :param ylabel: Label for Y axis
+ :param zlabel: Label for Z axis
+ :param title: Graph title
+ """
+ if self.__selector_is_connected:
+ self._selector.selectionChanged.disconnect(self._updateStack)
+ self.__selector_is_connected = False
+
+ self.__signal = signal
+ self.__signal_name = signal_name or ""
+ self.__x_axis = x_axis
+ self.__x_axis_name = xlabel
+ self.__y_axis = y_axis
+ self.__y_axis_name = ylabel
+ self.__z_axis = z_axis
+ self.__z_axis_name = zlabel
+
+ self._selector.setData(signal)
+ self._selector.setAxisNames([ylabel or "Y", xlabel or "X", zlabel or "Z"])
+
+ self._stack_view.setGraphTitle(title or "")
+ # by default, the z axis is the image position (dimension not plotted)
+ self._stack_view.setGraphXLabel(self.__x_axis_name or "X")
+ self._stack_view.setGraphYLabel(self.__y_axis_name or "Y")
+
+ self._updateStack()
+
+ ndims = len(signal.shape)
+ self._stack_view.setFirstStackDimension(ndims - 3)
+
+ # the legend label shows the selection slice producing the volume
+ # (only interesting for ndim > 3)
+ if ndims > 3:
+ self._selector.setVisible(True)
+ self._legend.setVisible(True)
+ self._hline.setVisible(True)
+ else:
+ self._selector.setVisible(False)
+ self._legend.setVisible(False)
+ self._hline.setVisible(False)
+
+ if not self.__selector_is_connected:
+ self._selector.selectionChanged.connect(self._updateStack)
+ self.__selector_is_connected = True
+
+ @staticmethod
+ def _get_origin_scale(axis):
+ """Assuming axis is a regularly spaced 1D array,
+ return a tuple (origin, scale) where:
+ - origin = axis[0]
+ - scale = (axis[n-1] - axis[0]) / (n -1)
+ :param axis: 1D numpy array
+ :return: Tuple (axis[0], (axis[-1] - axis[0]) / (len(axis) - 1))
+ """
+ return axis[0], (axis[-1] - axis[0]) / (len(axis) - 1)
+
+ def _updateStack(self):
+ """Update displayed stack according to the current axes selector
+ data."""
+ stk = self._selector.selectedData()
+ x_axis = self.__x_axis
+ y_axis = self.__y_axis
+ z_axis = self.__z_axis
+
+ calibrations = []
+ for axis in [z_axis, y_axis, x_axis]:
+
+ if axis is None:
+ calibrations.append(NoCalibration())
+ elif len(axis) == 2:
+ calibrations.append(
+ LinearCalibration(y_intercept=axis[0],
+ slope=axis[1]))
+ else:
+ calibrations.append(ArrayCalibration(axis))
+
+ legend = self.__signal_name + "["
+ for sl in self._selector.selection():
+ if sl == slice(None):
+ legend += ":, "
+ else:
+ legend += str(sl) + ", "
+ legend = legend[:-2] + "]"
+ self._legend.setText("Displayed data: " + legend)
+
+ self._stack_view.setStack(stk, calibrations=calibrations)
+ self._stack_view.setLabels(
+ labels=[self.__z_axis_name,
+ self.__y_axis_name,
+ self.__x_axis_name])
+
+ def clear(self):
+ self._stack_view.clear()
diff --git a/silx/gui/data/NumpyAxesSelector.py b/silx/gui/data/NumpyAxesSelector.py
new file mode 100644
index 0000000..f4641da
--- /dev/null
+++ b/silx/gui/data/NumpyAxesSelector.py
@@ -0,0 +1,468 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module defines a widget able to convert a numpy array from n-dimensions
+to a numpy array with less dimensions.
+"""
+from __future__ import division
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+import numpy
+import functools
+from silx.gui.widgets.FrameBrowser import HorizontalSliderWithBrowser
+from silx.gui import qt
+import silx.utils.weakref
+
+
+class _Axis(qt.QWidget):
+ """Widget displaying an axis.
+
+ It allows to display and scroll in the axis, and provide a widget to
+ map the axis with a named axis (the one from the view).
+ """
+
+ valueChanged = qt.Signal(int)
+ """Emitted when the location on the axis change."""
+
+ axisNameChanged = qt.Signal(object)
+ """Emitted when the user change the name of the axis."""
+
+ def __init__(self, parent=None):
+ """Constructor
+
+ :param parent: Parent of the widget
+ """
+ super(_Axis, self).__init__(parent)
+ self.__axisNumber = None
+ self.__customAxisNames = set([])
+ self.__label = qt.QLabel(self)
+ self.__axes = qt.QComboBox(self)
+ self.__axes.currentIndexChanged[int].connect(self.__axisMappingChanged)
+ self.__slider = HorizontalSliderWithBrowser(self)
+ self.__slider.valueChanged[int].connect(self.__sliderValueChanged)
+ layout = qt.QHBoxLayout(self)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.addWidget(self.__label)
+ layout.addWidget(self.__axes)
+ layout.addWidget(self.__slider, 10000)
+ layout.addStretch(1)
+ self.setLayout(layout)
+
+ def slider(self):
+ """Returns the slider used to display axes location.
+
+ :rtype: HorizontalSliderWithBrowser
+ """
+ return self.__slider
+
+ def setAxis(self, number, position, size):
+ """Set axis information.
+
+ :param int number: The number of the axis (from the original numpy
+ array)
+ :param int position: The current position in the axis (for a slicing)
+ :param int size: The size of this axis (0..n)
+ """
+ self.__label.setText("Dimension %s" % number)
+ self.__axisNumber = number
+ self.__slider.setMaximum(size - 1)
+
+ def axisNumber(self):
+ """Returns the axis number.
+
+ :rtype: int
+ """
+ return self.__axisNumber
+
+ def setAxisName(self, axisName):
+ """Set the current used axis name.
+
+ If this name is not available an exception is raised. An empty string
+ means that no name is selected.
+
+ :param str axisName: The new name of the axis
+ :raise ValueError: When the name is not available
+ """
+ if axisName == "" and self.__axes.count() == 0:
+ self.__axes.setCurrentIndex(-1)
+ self.__updateSliderVisibility()
+ for index in range(self.__axes.count()):
+ name = self.__axes.itemData(index)
+ if name == axisName:
+ self.__axes.setCurrentIndex(index)
+ self.__updateSliderVisibility()
+ return
+ raise ValueError("Axis name '%s' not found", axisName)
+
+ def axisName(self):
+ """Returns the selected axis name.
+
+ If no names are selected, an empty string is retruned.
+
+ :rtype: str
+ """
+ index = self.__axes.currentIndex()
+ if index == -1:
+ return ""
+ return self.__axes.itemData(index)
+
+ def setAxisNames(self, axesNames):
+ """Set the available list of names for the axis.
+
+ :param list[str] axesNames: List of available names
+ """
+ self.__axes.clear()
+ previous = self.__axes.blockSignals(True)
+ self.__axes.addItem(" ", "")
+ for axis in axesNames:
+ self.__axes.addItem(axis, axis)
+ self.__axes.blockSignals(previous)
+ self.__updateSliderVisibility()
+
+ def setCustomAxis(self, axesNames):
+ """Set the available list of named axis which can be set to a value.
+
+ :param list[str] axesNames: List of customable axis names
+ """
+ self.__customAxisNames = set(axesNames)
+ self.__updateSliderVisibility()
+
+ def __axisMappingChanged(self, index):
+ """Called when the selected name change.
+
+ :param int index: Selected index
+ """
+ self.__updateSliderVisibility()
+ name = self.axisName()
+ self.axisNameChanged.emit(name)
+
+ def __updateSliderVisibility(self):
+ """Update the visibility of the slider according to axis names and
+ customable axis names."""
+ name = self.axisName()
+ isVisible = name == "" or name in self.__customAxisNames
+ self.__slider.setVisible(isVisible)
+
+ def value(self):
+ """Returns the current selected position in the axis.
+
+ :rtype: int
+ """
+ return self.__slider.value()
+
+ def __sliderValueChanged(self, value):
+ """Called when the selected position in the axis change.
+
+ :param int value: Position of the axis
+ """
+ self.valueChanged.emit(value)
+
+ def setNamedAxisSelectorVisibility(self, visible):
+ """Hide or show the named axis combobox.
+ If both the selector and the slider are hidden,
+ hide the entire widget.
+
+ :param visible: boolean
+ """
+ self.__axes.setVisible(visible)
+ name = self.axisName()
+
+ if not visible and name != "":
+ self.setVisible(False)
+ else:
+ self.setVisible(True)
+
+
+class NumpyAxesSelector(qt.QWidget):
+ """Widget to select a view from a numpy array.
+
+ .. image:: img/NumpyAxesSelector.png
+
+ The widget is set with an input data using :meth:`setData`, and a requested
+ output dimension using :meth:`setAxisNames`.
+
+ Widgets are provided to selected expected input axis, and a slice on the
+ non-selected axis.
+
+ The final selected array can be reached using the getter
+ :meth:`selectedData`, and the event `selectionChanged`.
+
+ If the input data is a HDF5 Dataset, the selected output data will be a
+ new numpy array.
+ """
+
+ dataChanged = qt.Signal()
+ """Emitted when the input data change"""
+
+ selectedAxisChanged = qt.Signal()
+ """Emitted when the selected axis change"""
+
+ selectionChanged = qt.Signal()
+ """Emitted when the selected data change"""
+
+ customAxisChanged = qt.Signal(str, int)
+ """Emitted when a custom axis change"""
+
+ def __init__(self, parent=None):
+ """Constructor
+
+ :param parent: Parent of the widget
+ """
+ super(NumpyAxesSelector, self).__init__(parent)
+
+ self.__data = None
+ self.__selectedData = None
+ self.__selection = tuple()
+ self.__axis = []
+ self.__axisNames = []
+ self.__customAxisNames = set([])
+ self.__namedAxesVisibility = True
+ layout = qt.QVBoxLayout(self)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setSizeConstraint(qt.QLayout.SetMinAndMaxSize)
+ self.setLayout(layout)
+
+ def clear(self):
+ """Clear the widget."""
+ self.setData(None)
+
+ def setAxisNames(self, axesNames):
+ """Set the axis names of the output selected data.
+
+ Axis names are defined from slower to faster axis.
+
+ The size of the list will constrain the dimension of the resulting
+ array.
+
+ :param list[str] axesNames: List of string identifying axis names
+ """
+ self.__axisNames = list(axesNames)
+ delta = len(self.__axis) - len(self.__axisNames)
+ if delta < 0:
+ delta = 0
+ for index, axis in enumerate(self.__axis):
+ previous = axis.blockSignals(True)
+ axis.setAxisNames(self.__axisNames)
+ if index >= delta and index - delta < len(self.__axisNames):
+ axis.setAxisName(self.__axisNames[index - delta])
+ else:
+ axis.setAxisName("")
+ axis.blockSignals(previous)
+ self.__updateSelectedData()
+
+ def setCustomAxis(self, axesNames):
+ """Set the available list of named axis which can be set to a value.
+
+ :param list[str] axesNames: List of customable axis names
+ """
+ self.__customAxisNames = set(axesNames)
+ for axis in self.__axis:
+ axis.setCustomAxis(self.__customAxisNames)
+
+ def setData(self, data):
+ """Set the input data unsed by the widget.
+
+ :param numpy.ndarray data: The input data
+ """
+ if self.__data is not None:
+ # clean up
+ for widget in self.__axis:
+ self.layout().removeWidget(widget)
+ widget.deleteLater()
+ self.__axis = []
+
+ self.__data = data
+
+ if data is not None:
+ # create expected axes
+ dimensionNumber = len(data.shape)
+ delta = dimensionNumber - len(self.__axisNames)
+ for index in range(dimensionNumber):
+ axis = _Axis(self)
+ axis.setAxis(index, 0, data.shape[index])
+ axis.setAxisNames(self.__axisNames)
+ axis.setCustomAxis(self.__customAxisNames)
+ if index >= delta and index - delta < len(self.__axisNames):
+ axis.setAxisName(self.__axisNames[index - delta])
+ # this weak method was expected to be able to delete sub widget
+ callback = functools.partial(silx.utils.weakref.WeakMethodProxy(self.__axisValueChanged), axis)
+ axis.valueChanged.connect(callback)
+ # this weak method was expected to be able to delete sub widget
+ callback = functools.partial(silx.utils.weakref.WeakMethodProxy(self.__axisNameChanged), axis)
+ axis.axisNameChanged.connect(callback)
+ axis.setNamedAxisSelectorVisibility(self.__namedAxesVisibility)
+ self.layout().addWidget(axis)
+ self.__axis.append(axis)
+ self.__normalizeAxisGeometry()
+
+ self.dataChanged.emit()
+ self.__updateSelectedData()
+
+ def __normalizeAxisGeometry(self):
+ """Update axes geometry to align all axes components together."""
+ if len(self.__axis) <= 0:
+ return
+ lineEditWidth = max([a.slider().lineEdit().minimumSize().width() for a in self.__axis])
+ limitWidth = max([a.slider().limitWidget().minimumSizeHint().width() for a in self.__axis])
+ for a in self.__axis:
+ a.slider().lineEdit().setFixedWidth(lineEditWidth)
+ a.slider().limitWidget().setFixedWidth(limitWidth)
+
+ def __axisValueChanged(self, axis, value):
+ name = axis.axisName()
+ if name in self.__customAxisNames:
+ self.customAxisChanged.emit(name, value)
+ else:
+ self.__updateSelectedData()
+
+ def __axisNameChanged(self, axis, name):
+ """Called when an axis name change.
+
+ :param _Axis axis: The changed axis
+ :param str name: The new name of the axis
+ """
+ names = [x.axisName() for x in self.__axis]
+ missingName = set(self.__axisNames) - set(names) - set("")
+ if len(missingName) == 0:
+ missingName = None
+ elif len(missingName) == 1:
+ missingName = list(missingName)[0]
+ else:
+ raise Exception("Unexpected state")
+
+ axisChanged = True
+
+ if axis.axisName() == "":
+ # set the removed label to another widget if it is possible
+ availableWidget = None
+ for widget in self.__axis:
+ if widget is axis:
+ continue
+ if widget.axisName() == "":
+ availableWidget = widget
+ break
+ if availableWidget is None:
+ # If there is no other solution we set the name at the same place
+ axisChanged = False
+ availableWidget = axis
+ previous = availableWidget.blockSignals(True)
+ availableWidget.setAxisName(missingName)
+ availableWidget.blockSignals(previous)
+ else:
+ # there is a duplicated name somewhere
+ # we swap it with the missing name or with nothing
+ dupWidget = None
+ for widget in self.__axis:
+ if widget is axis:
+ continue
+ if widget.axisName() == axis.axisName():
+ dupWidget = widget
+ break
+ if missingName is None:
+ missingName = ""
+ previous = dupWidget.blockSignals(True)
+ dupWidget.setAxisName(missingName)
+ dupWidget.blockSignals(previous)
+
+ if self.__data is None:
+ return
+ if axisChanged:
+ self.selectedAxisChanged.emit()
+ self.__updateSelectedData()
+
+ def __updateSelectedData(self):
+ """Update the selected data according to the state of the widget.
+
+ It fires a `selectionChanged` event.
+ """
+ if self.__data is None:
+ if self.__selectedData is not None:
+ self.__selectedData = None
+ self.__selection = tuple()
+ self.selectionChanged.emit()
+ return
+
+ selection = []
+ axisNames = []
+ for slider in self.__axis:
+ name = slider.axisName()
+ if name == "":
+ selection.append(slider.value())
+ else:
+ selection.append(slice(None))
+ axisNames.append(name)
+
+ self.__selection = tuple(selection)
+ # get a view with few fixed dimensions
+ # with a h5py dataset, it create a copy
+ # TODO we can reuse the same memory in case of a copy
+ view = self.__data[self.__selection]
+
+ # order axis as expected
+ source = []
+ destination = []
+ order = []
+ for index, name in enumerate(self.__axisNames):
+ destination.append(index)
+ source.append(axisNames.index(name))
+ for _, s in sorted(zip(destination, source)):
+ order.append(s)
+ view = numpy.transpose(view, order)
+
+ self.__selectedData = view
+ self.selectionChanged.emit()
+
+ def data(self):
+ """Returns the input data.
+
+ :rtype: numpy.ndarray
+ """
+ return self.__data
+
+ def selectedData(self):
+ """Returns the output data.
+
+ :rtype: numpy.ndarray
+ """
+ return self.__selectedData
+
+ def selection(self):
+ """Returns the selection tuple used to slice the data.
+
+ :rtype: tuple
+ """
+ return self.__selection
+
+ def setNamedAxesSelectorVisibility(self, visible):
+ """Show or hide the combo-boxes allowing to map the plot axes
+ to the data dimension.
+
+ :param visible: Boolean
+ """
+ self.__namedAxesVisibility = visible
+ for axis in self.__axis:
+ axis.setNamedAxisSelectorVisibility(visible)
diff --git a/silx/gui/data/RecordTableView.py b/silx/gui/data/RecordTableView.py
new file mode 100644
index 0000000..ce6a178
--- /dev/null
+++ b/silx/gui/data/RecordTableView.py
@@ -0,0 +1,405 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""
+This module define model and widget to display 1D slices from numpy
+array using compound data types or hdf5 databases.
+"""
+from __future__ import division
+
+import itertools
+import numpy
+from silx.gui import qt
+import silx.io
+from .TextFormatter import TextFormatter
+from silx.gui.widgets.TableWidget import CopySelectedCellsAction
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "27/01/2017"
+
+
+class _MultiLineItem(qt.QItemDelegate):
+ """Draw a multiline text without hiding anything.
+
+ The paint method display a cell without any wrap. And an editor is
+ available to scroll into the selected cell.
+ """
+
+ def __init__(self, parent=None):
+ """
+ Constructor
+
+ :param qt.QWidget parent: Parent of the widget
+ """
+ qt.QItemDelegate.__init__(self, parent)
+ self.__textOptions = qt.QTextOption()
+ self.__textOptions.setFlags(qt.QTextOption.IncludeTrailingSpaces |
+ qt.QTextOption.ShowTabsAndSpaces)
+ self.__textOptions.setWrapMode(qt.QTextOption.NoWrap)
+ self.__textOptions.setAlignment(qt.Qt.AlignTop | qt.Qt.AlignLeft)
+
+ def paint(self, painter, option, index):
+ """
+ Write multiline text without using any wrap or any alignment according
+ to the cell size.
+
+ :param qt.QPainter painter: Painter context used to displayed the cell
+ :param qt.QStyleOptionViewItem option: Control how the editor is shown
+ :param qt.QIndex index: Index of the data to display
+ """
+ painter.save()
+
+ # set colors
+ painter.setPen(qt.QPen(qt.Qt.NoPen))
+ if option.state & qt.QStyle.State_Selected:
+ brush = option.palette.highlight()
+ painter.setBrush(brush)
+ else:
+ brush = index.data(qt.Qt.BackgroundRole)
+ if brush is None:
+ # default background color for a cell
+ brush = qt.Qt.white
+ painter.setBrush(brush)
+ painter.drawRect(option.rect)
+
+ if index.isValid():
+ if option.state & qt.QStyle.State_Selected:
+ brush = option.palette.highlightedText()
+ else:
+ brush = index.data(qt.Qt.ForegroundRole)
+ if brush is None:
+ brush = option.palette.text()
+ painter.setPen(qt.QPen(brush.color()))
+ text = index.data(qt.Qt.DisplayRole)
+ painter.drawText(qt.QRectF(option.rect), text, self.__textOptions)
+
+ painter.restore()
+
+ def createEditor(self, parent, option, index):
+ """
+ Returns the widget used to edit the item specified by index for editing.
+
+ We use it not to edit the content but to show the content with a
+ convenient scroll bar.
+
+ :param qt.QWidget parent: Parent of the widget
+ :param qt.QStyleOptionViewItem option: Control how the editor is shown
+ :param qt.QIndex index: Index of the data to display
+ """
+ if not index.isValid():
+ return super(_MultiLineItem, self).createEditor(parent, option, index)
+
+ editor = qt.QTextEdit(parent)
+ editor.setReadOnly(True)
+ return editor
+
+ def setEditorData(self, editor, index):
+ """
+ Read data from the model and feed the editor.
+
+ :param qt.QWidget editor: Editor widget
+ :param qt.QIndex index: Index of the data to display
+ """
+ text = index.model().data(index, qt.Qt.EditRole)
+ editor.setText(text)
+
+ def updateEditorGeometry(self, editor, option, index):
+ """
+ Update the geometry of the editor according to the changes of the view.
+
+ :param qt.QWidget editor: Editor widget
+ :param qt.QStyleOptionViewItem option: Control how the editor is shown
+ :param qt.QIndex index: Index of the data to display
+ """
+ editor.setGeometry(option.rect)
+
+
+class RecordTableModel(qt.QAbstractTableModel):
+ """This data model provides access to 1D slices from numpy array using
+ compound data types or hdf5 databases.
+
+ Each entries are displayed in a single row, and each columns contain a
+ specific field of the compound type.
+
+ It also allows to display 1D arrays of simple data types.
+ array.
+
+ :param qt.QObject parent: Parent object
+ :param numpy.ndarray data: A numpy array or a h5py dataset
+ """
+ def __init__(self, parent=None, data=None):
+ qt.QAbstractTableModel.__init__(self, parent)
+
+ self.__data = None
+ self.__is_array = False
+ self.__fields = None
+ self.__formatter = None
+ self.__editFormatter = None
+ self.setFormatter(TextFormatter(self))
+
+ # set _data
+ self.setArrayData(data)
+
+ # Methods to be implemented to subclass QAbstractTableModel
+ def rowCount(self, parent_idx=None):
+ """Returns number of rows to be displayed in table"""
+ if self.__data is None:
+ return 0
+ elif not self.__is_array:
+ return 1
+ else:
+ return len(self.__data)
+
+ def columnCount(self, parent_idx=None):
+ """Returns number of columns to be displayed in table"""
+ if self.__fields is None:
+ return 1
+ else:
+ return len(self.__fields)
+
+ def data(self, index, role=qt.Qt.DisplayRole):
+ """QAbstractTableModel method to access data values
+ in the format ready to be displayed"""
+ if not index.isValid():
+ return None
+
+ if self.__data is None:
+ return None
+
+ if self.__is_array:
+ if index.row() >= len(self.__data):
+ return None
+ data = self.__data[index.row()]
+ else:
+ if index.row() > 0:
+ return None
+ data = self.__data
+
+ if self.__fields is not None:
+ if index.column() >= len(self.__fields):
+ return None
+ key = self.__fields[index.column()][1]
+ data = data[key[0]]
+ if len(key) > 1:
+ data = data[key[1]]
+
+ if role == qt.Qt.DisplayRole:
+ return self.__formatter.toString(data)
+ elif role == qt.Qt.EditRole:
+ return self.__editFormatter.toString(data)
+ return None
+
+ def headerData(self, section, orientation, role=qt.Qt.DisplayRole):
+ """Returns the 0-based row or column index, for display in the
+ horizontal and vertical headers"""
+ if section == -1:
+ # PyQt4 send -1 when there is columns but no rows
+ return None
+
+ if role == qt.Qt.DisplayRole:
+ if orientation == qt.Qt.Vertical:
+ if not self.__is_array:
+ return "Scalar"
+ else:
+ return str(section)
+ if orientation == qt.Qt.Horizontal:
+ if self.__fields is None:
+ if section == 0:
+ return "Data"
+ else:
+ return None
+ else:
+ if section < len(self.__fields):
+ return self.__fields[section][0]
+ else:
+ return None
+ return None
+
+ def flags(self, index):
+ """QAbstractTableModel method to inform the view whether data
+ is editable or not.
+ """
+ return qt.QAbstractTableModel.flags(self, index)
+
+ def setArrayData(self, data):
+ """Set the data array and the viewing perspective.
+
+ You can set ``copy=False`` if you need more performances, when dealing
+ with a large numpy array. In this case, a simple reference to the data
+ is used to access the data, rather than a copy of the array.
+
+ .. warning::
+
+ Any change to the data model will affect your original data
+ array, when using a reference rather than a copy..
+
+ :param data: 1D numpy array, or any object that can be
+ converted to a numpy array using ``numpy.array(data)`` (e.g.
+ a nested sequence).
+ """
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+
+ self.__data = data
+ if isinstance(data, numpy.ndarray):
+ self.__is_array = True
+ elif silx.io.is_dataset(data) and data.shape != tuple():
+ self.__is_array = True
+ else:
+ self.__is_array = False
+
+
+ self.__fields = []
+ if data is not None:
+ if data.dtype.fields is not None:
+ for name, (dtype, _index) in data.dtype.fields.items():
+ if dtype.shape != tuple():
+ keys = itertools.product(*[range(x) for x in dtype.shape])
+ for key in keys:
+ label = "%s%s" % (name, list(key))
+ array_key = (name, key)
+ self.__fields.append((label, array_key))
+ else:
+ self.__fields.append((name, (name,)))
+ else:
+ self.__fields = None
+
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+ else:
+ self.reset()
+
+ def arrayData(self):
+ """Returns the internal data.
+
+ :rtype: numpy.ndarray of h5py.Dataset
+ """
+ return self.__data
+
+ def setFormatter(self, formatter):
+ """Set the formatter object to be used to display data from the model
+
+ :param TextFormatter formatter: Formatter to use
+ """
+ if formatter is self.__formatter:
+ return
+
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+
+ if self.__formatter is not None:
+ self.__formatter.formatChanged.disconnect(self.__formatChanged)
+
+ self.__formatter = formatter
+ self.__editFormatter = TextFormatter(formatter)
+ self.__editFormatter.setUseQuoteForText(False)
+
+ if self.__formatter is not None:
+ self.__formatter.formatChanged.connect(self.__formatChanged)
+
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+ else:
+ self.reset()
+
+ def getFormatter(self):
+ """Returns the text formatter used.
+
+ :rtype: TextFormatter
+ """
+ return self.__formatter
+
+ def __formatChanged(self):
+ """Called when the format changed.
+ """
+ self.__editFormatter = TextFormatter(self, self.getFormatter())
+ self.__editFormatter.setUseQuoteForText(False)
+ self.reset()
+
+
+class _ShowEditorProxyModel(qt.QIdentityProxyModel):
+ """
+ Allow to custom the flag edit of the model
+ """
+
+ def __init__(self, parent=None):
+ """
+ Constructor
+
+ :param qt.QObject arent: parent object
+ """
+ super(_ShowEditorProxyModel, self).__init__(parent)
+ self.__forceEditable = False
+
+ def flags(self, index):
+ flag = qt.QIdentityProxyModel.flags(self, index)
+ if self.__forceEditable:
+ flag = flag | qt.Qt.ItemIsEditable
+ return flag
+
+ def forceCellEditor(self, show):
+ """
+ Enable the editable flag to allow to display cell editor.
+ """
+ if self.__forceEditable == show:
+ return
+ self.beginResetModel()
+ self.__forceEditable = show
+ self.endResetModel()
+
+
+class RecordTableView(qt.QTableView):
+ """TableView using DatabaseTableModel as default model.
+ """
+ def __init__(self, parent=None):
+ """
+ Constructor
+
+ :param qt.QWidget parent: parent QWidget
+ """
+ qt.QTableView.__init__(self, parent)
+
+ model = _ShowEditorProxyModel(self)
+ model.setSourceModel(RecordTableModel())
+ self.setModel(model)
+ self.__multilineView = _MultiLineItem(self)
+ self.setEditTriggers(qt.QAbstractItemView.AllEditTriggers)
+ self._copyAction = CopySelectedCellsAction(self)
+ self.addAction(self._copyAction)
+
+ def copy(self):
+ self._copyAction.trigger()
+
+ def setArrayData(self, data):
+ self.model().sourceModel().setArrayData(data)
+ if data is not None:
+ if issubclass(data.dtype.type, (numpy.string_, numpy.unicode_)):
+ # TODO it would be nice to also fix fields
+ # but using it only for string array is already very useful
+ self.setItemDelegateForColumn(0, self.__multilineView)
+ self.model().forceCellEditor(True)
+ else:
+ self.setItemDelegateForColumn(0, None)
+ self.model().forceCellEditor(False)
diff --git a/silx/gui/data/TextFormatter.py b/silx/gui/data/TextFormatter.py
new file mode 100644
index 0000000..f074de5
--- /dev/null
+++ b/silx/gui/data/TextFormatter.py
@@ -0,0 +1,222 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This package provides a class sharred by widget from the
+data module to format data as text in the same way."""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+import numpy
+import numbers
+import binascii
+from silx.third_party import six
+from silx.gui import qt
+
+
+class TextFormatter(qt.QObject):
+ """Formatter to convert data to string.
+
+ The method :meth:`toString` returns a formatted string from an input data
+ using parameters set to this object.
+
+ It support most python and numpy data, expecting dictionary. Unsupported
+ data are displayed using the string representation of the object (`str`).
+
+ It provides a set of parameters to custom the formatting of integer and
+ float values (:meth:`setIntegerFormat`, :meth:`setFloatFormat`).
+
+ It also allows to custom the use of quotes to display text data
+ (:meth:`setUseQuoteForText`), and custom unit used to display imaginary
+ numbers (:meth:`setImaginaryUnit`).
+
+ The object emit an event `formatChanged` every time a parametter is
+ changed.
+ """
+
+ formatChanged = qt.Signal()
+ """Emitted when properties of the formatter change."""
+
+ def __init__(self, parent=None, formatter=None):
+ """
+ Constructor
+
+ :param qt.QObject parent: Owner of the object
+ :param TextFormatter formatter: Instantiate this object from the
+ formatter
+ """
+ qt.QObject.__init__(self, parent)
+ if formatter is not None:
+ self.__integerFormat = formatter.integerFormat()
+ self.__floatFormat = formatter.floatFormat()
+ self.__useQuoteForText = formatter.useQuoteForText()
+ self.__imaginaryUnit = formatter.imaginaryUnit()
+ else:
+ self.__integerFormat = "%d"
+ self.__floatFormat = "%g"
+ self.__useQuoteForText = True
+ self.__imaginaryUnit = u"j"
+
+ def integerFormat(self):
+ """Returns the format string controlling how the integer data
+ are formated by this object.
+
+ This is the C-style format string used by python when formatting
+ strings with the modulus operator.
+
+ :rtype: str
+ """
+ return self.__integerFormat
+
+ def setIntegerFormat(self, value):
+ """Set format string controlling how the integer data are
+ formated by this object.
+
+ :param str value: Format string (e.g. "%d", "%i", "%08i").
+ This is the C-style format string used by python when formatting
+ strings with the modulus operator.
+ """
+ if self.__integerFormat == value:
+ return
+ self.__integerFormat = value
+ self.formatChanged.emit()
+
+ def floatFormat(self):
+ """Returns the format string controlling how the floating-point data
+ are formated by this object.
+
+ This is the C-style format string used by python when formatting
+ strings with the modulus operator.
+
+ :rtype: str
+ """
+ return self.__floatFormat
+
+ def setFloatFormat(self, value):
+ """Set format string controlling how the floating-point data are
+ formated by this object.
+
+ :param str value: Format string (e.g. "%.3f", "%d", "%-10.2f",
+ "%10.3e").
+ This is the C-style format string used by python when formatting
+ strings with the modulus operator.
+ """
+ if self.__floatFormat == value:
+ return
+ self.__floatFormat = value
+ self.formatChanged.emit()
+
+ def useQuoteForText(self):
+ """Returns true if the string data are formatted using double quotes.
+
+ Else, no quotes are used.
+ """
+ return self.__integerFormat
+
+ def setUseQuoteForText(self, useQuote):
+ """Set the use of quotes to delimit string data.
+
+ :param bool useQuote: True to use quotes.
+ """
+ if self.__useQuoteForText == useQuote:
+ return
+ self.__useQuoteForText = useQuote
+ self.formatChanged.emit()
+
+ def imaginaryUnit(self):
+ """Returns the unit display for imaginary numbers.
+
+ :rtype: str
+ """
+ return self.__imaginaryUnit
+
+ def setImaginaryUnit(self, imaginaryUnit):
+ """Set the unit display for imaginary numbers.
+
+ :param str imaginaryUnit: Unit displayed after imaginary numbers
+ """
+ if self.__imaginaryUnit == imaginaryUnit:
+ return
+ self.__imaginaryUnit = imaginaryUnit
+ self.formatChanged.emit()
+
+ def toString(self, data):
+ """Format a data into a string using formatter options
+
+ :param object data: Data to render
+ :rtype: str
+ """
+ if isinstance(data, tuple):
+ text = [self.toString(d) for d in data]
+ return "(" + " ".join(text) + ")"
+ elif isinstance(data, (list, numpy.ndarray)):
+ text = [self.toString(d) for d in data]
+ return "[" + " ".join(text) + "]"
+ elif isinstance(data, numpy.void):
+ dtype = data.dtype
+ if data.dtype.fields is not None:
+ text = [self.toString(data[f]) for f in dtype.fields]
+ return "(" + " ".join(text) + ")"
+ return "0x" + binascii.hexlify(data).decode("ascii")
+ elif isinstance(data, (numpy.string_, numpy.object_, bytes)):
+ # This have to be done before checking python string inheritance
+ try:
+ text = "%s" % data.decode("utf-8")
+ if self.__useQuoteForText:
+ text = "\"%s\"" % text.replace("\"", "\\\"")
+ return text
+ except UnicodeDecodeError:
+ pass
+ return "0x" + binascii.hexlify(data).decode("ascii")
+ elif isinstance(data, six.string_types):
+ text = "%s" % data
+ if self.__useQuoteForText:
+ text = "\"%s\"" % text.replace("\"", "\\\"")
+ return text
+ elif isinstance(data, (numpy.integer, numbers.Integral)):
+ return self.__integerFormat % data
+ elif isinstance(data, (numbers.Real, numpy.floating)):
+ # It have to be done before complex checking
+ return self.__floatFormat % data
+ elif isinstance(data, (numpy.complex_, numbers.Complex)):
+ text = ""
+ if data.real != 0:
+ text += self.__floatFormat % data.real
+ if data.real != 0 and data.imag != 0:
+ if data.imag < 0:
+ template = self.__floatFormat + " - " + self.__floatFormat + self.__imaginaryUnit
+ params = (data.real, -data.imag)
+ else:
+ template = self.__floatFormat + " + " + self.__floatFormat + self.__imaginaryUnit
+ params = (data.real, data.imag)
+ else:
+ if data.imag != 0:
+ template = self.__floatFormat + self.__imaginaryUnit
+ params = (data.imag)
+ else:
+ template = self.__floatFormat
+ params = (data.real)
+ return template % params
+ return str(data)
diff --git a/silx/gui/data/__init__.py b/silx/gui/data/__init__.py
new file mode 100644
index 0000000..560062d
--- /dev/null
+++ b/silx/gui/data/__init__.py
@@ -0,0 +1,35 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This package provides a set of Qt widgets for displaying data arrays using
+table views and plot widgets.
+
+.. note::
+
+ Widgets in this package may rely on additional dependencies that are
+ not mandatory for *silx*.
+ :class:`DataViewer.DataViewer` relies on :mod:`silx.gui.plot` which
+ depends on *matplotlib*. It also optionally depends on *PyOpenGL* for 3D
+ visualization.
+"""
diff --git a/silx/gui/data/setup.py b/silx/gui/data/setup.py
new file mode 100644
index 0000000..23ccbdd
--- /dev/null
+++ b/silx/gui/data/setup.py
@@ -0,0 +1,41 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('data', parent_package, top_path)
+ config.add_subpackage('test')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
diff --git a/silx/gui/data/test/__init__.py b/silx/gui/data/test/__init__.py
new file mode 100644
index 0000000..08c044b
--- /dev/null
+++ b/silx/gui/data/test/__init__.py
@@ -0,0 +1,45 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+import unittest
+
+from . import test_arraywidget
+from . import test_numpyaxesselector
+from . import test_dataviewer
+from . import test_textformatter
+
+__authors__ = ["V. Valls", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "24/01/2017"
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTests(
+ [test_arraywidget.suite(),
+ test_numpyaxesselector.suite(),
+ test_dataviewer.suite(),
+ test_textformatter.suite(),
+ ])
+ return test_suite
diff --git a/silx/gui/data/test/test_arraywidget.py b/silx/gui/data/test/test_arraywidget.py
new file mode 100644
index 0000000..bbd7ee5
--- /dev/null
+++ b/silx/gui/data/test/test_arraywidget.py
@@ -0,0 +1,320 @@
+# 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.
+#
+# ###########################################################################*/
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+import os
+import tempfile
+import unittest
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.data import ArrayTableWidget
+from silx.gui.test.utils import TestCaseQt
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+
+class TestArrayWidget(TestCaseQt):
+ """Basic test for ArrayTableWidget with a numpy array"""
+ def setUp(self):
+ super(TestArrayWidget, self).setUp()
+ self.aw = ArrayTableWidget.ArrayTableWidget()
+
+ def tearDown(self):
+ del self.aw
+ super(TestArrayWidget, self).tearDown()
+
+ def testShow(self):
+ """test for errors"""
+ self.aw.show()
+ self.qWaitForWindowExposed(self.aw)
+
+ def testSetData0D(self):
+ a = 1
+ self.aw.setArrayData(a)
+ b = self.aw.getData(copy=True)
+
+ self.assertTrue(numpy.array_equal(a, b))
+
+ # scalar/0D data has no frame index
+ self.assertEqual(len(self.aw.model._index), 0)
+ # and no perspective
+ self.assertEqual(len(self.aw.model._perspective), 0)
+
+ def testSetData1D(self):
+ a = [1, 2]
+ self.aw.setArrayData(a)
+ b = self.aw.getData(copy=True)
+
+ self.assertTrue(numpy.array_equal(a, b))
+
+ # 1D data has no frame index
+ self.assertEqual(len(self.aw.model._index), 0)
+ # and no perspective
+ self.assertEqual(len(self.aw.model._perspective), 0)
+
+ def testSetData4D(self):
+ a = numpy.reshape(numpy.linspace(0.213, 1.234, 1250),
+ (5, 5, 5, 10))
+ self.aw.setArrayData(a)
+
+ # default perspective (0, 1)
+ self.assertEqual(list(self.aw.model._perspective),
+ [0, 1])
+ self.aw.setPerspective((1, 3))
+ self.assertEqual(list(self.aw.model._perspective),
+ [1, 3])
+
+ b = self.aw.getData(copy=True)
+ self.assertTrue(numpy.array_equal(a, b))
+
+ # 4D data has a 2-tuple as frame index
+ self.assertEqual(len(self.aw.model._index), 2)
+ # default index is (0, 0)
+ self.assertEqual(list(self.aw.model._index),
+ [0, 0])
+ self.aw.setFrameIndex((3, 1))
+
+ self.assertEqual(list(self.aw.model._index),
+ [3, 1])
+
+ def testColors(self):
+ a = numpy.arange(256, dtype=numpy.uint8)
+ self.aw.setArrayData(a)
+
+ bgcolor = numpy.empty(a.shape + (3,), dtype=numpy.uint8)
+ # Black & white palette
+ bgcolor[..., 0] = a
+ bgcolor[..., 1] = a
+ bgcolor[..., 2] = a
+
+ fgcolor = numpy.bitwise_xor(bgcolor, 255)
+
+ self.aw.setArrayColors(bgcolor, fgcolor)
+
+ # test colors are as expected in model
+ for i in range(256):
+ # all RGB channels for BG equal to data value
+ self.assertEqual(
+ self.aw.model.data(self.aw.model.index(0, i),
+ role=qt.Qt.BackgroundRole),
+ qt.QColor(i, i, i),
+ "Unexpected background color"
+ )
+
+ # all RGB channels for FG equal to XOR(data value, 255)
+ self.assertEqual(
+ self.aw.model.data(self.aw.model.index(0, i),
+ role=qt.Qt.ForegroundRole),
+ qt.QColor(i ^ 255, i ^ 255, i ^ 255),
+ "Unexpected text color"
+ )
+
+ # test colors are reset to None when a new data array is loaded
+ # with different shape
+ self.aw.setArrayData(numpy.arange(300))
+
+ for i in range(300):
+ # all RGB channels for BG equal to data value
+ self.assertIsNone(
+ self.aw.model.data(self.aw.model.index(0, i),
+ role=qt.Qt.BackgroundRole))
+
+ def testDefaultFlagNotEditable(self):
+ """editable should be False by default, in setArrayData"""
+ self.aw.setArrayData([[0]])
+ idx = self.aw.model.createIndex(0, 0)
+ # model is editable
+ self.assertFalse(
+ self.aw.model.flags(idx) & qt.Qt.ItemIsEditable)
+
+ def testFlagEditable(self):
+ self.aw.setArrayData([[0]], editable=True)
+ idx = self.aw.model.createIndex(0, 0)
+ # model is editable
+ self.assertTrue(
+ self.aw.model.flags(idx) & qt.Qt.ItemIsEditable)
+
+ def testFlagNotEditable(self):
+ self.aw.setArrayData([[0]], editable=False)
+ idx = self.aw.model.createIndex(0, 0)
+ # model is editable
+ self.assertFalse(
+ self.aw.model.flags(idx) & qt.Qt.ItemIsEditable)
+
+ def testReferenceReturned(self):
+ """when setting the data with copy=False and
+ retrieving it with getData(copy=False), we should recover
+ the same original object.
+ """
+ # n-D (n >=2)
+ a0 = numpy.reshape(numpy.linspace(0.213, 1.234, 1000),
+ (10, 10, 10))
+ self.aw.setArrayData(a0, copy=False)
+ a1 = self.aw.getData(copy=False)
+
+ self.assertIs(a0, a1)
+
+ # 1D
+ b0 = numpy.linspace(0.213, 1.234, 1000)
+ self.aw.setArrayData(b0, copy=False)
+ b1 = self.aw.getData(copy=False)
+ self.assertIs(b0, b1)
+
+
+@unittest.skipIf(h5py is None, "Could not import h5py")
+class TestH5pyArrayWidget(TestCaseQt):
+ """Basic test for ArrayTableWidget with a dataset.
+
+ Test flags, for dataset open in read-only or read-write modes"""
+ def setUp(self):
+ super(TestH5pyArrayWidget, self).setUp()
+ self.aw = ArrayTableWidget.ArrayTableWidget()
+ self.data = numpy.reshape(numpy.linspace(0.213, 1.234, 1000),
+ (10, 10, 10))
+ # create an h5py file with a dataset
+ self.tempdir = tempfile.mkdtemp()
+ self.h5_fname = os.path.join(self.tempdir, "array.h5")
+ h5f = h5py.File(self.h5_fname)
+ h5f["my_array"] = self.data
+ h5f["my_scalar"] = 3.14
+ h5f["my_1D_array"] = numpy.array(numpy.arange(1000))
+ h5f.close()
+
+ def tearDown(self):
+ del self.aw
+ os.unlink(self.h5_fname)
+ os.rmdir(self.tempdir)
+ super(TestH5pyArrayWidget, self).tearDown()
+
+ def testShow(self):
+ self.aw.show()
+ self.qWaitForWindowExposed(self.aw)
+
+ def testReadOnly(self):
+ """Open H5 dataset in read-only mode, ensure the model is not editable."""
+ h5f = h5py.File(self.h5_fname, "r")
+ a = h5f["my_array"]
+ # ArrayTableModel relies on following condition
+ self.assertTrue(a.file.mode == "r")
+
+ self.aw.setArrayData(a, copy=False, editable=True)
+
+ self.assertIsInstance(a, h5py.Dataset) # simple sanity check
+ # internal representation must be a reference to original data (copy=False)
+ self.assertIsInstance(self.aw.model._array, h5py.Dataset)
+ self.assertTrue(self.aw.model._array.file.mode == "r")
+
+ b = self.aw.getData()
+ self.assertTrue(numpy.array_equal(self.data, b))
+
+ # model must have detected read-only dataset and disabled editing
+ self.assertFalse(self.aw.model._editable)
+ idx = self.aw.model.createIndex(0, 0)
+ self.assertFalse(
+ self.aw.model.flags(idx) & qt.Qt.ItemIsEditable)
+
+ # force editing read-only datasets raises IOError
+ self.assertRaises(IOError, self.aw.model.setData,
+ idx, 123.4, role=qt.Qt.EditRole)
+ h5f.close()
+
+ def testReadWrite(self):
+ h5f = h5py.File(self.h5_fname, "r+")
+ a = h5f["my_array"]
+ self.assertTrue(a.file.mode == "r+")
+
+ self.aw.setArrayData(a, copy=False, editable=True)
+ b = self.aw.getData(copy=False)
+ self.assertTrue(numpy.array_equal(self.data, b))
+
+ idx = self.aw.model.createIndex(0, 0)
+ # model is editable
+ self.assertTrue(
+ self.aw.model.flags(idx) & qt.Qt.ItemIsEditable)
+ h5f.close()
+
+ def testSetData0D(self):
+ h5f = h5py.File(self.h5_fname, "r+")
+ a = h5f["my_scalar"]
+ self.aw.setArrayData(a)
+ b = self.aw.getData(copy=True)
+
+ self.assertTrue(numpy.array_equal(a, b))
+
+ h5f.close()
+
+ def testSetData1D(self):
+ h5f = h5py.File(self.h5_fname, "r+")
+ a = h5f["my_1D_array"]
+ self.aw.setArrayData(a)
+ b = self.aw.getData(copy=True)
+
+ self.assertTrue(numpy.array_equal(a, b))
+
+ h5f.close()
+
+ def testReferenceReturned(self):
+ """when setting the data with copy=False and
+ retrieving it with getData(copy=False), we should recover
+ the same original object.
+
+ This only works for array with at least 2D. For 1D and 0D
+ arrays, a view is created at some point, which in the case
+ of an hdf5 dataset creates a copy."""
+ h5f = h5py.File(self.h5_fname, "r+")
+
+ # n-D
+ a0 = h5f["my_array"]
+ self.aw.setArrayData(a0, copy=False)
+ a1 = self.aw.getData(copy=False)
+ self.assertIs(a0, a1)
+
+ # 1D
+ b0 = h5f["my_1D_array"]
+ self.aw.setArrayData(b0, copy=False)
+ b1 = self.aw.getData(copy=False)
+ self.assertIs(b0, b1)
+
+ h5f.close()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestArrayWidget))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestH5pyArrayWidget))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/data/test/test_dataviewer.py b/silx/gui/data/test/test_dataviewer.py
new file mode 100644
index 0000000..5a0de0b
--- /dev/null
+++ b/silx/gui/data/test/test_dataviewer.py
@@ -0,0 +1,281 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "10/04/2017"
+
+import os
+import tempfile
+import unittest
+from contextlib import contextmanager
+
+import numpy
+from ..DataViewer import DataViewer
+from ..DataViews import DataView
+from .. import DataViews
+
+from silx.gui import qt
+
+from silx.gui.data.DataViewerFrame import DataViewerFrame
+from silx.gui.test.utils import SignalListener
+from silx.gui.test.utils import TestCaseQt
+
+from silx.gui.hdf5.test import _mock
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+
+class _DataViewMock(DataView):
+ """Dummy view to display nothing"""
+
+ def __init__(self, parent):
+ DataView.__init__(self, parent)
+
+ def axesNames(self, data, info):
+ return []
+
+ def createWidget(self, parent):
+ return qt.QLabel(parent)
+
+ def getDataPriority(self, data, info):
+ return 0
+
+
+class AbstractDataViewerTests(TestCaseQt):
+
+ def create_widget(self):
+ raise NotImplementedError()
+
+ @contextmanager
+ def h5_temporary_file(self):
+ # create tmp file
+ fd, tmp_name = tempfile.mkstemp(suffix=".h5")
+ os.close(fd)
+ data = numpy.arange(3 * 3 * 3)
+ data.shape = 3, 3, 3
+ # create h5 data
+ h5file = h5py.File(tmp_name, "w")
+ h5file["data"] = data
+ yield h5file
+ # clean up
+ h5file.close()
+ os.unlink(tmp_name)
+
+ def test_text_data(self):
+ data_list = ["aaa", int, 8, self]
+ widget = self.create_widget()
+ for data in data_list:
+ widget.setData(data)
+ self.assertEqual(DataViewer.RAW_MODE, widget.displayMode())
+
+ def test_plot_1d_data(self):
+ data = numpy.arange(3 ** 1)
+ data.shape = [3] * 1
+ widget = self.create_widget()
+ widget.setData(data)
+ availableModes = set([v.modeId() for v in widget.currentAvailableViews()])
+ self.assertEqual(DataViewer.RAW_MODE, widget.displayMode())
+ self.assertIn(DataViewer.PLOT1D_MODE, availableModes)
+
+ def test_plot_2d_data(self):
+ data = numpy.arange(3 ** 2)
+ data.shape = [3] * 2
+ widget = self.create_widget()
+ widget.setData(data)
+ availableModes = set([v.modeId() for v in widget.currentAvailableViews()])
+ self.assertEqual(DataViewer.RAW_MODE, widget.displayMode())
+ self.assertIn(DataViewer.PLOT2D_MODE, availableModes)
+
+ def test_plot_3d_data(self):
+ data = numpy.arange(3 ** 3)
+ data.shape = [3] * 3
+ widget = self.create_widget()
+ widget.setData(data)
+ availableModes = set([v.modeId() for v in widget.currentAvailableViews()])
+ try:
+ import silx.gui.plot3d # noqa
+ self.assertIn(DataViewer.PLOT3D_MODE, availableModes)
+ except ImportError:
+ self.assertIn(DataViewer.STACK_MODE, availableModes)
+ self.assertEqual(DataViewer.RAW_MODE, widget.displayMode())
+
+ def test_array_1d_data(self):
+ data = numpy.array(["aaa"] * (3 ** 1))
+ data.shape = [3] * 1
+ widget = self.create_widget()
+ widget.setData(data)
+ self.assertEqual(DataViewer.RAW_MODE, widget.displayedView().modeId())
+
+ def test_array_2d_data(self):
+ data = numpy.array(["aaa"] * (3 ** 2))
+ data.shape = [3] * 2
+ widget = self.create_widget()
+ widget.setData(data)
+ self.assertEqual(DataViewer.RAW_MODE, widget.displayedView().modeId())
+
+ def test_array_4d_data(self):
+ data = numpy.array(["aaa"] * (3 ** 4))
+ data.shape = [3] * 4
+ widget = self.create_widget()
+ widget.setData(data)
+ self.assertEqual(DataViewer.RAW_MODE, widget.displayedView().modeId())
+
+ def test_record_4d_data(self):
+ data = numpy.zeros(3 ** 4, dtype='3int8, float32, (2,3)float64')
+ data.shape = [3] * 4
+ widget = self.create_widget()
+ widget.setData(data)
+ self.assertEqual(DataViewer.RAW_MODE, widget.displayedView().modeId())
+
+ def test_3d_h5_dataset(self):
+ if h5py is None:
+ self.skipTest("h5py library is not available")
+ with self.h5_temporary_file() as h5file:
+ dataset = h5file["data"]
+ widget = self.create_widget()
+ widget.setData(dataset)
+
+ def test_data_event(self):
+ listener = SignalListener()
+ widget = self.create_widget()
+ widget.dataChanged.connect(listener)
+ widget.setData(10)
+ widget.setData(None)
+ self.assertEquals(listener.callCount(), 2)
+
+ def test_display_mode_event(self):
+ listener = SignalListener()
+ widget = self.create_widget()
+ widget.displayedViewChanged.connect(listener)
+ widget.setData(10)
+ widget.setData(None)
+ modes = [v.modeId() for v in listener.arguments(argumentIndex=0)]
+ self.assertEquals(modes, [DataViewer.RAW_MODE, DataViewer.EMPTY_MODE])
+ listener.clear()
+
+ def test_change_display_mode(self):
+ data = numpy.arange(10 ** 4)
+ data.shape = [10] * 4
+ widget = self.create_widget()
+ widget.setData(data)
+ widget.setDisplayMode(DataViewer.PLOT1D_MODE)
+ self.assertEquals(widget.displayedView().modeId(), DataViewer.PLOT1D_MODE)
+ widget.setDisplayMode(DataViewer.PLOT2D_MODE)
+ self.assertEquals(widget.displayedView().modeId(), DataViewer.PLOT2D_MODE)
+ widget.setDisplayMode(DataViewer.RAW_MODE)
+ self.assertEquals(widget.displayedView().modeId(), DataViewer.RAW_MODE)
+ widget.setDisplayMode(DataViewer.EMPTY_MODE)
+ self.assertEquals(widget.displayedView().modeId(), DataViewer.EMPTY_MODE)
+
+ def test_create_default_views(self):
+ widget = self.create_widget()
+ views = widget.createDefaultViews()
+ self.assertTrue(len(views) > 0)
+
+ def test_add_view(self):
+ widget = self.create_widget()
+ view = _DataViewMock(widget)
+ widget.addView(view)
+ self.assertTrue(view in widget.availableViews())
+ self.assertTrue(view in widget.currentAvailableViews())
+
+ def test_remove_view(self):
+ widget = self.create_widget()
+ widget.setData("foobar")
+ view = widget.currentAvailableViews()[0]
+ widget.removeView(view)
+ self.assertTrue(view not in widget.availableViews())
+ self.assertTrue(view not in widget.currentAvailableViews())
+
+class TestDataViewer(AbstractDataViewerTests):
+ def create_widget(self):
+ return DataViewer()
+
+
+class TestDataViewerFrame(AbstractDataViewerTests):
+ def create_widget(self):
+ return DataViewerFrame()
+
+
+class TestDataView(TestCaseQt):
+
+ def createComplexData(self):
+ line = [1, 2j, 3+3j, 4]
+ image = [line, line, line, line]
+ cube = [image, image, image, image]
+ data = numpy.array(cube,
+ dtype=numpy.complex)
+ return data
+
+ def createDataViewWithData(self, dataViewClass, data):
+ viewer = dataViewClass(None)
+ widget = viewer.getWidget()
+ viewer.setData(data)
+ return widget
+
+ def testCurveWithComplex(self):
+ data = self.createComplexData()
+ dataViewClass = DataViews._Plot1dView
+ widget = self.createDataViewWithData(dataViewClass, data[0, 0])
+ self.qWaitForWindowExposed(widget)
+
+ def testImageWithComplex(self):
+ data = self.createComplexData()
+ dataViewClass = DataViews._Plot2dView
+ widget = self.createDataViewWithData(dataViewClass, data[0])
+ self.qWaitForWindowExposed(widget)
+
+ def testCubeWithComplex(self):
+ self.skipTest("OpenGL widget not yet tested")
+ try:
+ import silx.gui.plot3d # noqa
+ except ImportError:
+ self.skipTest("OpenGL not available")
+ data = self.createComplexData()
+ dataViewClass = DataViews._Plot3dView
+ widget = self.createDataViewWithData(dataViewClass, data)
+ self.qWaitForWindowExposed(widget)
+
+ def testImageStackWithComplex(self):
+ data = self.createComplexData()
+ dataViewClass = DataViews._StackView
+ widget = self.createDataViewWithData(dataViewClass, data)
+ self.qWaitForWindowExposed(widget)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ loadTestsFromTestCase = unittest.defaultTestLoader.loadTestsFromTestCase
+ test_suite.addTest(loadTestsFromTestCase(TestDataViewer))
+ test_suite.addTest(loadTestsFromTestCase(TestDataViewerFrame))
+ test_suite.addTest(loadTestsFromTestCase(TestDataView))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/data/test/test_numpyaxesselector.py b/silx/gui/data/test/test_numpyaxesselector.py
new file mode 100644
index 0000000..cc15f83
--- /dev/null
+++ b/silx/gui/data/test/test_numpyaxesselector.py
@@ -0,0 +1,152 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "15/12/2016"
+
+import os
+import tempfile
+import unittest
+from contextlib import contextmanager
+
+import numpy
+
+from silx.gui.data.NumpyAxesSelector import NumpyAxesSelector
+from silx.gui.test.utils import SignalListener
+from silx.gui.test.utils import TestCaseQt
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+
+class TestNumpyAxesSelector(TestCaseQt):
+
+ def test_creation(self):
+ data = numpy.arange(3 * 3 * 3)
+ data.shape = 3, 3, 3
+ widget = NumpyAxesSelector()
+ widget.setVisible(True)
+
+ def test_none(self):
+ data = numpy.arange(3 * 3 * 3)
+ widget = NumpyAxesSelector()
+ widget.setData(data)
+ widget.setData(None)
+ result = widget.selectedData()
+ self.assertIsNone(result)
+
+ def test_output_samedim(self):
+ data = numpy.arange(3 * 3 * 3)
+ data.shape = 3, 3, 3
+ expectedResult = data
+
+ widget = NumpyAxesSelector()
+ widget.setAxisNames(["x", "y", "z"])
+ widget.setData(data)
+ result = widget.selectedData()
+ self.assertTrue(numpy.array_equal(result, expectedResult))
+
+ def test_output_lessdim(self):
+ data = numpy.arange(3 * 3 * 3)
+ data.shape = 3, 3, 3
+ expectedResult = data[0]
+
+ widget = NumpyAxesSelector()
+ widget.setAxisNames(["y", "x"])
+ widget.setData(data)
+ result = widget.selectedData()
+ self.assertTrue(numpy.array_equal(result, expectedResult))
+
+ def test_output_1dim(self):
+ data = numpy.arange(3 * 3 * 3)
+ data.shape = 3, 3, 3
+ expectedResult = data[0, 0, 0]
+
+ widget = NumpyAxesSelector()
+ widget.setData(data)
+ result = widget.selectedData()
+ self.assertTrue(numpy.array_equal(result, expectedResult))
+
+ @contextmanager
+ def h5_temporary_file(self):
+ # create tmp file
+ fd, tmp_name = tempfile.mkstemp(suffix=".h5")
+ os.close(fd)
+ data = numpy.arange(3 * 3 * 3)
+ data.shape = 3, 3, 3
+ # create h5 data
+ h5file = h5py.File(tmp_name, "w")
+ h5file["data"] = data
+ yield h5file
+ # clean up
+ h5file.close()
+ os.unlink(tmp_name)
+
+ def test_h5py_dataset(self):
+ if h5py is None:
+ self.skipTest("h5py library is not available")
+ with self.h5_temporary_file() as h5file:
+ dataset = h5file["data"]
+ expectedResult = dataset[0]
+
+ widget = NumpyAxesSelector()
+ widget.setData(dataset)
+ widget.setAxisNames(["y", "x"])
+ result = widget.selectedData()
+ self.assertTrue(numpy.array_equal(result, expectedResult))
+
+ def test_data_event(self):
+ data = numpy.arange(3 * 3 * 3)
+ widget = NumpyAxesSelector()
+ listener = SignalListener()
+ widget.dataChanged.connect(listener)
+ widget.setData(data)
+ widget.setData(None)
+ self.assertEqual(listener.callCount(), 2)
+
+ def test_selected_data_event(self):
+ data = numpy.arange(3 * 3 * 3)
+ data.shape = 3, 3, 3
+ widget = NumpyAxesSelector()
+ listener = SignalListener()
+ widget.selectionChanged.connect(listener)
+ widget.setData(data)
+ widget.setAxisNames(["x"])
+ widget.setData(None)
+ self.assertEqual(listener.callCount(), 3)
+ listener.clear()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestNumpyAxesSelector))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/data/test/test_textformatter.py b/silx/gui/data/test/test_textformatter.py
new file mode 100644
index 0000000..f21e033
--- /dev/null
+++ b/silx/gui/data/test/test_textformatter.py
@@ -0,0 +1,94 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "24/01/2017"
+
+import unittest
+
+from silx.gui.test.utils import TestCaseQt
+from silx.gui.test.utils import SignalListener
+from ..TextFormatter import TextFormatter
+
+
+class TestTextFormatter(TestCaseQt):
+
+ def test_copy(self):
+ formatter = TextFormatter()
+ copy = TextFormatter(formatter=formatter)
+ self.assertIsNot(formatter, copy)
+ copy.setFloatFormat("%.3f")
+ self.assertEquals(formatter.integerFormat(), copy.integerFormat())
+ self.assertNotEquals(formatter.floatFormat(), copy.floatFormat())
+ self.assertEquals(formatter.useQuoteForText(), copy.useQuoteForText())
+ self.assertEquals(formatter.imaginaryUnit(), copy.imaginaryUnit())
+
+ def test_event(self):
+ listener = SignalListener()
+ formatter = TextFormatter()
+ formatter.formatChanged.connect(listener)
+ formatter.setFloatFormat("%.3f")
+ formatter.setIntegerFormat("%03i")
+ formatter.setUseQuoteForText(False)
+ formatter.setImaginaryUnit("z")
+ self.assertEquals(listener.callCount(), 4)
+
+ def test_int(self):
+ formatter = TextFormatter()
+ formatter.setIntegerFormat("%05i")
+ result = formatter.toString(512)
+ self.assertEquals(result, "00512")
+
+ def test_float(self):
+ formatter = TextFormatter()
+ formatter.setFloatFormat("%.3f")
+ result = formatter.toString(1.3)
+ self.assertEquals(result, "1.300")
+
+ def test_complex(self):
+ formatter = TextFormatter()
+ formatter.setFloatFormat("%.1f")
+ formatter.setImaginaryUnit("i")
+ result = formatter.toString(1.0 + 5j)
+ result = result.replace(" ", "")
+ self.assertEquals(result, "1.0+5.0i")
+
+ def test_string(self):
+ formatter = TextFormatter()
+ formatter.setIntegerFormat("%.1f")
+ formatter.setImaginaryUnit("z")
+ result = formatter.toString("toto")
+ self.assertEquals(result, '"toto"')
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestTextFormatter))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/fit/BackgroundWidget.py b/silx/gui/fit/BackgroundWidget.py
new file mode 100644
index 0000000..577a8c7
--- /dev/null
+++ b/silx/gui/fit/BackgroundWidget.py
@@ -0,0 +1,530 @@
+# coding: utf-8
+#/*##########################################################################
+# Copyright (C) 2004-2017 V.A. Sole, European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# 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.
+#
+# #########################################################################*/
+"""This module provides a background configuration widget
+:class:`BackgroundWidget` and a corresponding dialog window
+:class:`BackgroundDialog`."""
+import sys
+import numpy
+from silx.gui import qt
+from silx.gui.plot import PlotWidget
+from silx.math.fit import filters
+
+__authors__ = ["V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "24/01/2017"
+
+
+class HorizontalSpacer(qt.QWidget):
+ def __init__(self, *args):
+ qt.QWidget.__init__(self, *args)
+ self.setSizePolicy(qt.QSizePolicy(qt.QSizePolicy.Expanding,
+ qt.QSizePolicy.Fixed))
+
+
+class BackgroundParamWidget(qt.QWidget):
+ """Background configuration composite widget.
+
+ Strip and snip filters parameters can be adjusted using input widgets.
+
+ Updating the widgets causes :attr:`sigBackgroundParamWidgetSignal` to
+ be emitted.
+ """
+ sigBackgroundParamWidgetSignal = qt.pyqtSignal(object)
+
+ def __init__(self, parent=None):
+ qt.QWidget.__init__(self, parent)
+
+ self.mainLayout = qt.QGridLayout(self)
+ self.mainLayout.setColumnStretch(1, 1)
+
+ # Algorithm choice ---------------------------------------------------
+ self.algorithmComboLabel = qt.QLabel(self)
+ self.algorithmComboLabel.setText("Background algorithm")
+ self.algorithmCombo = qt.QComboBox(self)
+ self.algorithmCombo.addItem("Strip")
+ self.algorithmCombo.addItem("Snip")
+ self.algorithmCombo.activated[int].connect(
+ self._algorithmComboActivated)
+
+ # Strip parameters ---------------------------------------------------
+ self.stripWidthLabel = qt.QLabel(self)
+ self.stripWidthLabel.setText("Strip Width")
+
+ self.stripWidthSpin = qt.QSpinBox(self)
+ self.stripWidthSpin.setMaximum(100)
+ self.stripWidthSpin.setMinimum(1)
+ self.stripWidthSpin.valueChanged[int].connect(self._emitSignal)
+
+ self.stripIterLabel = qt.QLabel(self)
+ self.stripIterLabel.setText("Strip Iterations")
+ self.stripIterValue = qt.QLineEdit(self)
+ validator = qt.QIntValidator(self.stripIterValue)
+ self.stripIterValue._v = validator
+ self.stripIterValue.setText("0")
+ self.stripIterValue.editingFinished[()].connect(self._emitSignal)
+ self.stripIterValue.setToolTip(
+ "Number of iterations for strip algorithm.\n" +
+ "If greater than 999, an 2nd pass of strip filter is " +
+ "applied to remove artifacts created by first pass.")
+
+ # Snip parameters ----------------------------------------------------
+ self.snipWidthLabel = qt.QLabel(self)
+ self.snipWidthLabel.setText("Snip Width")
+
+ self.snipWidthSpin = qt.QSpinBox(self)
+ self.snipWidthSpin.setMaximum(300)
+ self.snipWidthSpin.setMinimum(0)
+ self.snipWidthSpin.valueChanged[int].connect(self._emitSignal)
+
+
+ # Smoothing parameters -----------------------------------------------
+ self.smoothingFlagCheck = qt.QCheckBox(self)
+ self.smoothingFlagCheck.setText("Smoothing Width (Savitsky-Golay)")
+ self.smoothingFlagCheck.toggled.connect(self._smoothingToggled)
+
+ self.smoothingSpin = qt.QSpinBox(self)
+ self.smoothingSpin.setMinimum(3)
+ #self.smoothingSpin.setMaximum(40)
+ self.smoothingSpin.setSingleStep(2)
+ self.smoothingSpin.valueChanged[int].connect(self._emitSignal)
+
+ # Anchors ------------------------------------------------------------
+
+ self.anchorsGroup = qt.QWidget(self)
+ anchorsLayout = qt.QHBoxLayout(self.anchorsGroup)
+ anchorsLayout.setSpacing(2)
+ anchorsLayout.setContentsMargins(0, 0, 0, 0)
+
+ self.anchorsFlagCheck = qt.QCheckBox(self.anchorsGroup)
+ self.anchorsFlagCheck.setText("Use anchors")
+ self.anchorsFlagCheck.setToolTip(
+ "Define X coordinates of points that must remain fixed")
+ self.anchorsFlagCheck.stateChanged[int].connect(
+ self._anchorsToggled)
+ anchorsLayout.addWidget(self.anchorsFlagCheck)
+
+ maxnchannel = 16384 * 4 # Fixme ?
+ self.anchorsList = []
+ num_anchors = 4
+ for i in range(num_anchors):
+ anchorSpin = qt.QSpinBox(self.anchorsGroup)
+ anchorSpin.setMinimum(0)
+ anchorSpin.setMaximum(maxnchannel)
+ anchorSpin.valueChanged[int].connect(self._emitSignal)
+ anchorsLayout.addWidget(anchorSpin)
+ self.anchorsList.append(anchorSpin)
+
+ # Layout ------------------------------------------------------------
+ self.mainLayout.addWidget(self.algorithmComboLabel, 0, 0)
+ self.mainLayout.addWidget(self.algorithmCombo, 0, 2)
+ self.mainLayout.addWidget(self.stripWidthLabel, 1, 0)
+ self.mainLayout.addWidget(self.stripWidthSpin, 1, 2)
+ self.mainLayout.addWidget(self.stripIterLabel, 2, 0)
+ self.mainLayout.addWidget(self.stripIterValue, 2, 2)
+ self.mainLayout.addWidget(self.snipWidthLabel, 3, 0)
+ self.mainLayout.addWidget(self.snipWidthSpin, 3, 2)
+ self.mainLayout.addWidget(self.smoothingFlagCheck, 4, 0)
+ self.mainLayout.addWidget(self.smoothingSpin, 4, 2)
+ self.mainLayout.addWidget(self.anchorsGroup, 5, 0, 1, 4)
+
+ # Initialize interface -----------------------------------------------
+ self._setAlgorithm("strip")
+ self.smoothingFlagCheck.setChecked(False)
+ self._smoothingToggled(is_checked=False)
+ self.anchorsFlagCheck.setChecked(False)
+ self._anchorsToggled(is_checked=False)
+
+ def _algorithmComboActivated(self, algorithm_index):
+ self._setAlgorithm("strip" if algorithm_index == 0 else "snip")
+
+ def _setAlgorithm(self, algorithm):
+ """Enable/disable snip and snip input widgets, depending on the
+ chosen algorithm.
+ :param algorithm: "snip" or "strip"
+ """
+ if algorithm not in ["strip", "snip"]:
+ raise ValueError(
+ "Unknown background filter algorithm %s" % algorithm)
+
+ self.algorithm = algorithm
+ self.stripWidthSpin.setEnabled(algorithm == "strip")
+ self.stripIterValue.setEnabled(algorithm == "strip")
+ self.snipWidthSpin.setEnabled(algorithm == "snip")
+
+ def _smoothingToggled(self, is_checked):
+ """Enable/disable smoothing input widgets, emit dictionary"""
+ self.smoothingSpin.setEnabled(is_checked)
+ self._emitSignal()
+
+ def _anchorsToggled(self, is_checked):
+ """Enable/disable all spin widgets defining anchor X coordinates,
+ emit signal.
+ """
+ for anchor_spin in self.anchorsList:
+ anchor_spin.setEnabled(is_checked)
+ self._emitSignal()
+
+ def setParameters(self, ddict):
+ """Set values for all input widgets.
+
+ :param dict ddict: Input dictionary, must have the same
+ keys as the dictionary output by :meth:`getParameters`
+ """
+ if "algorithm" in ddict:
+ self._setAlgorithm(ddict["algorithm"])
+
+ if "SnipWidth" in ddict:
+ self.snipWidthSpin.setValue(int(ddict["SnipWidth"]))
+
+ if "StripWidth" in ddict:
+ self.stripWidthSpin.setValue(int(ddict["StripWidth"]))
+
+ if "StripIterations" in ddict:
+ self.stripIterValue.setText("%d" % int(ddict["StripIterations"]))
+
+ if "SmoothingFlag" in ddict:
+ self.smoothingFlagCheck.setChecked(bool(ddict["SmoothingFlag"]))
+
+ if "SmoothingWidth" in ddict:
+ self.smoothingSpin.setValue(int(ddict["SmoothingWidth"]))
+
+ if "AnchorsFlag" in ddict:
+ self.anchorsFlagCheck.setChecked(bool(ddict["AnchorsFlag"]))
+
+ if "AnchorsList" in ddict:
+ anchorslist = ddict["AnchorsList"]
+ if anchorslist in [None, 'None']:
+ anchorslist = []
+ for spin in self.anchorsList:
+ spin.setValue(0)
+
+ i = 0
+ for value in anchorslist:
+ self.anchorsList[i].setValue(int(value))
+ i += 1
+
+ def getParameters(self):
+ """Return dictionary of parameters defined in the GUI
+
+ The returned dictionary contains following values:
+
+ - *algorithm*: *"strip"* or *"snip"*
+ - *StripWidth*: width of strip iterator
+ - *StripIterations*: number of iterations
+ - *StripThreshold*: curvature parameter (currently fixed to 1.0)
+ - *SnipWidth*: width of snip algorithm
+ - *SmoothingFlag*: flag to enable/disable smoothing
+ - *SmoothingWidth*: width of Savitsky-Golay smoothing filter
+ - *AnchorsFlag*: flag to enable/disable anchors
+ - *AnchorsList*: list of anchors (X coordinates of fixed values)
+ """
+ stripitertext = self.stripIterValue.text()
+ stripiter = int(stripitertext) if len(stripitertext) else 0
+
+ return {"algorithm": self.algorithm,
+ "StripThreshold": 1.0,
+ "SnipWidth": self.snipWidthSpin.value(),
+ "StripIterations": stripiter,
+ "StripWidth": self.stripWidthSpin.value(),
+ "SmoothingFlag": self.smoothingFlagCheck.isChecked(),
+ "SmoothingWidth": self.smoothingSpin.value(),
+ "AnchorsFlag": self.anchorsFlagCheck.isChecked(),
+ "AnchorsList": [spin.value() for spin in self.anchorsList]}
+
+ def _emitSignal(self, dummy=None):
+ self.sigBackgroundParamWidgetSignal.emit(
+ {'event': 'ParametersChanged',
+ 'parameters': self.getParameters()})
+
+
+class BackgroundWidget(qt.QWidget):
+ """Background configuration widget, with a :class:`PlotWindow`.
+
+ Strip and snip filters parameters can be adjusted using input widgets,
+ and the computed backgrounds are plotted next to the original data to
+ show the result."""
+ def __init__(self, parent=None):
+ qt.QWidget.__init__(self, parent)
+ self.setWindowTitle("Strip and SNIP Configuration Window")
+ self.mainLayout = qt.QVBoxLayout(self)
+ self.mainLayout.setContentsMargins(0, 0, 0, 0)
+ self.mainLayout.setSpacing(2)
+ self.parametersWidget = BackgroundParamWidget(self)
+ self.graphWidget = PlotWidget(parent=self)
+ self.mainLayout.addWidget(self.parametersWidget)
+ self.mainLayout.addWidget(self.graphWidget)
+ self._x = None
+ self._y = None
+ self.parametersWidget.sigBackgroundParamWidgetSignal.connect(self._slot)
+
+ def getParameters(self):
+ """Return dictionary of parameters defined in the GUI
+
+ The returned dictionary contains following values:
+
+ - *algorithm*: *"strip"* or *"snip"*
+ - *StripWidth*: width of strip iterator
+ - *StripIterations*: number of iterations
+ - *StripThreshold*: strip curvature (currently fixed to 1.0)
+ - *SnipWidth*: width of snip algorithm
+ - *SmoothingFlag*: flag to enable/disable smoothing
+ - *SmoothingWidth*: width of Savitsky-Golay smoothing filter
+ - *AnchorsFlag*: flag to enable/disable anchors
+ - *AnchorsList*: list of anchors (X coordinates of fixed values)
+ """
+ return self.parametersWidget.getParameters()
+
+ def setParameters(self, ddict):
+ """Set values for all input widgets.
+
+ :param dict ddict: Input dictionary, must have the same
+ keys as the dictionary output by :meth:`getParameters`
+ """
+ return self.parametersWidget.setParameters(ddict)
+
+ def setData(self, x, y, xmin=None, xmax=None):
+ """Set data for the original curve, and _update strip and snip
+ curves accordingly.
+
+ :param x: Array or sequence of curve abscissa values
+ :param y: Array or sequence of curve ordinate values
+ :param xmin: Min value to be displayed on the X axis
+ :param xmax: Max value to be displayed on the X axis
+ """
+ self._x = x
+ self._y = y
+ self._xmin = xmin
+ self._xmax = xmax
+ self._update(resetzoom=True)
+
+ def _slot(self, ddict):
+ self._update()
+
+ def _update(self, resetzoom=False):
+ """Compute strip and snip backgrounds, update the curves
+ """
+ if self._y is None:
+ return
+
+ pars = self.getParameters()
+
+ # smoothed data
+ y = numpy.ravel(numpy.array(self._y)).astype(numpy.float)
+ if pars["SmoothingFlag"]:
+ ysmooth = filters.savitsky_golay(y, pars['SmoothingWidth'])
+ f = [0.25, 0.5, 0.25]
+ ysmooth[1:-1] = numpy.convolve(ysmooth, f, mode=0)
+ ysmooth[0] = 0.5 * (ysmooth[0] + ysmooth[1])
+ ysmooth[-1] = 0.5 * (ysmooth[-1] + ysmooth[-2])
+ else:
+ ysmooth = y
+
+
+ # loop for anchors
+ x = self._x
+ niter = pars['StripIterations']
+ anchors_indices = []
+ if pars['AnchorsFlag'] and pars['AnchorsList'] is not None:
+ ravelled = x
+ for channel in pars['AnchorsList']:
+ if channel <= ravelled[0]:
+ continue
+ index = numpy.nonzero(ravelled >= channel)[0]
+ if len(index):
+ index = min(index)
+ if index > 0:
+ anchors_indices.append(index)
+
+ stripBackground = filters.strip(ysmooth,
+ w=pars['StripWidth'],
+ niterations=niter,
+ factor=pars['StripThreshold'],
+ anchors=anchors_indices)
+
+ if niter >= 1000:
+ # final smoothing
+ stripBackground = filters.strip(stripBackground,
+ w=1,
+ niterations=50*pars['StripWidth'],
+ factor=pars['StripThreshold'],
+ anchors=anchors_indices)
+
+ if len(anchors_indices) == 0:
+ anchors_indices = [0, len(ysmooth)-1]
+ anchors_indices.sort()
+ snipBackground = 0.0 * ysmooth
+ lastAnchor = 0
+ for anchor in anchors_indices:
+ if (anchor > lastAnchor) and (anchor < len(ysmooth)):
+ snipBackground[lastAnchor:anchor] =\
+ filters.snip1d(ysmooth[lastAnchor:anchor],
+ pars['SnipWidth'])
+ lastAnchor = anchor
+ if lastAnchor < len(ysmooth):
+ snipBackground[lastAnchor:] =\
+ filters.snip1d(ysmooth[lastAnchor:],
+ pars['SnipWidth'])
+
+ self.graphWidget.addCurve(x, y,
+ legend='Input Data',
+ replace=True,
+ resetzoom=resetzoom)
+ self.graphWidget.addCurve(x, stripBackground,
+ legend='Strip Background',
+ resetzoom=False)
+ self.graphWidget.addCurve(x, snipBackground,
+ legend='SNIP Background',
+ resetzoom=False)
+ if self._xmin is not None and self._xmax is not None:
+ self.graphWidget.setGraphXLimits(xmin=self._xmin, xmax=self._xmax)
+
+
+class BackgroundDialog(qt.QDialog):
+ """QDialog window featuring a :class:`BackgroundWidget`"""
+ def __init__(self, parent=None):
+ qt.QDialog.__init__(self, parent)
+ self.setWindowTitle("Strip and Snip Configuration Window")
+ self.mainLayout = qt.QVBoxLayout(self)
+ self.mainLayout.setContentsMargins(0, 0, 0, 0)
+ self.mainLayout.setSpacing(2)
+ self.parametersWidget = BackgroundWidget(self)
+ self.mainLayout.addWidget(self.parametersWidget)
+ hbox = qt.QWidget(self)
+ hboxLayout = qt.QHBoxLayout(hbox)
+ hboxLayout.setContentsMargins(0, 0, 0, 0)
+ hboxLayout.setSpacing(2)
+ self.okButton = qt.QPushButton(hbox)
+ self.okButton.setText("OK")
+ self.okButton.setAutoDefault(False)
+ self.dismissButton = qt.QPushButton(hbox)
+ self.dismissButton.setText("Cancel")
+ self.dismissButton.setAutoDefault(False)
+ hboxLayout.addWidget(HorizontalSpacer(hbox))
+ hboxLayout.addWidget(self.okButton)
+ hboxLayout.addWidget(self.dismissButton)
+ self.mainLayout.addWidget(hbox)
+ self.dismissButton.clicked.connect(self.reject)
+ self.okButton.clicked.connect(self.accept)
+
+ self.output = {}
+ """Configuration dictionary containing following fields:
+
+ - *SmoothingFlag*
+ - *SmoothingWidth*
+ - *StripWidth*
+ - *StripIterations*
+ - *StripThreshold*
+ - *SnipWidth*
+ - *AnchorsFlag*
+ - *AnchorsList*
+ """
+
+ # self.parametersWidget.parametersWidget.sigBackgroundParamWidgetSignal.connect(self.updateOutput)
+
+ # def updateOutput(self, ddict):
+ # self.output = ddict
+
+ def accept(self):
+ """Update :attr:`output`, then call :meth:`QDialog.accept`
+ """
+ self.output = self.getParameters()
+ super(BackgroundDialog, self).accept()
+
+ def sizeHint(self):
+ return qt.QSize(int(1.5*qt.QDialog.sizeHint(self).width()),
+ qt.QDialog.sizeHint(self).height())
+
+ def setData(self, x, y, xmin=None, xmax=None):
+ """See :meth:`BackgroundWidget.setData`"""
+ return self.parametersWidget.setData(x, y, xmin, xmax)
+
+ def getParameters(self):
+ """See :meth:`BackgroundWidget.getParameters`"""
+ return self.parametersWidget.getParameters()
+
+ def setParameters(self, ddict):
+ """See :meth:`BackgroundWidget.setParameters`"""
+ return self.parametersWidget.setParameters(ddict)
+
+ def setDefault(self, ddict):
+ """Alias for :meth:`setParameters`"""
+ return self.setParameters(ddict)
+
+
+def getBgDialog(parent=None, default=None, modal=True):
+ """Instantiate and return a bg configuration dialog, adapted
+ for configuring standard background theories from
+ :mod:`silx.math.fit.bgtheories`.
+
+ :return: Instance of :class:`BackgroundDialog`
+ """
+ bgd = BackgroundDialog(parent=parent)
+ # apply default to newly added pages
+ bgd.setParameters(default)
+
+ return bgd
+
+
+def main():
+ # synthetic data
+ 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 + numpy.average(y0) * noise + actual_bg
+
+ # Open widget
+ a = qt.QApplication(sys.argv)
+ a.lastWindowClosed.connect(a.quit)
+
+ def mySlot(ddict):
+ print(ddict)
+
+ w = BackgroundDialog()
+ w.parametersWidget.parametersWidget.sigBackgroundParamWidgetSignal.connect(mySlot)
+ w.setData(x, y)
+ w.exec_()
+ #a.exec_()
+
+if __name__ == "__main__":
+ main()
diff --git a/silx/gui/fit/FitConfig.py b/silx/gui/fit/FitConfig.py
new file mode 100644
index 0000000..70b6fbe
--- /dev/null
+++ b/silx/gui/fit/FitConfig.py
@@ -0,0 +1,540 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2004-2016 V.A. Sole, European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# 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.
+#
+# ######################################################################### */
+"""This module defines widgets used to build a fit configuration dialog.
+The resulting dialog widget outputs a dictionary of configuration parameters.
+"""
+from silx.gui import qt
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "30/11/2016"
+
+
+class TabsDialog(qt.QDialog):
+ """Dialog widget containing a QTabWidget :attr:`tabWidget`
+ and a buttons:
+
+ # - buttonHelp
+ - buttonDefaults
+ - buttonOk
+ - buttonCancel
+
+ This dialog defines a __len__ returning the number of tabs,
+ and an __iter__ method yielding the tab widgets.
+ """
+ def __init__(self, parent=None):
+ qt.QDialog.__init__(self, parent)
+ self.tabWidget = qt.QTabWidget(self)
+
+ layout = qt.QVBoxLayout(self)
+ layout.addWidget(self.tabWidget)
+
+ layout2 = qt.QHBoxLayout(None)
+
+ # self.buttonHelp = qt.QPushButton(self)
+ # self.buttonHelp.setText("Help")
+ # layout2.addWidget(self.buttonHelp)
+
+ self.buttonDefault = qt.QPushButton(self)
+ self.buttonDefault.setText("Default")
+ layout2.addWidget(self.buttonDefault)
+
+ spacer = qt.QSpacerItem(20, 20,
+ qt.QSizePolicy.Expanding,
+ qt.QSizePolicy.Minimum)
+ layout2.addItem(spacer)
+
+ self.buttonOk = qt.QPushButton(self)
+ self.buttonOk.setText("OK")
+ layout2.addWidget(self.buttonOk)
+
+ self.buttonCancel = qt.QPushButton(self)
+ self.buttonCancel.setText("Cancel")
+ layout2.addWidget(self.buttonCancel)
+
+ layout.addLayout(layout2)
+
+ self.buttonOk.clicked.connect(self.accept)
+ self.buttonCancel.clicked.connect(self.reject)
+
+ def __len__(self):
+ """Return number of tabs"""
+ return self.tabWidget.count()
+
+ def __iter__(self):
+ """Return the next tab widget in :attr:`tabWidget` every
+ time this method is called.
+
+ :return: Tab widget
+ :rtype: QWidget
+ """
+ for widget_index in range(len(self)):
+ yield self.tabWidget.widget(widget_index)
+
+ def addTab(self, page, label):
+ """Add a new tab
+
+ :param page: Content of new page. Must be a widget with
+ a get() method returning a dictionary.
+ :param str label: Tab label
+ """
+ self.tabWidget.addTab(page, label)
+
+ def getTabLabels(self):
+ """
+ Return a list of all tab labels in :attr:`tabWidget`
+ """
+ return [self.tabWidget.tabText(i) for i in range(len(self))]
+
+
+class TabsDialogData(TabsDialog):
+ """This dialog adds a data attribute to :class:`TabsDialog`.
+
+ Data input in widgets, such as text entries or checkboxes, is stored in an
+ attribute :attr:`output` when the user clicks the OK button.
+
+ A default dictionary can be supplied when this dialog is initialized, to
+ be used as default data for :attr:`output`.
+ """
+ def __init__(self, parent=None, modal=True, default=None):
+ """
+
+ :param parent: Parent :class:`QWidget`
+ :param modal: If `True`, dialog is modal, meaning this dialog remains
+ in front of it's parent window and disables it until the user is
+ done interacting with the dialog
+ :param default: Default dictionary, used to initialize and reset
+ :attr:`output`.
+ """
+ TabsDialog.__init__(self, parent)
+ self.setModal(modal)
+ self.setWindowTitle("Fit configuration")
+
+ self.output = {}
+
+ self.default = {} if default is None else default
+
+ self.buttonDefault.clicked.connect(self.setDefault)
+ # self.keyPressEvent(qt.Qt.Key_Enter).
+
+ def keyPressEvent(self, event):
+ """Redefining this method to ignore Enter key
+ (for some reason it activates buttonDefault callback which
+ resets all widgets)
+ """
+ if event.key() in [qt.Qt.Key_Enter, qt.Qt.Key_Return]:
+ return
+ TabsDialog.keyPressEvent(self, event)
+
+ def accept(self):
+ """When *OK* is clicked, update :attr:`output` with data from
+ various widgets
+ """
+ self.output.update(self.default)
+
+ # loop over all tab widgets (uses TabsDialog.__iter__)
+ for tabWidget in self:
+ self.output.update(tabWidget.get())
+
+ # avoid pathological None cases
+ for key in self.output.keys():
+ if self.output[key] is None:
+ if key in self.default:
+ self.output[key] = self.default[key]
+ super(TabsDialogData, self).accept()
+
+ def reject(self):
+ """When the *Cancel* button is clicked, reinitialize :attr:`output`
+ and quit
+ """
+ self.setDefault()
+ super(TabsDialogData, self).reject()
+
+ def setDefault(self, newdefault=None):
+ """Reinitialize :attr:`output` with :attr:`default` or with
+ new dictionary ``newdefault`` if provided.
+ Call :meth:`setDefault` for each tab widget, if available.
+ """
+ self.output = {}
+ if newdefault is None:
+ newdefault = self.default
+ else:
+ self.default = newdefault
+ self.output.update(newdefault)
+
+ for tabWidget in self:
+ if hasattr(tabWidget, "setDefault"):
+ tabWidget.setDefault(self.output)
+
+
+class ConstraintsPage(qt.QGroupBox):
+ """Checkable QGroupBox widget filled with QCheckBox widgets,
+ to configure the fit estimation for standard fit theories.
+ """
+ def __init__(self, parent=None, title="Set constraints"):
+ super(ConstraintsPage, self).__init__(parent)
+ self.setTitle(title)
+ self.setToolTip("Disable 'Set constraints' to remove all " +
+ "constraints on all fit parameters")
+ self.setCheckable(True)
+
+ layout = qt.QVBoxLayout(self)
+ self.setLayout(layout)
+
+ self.positiveHeightCB = qt.QCheckBox("Force positive height/area", self)
+ self.positiveHeightCB.setToolTip("Fit must find positive peaks")
+ layout.addWidget(self.positiveHeightCB)
+
+ self.positionInIntervalCB = qt.QCheckBox("Force position in interval", self)
+ self.positionInIntervalCB.setToolTip(
+ "Fit must position peak within X limits")
+ layout.addWidget(self.positionInIntervalCB)
+
+ self.positiveFwhmCB = qt.QCheckBox("Force positive FWHM", self)
+ self.positiveFwhmCB.setToolTip("Fit must find a positive FWHM")
+ layout.addWidget(self.positiveFwhmCB)
+
+ self.sameFwhmCB = qt.QCheckBox("Force same FWHM for all peaks", self)
+ self.sameFwhmCB.setToolTip("Fit must find same FWHM for all peaks")
+ layout.addWidget(self.sameFwhmCB)
+
+ self.quotedEtaCB = qt.QCheckBox("Force Eta between 0 and 1", self)
+ self.quotedEtaCB.setToolTip(
+ "Fit must find Eta between 0 and 1 for pseudo-Voigt function")
+ layout.addWidget(self.quotedEtaCB)
+
+ layout.addStretch()
+
+ self.setDefault()
+
+ def setDefault(self, default_dict=None):
+ """Set default state for all widgets.
+
+ :param default_dict: If a default config dictionary is provided as
+ a parameter, its values are used as default state."""
+ if default_dict is None:
+ default_dict = {}
+ # this one uses reverse logic: if checked, NoConstraintsFlag must be False
+ self.setChecked(
+ not default_dict.get('NoConstraintsFlag', False))
+ self.positiveHeightCB.setChecked(
+ default_dict.get('PositiveHeightAreaFlag', True))
+ self.positionInIntervalCB.setChecked(
+ default_dict.get('QuotedPositionFlag', False))
+ self.positiveFwhmCB.setChecked(
+ default_dict.get('PositiveFwhmFlag', True))
+ self.sameFwhmCB.setChecked(
+ default_dict.get('SameFwhmFlag', False))
+ self.quotedEtaCB.setChecked(
+ default_dict.get('QuotedEtaFlag', False))
+
+ def get(self):
+ """Return a dictionary of constraint flags, to be processed by the
+ :meth:`configure` method of the selected fit theory."""
+ ddict = {
+ 'NoConstraintsFlag': not self.isChecked(),
+ 'PositiveHeightAreaFlag': self.positiveHeightCB.isChecked(),
+ 'QuotedPositionFlag': self.positionInIntervalCB.isChecked(),
+ 'PositiveFwhmFlag': self.positiveFwhmCB.isChecked(),
+ 'SameFwhmFlag': self.sameFwhmCB.isChecked(),
+ 'QuotedEtaFlag': self.quotedEtaCB.isChecked(),
+ }
+ return ddict
+
+
+class SearchPage(qt.QWidget):
+ def __init__(self, parent=None):
+ super(SearchPage, self).__init__(parent)
+ layout = qt.QVBoxLayout(self)
+
+ self.manualFwhmGB = qt.QGroupBox("Define FWHM manually", self)
+ self.manualFwhmGB.setCheckable(True)
+ self.manualFwhmGB.setToolTip(
+ "If disabled, the FWHM parameter used for peak search is " +
+ "estimated based on the highest peak in the data")
+ layout.addWidget(self.manualFwhmGB)
+ # ------------ GroupBox fwhm--------------------------
+ layout2 = qt.QHBoxLayout(self.manualFwhmGB)
+ self.manualFwhmGB.setLayout(layout2)
+
+ label = qt.QLabel("Fwhm Points", self.manualFwhmGB)
+ layout2.addWidget(label)
+
+ self.fwhmPointsSpin = qt.QSpinBox(self.manualFwhmGB)
+ self.fwhmPointsSpin.setRange(0, 999999)
+ self.fwhmPointsSpin.setToolTip("Typical peak fwhm (number of data points)")
+ layout2.addWidget(self.fwhmPointsSpin)
+ # ----------------------------------------------------
+
+ self.manualScalingGB = qt.QGroupBox("Define scaling manually", self)
+ self.manualScalingGB.setCheckable(True)
+ self.manualScalingGB.setToolTip(
+ "If disabled, the Y scaling used for peak search is " +
+ "estimated automatically")
+ layout.addWidget(self.manualScalingGB)
+ # ------------ GroupBox scaling-----------------------
+ layout3 = qt.QHBoxLayout(self.manualScalingGB)
+ self.manualScalingGB.setLayout(layout3)
+
+ label = qt.QLabel("Y Scaling", self.manualScalingGB)
+ layout3.addWidget(label)
+
+ self.yScalingEntry = qt.QLineEdit(self.manualScalingGB)
+ self.yScalingEntry.setToolTip(
+ "Data values will be multiplied by this value prior to peak" +
+ " search")
+ self.yScalingEntry.setValidator(qt.QDoubleValidator())
+ layout3.addWidget(self.yScalingEntry)
+ # ----------------------------------------------------
+
+ # ------------------- grid layout --------------------
+ containerWidget = qt.QWidget(self)
+ layout4 = qt.QHBoxLayout(containerWidget)
+ containerWidget.setLayout(layout4)
+
+ label = qt.QLabel("Sensitivity", containerWidget)
+ layout4.addWidget(label)
+
+ self.sensitivityEntry = qt.QLineEdit(containerWidget)
+ self.sensitivityEntry.setToolTip(
+ "Peak search sensitivity threshold, expressed as a multiple " +
+ "of the standard deviation of the noise.\nMinimum value is 1 " +
+ "(to be detected, peak must be higher than the estimated noise)")
+ sensivalidator = qt.QDoubleValidator()
+ sensivalidator.setBottom(1.0)
+ self.sensitivityEntry.setValidator(sensivalidator)
+ layout4.addWidget(self.sensitivityEntry)
+ # ----------------------------------------------------
+ layout.addWidget(containerWidget)
+
+ self.forcePeakPresenceCB = qt.QCheckBox("Force peak presence", self)
+ self.forcePeakPresenceCB.setToolTip(
+ "If peak search algorithm is unsuccessful, place one peak " +
+ "at the maximum of the curve")
+ layout.addWidget(self.forcePeakPresenceCB)
+
+ layout.addStretch()
+
+ self.setDefault()
+
+ def setDefault(self, default_dict=None):
+ """Set default values for all widgets.
+
+ :param default_dict: If a default config dictionary is provided as
+ a parameter, its values are used as default values."""
+ if default_dict is None:
+ default_dict = {}
+ self.manualFwhmGB.setChecked(
+ not default_dict.get('AutoFwhm', True))
+ self.fwhmPointsSpin.setValue(
+ default_dict.get('FwhmPoints', 8))
+ self.sensitivityEntry.setText(
+ str(default_dict.get('Sensitivity', 1.0)))
+ self.manualScalingGB.setChecked(
+ not default_dict.get('AutoScaling', False))
+ self.yScalingEntry.setText(
+ str(default_dict.get('Yscaling', 1.0)))
+ self.forcePeakPresenceCB.setChecked(
+ default_dict.get('ForcePeakPresence', False))
+
+ def get(self):
+ """Return a dictionary of peak search parameters, to be processed by
+ the :meth:`configure` method of the selected fit theory."""
+ ddict = {
+ 'AutoFwhm': not self.manualFwhmGB.isChecked(),
+ 'FwhmPoints': self.fwhmPointsSpin.value(),
+ 'Sensitivity': safe_float(self.sensitivityEntry.text()),
+ 'AutoScaling': not self.manualScalingGB.isChecked(),
+ 'Yscaling': safe_float(self.yScalingEntry.text()),
+ 'ForcePeakPresence': self.forcePeakPresenceCB.isChecked()
+ }
+ return ddict
+
+
+class BackgroundPage(qt.QGroupBox):
+ """Background subtraction configuration, specific to fittheories
+ estimation functions."""
+ def __init__(self, parent=None,
+ title="Subtract strip background prior to estimation"):
+ super(BackgroundPage, self).__init__(parent)
+ self.setTitle(title)
+ self.setCheckable(True)
+ self.setToolTip(
+ "The strip algorithm strips away peaks to compute the " +
+ "background signal.\nAt each iteration, a sample is compared " +
+ "to the average of the two samples at a given distance in both" +
+ " directions,\n and if its value is higher than the average,"
+ "it is replaced by the average.")
+
+ layout = qt.QGridLayout(self)
+ self.setLayout(layout)
+
+ for i, label_text in enumerate(
+ ["Strip width (in samples)",
+ "Number of iterations",
+ "Strip threshold factor"]):
+ label = qt.QLabel(label_text)
+ layout.addWidget(label, i, 0)
+
+ self.stripWidthSpin = qt.QSpinBox(self)
+ self.stripWidthSpin.setToolTip(
+ "Width, in number of samples, of the strip operator")
+ self.stripWidthSpin.setRange(1, 999999)
+
+ layout.addWidget(self.stripWidthSpin, 0, 1)
+
+ self.numIterationsSpin = qt.QSpinBox(self)
+ self.numIterationsSpin.setToolTip(
+ "Number of iterations of the strip algorithm")
+ self.numIterationsSpin.setRange(1, 999999)
+ layout.addWidget(self.numIterationsSpin, 1, 1)
+
+ self.thresholdFactorEntry = qt.QLineEdit(self)
+ self.thresholdFactorEntry.setToolTip(
+ "Factor used by the strip algorithm to decide whether a sample" +
+ "value should be stripped.\nThe value must be higher than the " +
+ "average of the 2 samples at +- w times this factor.\n")
+ self.thresholdFactorEntry.setValidator(qt.QDoubleValidator())
+ layout.addWidget(self.thresholdFactorEntry, 2, 1)
+
+ self.smoothStripGB = qt.QGroupBox("Apply smoothing prior to strip", self)
+ self.smoothStripGB.setCheckable(True)
+ self.smoothStripGB.setToolTip(
+ "Apply a smoothing before subtracting strip background" +
+ " in fit and estimate processes")
+ smoothlayout = qt.QHBoxLayout(self.smoothStripGB)
+ label = qt.QLabel("Smoothing width (Savitsky-Golay)")
+ smoothlayout.addWidget(label)
+ self.smoothingWidthSpin = qt.QSpinBox(self)
+ self.smoothingWidthSpin.setToolTip(
+ "Width parameter for Savitsky-Golay smoothing (number of samples, must be odd)")
+ self.smoothingWidthSpin.setRange(3, 101)
+ self.smoothingWidthSpin.setSingleStep(2)
+ smoothlayout.addWidget(self.smoothingWidthSpin)
+
+ layout.addWidget(self.smoothStripGB, 3, 0, 1, 2)
+
+ layout.setRowStretch(4, 1)
+
+ self.setDefault()
+
+ def setDefault(self, default_dict=None):
+ """Set default values for all widgets.
+
+ :param default_dict: If a default config dictionary is provided as
+ a parameter, its values are used as default values."""
+ if default_dict is None:
+ default_dict = {}
+
+ self.setChecked(
+ default_dict.get('StripBackgroundFlag', True))
+
+ self.stripWidthSpin.setValue(
+ default_dict.get('StripWidth', 2))
+ self.numIterationsSpin.setValue(
+ default_dict.get('StripIterations', 5000))
+ self.thresholdFactorEntry.setText(
+ str(default_dict.get('StripThreshold', 1.0)))
+ self.smoothStripGB.setChecked(
+ default_dict.get('SmoothingFlag', False))
+ self.smoothingWidthSpin.setValue(
+ default_dict.get('SmoothingWidth', 3))
+
+ def get(self):
+ """Return a dictionary of background subtraction parameters, to be
+ processed by the :meth:`configure` method of the selected fit theory.
+ """
+ ddict = {
+ 'StripBackgroundFlag': self.isChecked(),
+ 'StripWidth': self.stripWidthSpin.value(),
+ 'StripIterations': self.numIterationsSpin.value(),
+ 'StripThreshold': safe_float(self.thresholdFactorEntry.text()),
+ 'SmoothingFlag': self.smoothStripGB.isChecked(),
+ 'SmoothingWidth': self.smoothingWidthSpin.value()
+ }
+ return ddict
+
+
+def safe_float(string_, default=1.0):
+ """Convert a string into a float.
+ If the conversion fails, return the default value.
+ """
+ try:
+ ret = float(string_)
+ except ValueError:
+ return default
+ else:
+ return ret
+
+
+def safe_int(string_, default=1):
+ """Convert a string into a integer.
+ If the conversion fails, return the default value.
+ """
+ try:
+ ret = int(float(string_))
+ except ValueError:
+ return default
+ else:
+ return ret
+
+
+def getFitConfigDialog(parent=None, default=None, modal=True):
+ """Instantiate and return a fit configuration dialog, adapted
+ for configuring standard fit theories from
+ :mod:`silx.math.fit.fittheories`.
+
+ :return: Instance of :class:`TabsDialogData` with 3 tabs:
+ :class:`ConstraintsPage`, :class:`SearchPage` and
+ :class:`BackgroundPage`
+ """
+ tdd = TabsDialogData(parent=parent, default=default)
+ tdd.addTab(ConstraintsPage(), label="Constraints")
+ tdd.addTab(SearchPage(), label="Peak search")
+ tdd.addTab(BackgroundPage(), label="Background")
+ # apply default to newly added pages
+ tdd.setDefault()
+
+ return tdd
+
+
+def main():
+ a = qt.QApplication([])
+
+ mw = qt.QMainWindow()
+ mw.show()
+
+ tdd = getFitConfigDialog(mw, default={"a": 1})
+ tdd.show()
+ tdd.exec_()
+ print("TabsDialogData result: ", tdd.result())
+ print("TabsDialogData output: ", tdd.output)
+
+ a.exec_()
+
+if __name__ == "__main__":
+ main()
diff --git a/silx/gui/fit/FitWidget.py b/silx/gui/fit/FitWidget.py
new file mode 100644
index 0000000..a5c3cfd
--- /dev/null
+++ b/silx/gui/fit/FitWidget.py
@@ -0,0 +1,727 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# 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.
+#
+# ######################################################################### */
+"""This module provides a widget designed to configure and run a fitting
+process with constraints on parameters.
+
+The main class is :class:`FitWidget`. It relies on
+:mod:`silx.math.fit.fitmanager`, which relies on :func:`silx.math.fit.leastsq`.
+
+The user can choose between functions before running the fit. These function can
+be user defined, or by default are loaded from
+:mod:`silx.math.fit.fittheories`.
+"""
+
+__authors__ = ["V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "15/02/2017"
+
+import logging
+import sys
+import traceback
+import warnings
+
+from silx.math.fit import fittheories
+from silx.math.fit import fitmanager, functions
+from silx.gui import qt
+from .FitWidgets import (FitActionsButtons, FitStatusLines,
+ FitConfigWidget, ParametersTab)
+from .FitConfig import getFitConfigDialog
+from .BackgroundWidget import getBgDialog, BackgroundDialog
+
+QTVERSION = qt.qVersion()
+DEBUG = 0
+_logger = logging.getLogger(__name__)
+
+
+__authors__ = ["V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "30/11/2016"
+
+
+class FitWidget(qt.QWidget):
+ """This widget can be used to configure, run and display results of a
+ fitting process.
+
+ The standard steps for using this widget is to initialize it, then load
+ the data to be fitted.
+
+ Optionally, you can also load user defined fit theories. If you skip this
+ step, a series of default fit functions will be presented (gaussian-like
+ functions), and you can later load your custom fit theories from an
+ external file using the GUI.
+
+ A fit theory is a fit function and its associated features:
+
+ - estimation function,
+ - list of parameter names
+ - numerical derivative algorithm
+ - configuration widget
+
+ Once the widget is up and running, the user may select a fit theory and a
+ background theory, change configuration parameters specific to the theory
+ run the estimation, set constraints on parameters and run the actual fit.
+
+ The results are displayed in a table.
+ """
+ sigFitWidgetSignal = qt.Signal(object)
+ """This signal is emitted by the estimation and fit methods.
+ It carries a dictionary with two items:
+
+ - *event*: one of the following strings
+
+ - *EstimateStarted*,
+ - *FitStarted*
+ - *EstimateFinished*,
+ - *FitFinished*
+ - *EstimateFailed*
+ - *FitFailed*
+
+ - *data*: None, or fit/estimate results (see documentation for
+ :attr:`silx.math.fit.fitmanager.FitManager.fit_results`)
+ """
+
+ def __init__(self, parent=None, title=None, fitmngr=None,
+ enableconfig=True, enablestatus=True, enablebuttons=True):
+ """
+
+ :param parent: Parent widget
+ :param title: Window title
+ :param fitmngr: User defined instance of
+ :class:`silx.math.fit.fitmanager.FitManager`, or ``None``
+ :param enableconfig: If ``True``, activate widgets to modify the fit
+ configuration (select between several fit functions or background
+ functions, apply global constraints, peak search parameters…)
+ :param enablestatus: If ``True``, add a fit status widget, to display
+ a message when fit estimation is available and when fit results
+ are available, as well as a measure of the fit error.
+ :param enablebuttons: If ``True``, add buttons to run estimation and
+ fitting.
+ """
+ if title is None:
+ title = "FitWidget"
+ qt.QWidget.__init__(self, parent)
+
+ self.setWindowTitle(title)
+ layout = qt.QVBoxLayout(self)
+
+ self.fitmanager = self._setFitManager(fitmngr)
+ """Instance of :class:`FitManager`.
+ This is the underlying data model of this FitWidget.
+
+ If no custom theories are defined, the default ones from
+ :mod:`silx.math.fit.fittheories` are imported.
+ """
+
+ # reference fitmanager.configure method for direct access
+ self.configure = self.fitmanager.configure
+ self.fitconfig = self.fitmanager.fitconfig
+
+ self.configdialogs = {}
+ """This dictionary defines the fit configuration widgets
+ associated with the fit theories in :attr:`fitmanager.theories`
+
+ Keys must correspond to existing theory names, i.e. existing keys
+ in :attr:`fitmanager.theories`.
+
+ Values must be instances of QDialog widgets with an additional
+ *output* attribute, a dictionary storing configuration parameters
+ interpreted by the corresponding fit theory.
+
+ The dialog can also define a *setDefault* method to initialize the
+ widget values with values in a dictionary passed as a parameter.
+ This will be executed first.
+
+ In case the widget does not actually inherit :class:`QDialog`, it
+ must at least implement the following methods (executed in this
+ particular order):
+
+ - :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 in
+ attribute :attr:`output` is to be accepted (user clicked *OK*),
+ or return ``False`` if :attr:`output` is to be rejected (user
+ clicked *Cancel*)
+
+ To associate a custom configuration widget with a fit theory, use
+ :meth:`associateConfigDialog`. E.g.::
+
+ fw = FitWidget()
+ my_config_widget = MyGaussianConfigWidget(parent=fw)
+ fw.associateConfigDialog(theory_name="Gaussians",
+ config_widget=my_config_widget)
+ """
+
+ self.bgconfigdialogs = {}
+ """Same as :attr:`configdialogs`, except that the widget is associated
+ with a background theory in :attr:`fitmanager.bgtheories`"""
+
+ self._associateDefaultConfigDialogs()
+
+ self.guiConfig = None
+ """Configuration widget at the top of FitWidget, to select
+ fit function, background function, and open an advanced
+ configuration dialog."""
+
+ self.guiParameters = ParametersTab(self)
+ """Table widget for display of fit parameters and constraints"""
+
+ if enableconfig:
+ self.guiConfig = FitConfigWidget(self)
+ """Function selector and configuration widget"""
+
+ self.guiConfig.FunConfigureButton.clicked.connect(
+ self.__funConfigureGuiSlot)
+ self.guiConfig.BgConfigureButton.clicked.connect(
+ self.__bgConfigureGuiSlot)
+
+ self.guiConfig.WeightCheckBox.setChecked(
+ self.fitconfig.get("WeightFlag", False))
+ self.guiConfig.WeightCheckBox.stateChanged[int].connect(self.weightEvent)
+
+ self.guiConfig.BkgComBox.activated[str].connect(self.bkgEvent)
+ self.guiConfig.FunComBox.activated[str].connect(self.funEvent)
+ self._populateFunctions()
+
+ layout.addWidget(self.guiConfig)
+
+ layout.addWidget(self.guiParameters)
+
+ if enablestatus:
+ self.guistatus = FitStatusLines(self)
+ """Status bar"""
+ layout.addWidget(self.guistatus)
+
+ if enablebuttons:
+ self.guibuttons = FitActionsButtons(self)
+ """Widget with estimate, start fit and dismiss buttons"""
+ self.guibuttons.EstimateButton.clicked.connect(self.estimate)
+ self.guibuttons.StartFitButton.clicked.connect(self.startFit)
+ self.guibuttons.DismissButton.clicked.connect(self.dismiss)
+ layout.addWidget(self.guibuttons)
+
+ def _setFitManager(self, fitinstance):
+ """Initialize a :class:`FitManager` instance, to be assigned to
+ :attr:`fitmanager`, or use a custom FitManager instance.
+
+ :param fitinstance: Existing instance of FitManager, possibly
+ customized by the user, or None to load a default instance."""
+ if isinstance(fitinstance, fitmanager.FitManager):
+ # customized
+ fitmngr = fitinstance
+ else:
+ # initialize default instance
+ fitmngr = fitmanager.FitManager()
+
+ # initialize the default fitting functions in case
+ # none is present
+ if not len(fitmngr.theories):
+ fitmngr.loadtheories(fittheories)
+
+ return fitmngr
+
+ def _associateDefaultConfigDialogs(self):
+ """Fill :attr:`bgconfigdialogs` and :attr:`configdialogs` by calling
+ :meth:`associateConfigDialog` with default config dialog widgets.
+ """
+ # associate silx.gui.fit.FitConfig with all theories
+ # Users can later associate their own custom dialogs to
+ # replace the default.
+ configdialog = getFitConfigDialog(parent=self,
+ default=self.fitconfig)
+ for theory in self.fitmanager.theories:
+ self.associateConfigDialog(theory, configdialog)
+ for bgtheory in self.fitmanager.bgtheories:
+ self.associateConfigDialog(bgtheory, configdialog,
+ theory_is_background=True)
+
+ # associate silx.gui.fit.BackgroundWidget with Strip and Snip
+ bgdialog = getBgDialog(parent=self,
+ default=self.fitconfig)
+ for bgtheory in ["Strip", "Snip"]:
+ if bgtheory in self.fitmanager.bgtheories:
+ self.associateConfigDialog(bgtheory, bgdialog,
+ theory_is_background=True)
+
+ def _populateFunctions(self):
+ """Fill combo-boxes with fit theories and background theories
+ loaded by :attr:`fitmanager`.
+ Run :meth:`fitmanager.configure` to ensure the custom configuration
+ of the selected theory has been loaded into :attr:`fitconfig`"""
+ for theory_name in self.fitmanager.bgtheories:
+ self.guiConfig.BkgComBox.addItem(theory_name)
+ self.guiConfig.BkgComBox.setItemData(
+ self.guiConfig.BkgComBox.findText(theory_name),
+ self.fitmanager.bgtheories[theory_name].description,
+ qt.Qt.ToolTipRole)
+
+ for theory_name in self.fitmanager.theories:
+ self.guiConfig.FunComBox.addItem(theory_name)
+ self.guiConfig.FunComBox.setItemData(
+ self.guiConfig.FunComBox.findText(theory_name),
+ self.fitmanager.theories[theory_name].description,
+ qt.Qt.ToolTipRole)
+
+ # - activate selected fit theory (if any)
+ # - activate selected bg theory (if any)
+ configuration = self.fitmanager.configure()
+ if self.fitmanager.selectedtheory is None:
+ # take the first one by default
+ self.guiConfig.FunComBox.setCurrentIndex(1)
+ self.funEvent(list(self.fitmanager.theories.keys())[0])
+ else:
+ idx = list(self.fitmanager.theories).index(self.fitmanager.selectedtheory)
+ self.guiConfig.FunComBox.setCurrentIndex(idx + 1)
+ self.funEvent(self.fitmanager.selectedtheory)
+
+ if self.fitmanager.selectedbg is None:
+ self.guiConfig.BkgComBox.setCurrentIndex(1)
+ self.bkgEvent(list(self.fitmanager.bgtheories.keys())[0])
+ else:
+ idx = list(self.fitmanager.bgtheories).index(self.fitmanager.selectedbg)
+ self.guiConfig.BkgComBox.setCurrentIndex(idx + 1)
+ self.bkgEvent(self.fitmanager.selectedbg)
+
+ configuration.update(self.configure())
+
+ def setdata(self, x, y, sigmay=None, xmin=None, xmax=None):
+ warnings.warn("Method renamed to setData",
+ DeprecationWarning)
+ self.setData(x, y, sigmay, xmin, xmax)
+
+ def setData(self, x, y, sigmay=None, xmin=None, xmax=None):
+ """Set data to be fitted.
+
+ :param x: Abscissa data. If ``None``, :attr:`xdata`` is set to
+ ``numpy.array([0.0, 1.0, 2.0, ..., len(y)-1])``
+ :type x: Sequence or numpy array or None
+ :param y: The dependant data ``y = f(x)``. ``y`` must have the same
+ shape as ``x`` if ``x`` is not ``None``.
+ :type y: Sequence or numpy array or None
+ :param sigmay: The uncertainties in the ``ydata`` array. These are
+ used as weights in the least-squares problem.
+ If ``None``, the uncertainties are assumed to be 1.
+ :type sigmay: Sequence or numpy array or None
+ :param xmin: Lower value of x values to use for fitting
+ :param xmax: Upper value of x values to use for fitting
+ """
+ self.fitmanager.setdata(x=x, y=y, sigmay=sigmay,
+ xmin=xmin, xmax=xmax)
+ for config_dialog in self.bgconfigdialogs.values():
+ if isinstance(config_dialog, BackgroundDialog):
+ config_dialog.setData(x, y, xmin=xmin, xmax=xmax)
+
+ def associateConfigDialog(self, theory_name, config_widget,
+ theory_is_background=False):
+ """Associate an instance of custom configuration dialog widget to
+ a fit theory or to a background theory.
+
+ This adds or modifies an item in the correspondence table
+ :attr:`configdialogs` or :attr:`bgconfigdialogs`.
+
+ :param str theory_name: Name of fit theory. This must be a key of dict
+ :attr:`fitmanager.theories`
+ :param config_widget: Custom configuration widget. See documentation
+ for :attr:`configdialogs`
+ :param bool theory_is_background: If flag is *True*, add dialog to
+ :attr:`bgconfigdialogs` rather than :attr:`configdialogs`
+ (default).
+ :raise: KeyError if parameter ``theory_name`` does not match an
+ existing fit theory or background theory in :attr:`fitmanager`.
+ :raise: AttributeError if the widget does not implement the mandatory
+ methods (*show*, *exec_*, *result*, *setDefault*) or the mandatory
+ attribute (*output*).
+ """
+ theories = self.fitmanager.bgtheories if theory_is_background else\
+ self.fitmanager.theories
+
+ if theory_name not in theories:
+ raise KeyError("%s does not match an existing fitmanager theory")
+
+ if config_widget is not None:
+ for mandatory_attr in ["show", "exec_", "result", "output"]:
+ if not hasattr(config_widget, mandatory_attr):
+ raise AttributeError(
+ "Custom configuration widget must define " +
+ "attribute or method " + mandatory_attr)
+
+ if theory_is_background:
+ self.bgconfigdialogs[theory_name] = config_widget
+ else:
+ self.configdialogs[theory_name] = config_widget
+
+ def _emitSignal(self, ddict):
+ """Emit pyqtSignal after estimation completed
+ (``ddict = {'event': 'EstimateFinished', 'data': fit_results}``)
+ and after fit completed
+ (``ddict = {'event': 'FitFinished', 'data': fit_results}``)"""
+ self.sigFitWidgetSignal.emit(ddict)
+
+ def __funConfigureGuiSlot(self):
+ """Open an advanced configuration dialog widget"""
+ self.__configureGui(dialog_type="function")
+
+ def __bgConfigureGuiSlot(self):
+ """Open an advanced configuration dialog widget"""
+ self.__configureGui(dialog_type="background")
+
+ def __configureGui(self, newconfiguration=None, dialog_type="function"):
+ """Open an advanced configuration dialog widget to get a configuration
+ dictionary, or use a supplied configuration dictionary. Call
+ :meth:`configure` with this dictionary as a parameter. Update the gui
+ accordingly. Reinitialize the fit results in the table and in
+ :attr:`fitmanager`.
+
+ :param newconfiguration: User supplied configuration dictionary. If ``None``,
+ open a dialog widget that returns a dictionary."""
+ configuration = self.configure()
+ # get new dictionary
+ if newconfiguration is None:
+ newconfiguration = self.configureDialog(configuration, dialog_type)
+ # update configuration
+ configuration.update(self.configure(**newconfiguration))
+ # set fit function theory
+ try:
+ i = 1 + \
+ list(self.fitmanager.theories.keys()).index(
+ self.fitmanager.selectedtheory)
+ self.guiConfig.FunComBox.setCurrentIndex(i)
+ self.funEvent(self.fitmanager.selectedtheory)
+ except ValueError:
+ _logger.error("Function not in list %s",
+ self.fitmanager.selectedtheory)
+ self.funEvent(list(self.fitmanager.theories.keys())[0])
+ # current background
+ try:
+ i = 1 + \
+ list(self.fitmanager.bgtheories.keys()).index(
+ self.fitmanager.selectedbg)
+ self.guiConfig.BkgComBox.setCurrentIndex(i)
+ self.bkgEvent(self.fitmanager.selectedbg)
+ except ValueError:
+ _logger.error("Background not in list %s",
+ self.fitmanager.selectedbg)
+ self.bkgEvent(list(self.fitmanager.bgtheories.keys())[0])
+
+ # update the Gui
+ self.__initialParameters()
+
+ def configureDialog(self, oldconfiguration, dialog_type="function"):
+ """Display a dialog, allowing the user to define fit configuration
+ parameters.
+
+ By default, a common dialog is used for all fit theories. But if the
+ defined a custom dialog using :meth:`associateConfigDialog`, it is
+ used instead.
+
+ :param dict oldconfiguration: Dictionary containing previous configuration
+ :param str dialog_type: "function" or "background"
+ :return: User defined parameters in a dictionary
+ """
+ newconfiguration = {}
+ newconfiguration.update(oldconfiguration)
+
+ if dialog_type == "function":
+ theory = self.fitmanager.selectedtheory
+ configdialog = self.configdialogs[theory]
+ elif dialog_type == "background":
+ theory = self.fitmanager.selectedbg
+ configdialog = self.bgconfigdialogs[theory]
+
+ # this should only happen if a user specifically associates None
+ # with a theory, to have no configuration option
+ if configdialog is None:
+ return {}
+
+ # update state of configdialog before showing it
+ if hasattr(configdialog, "setDefault"):
+ configdialog.setDefault(newconfiguration)
+ configdialog.show()
+ configdialog.exec_()
+ if configdialog.result():
+ newconfiguration.update(configdialog.output)
+
+ return newconfiguration
+
+ def estimate(self):
+ """Run parameter estimation function then emit
+ :attr:`sigFitWidgetSignal` with a dictionary containing a status
+ message and a list of fit parameters estimations
+ in the format defined in
+ :attr:`silx.math.fit.fitmanager.FitManager.fit_results`
+
+ The emitted dictionary has an *"event"* key that can have
+ following values:
+
+ - *'EstimateStarted'*
+ - *'EstimateFailed'*
+ - *'EstimateFinished'*
+ """
+ try:
+ theory_name = self.fitmanager.selectedtheory
+ estimation_function = self.fitmanager.theories[theory_name].estimate
+ if estimation_function is not None:
+ ddict = {'event': 'EstimateStarted',
+ 'data': None}
+ self._emitSignal(ddict)
+ self.fitmanager.estimate(callback=self.fitStatus)
+ else:
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Information)
+ text = "Function does not define a way to estimate\n"
+ text += "the initial parameters. Please, fill them\n"
+ text += "yourself in the table and press Start Fit\n"
+ msg.setText(text)
+ msg.setWindowTitle('FitWidget Message')
+ msg.exec_()
+ return
+ except: # noqa (we want to catch and report all errors)
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setText("Error on estimate: %s" % traceback.format_exc())
+ msg.exec_()
+ ddict = {
+ 'event': 'EstimateFailed',
+ 'data': None}
+ self._emitSignal(ddict)
+ return
+
+ self.guiParameters.fillFromFit(
+ self.fitmanager.fit_results, view='Fit')
+ self.guiParameters.removeAllViews(keep='Fit')
+ ddict = {
+ 'event': 'EstimateFinished',
+ 'data': self.fitmanager.fit_results}
+ self._emitSignal(ddict)
+
+ def startfit(self):
+ warnings.warn("Method renamed to startFit",
+ DeprecationWarning)
+ self.startFit()
+
+ def startFit(self):
+ """Run fit, then emit :attr:`sigFitWidgetSignal` with a dictionary
+ containing a status message and a list of fit
+ parameters results in the format defined in
+ :attr:`silx.math.fit.fitmanager.FitManager.fit_results`
+
+ The emitted dictionary has an *"event"* key that can have
+ following values:
+
+ - *'FitStarted'*
+ - *'FitFailed'*
+ - *'FitFinished'*
+ """
+ self.fitmanager.fit_results = self.guiParameters.getFitResults()
+ try:
+ ddict = {'event': 'FitStarted',
+ 'data': None}
+ self._emitSignal(ddict)
+ self.fitmanager.runfit(callback=self.fitStatus)
+ except: # noqa (we want to catch and report all errors)
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setText("Error on Fit: %s" % traceback.format_exc())
+ msg.exec_()
+ ddict = {
+ 'event': 'FitFailed',
+ 'data': None
+ }
+ self._emitSignal(ddict)
+ return
+
+ self.guiParameters.fillFromFit(
+ self.fitmanager.fit_results, view='Fit')
+ self.guiParameters.removeAllViews(keep='Fit')
+ ddict = {
+ 'event': 'FitFinished',
+ 'data': self.fitmanager.fit_results
+ }
+ self._emitSignal(ddict)
+ return
+
+ def bkgEvent(self, bgtheory):
+ """Select background theory, then reinitialize parameters"""
+ bgtheory = str(bgtheory)
+ if bgtheory in self.fitmanager.bgtheories:
+ self.fitmanager.setbackground(bgtheory)
+ else:
+ functionsfile = qt.QFileDialog.getOpenFileName(
+ self, "Select python module with your function(s)", "",
+ "Python Files (*.py);;All Files (*)")
+
+ if len(functionsfile):
+ try:
+ self.fitmanager.loadbgtheories(functionsfile)
+ except ImportError:
+ qt.QMessageBox.critical(self, "ERROR",
+ "Function not imported")
+ return
+ else:
+ # empty the ComboBox
+ while self.guiConfig.BkgComBox.count() > 1:
+ self.guiConfig.BkgComBox.removeItem(1)
+ # and fill it again
+ for key in self.fitmanager.bgtheories:
+ self.guiConfig.BkgComBox.addItem(str(key))
+
+ i = 1 + \
+ list(self.fitmanager.bgtheories.keys()).index(
+ self.fitmanager.selectedbg)
+ self.guiConfig.BkgComBox.setCurrentIndex(i)
+ self.__initialParameters()
+
+ def funEvent(self, theoryname):
+ """Select a fit theory to be used for fitting. If this theory exists
+ in :attr:`fitmanager`, use it. Then, reinitialize table.
+
+ :param theoryname: Name of the fit theory to use for fitting. If this theory
+ exists in :attr:`fitmanager`, use it. Else, open a file dialog to open
+ a custom fit function definition file with
+ :meth:`fitmanager.loadtheories`.
+ """
+ theoryname = str(theoryname)
+ if theoryname in self.fitmanager.theories:
+ self.fitmanager.settheory(theoryname)
+ else:
+ # open a load file dialog
+ functionsfile = qt.QFileDialog.getOpenFileName(
+ self, "Select python module with your function(s)", "",
+ "Python Files (*.py);;All Files (*)")
+
+ if len(functionsfile):
+ try:
+ self.fitmanager.loadtheories(functionsfile)
+ except ImportError:
+ qt.QMessageBox.critical(self, "ERROR",
+ "Function not imported")
+ return
+ else:
+ # empty the ComboBox
+ while self.guiConfig.FunComBox.count() > 1:
+ self.guiConfig.FunComBox.removeItem(1)
+ # and fill it again
+ for key in self.fitmanager.theories:
+ self.guiConfig.FunComBox.addItem(str(key))
+
+ i = 1 + \
+ list(self.fitmanager.theories.keys()).index(
+ self.fitmanager.selectedtheory)
+ self.guiConfig.FunComBox.setCurrentIndex(i)
+ self.__initialParameters()
+
+ def weightEvent(self, flag):
+ """This is called when WeightCheckBox is clicked, to configure the
+ *WeightFlag* field in :attr:`fitmanager.fitconfig` and set weights
+ in the least-square problem."""
+ self.configure(WeightFlag=flag)
+ if flag:
+ self.fitmanager.enableweight()
+ else:
+ # set weights back to 1
+ self.fitmanager.disableweight()
+
+ def __initialParameters(self):
+ """Fill the fit parameters names with names of the parameters of
+ the selected background theory and the selected fit theory.
+ Initialize :attr:`fitmanager.fit_results` with these names, and
+ initialize the table with them. This creates a view called "Fit"
+ in :attr:`guiParameters`"""
+ self.fitmanager.parameter_names = []
+ self.fitmanager.fit_results = []
+ for pname in self.fitmanager.bgtheories[self.fitmanager.selectedbg].parameters:
+ self.fitmanager.parameter_names.append(pname)
+ self.fitmanager.fit_results.append({'name': pname,
+ 'estimation': 0,
+ 'group': 0,
+ 'code': 'FREE',
+ 'cons1': 0,
+ 'cons2': 0,
+ 'fitresult': 0.0,
+ 'sigma': 0.0,
+ 'xmin': None,
+ 'xmax': None})
+ if self.fitmanager.selectedtheory is not None:
+ theory = self.fitmanager.selectedtheory
+ for pname in self.fitmanager.theories[theory].parameters:
+ self.fitmanager.parameter_names.append(pname + "1")
+ self.fitmanager.fit_results.append({'name': pname + "1",
+ 'estimation': 0,
+ 'group': 1,
+ 'code': 'FREE',
+ 'cons1': 0,
+ 'cons2': 0,
+ 'fitresult': 0.0,
+ 'sigma': 0.0,
+ 'xmin': None,
+ 'xmax': None})
+
+ self.guiParameters.fillFromFit(
+ self.fitmanager.fit_results, view='Fit')
+
+ def fitStatus(self, data):
+ """Set *status* and *chisq* in status bar"""
+ if 'chisq' in data:
+ if data['chisq'] is None:
+ self.guistatus.ChisqLine.setText(" ")
+ else:
+ chisq = data['chisq']
+ self.guistatus.ChisqLine.setText("%6.2f" % chisq)
+
+ if 'status' in data:
+ status = data['status']
+ self.guistatus.StatusLine.setText(str(status))
+
+ def dismiss(self):
+ """Close FitWidget"""
+ self.close()
+
+
+if __name__ == "__main__":
+ import numpy
+
+ x = numpy.arange(1500).astype(numpy.float)
+ constant_bg = 3.14
+
+ p = [1000, 100., 30.0,
+ 500, 300., 25.,
+ 1700, 500., 35.,
+ 750, 700., 30.0,
+ 1234, 900., 29.5,
+ 302, 1100., 30.5,
+ 75, 1300., 21.]
+ y = functions.sum_gauss(x, *p) + constant_bg
+
+ a = qt.QApplication(sys.argv)
+ w = FitWidget()
+ w.setData(x=x, y=y)
+ w.show()
+ a.exec_()
diff --git a/silx/gui/fit/FitWidgets.py b/silx/gui/fit/FitWidgets.py
new file mode 100644
index 0000000..408666b
--- /dev/null
+++ b/silx/gui/fit/FitWidgets.py
@@ -0,0 +1,559 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2004-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.
+#
+# ######################################################################### */
+"""Collection of widgets used to build
+:class:`silx.gui.fit.FitWidget.FitWidget`"""
+
+from collections import OrderedDict
+
+from silx.gui import qt
+from silx.gui.fit.Parameters import Parameters
+
+QTVERSION = qt.qVersion()
+
+__authors__ = ["V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "13/10/2016"
+
+
+class FitActionsButtons(qt.QWidget):
+ """Widget with 3 ``QPushButton``:
+
+ The buttons can be accessed as public attributes::
+
+ - ``EstimateButton``
+ - ``StartFitButton``
+ - ``DismissButton``
+
+ You will typically need to access these attributes to connect the buttons
+ to actions. For instance, if you have 3 functions ``estimate``,
+ ``runfit`` and ``dismiss``, you can connect them like this::
+
+ >>> fit_actions_buttons = FitActionsButtons()
+ >>> fit_actions_buttons.EstimateButton.clicked.connect(estimate)
+ >>> fit_actions_buttons.StartFitButton.clicked.connect(runfit)
+ >>> fit_actions_buttons.DismissButton.clicked.connect(dismiss)
+
+ """
+
+ def __init__(self, parent=None):
+ qt.QWidget.__init__(self, parent)
+
+ self.resize(234, 53)
+
+ grid_layout = qt.QGridLayout(self)
+ grid_layout.setContentsMargins(11, 11, 11, 11)
+ grid_layout.setSpacing(6)
+ layout = qt.QHBoxLayout(None)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setSpacing(6)
+
+ self.EstimateButton = qt.QPushButton(self)
+ self.EstimateButton.setText("Estimate")
+ layout.addWidget(self.EstimateButton)
+ spacer = qt.QSpacerItem(20, 20,
+ qt.QSizePolicy.Expanding,
+ qt.QSizePolicy.Minimum)
+ layout.addItem(spacer)
+
+ self.StartFitButton = qt.QPushButton(self)
+ self.StartFitButton.setText("Start Fit")
+ layout.addWidget(self.StartFitButton)
+ spacer_2 = qt.QSpacerItem(20, 20,
+ qt.QSizePolicy.Expanding,
+ qt.QSizePolicy.Minimum)
+ layout.addItem(spacer_2)
+
+ self.DismissButton = qt.QPushButton(self)
+ self.DismissButton.setText("Dismiss")
+ layout.addWidget(self.DismissButton)
+
+ grid_layout.addLayout(layout, 0, 0)
+
+
+class FitStatusLines(qt.QWidget):
+ """Widget with 2 greyed out write-only ``QLineEdit``.
+
+ These text widgets can be accessed as public attributes::
+
+ - ``StatusLine``
+ - ``ChisqLine``
+
+ You will typically need to access these widgets to update the displayed
+ text::
+
+ >>> fit_status_lines = FitStatusLines()
+ >>> fit_status_lines.StatusLine.setText("Ready")
+ >>> fit_status_lines.ChisqLine.setText("%6.2f" % 0.01)
+
+ """
+
+ def __init__(self, parent=None):
+ qt.QWidget.__init__(self, parent)
+
+ self.resize(535, 47)
+
+ layout = qt.QHBoxLayout(self)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setSpacing(6)
+
+ self.StatusLabel = qt.QLabel(self)
+ self.StatusLabel.setText("Status:")
+ layout.addWidget(self.StatusLabel)
+
+ self.StatusLine = qt.QLineEdit(self)
+ self.StatusLine.setText("Ready")
+ self.StatusLine.setReadOnly(1)
+ layout.addWidget(self.StatusLine)
+
+ self.ChisqLabel = qt.QLabel(self)
+ self.ChisqLabel.setText("Reduced chisq:")
+ layout.addWidget(self.ChisqLabel)
+
+ self.ChisqLine = qt.QLineEdit(self)
+ self.ChisqLine.setMaximumSize(qt.QSize(16000, 32767))
+ self.ChisqLine.setText("")
+ self.ChisqLine.setReadOnly(1)
+ layout.addWidget(self.ChisqLine)
+
+
+class FitConfigWidget(qt.QWidget):
+ """Widget whose purpose is to select a fit theory and a background
+ theory, load a new fit theory definition file and provide
+ a "Configure" button to open an advanced configuration dialog.
+
+ This is used in :class:`silx.gui.fit.FitWidget.FitWidget`, to offer
+ an interface to quickly modify the main parameters prior to running a fit:
+
+ - select a fitting function through :attr:`FunComBox`
+ - select a background function through :attr:`BkgComBox`
+ - open a dialog for modifying advanced parameters through
+ :attr:`FunConfigureButton`
+ """
+ def __init__(self, parent=None):
+ qt.QWidget.__init__(self, parent)
+
+ self.setWindowTitle("FitConfigGUI")
+
+ layout = qt.QGridLayout(self)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setSpacing(6)
+
+ self.FunLabel = qt.QLabel(self)
+ self.FunLabel.setText("Function")
+ layout.addWidget(self.FunLabel, 0, 0)
+
+ self.FunComBox = qt.QComboBox(self)
+ self.FunComBox.addItem("Add Function(s)")
+ self.FunComBox.setItemData(self.FunComBox.findText("Add Function(s)"),
+ "Load fit theories from a file",
+ qt.Qt.ToolTipRole)
+ layout.addWidget(self.FunComBox, 0, 1)
+
+ self.BkgLabel = qt.QLabel(self)
+ self.BkgLabel.setText("Background")
+ layout.addWidget(self.BkgLabel, 1, 0)
+
+ self.BkgComBox = qt.QComboBox(self)
+ self.BkgComBox.addItem("Add Background(s)")
+ self.BkgComBox.setItemData(self.BkgComBox.findText("Add Background(s)"),
+ "Load background theories from a file",
+ qt.Qt.ToolTipRole)
+ layout.addWidget(self.BkgComBox, 1, 1)
+
+ self.FunConfigureButton = qt.QPushButton(self)
+ self.FunConfigureButton.setText("Configure")
+ self.FunConfigureButton.setToolTip(
+ "Open a configuration dialog for the selected function")
+ layout.addWidget(self.FunConfigureButton, 0, 2)
+
+ self.BgConfigureButton = qt.QPushButton(self)
+ self.BgConfigureButton.setText("Configure")
+ self.BgConfigureButton.setToolTip(
+ "Open a configuration dialog for the selected background")
+ layout.addWidget(self.BgConfigureButton, 1, 2)
+
+ self.WeightCheckBox = qt.QCheckBox(self)
+ self.WeightCheckBox.setText("Weighted fit")
+ self.WeightCheckBox.setToolTip(
+ "Enable usage of weights in the least-square problem.\n Use" +
+ " the uncertainties (sigma) if provided, else use sqrt(y).")
+
+ layout.addWidget(self.WeightCheckBox, 0, 3, 2, 1)
+
+ layout.setColumnStretch(4, 1)
+
+
+class ParametersTab(qt.QTabWidget):
+ """This widget provides tabs to display and modify fit parameters. Each
+ tab contains a table with fit data such as parameter names, estimated
+ values, fit constraints, and final fit results.
+
+ The usual way to initialize the table is to fill it with the fit
+ parameters from a :class:`silx.math.fit.fitmanager.FitManager` object, after
+ the estimation process or after the final fit.
+
+ In the following example we use a :class:`ParametersTab` to display the
+ results of two separate fits::
+
+ from silx.math.fit import fittheories
+ from silx.math.fit import fitmanager
+ from silx.math.fit import functions
+ from silx.gui import qt
+ import numpy
+
+ a = qt.QApplication([])
+
+ # Create synthetic data
+ x = numpy.arange(1000)
+ y1 = functions.sum_gauss(x, 100, 400, 100)
+
+ fit = fitmanager.FitManager(x=x, y=y1)
+
+ fitfuns = fittheories.FitTheories()
+ fit.addtheory(theory="Gaussian",
+ function=functions.sum_gauss,
+ parameters=("height", "peak center", "fwhm"),
+ estimate=fitfuns.estimate_height_position_fwhm)
+ fit.settheory('Gaussian')
+ fit.configure(PositiveFwhmFlag=True,
+ PositiveHeightAreaFlag=True,
+ AutoFwhm=True,)
+
+ # Fit
+ fit.estimate()
+ fit.runfit()
+
+ # Show first fit result in a tab in our widget
+ w = ParametersTab()
+ w.show()
+ w.fillFromFit(fit.fit_results, view='Gaussians')
+
+ # new synthetic data
+ y2 = functions.sum_splitgauss(x,
+ 100, 400, 100, 40,
+ 10, 600, 50, 500,
+ 80, 850, 10, 50)
+ fit.setData(x=x, y=y2)
+
+ # Define new theory
+ fit.addtheory(theory="Asymetric gaussian",
+ function=functions.sum_splitgauss,
+ parameters=("height", "peak center", "left fwhm", "right fwhm"),
+ estimate=fitfuns.estimate_splitgauss)
+ fit.settheory('Asymetric gaussian')
+
+ # Fit
+ fit.estimate()
+ fit.runfit()
+
+ # Show first fit result in another tab in our widget
+ w.fillFromFit(fit.fit_results, view='Asymetric gaussians')
+ a.exec_()
+
+ """
+
+ def __init__(self, parent=None, name="FitParameters"):
+ """
+
+ :param parent: Parent widget
+ :param name: Widget title
+ """
+ qt.QTabWidget.__init__(self, parent)
+ self.setWindowTitle(name)
+ self.setContentsMargins(0, 0, 0, 0)
+
+ self.views = OrderedDict()
+ """Dictionary of views. Keys are view names,
+ items are :class:`Parameters` widgets"""
+
+ self.latest_view = None
+ """Name of latest view"""
+
+ # the widgets/tables themselves
+ self.tables = {}
+ """Dictionary of :class:`silx.gui.fit.parameters.Parameters` objects.
+ These objects store fit results
+ """
+
+ self.setContentsMargins(10, 10, 10, 10)
+
+ def setView(self, view=None, fitresults=None):
+ """Add or update a table. Fill it with data from a fit
+
+ :param view: Tab name to be added or updated. If ``None``, use the
+ latest view.
+ :param fitresults: Fit data to be added to the table
+ :raise: KeyError if no view name specified and no latest view
+ available.
+ """
+ if view is None:
+ if self.latest_view is not None:
+ view = self.latest_view
+ else:
+ raise KeyError(
+ "No view available. You must specify a view" +
+ " name the first time you call this method."
+ )
+
+ if view in self.tables.keys():
+ table = self.tables[view]
+ else:
+ # create the parameters instance
+ self.tables[view] = Parameters(self)
+ table = self.tables[view]
+ self.views[view] = table
+ self.addTab(table, str(view))
+
+ if fitresults is not None:
+ table.fillFromFit(fitresults)
+
+ self.setCurrentWidget(self.views[view])
+ self.latest_view = view
+
+ def renameView(self, oldname=None, newname=None):
+ """Rename a view (tab)
+
+ :param oldname: Name of the view to be renamed
+ :param newname: New name of the view"""
+ error = 1
+ if newname is not None:
+ if newname not in self.views.keys():
+ if oldname in self.views.keys():
+ parameterlist = self.tables[oldname].getFitResults()
+ self.setView(view=newname, fitresults=parameterlist)
+ self.removeView(oldname)
+ error = 0
+ return error
+
+ def fillFromFit(self, fitparameterslist, view=None):
+ """Update a view with data from a fit (alias for :meth:`setView`)
+
+ :param view: Tab name to be added or updated (default: latest view)
+ :param fitparameterslist: Fit data to be added to the table
+ """
+ self.setView(view=view, fitresults=fitparameterslist)
+
+ def getFitResults(self, name=None):
+ """Call :meth:`getFitResults` for the
+ :class:`silx.gui.fit.parameters.Parameters` corresponding to the
+ latest table or to the named table (if ``name`` is not
+ ``None``). This return a list of dictionaries in the format used by
+ :class:`silx.math.fit.fitmanager.FitManager` to store fit parameter
+ results.
+
+ :param name: View name.
+ """
+ if name is None:
+ name = self.latest_view
+ return self.tables[name].getFitResults()
+
+ def removeView(self, name):
+ """Remove a view by name.
+
+ :param name: View name.
+ """
+ if name in self.views:
+ index = self.indexOf(self.tables[name])
+ self.removeTab(index)
+ index = self.indexOf(self.views[name])
+ self.removeTab(index)
+ del self.tables[name]
+ del self.views[name]
+
+ def removeAllViews(self, keep=None):
+ """Remove all views, except the one specified (argument
+ ``keep``)
+
+ :param keep: Name of the view to be kept."""
+ for view in self.tables:
+ if view != keep:
+ self.removeView(view)
+
+ def getHtmlText(self, name=None):
+ """Return the table data as HTML
+
+ :param name: View name."""
+ if name is None:
+ name = self.latest_view
+ table = self.tables[name]
+ lemon = ("#%x%x%x" % (255, 250, 205)).upper()
+ hcolor = ("#%x%x%x" % (230, 240, 249)).upper()
+ text = ""
+ text += "<nobr>"
+ text += "<table>"
+ text += "<tr>"
+ ncols = table.columnCount()
+ for l in range(ncols):
+ text += ('<td align="left" bgcolor="%s"><b>' % hcolor)
+ if QTVERSION < '4.0.0':
+ text += (str(table.horizontalHeader().label(l)))
+ else:
+ text += (str(table.horizontalHeaderItem(l).text()))
+ text += "</b></td>"
+ text += "</tr>"
+ nrows = table.rowCount()
+ for r in range(nrows):
+ text += "<tr>"
+ item = table.item(r, 0)
+ newtext = ""
+ if item is not None:
+ newtext = str(item.text())
+ if len(newtext):
+ color = "white"
+ b = "<b>"
+ else:
+ b = ""
+ color = lemon
+ try:
+ # MyQTable item has color defined
+ cc = table.item(r, 0).color
+ cc = ("#%x%x%x" % (cc.red(), cc.green(), cc.blue())).upper()
+ color = cc
+ except:
+ pass
+ for c in range(ncols):
+ item = table.item(r, c)
+ newtext = ""
+ if item is not None:
+ newtext = str(item.text())
+ if len(newtext):
+ finalcolor = color
+ else:
+ finalcolor = "white"
+ if c < 2:
+ text += ('<td align="left" bgcolor="%s">%s' %
+ (finalcolor, b))
+ else:
+ text += ('<td align="right" bgcolor="%s">%s' %
+ (finalcolor, b))
+ text += newtext
+ if len(b):
+ text += "</td>"
+ else:
+ text += "</b></td>"
+ item = table.item(r, 0)
+ newtext = ""
+ if item is not None:
+ newtext = str(item.text())
+ if len(newtext):
+ text += "</b>"
+ text += "</tr>"
+ text += "\n"
+ text += "</table>"
+ text += "</nobr>"
+ return text
+
+ def getText(self, name=None):
+ """Return the table data as CSV formatted text, using tabulation
+ characters as separators.
+
+ :param name: View name."""
+ if name is None:
+ name = self.latest_view
+ table = self.tables[name]
+ text = ""
+ ncols = table.columnCount()
+ for l in range(ncols):
+ text += (str(table.horizontalHeaderItem(l).text())) + "\t"
+ text += "\n"
+ nrows = table.rowCount()
+ for r in range(nrows):
+ for c in range(ncols):
+ newtext = ""
+ if c != 4:
+ item = table.item(r, c)
+ if item is not None:
+ newtext = str(item.text())
+ else:
+ item = table.cellWidget(r, c)
+ if item is not None:
+ newtext = str(item.currentText())
+ text += newtext + "\t"
+ text += "\n"
+ text += "\n"
+ return text
+
+
+def test():
+ from silx.math.fit import fittheories
+ from silx.math.fit import fitmanager
+ from silx.math.fit import functions
+ from silx.gui.plot.PlotWindow import PlotWindow
+ import numpy
+
+ a = qt.QApplication([])
+
+ x = numpy.arange(1000)
+ y1 = functions.sum_gauss(x, 100, 400, 100)
+
+ fit = fitmanager.FitManager(x=x, y=y1)
+
+ fitfuns = fittheories.FitTheories()
+ fit.addtheory(name="Gaussian",
+ function=functions.sum_gauss,
+ parameters=("height", "peak center", "fwhm"),
+ estimate=fitfuns.estimate_height_position_fwhm)
+ fit.settheory('Gaussian')
+ fit.configure(PositiveFwhmFlag=True,
+ PositiveHeightAreaFlag=True,
+ AutoFwhm=True,)
+
+ # Fit
+ fit.estimate()
+ fit.runfit()
+
+ w = ParametersTab()
+ w.show()
+ w.fillFromFit(fit.fit_results, view='Gaussians')
+
+ y2 = functions.sum_splitgauss(x,
+ 100, 400, 100, 40,
+ 10, 600, 50, 500,
+ 80, 850, 10, 50)
+ fit.setdata(x=x, y=y2)
+
+ # Define new theory
+ fit.addtheory(name="Asymetric gaussian",
+ function=functions.sum_splitgauss,
+ parameters=("height", "peak center", "left fwhm", "right fwhm"),
+ estimate=fitfuns.estimate_splitgauss)
+ fit.settheory('Asymetric gaussian')
+
+ # Fit
+ fit.estimate()
+ fit.runfit()
+
+ w.fillFromFit(fit.fit_results, view='Asymetric gaussians')
+
+ # Plot
+ pw = PlotWindow(control=True)
+ pw.addCurve(x, y1, "Gaussians")
+ pw.addCurve(x, y2, "Asymetric gaussians")
+ pw.show()
+
+ a.exec_()
+
+
+if __name__ == "__main__":
+ test()
diff --git a/silx/gui/fit/Parameters.py b/silx/gui/fit/Parameters.py
new file mode 100644
index 0000000..62e3278
--- /dev/null
+++ b/silx/gui/fit/Parameters.py
@@ -0,0 +1,882 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2004-2017 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.
+#
+# ######################################################################### */
+"""This module defines a table widget that is specialized in displaying fit
+parameter results and associated constraints."""
+__authors__ = ["V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "25/11/2016"
+
+import sys
+from collections import OrderedDict
+
+from silx.gui import qt
+from silx.gui.widgets.TableWidget import TableWidget
+
+
+def float_else_zero(sstring):
+ """Return converted string to float. If conversion fail, return zero.
+
+ :param sstring: String to be converted
+ :return: ``float(sstrinq)`` if ``sstring`` can be converted to float
+ (e.g. ``"3.14"``), else ``0``
+ """
+ try:
+ return float(sstring)
+ except ValueError:
+ return 0
+
+
+class QComboTableItem(qt.QComboBox):
+ """:class:`qt.QComboBox` augmented with a ``sigCellChanged`` signal
+ to emit a tuple of ``(row, column)`` coordinates when the value is
+ changed.
+
+ This signal can be used to locate the modified combo box in a table.
+
+ :param row: Row number of the table cell containing this widget
+ :param col: Column number of the table cell containing this widget"""
+ sigCellChanged = qt.Signal(int, int)
+ """Signal emitted when this ``QComboBox`` is activated.
+ A ``(row, column)`` tuple is passed."""
+
+ def __init__(self, parent=None, row=None, col=None):
+ self._row = row
+ self._col = col
+ qt.QComboBox.__init__(self, parent)
+ self.activated[int].connect(self._cellChanged)
+
+ def _cellChanged(self, idx): # noqa
+ self.sigCellChanged.emit(self._row, self._col)
+
+
+class QCheckBoxItem(qt.QCheckBox):
+ """:class:`qt.QCheckBox` augmented with a ``sigCellChanged`` signal
+ to emit a tuple of ``(row, column)`` coordinates when the check box has
+ been clicked on.
+
+ This signal can be used to locate the modified check box in a table.
+
+ :param row: Row number of the table cell containing this widget
+ :param col: Column number of the table cell containing this widget"""
+ sigCellChanged = qt.Signal(int, int)
+ """Signal emitted when this ``QCheckBox`` is clicked.
+ A ``(row, column)`` tuple is passed."""
+
+ def __init__(self, parent=None, row=None, col=None):
+ self._row = row
+ self._col = col
+ qt.QCheckBox.__init__(self, parent)
+ self.clicked.connect(self._cellChanged)
+
+ def _cellChanged(self):
+ self.sigCellChanged.emit(self._row, self._col)
+
+
+class Parameters(TableWidget):
+ """:class:`TableWidget` customized to display fit results
+ and to interact with :class:`FitManager` objects.
+
+ Data and references to cell widgets are kept in a dictionary
+ attribute :attr:`parameters`.
+
+ :param parent: Parent widget
+ :param labels: Column headers. If ``None``, default headers will be used.
+ :type labels: List of strings or None
+ :param paramlist: List of fit parameters to be displayed for each fitted
+ peak.
+ :type paramlist: list[str] or None
+ """
+ def __init__(self, parent=None, paramlist=None):
+ TableWidget.__init__(self, parent)
+ self.setContentsMargins(0, 0, 0, 0)
+
+ labels = ['Parameter', 'Estimation', 'Fit Value', 'Sigma',
+ 'Constraints', 'Min/Parame', 'Max/Factor/Delta']
+ tooltips = ["Fit parameter name",
+ "Estimated value for fit parameter. You can edit this column.",
+ "Actual value for parameter, after fit",
+ "Uncertainty (same unit as the parameter)",
+ "Constraint to be applied to the parameter for fit",
+ "First parameter for constraint (name of another param or min value)",
+ "Second parameter for constraint (max value, or factor/delta)"]
+
+ self.columnKeys = ['name', 'estimation', 'fitresult',
+ 'sigma', 'code', 'val1', 'val2']
+ """This list assigns shorter keys to refer to columns than the
+ displayed labels."""
+
+ self.__configuring = False
+
+ # column headers and associated tooltips
+ self.setColumnCount(len(labels))
+
+ for i, label in enumerate(labels):
+ item = self.horizontalHeaderItem(i)
+ if item is None:
+ item = qt.QTableWidgetItem(label,
+ qt.QTableWidgetItem.Type)
+ self.setHorizontalHeaderItem(i, item)
+
+ item.setText(label)
+ if tooltips is not None:
+ item.setToolTip(tooltips[i])
+
+ # resize columns
+ for col_key in ["name", "estimation", "sigma", "val1", "val2"]:
+ col_idx = self.columnIndexByField(col_key)
+ self.resizeColumnToContents(col_idx)
+
+ # Initialize the table with one line per supplied parameter
+ paramlist = paramlist if paramlist is not None else []
+ self.parameters = OrderedDict()
+ """This attribute stores all the data in an ordered dictionary.
+ New data can be added using :meth:`newParameterLine`.
+ Existing data can be modified using :meth:`configureLine`
+
+ Keys of the dictionary are:
+
+ - 'name': parameter name
+ - 'line': line index for the parameter in the table
+ - 'estimation'
+ - 'fitresult'
+ - 'sigma'
+ - 'code': constraint code (one of the elements of
+ :attr:`code_options`)
+ - 'val1': first parameter related to constraint, formatted
+ as a string, as typed in the table
+ - 'val2': second parameter related to constraint, formatted
+ as a string, as typed in the table
+ - 'cons1': scalar representation of 'val1'
+ (e.g. when val1 is the name of a fit parameter, cons1
+ will be the line index of this parameter)
+ - 'cons2': scalar representation of 'val2'
+ - 'vmin': equal to 'val1' when 'code' is "QUOTED"
+ - 'vmax': equal to 'val2' when 'code' is "QUOTED"
+ - 'relatedto': name of related parameter when this parameter
+ is constrained to another parameter (same as 'val1')
+ - 'factor': same as 'val2' when 'code' is 'FACTOR'
+ - 'delta': same as 'val2' when 'code' is 'DELTA'
+ - 'sum': same as 'val2' when 'code' is 'SUM'
+ - 'group': group index for the parameter
+ - 'xmin': data range minimum
+ - 'xmax': data range maximum
+ """
+ for line, param in enumerate(paramlist):
+ self.newParameterLine(param, line)
+
+ self.code_options = ["FREE", "POSITIVE", "QUOTED", "FIXED",
+ "FACTOR", "DELTA", "SUM", "IGNORE", "ADD"]
+ """Possible values in the combo boxes in the 'Constraints' column.
+ """
+
+ # connect signal
+ self.cellChanged[int, int].connect(self.onCellChanged)
+
+ def newParameterLine(self, param, line):
+ """Add a line to the :class:`QTableWidget`.
+
+ Each line represents one of the fit parameters for one of
+ the fitted peaks.
+
+ :param param: Name of the fit parameter
+ :type param: str
+ :param line: 0-based line index
+ :type line: int
+ """
+ # get current number of lines
+ nlines = self.rowCount()
+ self.__configuring = True
+ if line >= nlines:
+ self.setRowCount(line + 1)
+
+ # default configuration for fit parameters
+ self.parameters[param] = OrderedDict((('line', line),
+ ('estimation', '0'),
+ ('fitresult', ''),
+ ('sigma', ''),
+ ('code', 'FREE'),
+ ('val1', ''),
+ ('val2', ''),
+ ('cons1', 0),
+ ('cons2', 0),
+ ('vmin', '0'),
+ ('vmax', '1'),
+ ('relatedto', ''),
+ ('factor', '1.0'),
+ ('delta', '0.0'),
+ ('sum', '0.0'),
+ ('group', ''),
+ ('name', param),
+ ('xmin', None),
+ ('xmax', None)))
+ self.setReadWrite(param, 'estimation')
+ self.setReadOnly(param, ['name', 'fitresult', 'sigma', 'val1', 'val2'])
+
+ # Constraint codes
+ a = []
+ for option in self.code_options:
+ a.append(option)
+
+ code_column_index = self.columnIndexByField('code')
+ cellWidget = self.cellWidget(line, code_column_index)
+ if cellWidget is None:
+ cellWidget = QComboTableItem(self, row=line,
+ col=code_column_index)
+ cellWidget.addItems(a)
+ self.setCellWidget(line, code_column_index, cellWidget)
+ cellWidget.sigCellChanged[int, int].connect(self.onCellChanged)
+ self.parameters[param]['code_item'] = cellWidget
+ self.parameters[param]['relatedto_item'] = None
+ self.__configuring = False
+
+ def columnIndexByField(self, field):
+ """
+
+ :param field: Field name (column key)
+ :return: Index of the column with this field name
+ """
+ return self.columnKeys.index(field)
+
+ def fillFromFit(self, fitresults):
+ """Fill table with values from a list of dictionaries
+ (see :attr:`silx.math.fit.fitmanager.FitManager.fit_results`)
+
+ :param fitresults: List of parameters as recorded
+ in the ``paramlist`` attribute of a :class:`FitManager` object
+ :type fitresults: list[dict]
+ """
+ self.setRowCount(len(fitresults))
+
+ # Reinitialize and fill self.parameters
+ self.parameters = OrderedDict()
+ for (line, param) in enumerate(fitresults):
+ self.newParameterLine(param['name'], line)
+
+ for param in fitresults:
+ name = param['name']
+ code = str(param['code'])
+ if code not in self.code_options:
+ # convert code from int to descriptive string
+ code = self.code_options[int(code)]
+ val1 = param['cons1']
+ val2 = param['cons2']
+ estimation = param['estimation']
+ group = param['group']
+ sigma = param['sigma']
+ fitresult = param['fitresult']
+
+ xmin = param.get('xmin')
+ xmax = param.get('xmax')
+
+ self.configureLine(name=name,
+ code=code,
+ val1=val1, val2=val2,
+ estimation=estimation,
+ fitresult=fitresult,
+ sigma=sigma,
+ group=group,
+ xmin=xmin, xmax=xmax)
+
+ def getConfiguration(self):
+ """Return ``FitManager.paramlist`` dictionary
+ encapsulated in another dictionary"""
+ return {'parameters': self.getFitResults()}
+
+ def setConfiguration(self, ddict):
+ """Fill table with values from a ``FitManager.paramlist`` dictionary
+ encapsulated in another dictionary"""
+ self.fillFromFit(ddict['parameters'])
+
+ def getFitResults(self):
+ """Return fit parameters as a list of dictionaries in the format used
+ by :class:`FitManager` (attribute ``paramlist``).
+ """
+ fitparameterslist = []
+ for param in self.parameters:
+ fitparam = {}
+ name = param
+ estimation, [code, cons1, cons2] = self.getEstimationConstraints(name)
+ buf = str(self.parameters[param]['fitresult'])
+ xmin = self.parameters[param]['xmin']
+ xmax = self.parameters[param]['xmax']
+ if len(buf):
+ fitresult = float(buf)
+ else:
+ fitresult = 0.0
+ buf = str(self.parameters[param]['sigma'])
+ if len(buf):
+ sigma = float(buf)
+ else:
+ sigma = 0.0
+ buf = str(self.parameters[param]['group'])
+ if len(buf):
+ group = float(buf)
+ else:
+ group = 0
+ fitparam['name'] = name
+ fitparam['estimation'] = estimation
+ fitparam['fitresult'] = fitresult
+ fitparam['sigma'] = sigma
+ fitparam['group'] = group
+ fitparam['code'] = code
+ fitparam['cons1'] = cons1
+ fitparam['cons2'] = cons2
+ fitparam['xmin'] = xmin
+ fitparam['xmax'] = xmax
+ fitparameterslist.append(fitparam)
+ return fitparameterslist
+
+ def onCellChanged(self, row, col):
+ """Slot called when ``cellChanged`` signal is emitted.
+ Checks the validity of the new text in the cell, then calls
+ :meth:`configureLine` to update the internal ``self.parameters``
+ dictionary.
+
+ :param row: Row number of the changed cell (0-based index)
+ :param col: Column number of the changed cell (0-based index)
+ """
+ if (col != self.columnIndexByField("code")) and (col != -1):
+ if row != self.currentRow():
+ return
+ if col != self.currentColumn():
+ return
+ if self.__configuring:
+ return
+ param = list(self.parameters)[row]
+ field = self.columnKeys[col]
+ oldvalue = self.parameters[param][field]
+ if col != 4:
+ item = self.item(row, col)
+ if item is not None:
+ newvalue = item.text()
+ else:
+ newvalue = ''
+ else:
+ # this is the combobox
+ widget = self.cellWidget(row, col)
+ newvalue = widget.currentText()
+ if self.validate(param, field, oldvalue, newvalue):
+ paramdict = {"name": param, field: newvalue}
+ self.configureLine(**paramdict)
+ else:
+ if field == 'code':
+ # New code not valid, try restoring the old one
+ index = self.code_options.index(oldvalue)
+ self.__configuring = True
+ try:
+ self.parameters[param]['code_item'].setCurrentIndex(index)
+ finally:
+ self.__configuring = False
+ else:
+ paramdict = {"name": param, field: oldvalue}
+ self.configureLine(**paramdict)
+
+ def validate(self, param, field, oldvalue, newvalue):
+ """Check validity of ``newvalue`` when a cell's value is modified.
+
+ :param param: Fit parameter name
+ :param field: Column name
+ :param oldvalue: Cell value before change attempt
+ :param newvalue: New value to be validated
+ :return: True if new cell value is valid, else False
+ """
+ if field == 'code':
+ return self.setCodeValue(param, oldvalue, newvalue)
+ # FIXME: validate() shouldn't have side effects. Move this bit to configureLine()?
+ if field == 'val1' and str(self.parameters[param]['code']) in ['DELTA', 'FACTOR', 'SUM']:
+ _, candidates = self.getRelatedCandidates(param)
+ # We expect val1 to be a fit parameter name
+ if str(newvalue) in candidates:
+ return True
+ else:
+ return False
+ # except for code, val1 and name (which is read-only and does not need
+ # validation), all fields must always be convertible to float
+ else:
+ try:
+ float(str(newvalue))
+ except ValueError:
+ return False
+ return True
+
+ def setCodeValue(self, param, oldvalue, newvalue):
+ """Update 'code' and 'relatedto' fields when code cell is
+ changed.
+
+ :param param: Fit parameter name
+ :param oldvalue: Cell value before change attempt
+ :param newvalue: New value to be validated
+ :return: ``True`` if code was successfully updated
+ """
+
+ if str(newvalue) in ['FREE', 'POSITIVE', 'QUOTED', 'FIXED']:
+ self.configureLine(name=param,
+ code=newvalue)
+ if str(oldvalue) == 'IGNORE':
+ self.freeRestOfGroup(param)
+ return True
+ elif str(newvalue) in ['FACTOR', 'DELTA', 'SUM']:
+ # I should check here that some parameter is set
+ best, candidates = self.getRelatedCandidates(param)
+ if len(candidates) == 0:
+ return False
+ self.configureLine(name=param,
+ code=newvalue,
+ relatedto=best)
+ if str(oldvalue) == 'IGNORE':
+ self.freeRestOfGroup(param)
+ return True
+
+ elif str(newvalue) == 'IGNORE':
+ # I should check if the group can be ignored
+ # for the time being I just fix all of them to ignore
+ group = int(float(str(self.parameters[param]['group'])))
+ candidates = []
+ for param in self.parameters.keys():
+ if group == int(float(str(self.parameters[param]['group']))):
+ candidates.append(param)
+ # print candidates
+ # I should check here if there is any relation to them
+ for param in candidates:
+ self.configureLine(name=param,
+ code=newvalue)
+ return True
+ elif str(newvalue) == 'ADD':
+ group = int(float(str(self.parameters[param]['group'])))
+ if group == 0:
+ # One cannot add a background group
+ return False
+ i = 0
+ for param in self.parameters:
+ if i <= int(float(str(self.parameters[param]['group']))):
+ i += 1
+ if (group == 0) and (i == 1): # FIXME: why +1?
+ i += 1
+ self.addGroup(i, group)
+ return False
+ elif str(newvalue) == 'SHOW':
+ print(self.getEstimationConstraints(param))
+ return False
+
+ def addGroup(self, newg, gtype):
+ """Add a fit parameter group with the same fit parameters as an
+ existing group.
+
+ This function is called when the user selects "ADD" in the
+ "constraints" combobox.
+
+ :param int newg: New group number
+ :param int gtype: Group number whose parameters we want to copy
+
+ """
+ newparam = []
+ # loop through parameters until we encounter group number `gtype`
+ for param in list(self.parameters):
+ paramgroup = int(float(str(self.parameters[param]['group'])))
+ # copy parameter names in group number `gtype`
+ if paramgroup == gtype:
+ # but replace `gtype` with `newg`
+ newparam.append(param.rstrip("0123456789") + "%d" % newg)
+
+ xmin = self.parameters[param]['xmin']
+ xmax = self.parameters[param]['xmax']
+
+ # Add new parameters (one table line per parameter) and configureLine each
+ # one by updating xmin and xmax to the same values as group `gtype`
+ line = len(list(self.parameters))
+ for param in newparam:
+ self.newParameterLine(param, line)
+ line += 1
+ for param in newparam:
+ self.configureLine(name=param, group=newg, xmin=xmin, xmax=xmax)
+
+ def freeRestOfGroup(self, workparam):
+ """Set ``code`` to ``"FREE"`` for all fit parameters belonging to
+ the same group as ``workparam``. This is done when the entire group
+ of parameters was previously ignored and one of them has his code
+ set to something different than ``"IGNORE"``.
+
+ :param workparam: Fit parameter name
+ """
+ if workparam in self.parameters.keys():
+ group = int(float(str(self.parameters[workparam]['group'])))
+ for param in self.parameters:
+ if param != workparam and\
+ group == int(float(str(self.parameters[param]['group']))):
+ self.configureLine(name=param,
+ code='FREE',
+ cons1=0,
+ cons2=0,
+ val1='',
+ val2='')
+
+ def getRelatedCandidates(self, workparam):
+ """If fit parameter ``workparam`` has a constraint that involves other
+ fit parameters, find possible candidates and try to guess which one
+ is the most likely.
+
+ :param workparam: Fit parameter name
+ :return: (best_candidate, possible_candidates) tuple
+ :rtype: (str, list[str])
+ """
+ candidates = []
+ for param_name in self.parameters:
+ if param_name != workparam:
+ # ignore parameters that are fixed by a constraint
+ if str(self.parameters[param_name]['code']) not in\
+ ['IGNORE', 'FACTOR', 'DELTA', 'SUM']:
+ candidates.append(param_name)
+ # take the previous one (before code cell changed) if possible
+ if str(self.parameters[workparam]['relatedto']) in candidates:
+ best = str(self.parameters[workparam]['relatedto'])
+ return best, candidates
+ # take the first with same base name (after removing numbers)
+ for param_name in candidates:
+ basename = param_name.rstrip("0123456789")
+ try:
+ pos = workparam.index(basename)
+ if pos == 0:
+ best = param_name
+ return best, candidates
+ except ValueError:
+ pass
+ # take the first
+ return candidates[0], candidates
+
+ def setReadOnly(self, parameter, fields):
+ """Make table cells read-only by setting it's flags and omitting
+ flag ``qt.Qt.ItemIsEditable``
+
+ :param parameter: Fit parameter names identifying the rows
+ :type parameter: str or list[str]
+ :param fields: Field names identifying the columns
+ :type fields: str or list[str]
+ """
+ editflags = qt.Qt.ItemIsSelectable | qt.Qt.ItemIsEnabled
+ self.setField(parameter, fields, editflags)
+
+ def setReadWrite(self, parameter, fields):
+ """Make table cells read-write by setting it's flags including
+ flag ``qt.Qt.ItemIsEditable``
+
+ :param parameter: Fit parameter names identifying the rows
+ :type parameter: str or list[str]
+ :param fields: Field names identifying the columns
+ :type fields: str or list[str]
+ """
+ editflags = qt.Qt.ItemIsSelectable |\
+ qt.Qt.ItemIsEnabled |\
+ qt.Qt.ItemIsEditable
+ self.setField(parameter, fields, editflags)
+
+ def setField(self, parameter, fields, edit_flags):
+ """Set text and flags in a table cell.
+
+ :param parameter: Fit parameter names identifying the rows
+ :type parameter: str or list[str]
+ :param fields: Field names identifying the columns
+ :type fields: str or list[str]
+ :param edit_flags: Flag combination, e.g::
+
+ qt.Qt.ItemIsSelectable | qt.Qt.ItemIsEnabled |
+ qt.Qt.ItemIsEditable
+ """
+ if isinstance(parameter, list) or \
+ isinstance(parameter, tuple):
+ paramlist = parameter
+ else:
+ paramlist = [parameter]
+ if isinstance(fields, list) or \
+ isinstance(fields, tuple):
+ fieldlist = fields
+ else:
+ fieldlist = [fields]
+
+ # Set _configuring flag to ignore cellChanged signals in
+ # self.onCellChanged
+ _oldvalue = self.__configuring
+ self.__configuring = True
+
+ # 2D loop through parameter list and field list
+ # to update their cells
+ for param in paramlist:
+ row = list(self.parameters.keys()).index(param)
+ for field in fieldlist:
+ col = self.columnIndexByField(field)
+ if field != 'code':
+ key = field + "_item"
+ item = self.item(row, col)
+ if item is None:
+ item = qt.QTableWidgetItem()
+ item.setText(self.parameters[param][field])
+ self.setItem(row, col, item)
+ else:
+ item.setText(self.parameters[param][field])
+ self.parameters[param][key] = item
+ item.setFlags(edit_flags)
+
+ # Restore previous _configuring flag
+ self.__configuring = _oldvalue
+
+ def configureLine(self, name, code=None, val1=None, val2=None,
+ sigma=None, estimation=None, fitresult=None,
+ group=None, xmin=None, xmax=None, relatedto=None,
+ cons1=None, cons2=None):
+ """This function updates values in a line of the table
+
+ :param name: Name of the parameter (serves as unique identifier for
+ a line).
+ :param code: Constraint code *FREE, FIXED, POSITIVE, DELTA, FACTOR,
+ SUM, QUOTED, IGNORE*
+ :param val1: Constraint 1 (can be the index or name of another
+ parameter for code *DELTA, FACTOR, SUM*, or a min value
+ for code *QUOTED*)
+ :param val2: Constraint 2
+ :param sigma: Standard deviation for a fit parameter
+ :param estimation: Estimated initial value for a fit parameter (used
+ as input to iterative fit)
+ :param fitresult: Final result of fit
+ :param group: Group number of a fit parameter (peak number when doing
+ multi-peak fitting, as each peak corresponds to a group
+ of several consecutive parameters)
+ :param xmin:
+ :param xmax:
+ :param relatedto: Index or name of another fit parameter
+ to which this parameter is related to (constraints)
+ :param cons1: similar meaning to ``val1``, but is always a number
+ :param cons2: similar meaning to ``val2``, but is always a number
+ :return:
+ """
+ paramlist = list(self.parameters.keys())
+
+ if name not in self.parameters:
+ raise KeyError("'%s' is not in the parameter list" % name)
+
+ # update code first, if specified
+ if code is not None:
+ code = str(code)
+ self.parameters[name]['code'] = code
+ # update combobox
+ index = self.parameters[name]['code_item'].findText(code)
+ self.parameters[name]['code_item'].setCurrentIndex(index)
+ else:
+ # set code to previous value, used later for setting val1 val2
+ code = self.parameters[name]['code']
+
+ # val1 and sigma have special formats
+ if val1 is not None:
+ fmt = None if self.parameters[name]['code'] in\
+ ['DELTA', 'FACTOR', 'SUM'] else "%8g"
+ self._updateField(name, "val1", val1, fmat=fmt)
+
+ if sigma is not None:
+ self._updateField(name, "sigma", sigma, fmat="%6.3g")
+
+ # other fields are formatted as "%8g"
+ keys_params = (("val2", val2), ("estimation", estimation),
+ ("fitresult", fitresult))
+ for key, value in keys_params:
+ if value is not None:
+ self._updateField(name, key, value, fmat="%8g")
+
+ # the rest of the parameters are treated as strings and don't need
+ # validation
+ keys_params = (("group", group), ("xmin", xmin),
+ ("xmax", xmax), ("relatedto", relatedto),
+ ("cons1", cons1), ("cons2", cons2))
+ for key, value in keys_params:
+ if value is not None:
+ self.parameters[name][key] = str(value)
+
+ # val1 and val2 have different meanings depending on the code
+ if code == 'QUOTED':
+ if val1 is not None:
+ self.parameters[name]['vmin'] = self.parameters[name]['val1']
+ else:
+ self.parameters[name]['val1'] = self.parameters[name]['vmin']
+ if val2 is not None:
+ self.parameters[name]['vmax'] = self.parameters[name]['val2']
+ else:
+ self.parameters[name]['val2'] = self.parameters[name]['vmax']
+
+ # cons1 and cons2 are scalar representations of val1 and val2
+ self.parameters[name]['cons1'] =\
+ float_else_zero(self.parameters[name]['val1'])
+ self.parameters[name]['cons2'] =\
+ float_else_zero(self.parameters[name]['val2'])
+
+ # cons1, cons2 = min(val1, val2), max(val1, val2)
+ if self.parameters[name]['cons1'] > self.parameters[name]['cons2']:
+ self.parameters[name]['cons1'], self.parameters[name]['cons2'] =\
+ self.parameters[name]['cons2'], self.parameters[name]['cons1']
+
+ elif code in ['DELTA', 'SUM', 'FACTOR']:
+ # For these codes, val1 is the fit parameter name on which the
+ # constraint depends
+ if val1 is not None and val1 in paramlist:
+ self.parameters[name]['relatedto'] = self.parameters[name]["val1"]
+
+ elif val1 is not None:
+ # val1 could be the index of the fit parameter
+ try:
+ self.parameters[name]['relatedto'] = paramlist[int(val1)]
+ except ValueError:
+ self.parameters[name]['relatedto'] = self.parameters[name]["val1"]
+
+ elif relatedto is not None:
+ # code changed, val1 not specified but relatedto specified:
+ # set val1 to relatedto (pre-fill best guess)
+ self.parameters[name]["val1"] = relatedto
+
+ # update fields "delta", "sum" or "factor"
+ key = code.lower()
+ self.parameters[name][key] = self.parameters[name]["val2"]
+
+ # FIXME: val1 is sometimes specified as an index rather than a param name
+ self.parameters[name]['val1'] = self.parameters[name]['relatedto']
+
+ # cons1 is the index of the fit parameter in the ordered dictionary
+ if self.parameters[name]['val1'] in paramlist:
+ self.parameters[name]['cons1'] =\
+ paramlist.index(self.parameters[name]['val1'])
+
+ # cons2 is the constraint value (factor, delta or sum)
+ try:
+ self.parameters[name]['cons2'] =\
+ float(str(self.parameters[name]['val2']))
+ except ValueError:
+ self.parameters[name]['cons2'] = 1.0 if code == "FACTOR" else 0.0
+
+ elif code in ['FREE', 'POSITIVE', 'IGNORE', 'FIXED']:
+ self.parameters[name]['val1'] = ""
+ self.parameters[name]['val2'] = ""
+ self.parameters[name]['cons1'] = 0
+ self.parameters[name]['cons2'] = 0
+
+ self._updateCellRWFlags(name, code)
+
+ def _updateField(self, name, field, value, fmat=None):
+ """Update field in ``self.parameters`` dictionary, if the new value
+ is valid.
+
+ :param name: Fit parameter name
+ :param field: Field name
+ :param value: New value to assign
+ :type value: String
+ :param fmat: Format string (e.g. "%8g") to be applied if value represents
+ a scalar. If ``None``, format is not modified. If ``value`` is an
+ empty string, ``fmat`` is ignored.
+ """
+ if value is not None:
+ oldvalue = self.parameters[name][field]
+ if fmat is not None:
+ newvalue = fmat % float(value) if value != "" else ""
+ else:
+ newvalue = value
+ self.parameters[name][field] = newvalue if\
+ self.validate(name, field, oldvalue, newvalue) else\
+ oldvalue
+
+ def _updateCellRWFlags(self, name, code=None):
+ """Set read-only or read-write flags in a row,
+ depending on the constraint code
+
+ :param name: Fit parameter name identifying the row
+ :param code: Constraint code, in `'FREE', 'POSITIVE', 'IGNORE',`
+ `'FIXED', 'FACTOR', 'DELTA', 'SUM', 'ADD'`
+ :return:
+ """
+ if code in ['FREE', 'POSITIVE', 'IGNORE', 'FIXED']:
+ self.setReadWrite(name, 'estimation')
+ self.setReadOnly(name, ['fitresult', 'sigma', 'val1', 'val2'])
+ else:
+ self.setReadWrite(name, ['estimation', 'val1', 'val2'])
+ self.setReadOnly(name, ['fitresult', 'sigma'])
+
+ def getEstimationConstraints(self, param):
+ """
+ Return tuple ``(estimation, constraints)`` where ``estimation`` is the
+ value in the ``estimate`` field and ``constraints`` are the relevant
+ constraints according to the active code
+ """
+ estimation = None
+ constraints = None
+ if param in self.parameters.keys():
+ buf = str(self.parameters[param]['estimation'])
+ if len(buf):
+ estimation = float(buf)
+ else:
+ estimation = 0
+ if str(self.parameters[param]['code']) in self.code_options:
+ code = self.code_options.index(
+ str(self.parameters[param]['code']))
+ else:
+ code = str(self.parameters[param]['code'])
+ cons1 = self.parameters[param]['cons1']
+ cons2 = self.parameters[param]['cons2']
+ constraints = [code, cons1, cons2]
+ return estimation, constraints
+
+
+def main(args):
+ from silx.math.fit import fittheories
+ from silx.math.fit import fitmanager
+ try:
+ from PyMca5 import PyMcaDataDir
+ except ImportError:
+ raise ImportError("This demo requires PyMca data. Install PyMca5.")
+ import numpy
+ import os
+ app = qt.QApplication(args)
+ tab = Parameters(paramlist=['Height', 'Position', 'FWHM'])
+ tab.showGrid()
+ tab.configureLine(name='Height', estimation='1234', group=0)
+ tab.configureLine(name='Position', code='FIXED', group=1)
+ tab.configureLine(name='FWHM', group=1)
+
+ y = numpy.loadtxt(os.path.join(PyMcaDataDir.PYMCA_DATA_DIR,
+ "XRFSpectrum.mca")) # FIXME
+
+ x = numpy.arange(len(y)) * 0.0502883 - 0.492773
+ fit = fitmanager.FitManager()
+ fit.setdata(x=x, y=y, xmin=20, xmax=150)
+
+ fit.loadtheories(fittheories)
+
+ fit.settheory('ahypermet')
+ fit.configure(Yscaling=1.,
+ PositiveFwhmFlag=True,
+ PositiveHeightAreaFlag=True,
+ FwhmPoints=16,
+ QuotedPositionFlag=1,
+ HypermetTails=1)
+ fit.setbackground('Linear')
+ fit.estimate()
+ fit.runfit()
+ tab.fillFromFit(fit.fit_results)
+ tab.show()
+ app.exec_()
+
+if __name__ == "__main__":
+ main(sys.argv)
diff --git a/silx/gui/fit/__init__.py b/silx/gui/fit/__init__.py
new file mode 100644
index 0000000..e4fd3ab
--- /dev/null
+++ b/silx/gui/fit/__init__.py
@@ -0,0 +1,28 @@
+# 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.
+#
+# ############################################################################*/
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "07/07/2016"
+
+from .FitWidget import FitWidget
diff --git a/silx/gui/fit/setup.py b/silx/gui/fit/setup.py
new file mode 100644
index 0000000..6672363
--- /dev/null
+++ b/silx/gui/fit/setup.py
@@ -0,0 +1,43 @@
+# 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.
+#
+# ###########################################################################*/
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "21/07/2016"
+
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('fit', parent_package, top_path)
+ config.add_subpackage('test')
+
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/gui/fit/test/__init__.py b/silx/gui/fit/test/__init__.py
new file mode 100644
index 0000000..2236d64
--- /dev/null
+++ b/silx/gui/fit/test/__init__.py
@@ -0,0 +1,43 @@
+# 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.
+#
+# ###########################################################################*/
+import unittest
+
+from .testFitWidget import suite as testFitWidgetSuite
+from .testFitConfig import suite as testFitConfigSuite
+from .testBackgroundWidget import suite as testBackgroundWidgetSuite
+
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "21/07/2016"
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTests(
+ [testFitWidgetSuite(),
+ testFitConfigSuite(),
+ testBackgroundWidgetSuite()])
+ return test_suite
diff --git a/silx/gui/fit/test/testBackgroundWidget.py b/silx/gui/fit/test/testBackgroundWidget.py
new file mode 100644
index 0000000..2e366e4
--- /dev/null
+++ b/silx/gui/fit/test/testBackgroundWidget.py
@@ -0,0 +1,83 @@
+# 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.
+#
+# ###########################################################################*/
+import unittest
+
+from ...test.utils import TestCaseQt
+
+from .. import BackgroundWidget
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+class TestBackgroundWidget(TestCaseQt):
+ def setUp(self):
+ super(TestBackgroundWidget, self).setUp()
+ self.bgdialog = BackgroundWidget.BackgroundDialog()
+ self.bgdialog.setData(list([0, 1, 2, 3]),
+ list([0, 1, 4, 8]))
+ self.qWaitForWindowExposed(self.bgdialog)
+
+ def tearDown(self):
+ del self.bgdialog
+ super(TestBackgroundWidget, self).tearDown()
+
+ def testShow(self):
+ self.bgdialog.show()
+ self.bgdialog.hide()
+
+ def testAccept(self):
+ self.bgdialog.accept()
+ self.assertTrue(self.bgdialog.result())
+
+ def testReject(self):
+ self.bgdialog.reject()
+ self.assertFalse(self.bgdialog.result())
+
+ def testDefaultOutput(self):
+ self.bgdialog.accept()
+ output = self.bgdialog.output
+
+ for key in ["algorithm", "StripThreshold", "SnipWidth",
+ "StripIterations", "StripWidth", "SmoothingFlag",
+ "SmoothingWidth", "AnchorsFlag", "AnchorsList"]:
+ self.assertIn(key, output)
+
+ self.assertFalse(output["AnchorsFlag"])
+ self.assertEqual(output["StripWidth"], 1)
+ self.assertEqual(output["SmoothingFlag"], False)
+ self.assertEqual(output["SmoothingWidth"], 3)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestBackgroundWidget))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/fit/test/testFitConfig.py b/silx/gui/fit/test/testFitConfig.py
new file mode 100644
index 0000000..eea35cc
--- /dev/null
+++ b/silx/gui/fit/test/testFitConfig.py
@@ -0,0 +1,95 @@
+# 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.
+#
+# ###########################################################################*/
+"""Basic tests for :class:`FitConfig`"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+import unittest
+
+from ...test.utils import TestCaseQt
+from .. import FitConfig
+
+
+class TestFitConfig(TestCaseQt):
+ """Basic test for FitWidget"""
+
+ def setUp(self):
+ super(TestFitConfig, self).setUp()
+ self.fit_config = FitConfig.getFitConfigDialog(modal=False)
+ self.qWaitForWindowExposed(self.fit_config)
+
+ def tearDown(self):
+ del self.fit_config
+ super(TestFitConfig, self).tearDown()
+
+ def testShow(self):
+ self.fit_config.show()
+ self.fit_config.hide()
+
+ def testAccept(self):
+ self.fit_config.accept()
+ self.assertTrue(self.fit_config.result())
+
+ def testReject(self):
+ self.fit_config.reject()
+ self.assertFalse(self.fit_config.result())
+
+ def testDefaultOutput(self):
+ self.fit_config.accept()
+ output = self.fit_config.output
+
+ for key in ["AutoFwhm",
+ "PositiveHeightAreaFlag",
+ "QuotedPositionFlag",
+ "PositiveFwhmFlag",
+ "SameFwhmFlag",
+ "QuotedEtaFlag",
+ "NoConstraintsFlag",
+ "FwhmPoints",
+ "Sensitivity",
+ "Yscaling",
+ "ForcePeakPresence",
+ "StripBackgroundFlag",
+ "StripWidth",
+ "StripIterations",
+ "StripThreshold",
+ "SmoothingFlag"]:
+ self.assertIn(key, output)
+
+ self.assertTrue(output["AutoFwhm"])
+ self.assertEqual(output["StripWidth"], 2)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestFitConfig))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/fit/test/testFitWidget.py b/silx/gui/fit/test/testFitWidget.py
new file mode 100644
index 0000000..d542fd0
--- /dev/null
+++ b/silx/gui/fit/test/testFitWidget.py
@@ -0,0 +1,135 @@
+# 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.
+#
+# ###########################################################################*/
+"""Basic tests for :class:`FitWidget`"""
+
+import unittest
+
+from ...test.utils import TestCaseQt
+
+from ... import qt
+from .. import FitWidget
+
+from ....math.fit.fittheory import FitTheory
+from ....math.fit.fitmanager import FitManager
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+class TestFitWidget(TestCaseQt):
+ """Basic test for FitWidget"""
+
+ def setUp(self):
+ super(TestFitWidget, self).setUp()
+ self.fit_widget = FitWidget()
+ self.fit_widget.show()
+ self.qWaitForWindowExposed(self.fit_widget)
+
+ def tearDown(self):
+ self.fit_widget.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.fit_widget.close()
+ del self.fit_widget
+ super(TestFitWidget, self).tearDown()
+
+ def testShow(self):
+ pass
+
+ def testInteract(self):
+ self.mouseClick(self.fit_widget, qt.Qt.LeftButton)
+ self.keyClick(self.fit_widget, qt.Qt.Key_Enter)
+ self.qapp.processEvents()
+
+ def testCustomConfigWidget(self):
+ class CustomConfigWidget(qt.QDialog):
+ def __init__(self):
+ qt.QDialog.__init__(self)
+ self.setModal(True)
+ 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.ok)
+ layout.addWidget(cancel)
+ self.output = {"hello": "world"}
+
+ def fitfun(x, a, b):
+ return a * x + b
+
+ x = list(range(0, 100))
+ y = [fitfun(x_, 2, 3) for x_ in x]
+
+ def conf(**kw):
+ return {"spam": "eggs",
+ "hello": "world!"}
+
+ theory = FitTheory(
+ function=fitfun,
+ parameters=["a", "b"],
+ configure=conf)
+
+ fitmngr = FitManager()
+ fitmngr.setdata(x, y)
+ fitmngr.addtheory("foo", theory)
+ fitmngr.addtheory("bar", theory)
+ fitmngr.addbgtheory("spam", theory)
+
+ fw = FitWidget(fitmngr=fitmngr)
+ fw.associateConfigDialog("spam", CustomConfigWidget(),
+ theory_is_background=True)
+ fw.associateConfigDialog("foo", CustomConfigWidget())
+ fw.show()
+ self.qWaitForWindowExposed(fw)
+
+ fw.bgconfigdialogs["spam"].accept()
+ self.assertTrue(fw.bgconfigdialogs["spam"].result())
+
+ self.assertEqual(fw.bgconfigdialogs["spam"].output,
+ {"hello": "world"})
+
+ fw.bgconfigdialogs["spam"].reject()
+ self.assertFalse(fw.bgconfigdialogs["spam"].result())
+
+ fw.configdialogs["foo"].accept()
+ self.assertTrue(fw.configdialogs["foo"].result())
+
+ # todo: figure out how to click fw.configdialog.ok to close dialog
+ # open dialog
+ # self.mouseClick(fw.guiConfig.FunConfigureButton, qt.Qt.LeftButton)
+ # clove dialog
+ # self.mouseClick(fw.configdialogs["foo"].ok, qt.Qt.LeftButton)
+ # self.qapp.processEvents()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestFitWidget))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/hdf5/Hdf5HeaderView.py b/silx/gui/hdf5/Hdf5HeaderView.py
new file mode 100644
index 0000000..5912230
--- /dev/null
+++ b/silx/gui/hdf5/Hdf5HeaderView.py
@@ -0,0 +1,192 @@
+# 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "08/11/2016"
+
+
+from .. import qt
+
+QTVERSION = qt.qVersion()
+
+
+class Hdf5HeaderView(qt.QHeaderView):
+ """
+ Default HDF5 header
+
+ Manage auto-resize and context menu to display/hide columns
+ """
+
+ def __init__(self, orientation, parent=None):
+ """
+ Constructor
+
+ :param orientation qt.Qt.Orientation: Orientation of the header
+ :param parent qt.QWidget: Parent of the widget
+ """
+ super(Hdf5HeaderView, self).__init__(orientation, parent)
+ self.setContextMenuPolicy(qt.Qt.CustomContextMenu)
+ self.customContextMenuRequested.connect(self.__createContextMenu)
+
+ # default initialization done by QTreeView for it's own header
+ if QTVERSION < "5.0":
+ self.setClickable(True)
+ self.setMovable(True)
+ else:
+ self.setSectionsClickable(True)
+ self.setSectionsMovable(True)
+ self.setDefaultAlignment(qt.Qt.AlignLeft | qt.Qt.AlignVCenter)
+ self.setStretchLastSection(True)
+
+ self.__auto_resize = True
+ self.__hide_columns_popup = True
+
+ def setModel(self, model):
+ """Override model to configure view when a model is expected
+
+ `qt.QHeaderView.setResizeMode` expect already existing columns
+ to work.
+
+ :param model qt.QAbstractItemModel: A model
+ """
+ super(Hdf5HeaderView, self).setModel(model)
+ self.__updateAutoResize()
+
+ def __updateAutoResize(self):
+ """Update the view according to the state of the auto-resize"""
+ if QTVERSION < "5.0":
+ setResizeMode = self.setResizeMode
+ else:
+ setResizeMode = self.setSectionResizeMode
+
+ if self.__auto_resize:
+ setResizeMode(0, qt.QHeaderView.ResizeToContents)
+ setResizeMode(1, qt.QHeaderView.ResizeToContents)
+ setResizeMode(2, qt.QHeaderView.ResizeToContents)
+ setResizeMode(3, qt.QHeaderView.Interactive)
+ setResizeMode(4, qt.QHeaderView.Interactive)
+ setResizeMode(5, qt.QHeaderView.ResizeToContents)
+ else:
+ setResizeMode(0, qt.QHeaderView.Interactive)
+ setResizeMode(1, qt.QHeaderView.Interactive)
+ setResizeMode(2, qt.QHeaderView.Interactive)
+ setResizeMode(3, qt.QHeaderView.Interactive)
+ setResizeMode(4, qt.QHeaderView.Interactive)
+ setResizeMode(5, qt.QHeaderView.Interactive)
+
+ def setAutoResizeColumns(self, autoResize):
+ """Enable/disable auto-resize. When auto-resized, the header take care
+ of the content of the column to set fixed size of some of them, or to
+ auto fix the size according to the content.
+
+ :param autoResize bool: Enable/disable auto-resize
+ """
+ if self.__auto_resize == autoResize:
+ return
+ self.__auto_resize = autoResize
+ self.__updateAutoResize()
+
+ def hasAutoResizeColumns(self):
+ """Is auto-resize enabled.
+
+ :rtype: bool
+ """
+ return self.__auto_resize
+
+ autoResizeColumns = qt.Property(bool, hasAutoResizeColumns, setAutoResizeColumns)
+ """Property to enable/disable auto-resize."""
+
+ def setEnableHideColumnsPopup(self, enablePopup):
+ """Enable/disable a popup to allow to hide/show each column of the
+ model.
+
+ :param bool enablePopup: Enable/disable popup to hide/show columns
+ """
+ self.__hide_columns_popup = enablePopup
+
+ def hasHideColumnsPopup(self):
+ """Is popup to hide/show columns is enabled.
+
+ :rtype: bool
+ """
+ return self.__hide_columns_popup
+
+ enableHideColumnsPopup = qt.Property(bool, hasHideColumnsPopup, setAutoResizeColumns)
+ """Property to enable/disable popup allowing to hide/show columns."""
+
+ def __genHideSectionEvent(self, column):
+ """Generate a callback which change the column visibility according to
+ the event parameter
+
+ :param int column: logical id of the column
+ :rtype: callable
+ """
+ return lambda checked: self.setSectionHidden(column, not checked)
+
+ def __createContextMenu(self, pos):
+ """Callback to create and display a context menu
+
+ :param pos qt.QPoint: Requested position for the context menu
+ """
+ if not self.__hide_columns_popup:
+ return
+
+ model = self.model()
+ if model.columnCount() > 1:
+ menu = qt.QMenu(self)
+ menu.setTitle("Display/hide columns")
+
+ action = qt.QAction("Display/hide column", self)
+ action.setEnabled(False)
+ menu.addAction(action)
+
+ for column in range(model.columnCount()):
+ if column == 0:
+ # skip the main column
+ continue
+ text = model.headerData(column, qt.Qt.Horizontal, qt.Qt.DisplayRole)
+ action = qt.QAction("%s displayed" % text, self)
+ action.setCheckable(True)
+ action.setChecked(not self.isSectionHidden(column))
+ action.toggled.connect(self.__genHideSectionEvent(column))
+ menu.addAction(action)
+
+ menu.popup(self.viewport().mapToGlobal(pos))
+
+ def setSections(self, logicalIndexes):
+ """
+ Defines order of visible sections by logical indexes.
+
+ Use `Hdf5TreeModel.NAME_COLUMN` to set the list.
+
+ :param list logicalIndexes: List of logical indexes to display
+ """
+ for pos, column_id in enumerate(logicalIndexes):
+ current_pos = self.visualIndex(column_id)
+ self.moveSection(current_pos, pos)
+ self.setSectionHidden(column_id, False)
+ for column_id in set(range(self.model().columnCount())) - set(logicalIndexes):
+ self.setSectionHidden(column_id, True)
diff --git a/silx/gui/hdf5/Hdf5Item.py b/silx/gui/hdf5/Hdf5Item.py
new file mode 100644
index 0000000..40793a4
--- /dev/null
+++ b/silx/gui/hdf5/Hdf5Item.py
@@ -0,0 +1,421 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "20/01/2017"
+
+
+import numpy
+import logging
+import collections
+from .. import qt
+from .. import icons
+from . import _utils
+from .Hdf5Node import Hdf5Node
+import silx.io.utils
+from silx.gui.data.TextFormatter import TextFormatter
+
+_logger = logging.getLogger(__name__)
+
+try:
+ import h5py
+except ImportError as e:
+ _logger.error("Module %s requires h5py", __name__)
+ raise e
+
+_formatter = TextFormatter()
+
+
+class Hdf5Item(Hdf5Node):
+ """Subclass of :class:`qt.QStandardItem` to represent an HDF5-like
+ item (dataset, file, group or link) as an element of a HDF5-like
+ tree structure.
+ """
+
+ def __init__(self, text, obj, parent, key=None, h5pyClass=None, isBroken=False, populateAll=False):
+ """
+ :param str text: text displayed
+ :param object obj: Pointer to h5py data. See the `obj` attribute.
+ """
+ self.__obj = obj
+ self.__key = key
+ self.__h5pyClass = h5pyClass
+ self.__isBroken = isBroken
+ self.__error = None
+ self.__text = text
+ Hdf5Node.__init__(self, parent, populateAll=populateAll)
+
+ @property
+ def obj(self):
+ if self.__key:
+ self.__initH5pyObject()
+ return self.__obj
+
+ @property
+ def basename(self):
+ return self.__text
+
+ @property
+ def h5pyClass(self):
+ """Returns the class of the stored object.
+
+ When the object is in lazy loading, this method should be able to
+ return the type of the futrue loaded object. It allows to delay the
+ real load of the object.
+
+ :rtype: h5py.File or h5py.Dataset or h5py.Group
+ """
+ if self.__h5pyClass is None:
+ self.__h5pyClass = silx.io.utils.get_h5py_class(self.obj)
+ return self.__h5pyClass
+
+ def isGroupObj(self):
+ """Returns true if the stored HDF5 object is a group (contains sub
+ groups or datasets).
+
+ :rtype: bool
+ """
+ return issubclass(self.h5pyClass, h5py.Group)
+
+ def isBrokenObj(self):
+ """Returns true if the stored HDF5 object is broken.
+
+ The stored object is then an h5py link (external or not) which point
+ to nowhere (tbhe external file is not here, the expected dataset is
+ still not on the file...)
+
+ :rtype: bool
+ """
+ return self.__isBroken
+
+ def _expectedChildCount(self):
+ if self.isGroupObj():
+ return len(self.obj)
+ return 0
+
+ def __initH5pyObject(self):
+ """Lazy load of the HDF5 node. It is reached from the parent node
+ with the key of the node."""
+ parent_obj = self.parent.obj
+
+ try:
+ obj = parent_obj.get(self.__key)
+ except Exception as e:
+ _logger.debug("Internal h5py error", exc_info=True)
+ try:
+ self.__obj = parent_obj.get(self.__key, getlink=True)
+ except Exception:
+ self.__obj = None
+ self.__error = e.args[0]
+ self.__isBroken = True
+ else:
+ if obj is None:
+ # that's a broken link
+ self.__obj = parent_obj.get(self.__key, getlink=True)
+
+ # TODO monkey-patch file (ask that in h5py for consistency)
+ if not hasattr(self.__obj, "name"):
+ parent_name = parent_obj.name
+ if parent_name == "/":
+ self.__obj.name = "/" + self.__key
+ else:
+ self.__obj.name = parent_name + "/" + self.__key
+ # TODO monkey-patch file (ask that in h5py for consistency)
+ if not hasattr(self.__obj, "file"):
+ self.__obj.file = parent_obj.file
+
+ if isinstance(self.__obj, h5py.ExternalLink):
+ message = "External link broken. Path %s::%s does not exist" % (self.__obj.filename, self.__obj.path)
+ elif isinstance(self.__obj, h5py.SoftLink):
+ message = "Soft link broken. Path %s does not exist" % (self.__obj.path)
+ else:
+ name = self.obj.__class__.__name__.split(".")[-1].capitalize()
+ message = "%s broken" % (name)
+ self.__error = message
+ self.__isBroken = True
+ else:
+ self.__obj = obj
+
+ self.__key = None
+
+ def _populateChild(self, populateAll=False):
+ if self.isGroupObj():
+ for name in self.obj:
+ try:
+ class_ = self.obj.get(name, getclass=True)
+ has_error = False
+ except Exception as e:
+ _logger.error("Internal h5py error", exc_info=True)
+ try:
+ class_ = self.obj.get(name, getclass=True, getlink=True)
+ except Exception as e:
+ class_ = h5py.HardLink
+ has_error = True
+ item = Hdf5Item(text=name, obj=None, parent=self, key=name, h5pyClass=class_, isBroken=has_error)
+ self.appendChild(item)
+
+ def hasChildren(self):
+ """Retuens true of this node have chrild.
+
+ :rtype: bool
+ """
+ if not self.isGroupObj():
+ return False
+ return Hdf5Node.hasChildren(self)
+
+ def _getDefaultIcon(self):
+ """Returns the icon displayed by the main column.
+
+ :rtype: qt.QIcon
+ """
+ style = qt.QApplication.style()
+ if self.__isBroken:
+ icon = style.standardIcon(qt.QStyle.SP_MessageBoxCritical)
+ return icon
+ class_ = self.h5pyClass
+ if issubclass(class_, h5py.File):
+ return style.standardIcon(qt.QStyle.SP_FileIcon)
+ elif issubclass(class_, h5py.Group):
+ return style.standardIcon(qt.QStyle.SP_DirIcon)
+ elif issubclass(class_, h5py.SoftLink):
+ return style.standardIcon(qt.QStyle.SP_DirLinkIcon)
+ elif issubclass(class_, h5py.ExternalLink):
+ return style.standardIcon(qt.QStyle.SP_FileLinkIcon)
+ elif issubclass(class_, h5py.Dataset):
+ if len(self.obj.shape) < 4:
+ name = "item-%ddim" % len(self.obj.shape)
+ else:
+ name = "item-ndim"
+ if str(self.obj.dtype) == "object":
+ name = "item-object"
+ icon = icons.getQIcon(name)
+ return icon
+ return None
+
+ def _humanReadableShape(self, dataset):
+ if dataset.shape == tuple():
+ return "scalar"
+ shape = [str(i) for i in dataset.shape]
+ text = u" \u00D7 ".join(shape)
+ return text
+
+ def _humanReadableValue(self, dataset):
+ if dataset.shape == tuple():
+ numpy_object = dataset[()]
+ text = _formatter.toString(numpy_object)
+ else:
+ if dataset.size < 5 and dataset.compression is None:
+ numpy_object = dataset[0:5]
+ text = _formatter.toString(numpy_object)
+ else:
+ dimension = len(dataset.shape)
+ if dataset.compression is not None:
+ text = "Compressed %dD data" % dimension
+ else:
+ text = "%dD data" % dimension
+ return text
+
+ def _humanReadableDType(self, dtype, full=False):
+ if dtype.type == numpy.string_:
+ text = "string"
+ elif dtype.type == numpy.unicode_:
+ text = "string"
+ elif dtype.type == numpy.object_:
+ text = "object"
+ elif dtype.type == numpy.bool_:
+ text = "bool"
+ elif dtype.type == numpy.void:
+ if dtype.fields is None:
+ text = "raw"
+ else:
+ if not full:
+ text = "compound"
+ else:
+ compound = [d[0] for d in dtype.fields.values()]
+ compound = [self._humanReadableDType(d) for d in compound]
+ text = "compound(%s)" % ", ".join(compound)
+ else:
+ text = str(dtype)
+ return text
+
+ def _humanReadableType(self, dataset, full=False):
+ return self._humanReadableDType(dataset.dtype, full)
+
+ def _setTooltipAttributes(self, attributeDict):
+ """
+ Add key/value attributes that will be displayed in the item tooltip
+
+ :param Dict[str,str] attributeDict: Key/value attributes
+ """
+ if issubclass(self.h5pyClass, h5py.Dataset):
+ attributeDict["Title"] = "HDF5 Dataset"
+ attributeDict["Name"] = self.basename
+ attributeDict["Path"] = self.obj.name
+ attributeDict["Shape"] = self._humanReadableShape(self.obj)
+ attributeDict["Value"] = self._humanReadableValue(self.obj)
+ attributeDict["Data type"] = self._humanReadableType(self.obj, full=True)
+ elif issubclass(self.h5pyClass, h5py.Group):
+ attributeDict["Title"] = "HDF5 Group"
+ attributeDict["Name"] = self.basename
+ attributeDict["Path"] = self.obj.name
+ elif issubclass(self.h5pyClass, h5py.File):
+ attributeDict["Title"] = "HDF5 File"
+ attributeDict["Name"] = self.basename
+ attributeDict["Path"] = "/"
+ elif isinstance(self.obj, h5py.ExternalLink):
+ attributeDict["Title"] = "HDF5 External Link"
+ attributeDict["Name"] = self.basename
+ attributeDict["Path"] = self.obj.name
+ attributeDict["Linked path"] = self.obj.path
+ attributeDict["Linked file"] = self.obj.filename
+ elif isinstance(self.obj, h5py.SoftLink):
+ attributeDict["Title"] = "HDF5 Soft Link"
+ attributeDict["Name"] = self.basename
+ attributeDict["Path"] = self.obj.name
+ attributeDict["Linked path"] = self.obj.path
+ else:
+ pass
+
+ def _getDefaultTooltip(self):
+ """Returns the default tooltip
+
+ :rtype: str
+ """
+ if self.__error is not None:
+ self.obj # lazy loading of the object
+ return self.__error
+
+ attrs = collections.OrderedDict()
+ self._setTooltipAttributes(attrs)
+
+ title = attrs.pop("Title", None)
+ if len(attrs) > 0:
+ tooltip = _utils.htmlFromDict(attrs, title=title)
+ else:
+ tooltip = ""
+
+ return tooltip
+
+ def dataName(self, role):
+ """Data for the name column"""
+ if role == qt.Qt.TextAlignmentRole:
+ return qt.Qt.AlignTop | qt.Qt.AlignLeft
+ if role == qt.Qt.DisplayRole:
+ return self.__text
+ if role == qt.Qt.DecorationRole:
+ return self._getDefaultIcon()
+ if role == qt.Qt.ToolTipRole:
+ return self._getDefaultTooltip()
+ return None
+
+ def dataType(self, role):
+ """Data for the type column"""
+ if role == qt.Qt.DecorationRole:
+ return None
+ if role == qt.Qt.TextAlignmentRole:
+ return qt.Qt.AlignTop | qt.Qt.AlignLeft
+ if role == qt.Qt.DisplayRole:
+ if self.__error is not None:
+ return ""
+ class_ = self.h5pyClass
+ if issubclass(class_, h5py.Dataset):
+ text = self._humanReadableType(self.obj)
+ else:
+ text = ""
+ return text
+
+ return None
+
+ def dataShape(self, role):
+ """Data for the shape column"""
+ if role == qt.Qt.DecorationRole:
+ return None
+ if role == qt.Qt.TextAlignmentRole:
+ return qt.Qt.AlignTop | qt.Qt.AlignLeft
+ if role == qt.Qt.DisplayRole:
+ if self.__error is not None:
+ return ""
+ class_ = self.h5pyClass
+ if not issubclass(class_, h5py.Dataset):
+ return ""
+ return self._humanReadableShape(self.obj)
+ return None
+
+ def dataValue(self, role):
+ """Data for the value column"""
+ if role == qt.Qt.DecorationRole:
+ return None
+ if role == qt.Qt.TextAlignmentRole:
+ return qt.Qt.AlignTop | qt.Qt.AlignLeft
+ if role == qt.Qt.DisplayRole:
+ if self.__error is not None:
+ return ""
+ if not issubclass(self.h5pyClass, h5py.Dataset):
+ return ""
+ return self._humanReadableValue(self.obj)
+ return None
+
+ def dataDescription(self, role):
+ """Data for the description column"""
+ if role == qt.Qt.DecorationRole:
+ return None
+ if role == qt.Qt.TextAlignmentRole:
+ return qt.Qt.AlignTop | qt.Qt.AlignLeft
+ if role == qt.Qt.DisplayRole:
+ if self.__isBroken:
+ self.obj # lazy loading of the object
+ return self.__error
+ if "desc" in self.obj.attrs:
+ text = self.obj.attrs["desc"]
+ else:
+ return ""
+ return text
+ if role == qt.Qt.ToolTipRole:
+ if self.__error is not None:
+ self.obj # lazy loading of the object
+ self.__initH5pyObject()
+ return self.__error
+ if "desc" in self.obj.attrs:
+ text = self.obj.attrs["desc"]
+ else:
+ return ""
+ return "Description: %s" % text
+ return None
+
+ def dataNode(self, role):
+ """Data for the node column"""
+ if role == qt.Qt.DecorationRole:
+ return None
+ if role == qt.Qt.TextAlignmentRole:
+ return qt.Qt.AlignTop | qt.Qt.AlignLeft
+ if role == qt.Qt.DisplayRole:
+ class_ = self.h5pyClass
+ text = class_.__name__.split(".")[-1]
+ return text
+ if role == qt.Qt.ToolTipRole:
+ class_ = self.h5pyClass
+ return "Class name: %s" % self.__class__
+ return None
diff --git a/silx/gui/hdf5/Hdf5LoadingItem.py b/silx/gui/hdf5/Hdf5LoadingItem.py
new file mode 100644
index 0000000..4467366
--- /dev/null
+++ b/silx/gui/hdf5/Hdf5LoadingItem.py
@@ -0,0 +1,68 @@
+# 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "23/09/2016"
+
+
+from .. import qt
+from .Hdf5Node import Hdf5Node
+
+
+class Hdf5LoadingItem(Hdf5Node):
+ """Item displayed when an Hdf5Node is loading.
+
+ At the end of the loading this item is replaced by the loaded one.
+ """
+
+ def __init__(self, text, parent, animatedIcon):
+ """Constructor"""
+ Hdf5Node.__init__(self, parent)
+ self.__text = text
+ self.__animatedIcon = animatedIcon
+ self.__animatedIcon.register(self)
+
+ @property
+ def obj(self):
+ return None
+
+ def dataName(self, role):
+ if role == qt.Qt.DecorationRole:
+ return self.__animatedIcon.currentIcon()
+ if role == qt.Qt.TextAlignmentRole:
+ return qt.Qt.AlignTop | qt.Qt.AlignLeft
+ if role == qt.Qt.DisplayRole:
+ return self.__text
+ return None
+
+ def dataDescription(self, role):
+ if role == qt.Qt.DecorationRole:
+ return None
+ if role == qt.Qt.TextAlignmentRole:
+ return qt.Qt.AlignTop | qt.Qt.AlignLeft
+ if role == qt.Qt.DisplayRole:
+ return "Loading..."
+ return None
diff --git a/silx/gui/hdf5/Hdf5Node.py b/silx/gui/hdf5/Hdf5Node.py
new file mode 100644
index 0000000..31bb097
--- /dev/null
+++ b/silx/gui/hdf5/Hdf5Node.py
@@ -0,0 +1,210 @@
+# 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "23/09/2016"
+
+
+class Hdf5Node(object):
+ """Abstract tree node
+
+ It provides link to the childs and to the parents, and a link to an
+ external object.
+ """
+ def __init__(self, parent=None, populateAll=False):
+ """
+ Constructor
+
+ :param Hdf5Node parent: Parent of the node, if exists, else None
+ :param bool populateAll: If true, populate all the tree node. Else
+ everything is lazy loaded.
+ """
+ self.__child = None
+ self.__parent = parent
+ if populateAll:
+ self.__child = []
+ self._populateChild(populateAll=True)
+
+ @property
+ def parent(self):
+ """Parent of the node, or None if the node is a root
+
+ :rtype: Hdf5Node
+ """
+ return self.__parent
+
+ def setParent(self, parent):
+ """Redefine the parent of the node.
+
+ It does not set the node as the children of the new parent.
+
+ :param Hdf5Node parent: The new parent
+ """
+ self.__parent = parent
+
+ def appendChild(self, child):
+ """Append a child to the node.
+
+ It does not update the parent of the child.
+
+ :param Hdf5Node child: Child to append to the node.
+ """
+ self.__initChild()
+ self.__child.append(child)
+
+ def removeChildAtIndex(self, index):
+ """Remove a child at an index of the children list.
+
+ The child is removed and returned.
+
+ :param int index: Index in the child list.
+ :rtype: Hdf5Node
+ :raises: IndexError if list is empty or index is out of range.
+ """
+ self.__initChild()
+ return self.__child.pop(index)
+
+ def insertChild(self, index, child):
+ """
+ Insert a child at a specific index of the child list.
+
+ It does not update the parent of the child.
+
+ :param int index: Index in the child list.
+ :param Hdf5Node child: Child to insert in the child list.
+ """
+ self.__initChild()
+ self.__child.insert(index, child)
+
+ def indexOfChild(self, child):
+ """
+ Returns the index of the child in the child list of this node.
+
+ :param Hdf5Node child: Child to find
+ :raises: ValueError if the value is not present.
+ """
+ self.__initChild()
+ return self.__child.index(child)
+
+ def hasChildren(self):
+ """Returns true if the node contains children.
+
+ :rtype: bool
+ """
+ return self.childCount() > 0
+
+ def childCount(self):
+ """Returns the number of child in this node.
+
+ :rtype: int
+ """
+ if self.__child is not None:
+ return len(self.__child)
+ return self._expectedChildCount()
+
+ def child(self, index):
+ """Return the child at an expected index.
+
+ :param int index: Index of the child in the child list of the node
+ :rtype: Hdf5Node
+ """
+ self.__initChild()
+ return self.__child[index]
+
+ def __initChild(self):
+ """Init the child of the node in case the list was lazy loaded."""
+ if self.__child is None:
+ self.__child = []
+ self._populateChild()
+
+ def _expectedChildCount(self):
+ """Returns the expected count of children
+
+ :rtype: int
+ """
+ return 0
+
+ def _populateChild(self, populateAll=False):
+ """Recurse through an HDF5 structure to append groups an datasets
+ into the tree model.
+
+ Overwrite it to implement the initialisation of child of the node.
+ """
+ pass
+
+ def dataName(self, role):
+ """Data for the name column
+
+ Overwrite it to implement the content of the 'name' column.
+
+ :rtype: qt.QVariant
+ """
+ return None
+
+ def dataType(self, role):
+ """Data for the type column
+
+ Overwrite it to implement the content of the 'type' column.
+
+ :rtype: qt.QVariant
+ """
+ return None
+
+ def dataShape(self, role):
+ """Data for the shape column
+
+ Overwrite it to implement the content of the 'shape' column.
+
+ :rtype: qt.QVariant
+ """
+ return None
+
+ def dataValue(self, role):
+ """Data for the value column
+
+ Overwrite it to implement the content of the 'value' column.
+
+ :rtype: qt.QVariant
+ """
+ return None
+
+ def dataDescription(self, role):
+ """Data for the description column
+
+ Overwrite it to implement the content of the 'description' column.
+
+ :rtype: qt.QVariant
+ """
+ return None
+
+ def dataNode(self, role):
+ """Data for the node column
+
+ Overwrite it to implement the content of the 'node' column.
+
+ :rtype: qt.QVariant
+ """
+ return None
diff --git a/silx/gui/hdf5/Hdf5TreeModel.py b/silx/gui/hdf5/Hdf5TreeModel.py
new file mode 100644
index 0000000..fb5de06
--- /dev/null
+++ b/silx/gui/hdf5/Hdf5TreeModel.py
@@ -0,0 +1,581 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "19/12/2016"
+
+
+import os
+import logging
+from .. import qt
+from .. import icons
+from .Hdf5Node import Hdf5Node
+from .Hdf5Item import Hdf5Item
+from .Hdf5LoadingItem import Hdf5LoadingItem
+from . import _utils
+from ... import io as silx_io
+
+_logger = logging.getLogger(__name__)
+
+"""Helpers to take care of None objects as signal parameters.
+PySide crash if a signal with a None parameter is emitted between threads.
+"""
+if qt.BINDING == 'PySide':
+ class _NoneWraper(object):
+ pass
+ _NoneWraperInstance = _NoneWraper()
+
+ def _wrapNone(x):
+ """Wrap x if it is a None value, else returns x"""
+ if x is None:
+ return _NoneWraperInstance
+ else:
+ return x
+
+ def _unwrapNone(x):
+ """Unwrap x as a None if a None was stored by `wrapNone`, else returns
+ x"""
+ if x is _NoneWraperInstance:
+ return None
+ else:
+ return x
+else:
+ # Allow to fix None event params to avoid PySide crashes
+ def _wrapNone(x):
+ return x
+
+ def _unwrapNone(x):
+ return x
+
+
+class LoadingItemRunnable(qt.QRunnable):
+ """Runner to process item loading from a file"""
+
+ class __Signals(qt.QObject):
+ """Signal holder"""
+ itemReady = qt.Signal(object, object, object)
+ runnerFinished = qt.Signal(object)
+
+ def __init__(self, filename, item):
+ """Constructor
+
+ :param LoadingItemWorker worker: Object holding data and signals
+ """
+ super(LoadingItemRunnable, self).__init__()
+ self.filename = filename
+ self.oldItem = item
+ self.signals = self.__Signals()
+
+ def setFile(self, filename, item):
+ self.filenames.append((filename, item))
+
+ @property
+ def itemReady(self):
+ return self.signals.itemReady
+
+ @property
+ def runnerFinished(self):
+ return self.signals.runnerFinished
+
+ def __loadItemTree(self, oldItem, h5obj):
+ """Create an item tree used by the GUI from an h5py object.
+
+ :param Hdf5Node oldItem: The current item displayed the GUI
+ :param h5py.File h5obj: The h5py object to display in the GUI
+ :rtpye: Hdf5Node
+ """
+ if silx_io.is_file(h5obj):
+ text = os.path.basename(h5obj.filename)
+ else:
+ filename = os.path.basename(h5obj.file.filename)
+ path = h5obj.name
+ text = "%s::%s" % (filename, path)
+ item = Hdf5Item(text=text, obj=h5obj, parent=oldItem.parent, populateAll=True)
+ return item
+
+ @qt.Slot()
+ def run(self):
+ """Process the file loading. The worker is used as holder
+ of the data and the signal. The result is sent as a signal.
+ """
+ try:
+ h5file = silx_io.open(self.filename)
+ newItem = self.__loadItemTree(self.oldItem, h5file)
+ error = None
+ except IOError as e:
+ # Should be logged
+ error = e
+ newItem = None
+
+ # Take care of None value in case of PySide
+ newItem = _wrapNone(newItem)
+ error = _wrapNone(error)
+ self.itemReady.emit(self.oldItem, newItem, error)
+ self.runnerFinished.emit(self)
+
+ def autoDelete(self):
+ return True
+
+
+class Hdf5TreeModel(qt.QAbstractItemModel):
+ """Tree model storing a list of :class:`h5py.File` like objects.
+
+ The main column display the :class:`h5py.File` list and there hierarchy.
+ Other columns display information on node hierarchy.
+ """
+
+ H5PY_ITEM_ROLE = qt.Qt.UserRole
+ """Role to reach h5py item from an item index"""
+
+ H5PY_OBJECT_ROLE = qt.Qt.UserRole + 1
+ """Role to reach h5py object from an item index"""
+
+ USER_ROLE = qt.Qt.UserRole + 2
+ """Start of range of available user role for derivative models"""
+
+ NAME_COLUMN = 0
+ """Column id containing HDF5 node names"""
+
+ TYPE_COLUMN = 1
+ """Column id containing HDF5 dataset types"""
+
+ SHAPE_COLUMN = 2
+ """Column id containing HDF5 dataset shapes"""
+
+ VALUE_COLUMN = 3
+ """Column id containing HDF5 dataset values"""
+
+ DESCRIPTION_COLUMN = 4
+ """Column id containing HDF5 node description/title/message"""
+
+ NODE_COLUMN = 5
+ """Column id containing HDF5 node type"""
+
+ COLUMN_IDS = [
+ NAME_COLUMN,
+ TYPE_COLUMN,
+ SHAPE_COLUMN,
+ VALUE_COLUMN,
+ DESCRIPTION_COLUMN,
+ NODE_COLUMN,
+ ]
+ """List of logical columns available"""
+
+ def __init__(self, parent=None):
+ super(Hdf5TreeModel, self).__init__(parent)
+
+ self.treeView = parent
+ self.header_labels = [None] * 6
+ self.header_labels[self.NAME_COLUMN] = 'Name'
+ self.header_labels[self.TYPE_COLUMN] = 'Type'
+ self.header_labels[self.SHAPE_COLUMN] = 'Shape'
+ self.header_labels[self.VALUE_COLUMN] = 'Value'
+ self.header_labels[self.DESCRIPTION_COLUMN] = 'Description'
+ self.header_labels[self.NODE_COLUMN] = 'Node'
+
+ # Create items
+ self.__root = Hdf5Node()
+ self.__fileDropEnabled = True
+ self.__fileMoveEnabled = True
+
+ self.__animatedIcon = icons.getWaitIcon()
+ self.__animatedIcon.iconChanged.connect(self.__updateLoadingItems)
+ self.__runnerSet = set([])
+
+ # store used icons to avoid to avoid the cache to release it
+ self.__icons = []
+ self.__icons.append(icons.getQIcon("item-0dim"))
+ self.__icons.append(icons.getQIcon("item-1dim"))
+ self.__icons.append(icons.getQIcon("item-2dim"))
+ self.__icons.append(icons.getQIcon("item-3dim"))
+ self.__icons.append(icons.getQIcon("item-ndim"))
+ self.__icons.append(icons.getQIcon("item-object"))
+
+ def __updateLoadingItems(self, icon):
+ for i in range(self.__root.childCount()):
+ item = self.__root.child(i)
+ if isinstance(item, Hdf5LoadingItem):
+ index1 = self.index(i, 0, qt.QModelIndex())
+ index2 = self.index(i, self.columnCount() - 1, qt.QModelIndex())
+ self.dataChanged.emit(index1, index2)
+
+ def __itemReady(self, oldItem, newItem, error):
+ """Called at the end of a concurent file loading, when the loading
+ item is ready. AN error is defined if an exception occured when
+ loading the newItem .
+
+ :param Hdf5Node oldItem: current displayed item
+ :param Hdf5Node newItem: item loaded, or None if error is defined
+ :param Exception error: An exception, or None if newItem is defined
+ """
+ # Take care of None value in case of PySide
+ newItem = _unwrapNone(newItem)
+ error = _unwrapNone(error)
+ row = self.__root.indexOfChild(oldItem)
+ rootIndex = qt.QModelIndex()
+ self.beginRemoveRows(rootIndex, row, row)
+ self.__root.removeChildAtIndex(row)
+ self.endRemoveRows()
+ if newItem is not None:
+ self.beginInsertRows(rootIndex, row, row)
+ self.__root.insertChild(row, newItem)
+ self.endInsertRows()
+ # FIXME the error must be displayed
+
+ def isFileDropEnabled(self):
+ return self.__fileDropEnabled
+
+ def setFileDropEnabled(self, enabled):
+ self.__fileDropEnabled = enabled
+
+ fileDropEnabled = qt.Property(bool, isFileDropEnabled, setFileDropEnabled)
+ """Property to enable/disable file dropping in the model."""
+
+ def isFileMoveEnabled(self):
+ return self.__fileMoveEnabled
+
+ def setFileMoveEnabled(self, enabled):
+ self.__fileMoveEnabled = enabled
+
+ fileMoveEnabled = qt.Property(bool, isFileMoveEnabled, setFileMoveEnabled)
+ """Property to enable/disable drag-and-drop of files to
+ change the ordering in the model."""
+
+ def supportedDropActions(self):
+ if self.__fileMoveEnabled or self.__fileDropEnabled:
+ return qt.Qt.CopyAction | qt.Qt.MoveAction
+ else:
+ return 0
+
+ def mimeTypes(self):
+ if self.__fileMoveEnabled:
+ return [_utils.Hdf5NodeMimeData.MIME_TYPE]
+ else:
+ return []
+
+ def mimeData(self, indexes):
+ """
+ Returns an object that contains serialized items of data corresponding
+ to the list of indexes specified.
+
+ :param list(qt.QModelIndex) indexes: List of indexes
+ :rtype: qt.QMimeData
+ """
+ if not self.__fileMoveEnabled or len(indexes) == 0:
+ return None
+
+ indexes = [i for i in indexes if i.column() == 0]
+ if len(indexes) > 1:
+ raise NotImplementedError("Drag of multi rows is not implemented")
+ if len(indexes) == 0:
+ raise NotImplementedError("Drag of cell is not implemented")
+
+ node = self.nodeFromIndex(indexes[0])
+ mimeData = _utils.Hdf5NodeMimeData(node)
+ return mimeData
+
+ def flags(self, index):
+ defaultFlags = qt.QAbstractItemModel.flags(self, index)
+
+ if index.isValid():
+ node = self.nodeFromIndex(index)
+ if self.__fileMoveEnabled and node.parent is self.__root:
+ # that's a root
+ return qt.Qt.ItemIsDragEnabled | defaultFlags
+ return defaultFlags
+ elif self.__fileDropEnabled or self.__fileMoveEnabled:
+ return qt.Qt.ItemIsDropEnabled | defaultFlags
+ else:
+ return defaultFlags
+
+ def dropMimeData(self, mimedata, action, row, column, parentIndex):
+ if action == qt.Qt.IgnoreAction:
+ return True
+
+ if self.__fileMoveEnabled and mimedata.hasFormat(_utils.Hdf5NodeMimeData.MIME_TYPE):
+ dragNode = mimedata.node()
+ parentNode = self.nodeFromIndex(parentIndex)
+ if parentNode is not dragNode.parent:
+ return False
+
+ if row == -1:
+ # append to the parent
+ row = parentNode.childCount()
+ else:
+ # insert at row
+ pass
+
+ dragNodeParent = dragNode.parent
+ sourceRow = dragNodeParent.indexOfChild(dragNode)
+ self.moveRow(parentIndex, sourceRow, parentIndex, row)
+ return True
+
+ if self.__fileDropEnabled and mimedata.hasFormat("text/uri-list"):
+
+ parentNode = self.nodeFromIndex(parentIndex)
+ if parentNode is not self.__root:
+ while(parentNode is not self.__root):
+ node = parentNode
+ parentNode = node.parent
+ row = parentNode.indexOfChild(node)
+ else:
+ if row == -1:
+ row = self.__root.childCount()
+
+ messages = []
+ for url in mimedata.urls():
+ try:
+ self.insertFileAsync(url.toLocalFile(), row)
+ row += 1
+ except IOError as e:
+ messages.append(e.args[0])
+ if len(messages) > 0:
+ title = "Error occurred when loading files"
+ message = "<html>%s:<ul><li>%s</li><ul></html>" % (title, "</li><li>".join(messages))
+ qt.QMessageBox.critical(None, title, message)
+ return True
+
+ return False
+
+ def headerData(self, section, orientation, role=qt.Qt.DisplayRole):
+ if orientation == qt.Qt.Horizontal:
+ if role in [qt.Qt.DisplayRole, qt.Qt.EditRole]:
+ return self.header_labels[section]
+ return None
+
+ def insertNode(self, row, node):
+ if row == -1:
+ row = self.__root.childCount()
+ self.beginInsertRows(qt.QModelIndex(), row, row)
+ self.__root.insertChild(row, node)
+ self.endInsertRows()
+
+ def moveRow(self, sourceParentIndex, sourceRow, destinationParentIndex, destinationRow):
+ if sourceRow == destinationRow or sourceRow == destinationRow - 1:
+ # abort move, same place
+ return
+ return self.moveRows(sourceParentIndex, sourceRow, 1, destinationParentIndex, destinationRow)
+
+ def moveRows(self, sourceParentIndex, sourceRow, count, destinationParentIndex, destinationRow):
+ self.beginMoveRows(sourceParentIndex, sourceRow, sourceRow, destinationParentIndex, destinationRow)
+ sourceNode = self.nodeFromIndex(sourceParentIndex)
+ destinationNode = self.nodeFromIndex(destinationParentIndex)
+
+ if sourceNode is destinationNode and sourceRow < destinationRow:
+ item = sourceNode.child(sourceRow)
+ destinationNode.insertChild(destinationRow, item)
+ sourceNode.removeChildAtIndex(sourceRow)
+ else:
+ item = sourceNode.removeChildAtIndex(sourceRow)
+ destinationNode.insertChild(destinationRow, item)
+
+ self.endMoveRows()
+ return True
+
+ def index(self, row, column, parent=qt.QModelIndex()):
+ try:
+ node = self.nodeFromIndex(parent)
+ return self.createIndex(row, column, node.child(row))
+ except IndexError:
+ return qt.QModelIndex()
+
+ def data(self, index, role=qt.Qt.DisplayRole):
+ node = self.nodeFromIndex(index)
+
+ if role == self.H5PY_ITEM_ROLE:
+ return node
+
+ if role == self.H5PY_OBJECT_ROLE:
+ return node.obj
+
+ if index.column() == self.NAME_COLUMN:
+ return node.dataName(role)
+ elif index.column() == self.TYPE_COLUMN:
+ return node.dataType(role)
+ elif index.column() == self.SHAPE_COLUMN:
+ return node.dataShape(role)
+ elif index.column() == self.VALUE_COLUMN:
+ return node.dataValue(role)
+ elif index.column() == self.DESCRIPTION_COLUMN:
+ return node.dataDescription(role)
+ elif index.column() == self.NODE_COLUMN:
+ return node.dataNode(role)
+ else:
+ return None
+
+ def columnCount(self, parent=qt.QModelIndex()):
+ return len(self.header_labels)
+
+ def hasChildren(self, parent=qt.QModelIndex()):
+ node = self.nodeFromIndex(parent)
+ if node is None:
+ return 0
+ return node.hasChildren()
+
+ def rowCount(self, parent=qt.QModelIndex()):
+ node = self.nodeFromIndex(parent)
+ if node is None:
+ return 0
+ return node.childCount()
+
+ def parent(self, child):
+ if not child.isValid():
+ return qt.QModelIndex()
+
+ node = self.nodeFromIndex(child)
+
+ if node is None:
+ return qt.QModelIndex()
+
+ parent = node.parent
+
+ if parent is None:
+ return qt.QModelIndex()
+
+ grandparent = parent.parent
+ if grandparent is None:
+ return qt.QModelIndex()
+ row = grandparent.indexOfChild(parent)
+
+ assert row != - 1
+ return self.createIndex(row, 0, parent)
+
+ def nodeFromIndex(self, index):
+ return index.internalPointer() if index.isValid() else self.__root
+
+ def synchronizeIndex(self, index):
+ """
+ Synchronize a file a given its index.
+
+ Basically close it and load it again.
+
+ :param qt.QModelIndex index: Index of the item to update
+ """
+ node = self.nodeFromIndex(index)
+ if node.parent is not self.__root:
+ return
+
+ self.removeIndex(index)
+ filename = node.obj.filename
+ node.obj.close()
+ self.insertFileAsync(filename, index.row())
+
+ def synchronizeH5pyObject(self, h5pyObject):
+ """
+ Synchronize a h5py object in all the tree.
+
+ Basically close it and load it again.
+
+ :param h5py.File h5pyObject: A :class:`h5py.File` object.
+ """
+ index = 0
+ while index < self.__root.childCount():
+ item = self.__root.child(index)
+ if item.obj is h5pyObject:
+ qindex = self.index(index, 0, qt.QModelIndex())
+ self.synchronizeIndex(qindex)
+ else:
+ index += 1
+
+ def removeIndex(self, index):
+ """
+ Remove an item from the model using its index.
+
+ :param qt.QModelIndex index: Index of the item to remove
+ """
+ node = self.nodeFromIndex(index)
+ if node.parent is not self.__root:
+ return
+ self.beginRemoveRows(qt.QModelIndex(), index.row(), index.row())
+ self.__root.removeChildAtIndex(index.row())
+ self.endRemoveRows()
+
+ def removeH5pyObject(self, h5pyObject):
+ """
+ Remove an item from the model using the holding h5py object.
+ It can remove more than one item.
+
+ :param h5py.File h5pyObject: A :class:`h5py.File` object.
+ """
+ index = 0
+ while index < self.__root.childCount():
+ item = self.__root.child(index)
+ if item.obj is h5pyObject:
+ qindex = self.index(index, 0, qt.QModelIndex())
+ self.removeIndex(qindex)
+ else:
+ index += 1
+
+ def insertH5pyObject(self, h5pyObject, text=None, row=-1):
+ """Append an HDF5 object from h5py to the tree.
+
+ :param h5pyObject: File handle/descriptor for a :class:`h5py.File`
+ or any other class of h5py file structure.
+ """
+ if text is None:
+ if silx_io.is_file(h5pyObject):
+ text = os.path.basename(h5pyObject.filename)
+ else:
+ filename = os.path.basename(h5pyObject.file.filename)
+ path = h5pyObject.name
+ text = "%s::%s" % (filename, path)
+ if row == -1:
+ row = self.__root.childCount()
+ self.insertNode(row, Hdf5Item(text=text, obj=h5pyObject, parent=self.__root))
+
+ def insertFileAsync(self, filename, row=-1):
+ if not os.path.isfile(filename):
+ raise IOError("Filename '%s' must be a file path" % filename)
+
+ # create temporary item
+ text = os.path.basename(filename)
+ item = Hdf5LoadingItem(text=text, parent=self.__root, animatedIcon=self.__animatedIcon)
+ self.insertNode(row, item)
+
+ # start loading the real one
+ runnable = LoadingItemRunnable(filename, item)
+ runnable.itemReady.connect(self.__itemReady)
+ self.__runnerSet.add(runnable)
+ runnable.runnerFinished.connect(self.__releaseRunner)
+ qt.QThreadPool.globalInstance().start(runnable)
+
+ def __releaseRunner(self, runner):
+ self.__runnerSet.remove(runner)
+
+ def insertFile(self, filename, row=-1):
+ """Load a HDF5 file into the data model.
+
+ :param filename: file path.
+ """
+ try:
+ h5file = silx_io.open(filename)
+ self.insertH5pyObject(h5file, row=row)
+ except IOError:
+ _logger.debug("File '%s' can't be read.", filename, exc_info=True)
+ raise
+
+ def appendFile(self, filename):
+ self.insertFile(filename, -1)
diff --git a/silx/gui/hdf5/Hdf5TreeView.py b/silx/gui/hdf5/Hdf5TreeView.py
new file mode 100644
index 0000000..09f6fcf
--- /dev/null
+++ b/silx/gui/hdf5/Hdf5TreeView.py
@@ -0,0 +1,204 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "27/09/2016"
+
+
+import logging
+from .. import qt
+from ...utils import weakref as silxweakref
+from .Hdf5TreeModel import Hdf5TreeModel
+from .Hdf5HeaderView import Hdf5HeaderView
+from .NexusSortFilterProxyModel import NexusSortFilterProxyModel
+from .Hdf5Item import Hdf5Item
+from . import _utils
+
+_logger = logging.getLogger(__name__)
+
+
+class Hdf5TreeView(qt.QTreeView):
+ """TreeView which allow to browse HDF5 file structure.
+
+ It provides columns width auto-resizing and additional
+ signals.
+
+ The default model is a :class:`NexusSortFilterProxyModel` sourcing
+ a :class:`Hdf5TreeModel`. The :class:`Hdf5TreeModel` is reachable using
+ :meth:`findHdf5TreeModel`. The default header is :class:`Hdf5HeaderView`.
+
+ Context menu is managed by the :meth:`setContextMenuPolicy` with the value
+ Qt.CustomContextMenu. This policy must not be changed, otherwise context
+ menus will not work anymore. You can use :meth:`addContextMenuCallback` and
+ :meth:`removeContextMenuCallback` to add your custum actions according
+ to the selected objects.
+ """
+ def __init__(self, parent=None):
+ """
+ Constructor
+
+ :param parent qt.QWidget: The parent widget
+ """
+ qt.QTreeView.__init__(self, parent)
+
+ model = Hdf5TreeModel(self)
+ proxy_model = NexusSortFilterProxyModel(self)
+ proxy_model.setSourceModel(model)
+ self.setModel(proxy_model)
+
+ self.setHeader(Hdf5HeaderView(qt.Qt.Horizontal, self))
+ self.setSelectionBehavior(qt.QAbstractItemView.SelectRows)
+ self.sortByColumn(0, qt.Qt.AscendingOrder)
+ # optimise the rendering
+ self.setUniformRowHeights(True)
+
+ self.setIconSize(qt.QSize(16, 16))
+ self.setAcceptDrops(True)
+ self.setDragEnabled(True)
+ self.setDragDropMode(qt.QAbstractItemView.DragDrop)
+ self.showDropIndicator()
+
+ self.__context_menu_callbacks = silxweakref.WeakList()
+ self.setContextMenuPolicy(qt.Qt.CustomContextMenu)
+ self.customContextMenuRequested.connect(self._createContextMenu)
+
+ def __removeContextMenuProxies(self, ref):
+ """Callback to remove dead proxy from the list"""
+ self.__context_menu_callbacks.remove(ref)
+
+ def _createContextMenu(self, pos):
+ """
+ Create context menu.
+
+ :param pos qt.QPoint: Position of the context menu
+ """
+ actions = []
+
+ menu = qt.QMenu(self)
+
+ hovered_index = self.indexAt(pos)
+ hovered_node = self.model().data(hovered_index, Hdf5TreeModel.H5PY_ITEM_ROLE)
+ if hovered_node is None or not isinstance(hovered_node, Hdf5Item):
+ return
+
+ hovered_object = _utils.H5Node(hovered_node)
+ event = _utils.Hdf5ContextMenuEvent(self, menu, hovered_object)
+
+ for callback in self.__context_menu_callbacks:
+ try:
+ callback(event)
+ except KeyboardInterrupt:
+ raise
+ except:
+ # make sure no user callback crash the application
+ _logger.error("Error while calling callback", exc_info=True)
+ pass
+
+ if len(menu.children()) > 0:
+ for action in actions:
+ menu.addAction(action)
+ menu.popup(self.viewport().mapToGlobal(pos))
+
+ def addContextMenuCallback(self, callback):
+ """Register a context menu callback.
+
+ The callback will be called when a context menu is requested with the
+ treeview and the list of selected h5py objects in parameters. The
+ callback must return a list of :class:`qt.QAction` object.
+
+ Callbacks are stored as saferef. The object must store a reference by
+ itself.
+ """
+ self.__context_menu_callbacks.append(callback)
+
+ def removeContextMenuCallback(self, callback):
+ """Unregister a context menu callback"""
+ self.__context_menu_callbacks.remove(callback)
+
+ def findHdf5TreeModel(self):
+ """Find the Hdf5TreeModel from the stack of model filters.
+
+ :returns: A Hdf5TreeModel, else None
+ :rtype: Hdf5TreeModel
+ """
+ model = self.model()
+ while model is not None:
+ if isinstance(model, qt.QAbstractProxyModel):
+ model = model.sourceModel()
+ else:
+ break
+ if model is None:
+ return None
+ if isinstance(model, Hdf5TreeModel):
+ return model
+ else:
+ return None
+
+ def dragEnterEvent(self, event):
+ model = self.findHdf5TreeModel()
+ if model is not None and model.isFileDropEnabled() and event.mimeData().hasFormat("text/uri-list"):
+ self.setState(qt.QAbstractItemView.DraggingState)
+ event.accept()
+ else:
+ qt.QTreeView.dragEnterEvent(self, event)
+
+ def dragMoveEvent(self, event):
+ model = self.findHdf5TreeModel()
+ if model is not None and model.isFileDropEnabled() and event.mimeData().hasFormat("text/uri-list"):
+ event.setDropAction(qt.Qt.CopyAction)
+ event.accept()
+ else:
+ qt.QTreeView.dragMoveEvent(self, event)
+
+ def selectedH5Nodes(self, ignoreBrokenLinks=True):
+ """Returns selected h5py objects like :class:`h5py.File`,
+ :class:`h5py.Group`, :class:`h5py.Dataset` or mimicked objects.
+
+ :param ignoreBrokenLinks bool: Returns objects which are not not
+ broken links.
+ :rtype: iterator(:class:`_utils.H5Node`)
+ """
+ for index in self.selectedIndexes():
+ if index.column() != 0:
+ continue
+ item = self.model().data(index, Hdf5TreeModel.H5PY_ITEM_ROLE)
+ if item is None:
+ continue
+ if isinstance(item, Hdf5Item):
+ if ignoreBrokenLinks and item.isBrokenObj():
+ continue
+ yield _utils.H5Node(item)
+
+ def mousePressEvent(self, event):
+ """Override mousePressEvent to provide a consistante compatible API
+ between Qt4 and Qt5
+ """
+ super(Hdf5TreeView, self).mousePressEvent(event)
+ if event.button() != qt.Qt.LeftButton:
+ # Qt5 only sends itemClicked on left button mouse click
+ if qt.qVersion() > "5":
+ qindex = self.indexAt(event.pos())
+ self.clicked.emit(qindex)
diff --git a/silx/gui/hdf5/NexusSortFilterProxyModel.py b/silx/gui/hdf5/NexusSortFilterProxyModel.py
new file mode 100644
index 0000000..9a4268c
--- /dev/null
+++ b/silx/gui/hdf5/NexusSortFilterProxyModel.py
@@ -0,0 +1,152 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "12/04/2017"
+
+
+import logging
+import re
+import numpy
+from .. import qt
+from .Hdf5TreeModel import Hdf5TreeModel
+
+_logger = logging.getLogger(__name__)
+
+try:
+ import h5py
+except ImportError as e:
+ _logger.error("Module %s requires h5py", __name__)
+ raise e
+
+_logger = logging.getLogger(__name__)
+
+
+class NexusSortFilterProxyModel(qt.QSortFilterProxyModel):
+ """Try to sort items according to Nexus structure. Else sort by name."""
+
+ def __init__(self, parent=None):
+ qt.QSortFilterProxyModel.__init__(self, parent)
+ self.__split = re.compile("(\\d+|\\D+)")
+
+ def lessThan(self, sourceLeft, sourceRight):
+ """Returns True if the value of the item referred to by the given
+ index `sourceLeft` is less than the value of the item referred to by
+ the given index `sourceRight`, otherwise returns false.
+
+ :param qt.QModelIndex sourceLeft:
+ :param qt.QModelIndex sourceRight:
+ :rtype: bool
+ """
+ if sourceLeft.column() != Hdf5TreeModel.NAME_COLUMN:
+ return super(NexusSortFilterProxyModel, self).lessThan(
+ sourceLeft, sourceRight)
+
+ # Do not sort child of root (files)
+ if sourceLeft.parent() == qt.QModelIndex():
+ return sourceLeft.row() < sourceRight.row()
+
+ left = self.sourceModel().data(sourceLeft, Hdf5TreeModel.H5PY_ITEM_ROLE)
+ right = self.sourceModel().data(sourceRight, Hdf5TreeModel.H5PY_ITEM_ROLE)
+
+ if self.__isNXentry(left) and self.__isNXentry(right):
+ less = self.childDatasetLessThan(left, right, "start_time")
+ if less is not None:
+ return less
+ less = self.childDatasetLessThan(left, right, "end_time")
+ if less is not None:
+ return less
+
+ left = self.sourceModel().data(sourceLeft, qt.Qt.DisplayRole)
+ right = self.sourceModel().data(sourceRight, qt.Qt.DisplayRole)
+ return self.nameLessThan(left, right)
+
+ def __isNXentry(self, node):
+ """Returns true if the node is an NXentry"""
+ if not issubclass(node.h5pyClass, h5py.Group):
+ return False
+ nxClass = node.obj.attrs.get("NX_class", None)
+ return nxClass == "NXentry"
+
+ def getWordsAndNumbers(self, name):
+ """
+ Returns a list of words and integers composing the name.
+
+ An input `"aaa10bbb50.30"` will return
+ `["aaa", 10, "bbb", 50, ".", 30]`.
+
+ :param str name: A name
+ :rtype: list
+ """
+ words = self.__split.findall(name)
+ result = []
+ for i in words:
+ if i[0].isdigit():
+ i = int(i)
+ result.append(i)
+ return result
+
+ def nameLessThan(self, left, right):
+ """Returns True if the left string is less than the right string.
+
+ Number composing the names are compared as integers, as result "name2"
+ is smaller than "name10".
+
+ :param str left: A string
+ :param str right: A string
+ :rtype: bool
+ """
+ leftList = self.getWordsAndNumbers(left)
+ rightList = self.getWordsAndNumbers(right)
+ try:
+ return leftList < rightList
+ except TypeError:
+ # Back to string comparison if list are not type consistent
+ return left < right
+
+ def childDatasetLessThan(self, left, right, childName):
+ """
+ Reach the same children name of two items and compare their values.
+
+ Returns True if the left one is smaller than the right one.
+
+ :param Hdf5Item left: An item
+ :param Hdf5Item right: An item
+ :param str childName: Name of the children to search. Returns None if
+ the children is not found.
+ :rtype: bool
+ """
+ try:
+ left_time = left.obj[childName][()]
+ right_time = right.obj[childName][()]
+ if isinstance(left_time, numpy.ndarray):
+ return left_time[0] < right_time[0]
+ return left_time < right_time
+ except KeyboardInterrupt:
+ raise
+ except Exception as e:
+ _logger.debug("Exception occurred", exc_info=True)
+ return None
diff --git a/silx/gui/hdf5/__init__.py b/silx/gui/hdf5/__init__.py
new file mode 100644
index 0000000..1b5a602
--- /dev/null
+++ b/silx/gui/hdf5/__init__.py
@@ -0,0 +1,44 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This package provides a set of Qt widgets for displaying content relative to
+HDF5 format.
+
+.. note::
+
+ This package depends on *h5py*.
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "23/09/2016"
+
+
+from .Hdf5TreeView import Hdf5TreeView # noqa
+from ._utils import H5Node
+from ._utils import Hdf5ContextMenuEvent # noqa
+from .NexusSortFilterProxyModel import NexusSortFilterProxyModel # noqa
+from .Hdf5TreeModel import Hdf5TreeModel # noqa
+
+__all__ = ['Hdf5TreeView', 'H5Node', 'Hdf5ContextMenuEvent', 'NexusSortFilterProxyModel', 'Hdf5TreeModel']
diff --git a/silx/gui/hdf5/_utils.py b/silx/gui/hdf5/_utils.py
new file mode 100644
index 0000000..af9c79f
--- /dev/null
+++ b/silx/gui/hdf5/_utils.py
@@ -0,0 +1,247 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This package provides a set of helper class and function used by the
+package `silx.gui.hdf5` package.
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+
+import logging
+import numpy
+from .. import qt
+import silx.io.utils
+from silx.utils.html import escape
+
+_logger = logging.getLogger(__name__)
+
+try:
+ import h5py
+except ImportError as e:
+ _logger.error("Module %s requires h5py", __name__)
+ raise e
+
+
+class Hdf5ContextMenuEvent(object):
+ """Hold information provided to context menu callbacks."""
+
+ def __init__(self, source, menu, hoveredObject):
+ """
+ Constructor
+
+ :param QWidget source: Widget source
+ :param QMenu menu: Context menu which will be displayed
+ :param H5Node hoveredObject: Hovered H5 node
+ """
+ self.__source = source
+ self.__menu = menu
+ self.__hoveredObject = hoveredObject
+
+ def source(self):
+ """Source of the event
+
+ :rtype: Hdf5TreeView
+ """
+ return self.__source
+
+ def menu(self):
+ """Menu which will be displayed
+
+ :rtype: qt.QMenu
+ """
+ return self.__menu
+
+ def hoveredObject(self):
+ """Item content hovered by the mouse when the context menu was
+ requested
+
+ :rtype: H5Node
+ """
+ return self.__hoveredObject
+
+
+def htmlFromDict(dictionary, title=None):
+ """Generate a readable HTML from a dictionary
+
+ :param dict dictionary: A Dictionary
+ :rtype: str
+ """
+ result = """<html>
+ <head>
+ <style type="text/css">
+ ul { -qt-list-indent: 0; list-style: none; }
+ li > b {display: inline-block; min-width: 4em; font-weight: bold; }
+ </style>
+ </head>
+ <body>
+ """
+ if title is not None:
+ result += "<b>%s</b>" % escape(title)
+ result += "<ul>"
+ for key, value in dictionary.items():
+ result += "<li><b>%s</b>: %s</li>" % (escape(key), escape(value))
+ result += "</ul>"
+ result += "</body></html>"
+ return result
+
+
+class Hdf5NodeMimeData(qt.QMimeData):
+ """Mimedata class to identify an internal drag and drop of a Hdf5Node."""
+
+ MIME_TYPE = "application/x-internal-h5py-node"
+
+ def __init__(self, node=None):
+ qt.QMimeData.__init__(self)
+ self.__node = node
+ self.setData(self.MIME_TYPE, "".encode(encoding='utf-8'))
+
+ def node(self):
+ return self.__node
+
+
+class H5Node(object):
+ """Adapter over an h5py object to provide missing informations from h5py
+ nodes, like internal node path and filename (which are not provided by
+ :mod:`h5py` for soft and external links).
+
+ It also provides an abstraction to reach node type for mimicked h5py
+ objects.
+ """
+
+ def __init__(self, h5py_item=None):
+ """Constructor
+
+ :param Hdf5Item h5py_item: An Hdf5Item
+ """
+ self.__h5py_object = h5py_item.obj
+ self.__h5py_item = h5py_item
+
+ def __getattr__(self, name):
+ return object.__getattribute__(self.__h5py_object, name)
+
+ @property
+ def h5py_object(self):
+ """Returns the internal h5py node.
+
+ :rtype: h5py.File or h5py.Group or h5py.Dataset
+ """
+ return self.__h5py_object
+
+ @property
+ def ntype(self):
+ """Returns the node type, as an h5py class.
+
+ :rtype:
+ :class:`h5py.File`, :class:`h5py.Group` or :class:`h5py.Dataset`
+ """
+ return silx.io.utils.get_h5py_class(self.__h5py_object)
+
+ @property
+ def basename(self):
+ """Returns the basename of this h5py node. It is the last identifier of
+ the path.
+
+ :rtype: str
+ """
+ return self.__h5py_object.name.split("/")[-1]
+
+ @property
+ def local_name(self):
+ """Returns the local path of this h5py node.
+
+ For links, this path is not equal to the h5py one.
+
+ :rtype: str
+ """
+ if self.__h5py_item is None:
+ raise RuntimeError("h5py_item is not defined")
+
+ result = []
+ item = self.__h5py_item
+ while item is not None:
+ if issubclass(item.h5pyClass, h5py.File):
+ break
+ result.append(item.basename)
+ item = item.parent
+ if item is None:
+ raise RuntimeError("The item does not have parent holding h5py.File")
+ if result == []:
+ return "/"
+ result.append("")
+ result.reverse()
+ return "/".join(result)
+
+ def __file_item(self):
+ """Returns the parent item holding the :class:`h5py.File` object
+
+ :rtype: h5py.File
+ :raises RuntimeException: If no file are found
+ """
+ item = self.__h5py_item
+ while item is not None:
+ if issubclass(item.h5pyClass, h5py.File):
+ return item
+ item = item.parent
+ raise RuntimeError("The item does not have parent holding h5py.File")
+
+ @property
+ def local_file(self):
+ """Returns the local :class:`h5py.File` object.
+
+ For path containing external links, this file is not equal to the h5py
+ one.
+
+ :rtype: h5py.File
+ :raises RuntimeException: If no file are found
+ """
+ item = self.__file_item()
+ return item.obj
+
+ @property
+ def local_filename(self):
+ """Returns the local filename of the h5py node.
+
+ For path containing external links, this path is not equal to the
+ filename provided by h5py.
+
+ :rtype: str
+ :raises RuntimeException: If no file are found
+ """
+ return self.local_file.filename
+
+ @property
+ def local_basename(self):
+ """Returns the local filename of the h5py node.
+
+ For path containing links, this basename can be different than the
+ basename provided by h5py.
+
+ :rtype: str
+ """
+ if issubclass(self.__h5py_item.h5pyClass, h5py.File):
+ return ""
+ return self.__h5py_item.basename
diff --git a/silx/gui/hdf5/setup.py b/silx/gui/hdf5/setup.py
new file mode 100644
index 0000000..786a851
--- /dev/null
+++ b/silx/gui/hdf5/setup.py
@@ -0,0 +1,41 @@
+# 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.
+#
+# ###########################################################################*/
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "28/09/2016"
+
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('hdf5', parent_package, top_path)
+ config.add_subpackage('test')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
diff --git a/silx/gui/hdf5/test/__init__.py b/silx/gui/hdf5/test/__init__.py
new file mode 100644
index 0000000..3000d96
--- /dev/null
+++ b/silx/gui/hdf5/test/__init__.py
@@ -0,0 +1,39 @@
+# 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.
+#
+# ###########################################################################*/
+import unittest
+
+from . import test_hdf5
+
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "28/09/2016"
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTests(
+ [test_hdf5.suite()])
+ return test_suite
diff --git a/silx/gui/hdf5/test/_mock.py b/silx/gui/hdf5/test/_mock.py
new file mode 100644
index 0000000..eada590
--- /dev/null
+++ b/silx/gui/hdf5/test/_mock.py
@@ -0,0 +1,130 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Mock for silx.gui.hdf5 module"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "12/04/2017"
+
+
+import numpy
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+
+class Node(object):
+
+ def __init__(self, basename, parent, h5py_class):
+ self.basename = basename
+ self.h5py_class = h5py_class
+ self.attrs = {}
+ self.parent = parent
+ if parent is not None:
+ self.parent._add(self)
+
+ @property
+ def name(self):
+ if self.parent is None:
+ return self.basename
+ if self.parent.name == "":
+ return self.basename
+ return self.parent.name + "/" + self.basename
+
+ @property
+ def file(self):
+ if self.parent is None:
+ return self
+ return self.parent.file
+
+
+class Group(Node):
+ """Mock an h5py Group"""
+
+ def __init__(self, name, parent, h5py_class=h5py.Group):
+ super(Group, self).__init__(name, parent, h5py_class)
+ self.__items = {}
+
+ def _add(self, node):
+ self.__items[node.basename] = node
+
+ def __getitem__(self, key):
+ return self.__items[key]
+
+ def __iter__(self):
+ for k in self.__items:
+ yield k
+
+ def __len__(self):
+ return len(self.__items)
+
+ def get(self, name, getclass=False, getlink=False):
+ result = self.__items[name]
+ if getclass:
+ return result.h5py_class
+ return result
+
+ def create_dataset(self, name, data):
+ return Dataset(name, self, data)
+
+ def create_group(self, name):
+ return Group(name, self)
+
+ def create_NXentry(self, name):
+ group = Group(name, self)
+ group.attrs["NX_class"] = "NXentry"
+ return group
+
+
+class File(Group):
+ """Mock an h5py File"""
+
+ def __init__(self, filename):
+ super(File, self).__init__("", None, h5py.File)
+ self.filename = filename
+
+
+class Dataset(Node):
+ """Mock an h5py Dataset"""
+
+ def __init__(self, name, parent, value):
+ super(Dataset, self).__init__(name, parent, h5py.Dataset)
+ self.__value = value
+ self.shape = self.__value.shape
+ self.dtype = self.__value.dtype
+ self.size = self.__value.size
+ self.compression = None
+ self.compression_opts = None
+
+ def __getitem__(self, key):
+ if not isinstance(self.__value, numpy.ndarray):
+ if key == tuple():
+ return self.__value
+ elif key == Ellipsis:
+ return numpy.array(self.__value)
+ else:
+ raise ValueError("Bad key")
+ return self.__value[key]
diff --git a/silx/gui/hdf5/test/test_hdf5.py b/silx/gui/hdf5/test/test_hdf5.py
new file mode 100644
index 0000000..3bf4897
--- /dev/null
+++ b/silx/gui/hdf5/test/test_hdf5.py
@@ -0,0 +1,480 @@
+# 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.
+#
+# ###########################################################################*/
+"""Test for silx.gui.hdf5 module"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "12/04/2017"
+
+
+import time
+import os
+import unittest
+import tempfile
+import numpy
+from contextlib import contextmanager
+from silx.gui import qt
+from silx.gui.test.utils import TestCaseQt
+from silx.gui import hdf5
+from . import _mock
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+
+_called = 0
+
+
+class _Holder(object):
+ def callback(self, *args, **kvargs):
+ _called += 1
+
+
+class TestHdf5TreeModel(TestCaseQt):
+
+ def setUp(self):
+ super(TestHdf5TreeModel, self).setUp()
+ if h5py is None:
+ self.skipTest("h5py is not available")
+
+ @contextmanager
+ def h5TempFile(self):
+ # create tmp file
+ fd, tmp_name = tempfile.mkstemp(suffix=".h5")
+ os.close(fd)
+ # create h5 data
+ h5file = h5py.File(tmp_name, "w")
+ g = h5file.create_group("arrays")
+ g.create_dataset("scalar", data=10)
+ h5file.close()
+ yield tmp_name
+ # clean up
+ os.unlink(tmp_name)
+
+ def testCreate(self):
+ model = hdf5.Hdf5TreeModel()
+ self.assertIsNotNone(model)
+
+ def testAppendFilename(self):
+ with self.h5TempFile() as filename:
+ model = hdf5.Hdf5TreeModel()
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 0)
+ model.appendFile(filename)
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 1)
+ # clean up
+ index = model.index(0, 0, qt.QModelIndex())
+ h5File = model.data(index, hdf5.Hdf5TreeModel.H5PY_OBJECT_ROLE)
+ h5File.close()
+
+ def testAppendBadFilename(self):
+ model = hdf5.Hdf5TreeModel()
+ self.assertRaises(IOError, model.appendFile, "#%$")
+
+ def testInsertFilename(self):
+ with self.h5TempFile() as filename:
+ model = hdf5.Hdf5TreeModel()
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 0)
+ model.insertFile(filename)
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 1)
+ # clean up
+ index = model.index(0, 0, qt.QModelIndex())
+ h5File = model.data(index, hdf5.Hdf5TreeModel.H5PY_OBJECT_ROLE)
+ h5File.close()
+
+ def testInsertFilenameAsync(self):
+ with self.h5TempFile() as filename:
+ model = hdf5.Hdf5TreeModel()
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 0)
+ model.insertFileAsync(filename)
+ index = model.index(0, 0, qt.QModelIndex())
+ self.assertIsInstance(model.nodeFromIndex(index), hdf5.Hdf5LoadingItem.Hdf5LoadingItem)
+ time.sleep(0.1)
+ self.qapp.processEvents()
+ time.sleep(0.1)
+ index = model.index(0, 0, qt.QModelIndex())
+ self.assertIsInstance(model.nodeFromIndex(index), hdf5.Hdf5Item.Hdf5Item)
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 1)
+ # clean up
+ index = model.index(0, 0, qt.QModelIndex())
+ h5File = model.data(index, hdf5.Hdf5TreeModel.H5PY_OBJECT_ROLE)
+ h5File.close()
+
+ def testInsertObject(self):
+ h5 = _mock.File("/foo/bar/1.mock")
+ model = hdf5.Hdf5TreeModel()
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 0)
+ model.insertH5pyObject(h5)
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 1)
+
+ def testRemoveObject(self):
+ h5 = _mock.File("/foo/bar/1.mock")
+ model = hdf5.Hdf5TreeModel()
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 0)
+ model.insertH5pyObject(h5)
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 1)
+ model.removeH5pyObject(h5)
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 0)
+
+ def testSynchronizeObject(self):
+ with self.h5TempFile() as filename:
+ h5 = h5py.File(filename)
+ model = hdf5.Hdf5TreeModel()
+ model.insertH5pyObject(h5)
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 1)
+ index = model.index(0, 0, qt.QModelIndex())
+ node1 = model.nodeFromIndex(index)
+ model.synchronizeH5pyObject(h5)
+ index = model.index(0, 0, qt.QModelIndex())
+ node2 = model.nodeFromIndex(index)
+ self.assertIsNot(node1, node2)
+ # after sync
+ time.sleep(0.1)
+ self.qapp.processEvents()
+ time.sleep(0.1)
+ index = model.index(0, 0, qt.QModelIndex())
+ self.assertIsInstance(model.nodeFromIndex(index), hdf5.Hdf5Item.Hdf5Item)
+ # clean up
+ index = model.index(0, 0, qt.QModelIndex())
+ h5File = model.data(index, hdf5.Hdf5TreeModel.H5PY_OBJECT_ROLE)
+ h5File.close()
+
+ def testFileMoveState(self):
+ model = hdf5.Hdf5TreeModel()
+ self.assertEquals(model.isFileMoveEnabled(), True)
+ model.setFileMoveEnabled(False)
+ self.assertEquals(model.isFileMoveEnabled(), False)
+
+ def testFileDropState(self):
+ model = hdf5.Hdf5TreeModel()
+ self.assertEquals(model.isFileDropEnabled(), True)
+ model.setFileDropEnabled(False)
+ self.assertEquals(model.isFileDropEnabled(), False)
+
+ def testSupportedDrop(self):
+ model = hdf5.Hdf5TreeModel()
+ self.assertNotEquals(model.supportedDropActions(), 0)
+
+ model.setFileMoveEnabled(False)
+ model.setFileDropEnabled(False)
+ self.assertEquals(model.supportedDropActions(), 0)
+
+ model.setFileMoveEnabled(False)
+ model.setFileDropEnabled(True)
+ self.assertNotEquals(model.supportedDropActions(), 0)
+
+ model.setFileMoveEnabled(True)
+ model.setFileDropEnabled(False)
+ self.assertNotEquals(model.supportedDropActions(), 0)
+
+ def testDropExternalFile(self):
+ with self.h5TempFile() as filename:
+ model = hdf5.Hdf5TreeModel()
+ mimeData = qt.QMimeData()
+ mimeData.setUrls([qt.QUrl.fromLocalFile(filename)])
+ model.dropMimeData(mimeData, qt.Qt.CopyAction, 0, 0, qt.QModelIndex())
+ self.assertEquals(model.rowCount(qt.QModelIndex()), 1)
+ # after sync
+ time.sleep(0.1)
+ self.qapp.processEvents()
+ time.sleep(0.1)
+ index = model.index(0, 0, qt.QModelIndex())
+ self.assertIsInstance(model.nodeFromIndex(index), hdf5.Hdf5Item.Hdf5Item)
+ # clean up
+ index = model.index(0, 0, qt.QModelIndex())
+ h5File = model.data(index, role=hdf5.Hdf5TreeModel.H5PY_OBJECT_ROLE)
+ h5File.close()
+
+ def getRowDataAsDict(self, model, row):
+ displayed = {}
+ roles = [qt.Qt.DisplayRole, qt.Qt.DecorationRole, qt.Qt.ToolTipRole, qt.Qt.TextAlignmentRole]
+ for column in range(0, model.columnCount(qt.QModelIndex())):
+ index = model.index(0, column, qt.QModelIndex())
+ for role in roles:
+ datum = model.data(index, role)
+ displayed[column, role] = datum
+ return displayed
+
+ def getItemName(self, model, row):
+ index = model.index(row, hdf5.Hdf5TreeModel.NAME_COLUMN, qt.QModelIndex())
+ return model.data(index, qt.Qt.DisplayRole)
+
+ def testFileData(self):
+ h5 = _mock.File("/foo/bar/1.mock")
+ model = hdf5.Hdf5TreeModel()
+ model.insertH5pyObject(h5)
+ displayed = self.getRowDataAsDict(model, row=0)
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.NAME_COLUMN, qt.Qt.DisplayRole], "1.mock")
+ self.assertIsInstance(displayed[hdf5.Hdf5TreeModel.NAME_COLUMN, qt.Qt.DecorationRole], qt.QIcon)
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.TYPE_COLUMN, qt.Qt.DisplayRole], "")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.SHAPE_COLUMN, qt.Qt.DisplayRole], "")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.VALUE_COLUMN, qt.Qt.DisplayRole], "")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.DESCRIPTION_COLUMN, qt.Qt.DisplayRole], "")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.NODE_COLUMN, qt.Qt.DisplayRole], "File")
+
+ def testGroupData(self):
+ h5 = _mock.File("/foo/bar/1.mock")
+ d = h5.create_group("foo")
+ d.attrs["desc"] = "fooo"
+
+ model = hdf5.Hdf5TreeModel()
+ model.insertH5pyObject(d)
+ displayed = self.getRowDataAsDict(model, row=0)
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.NAME_COLUMN, qt.Qt.DisplayRole], "1.mock::foo")
+ self.assertIsInstance(displayed[hdf5.Hdf5TreeModel.NAME_COLUMN, qt.Qt.DecorationRole], qt.QIcon)
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.TYPE_COLUMN, qt.Qt.DisplayRole], "")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.SHAPE_COLUMN, qt.Qt.DisplayRole], "")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.VALUE_COLUMN, qt.Qt.DisplayRole], "")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.DESCRIPTION_COLUMN, qt.Qt.DisplayRole], "fooo")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.NODE_COLUMN, qt.Qt.DisplayRole], "Group")
+
+ def testDatasetData(self):
+ h5 = _mock.File("/foo/bar/1.mock")
+ value = numpy.array([1, 2, 3])
+ d = h5.create_dataset("foo", value)
+
+ model = hdf5.Hdf5TreeModel()
+ model.insertH5pyObject(d)
+ displayed = self.getRowDataAsDict(model, row=0)
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.NAME_COLUMN, qt.Qt.DisplayRole], "1.mock::foo")
+ self.assertIsInstance(displayed[hdf5.Hdf5TreeModel.NAME_COLUMN, qt.Qt.DecorationRole], qt.QIcon)
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.TYPE_COLUMN, qt.Qt.DisplayRole], value.dtype.name)
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.SHAPE_COLUMN, qt.Qt.DisplayRole], "3")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.VALUE_COLUMN, qt.Qt.DisplayRole], "[1 2 3]")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.DESCRIPTION_COLUMN, qt.Qt.DisplayRole], "")
+ self.assertEquals(displayed[hdf5.Hdf5TreeModel.NODE_COLUMN, qt.Qt.DisplayRole], "Dataset")
+
+ def testDropLastAsFirst(self):
+ model = hdf5.Hdf5TreeModel()
+ h5_1 = _mock.File("/foo/bar/1.mock")
+ h5_2 = _mock.File("/foo/bar/2.mock")
+ model.insertH5pyObject(h5_1)
+ model.insertH5pyObject(h5_2)
+ self.assertEquals(self.getItemName(model, 0), "1.mock")
+ self.assertEquals(self.getItemName(model, 1), "2.mock")
+ index = model.index(1, 0, qt.QModelIndex())
+ mimeData = model.mimeData([index])
+ model.dropMimeData(mimeData, qt.Qt.MoveAction, 0, 0, qt.QModelIndex())
+ self.assertEquals(self.getItemName(model, 0), "2.mock")
+ self.assertEquals(self.getItemName(model, 1), "1.mock")
+
+ def testDropFirstAsLast(self):
+ model = hdf5.Hdf5TreeModel()
+ h5_1 = _mock.File("/foo/bar/1.mock")
+ h5_2 = _mock.File("/foo/bar/2.mock")
+ model.insertH5pyObject(h5_1)
+ model.insertH5pyObject(h5_2)
+ self.assertEquals(self.getItemName(model, 0), "1.mock")
+ self.assertEquals(self.getItemName(model, 1), "2.mock")
+ index = model.index(0, 0, qt.QModelIndex())
+ mimeData = model.mimeData([index])
+ model.dropMimeData(mimeData, qt.Qt.MoveAction, 2, 0, qt.QModelIndex())
+ self.assertEquals(self.getItemName(model, 0), "2.mock")
+ self.assertEquals(self.getItemName(model, 1), "1.mock")
+
+ def testRootParent(self):
+ model = hdf5.Hdf5TreeModel()
+ h5_1 = _mock.File("/foo/bar/1.mock")
+ model.insertH5pyObject(h5_1)
+ index = model.index(0, 0, qt.QModelIndex())
+ index = model.parent(index)
+ self.assertEquals(index, qt.QModelIndex())
+
+
+class TestNexusSortFilterProxyModel(TestCaseQt):
+
+ def getChildNames(self, model, index):
+ count = model.rowCount(index)
+ result = []
+ for row in range(0, count):
+ itemIndex = model.index(row, hdf5.Hdf5TreeModel.NAME_COLUMN, index)
+ name = model.data(itemIndex, qt.Qt.DisplayRole)
+ result.append(name)
+ return result
+
+ def testNXentryStartTime(self):
+ """Test NXentry with start_time"""
+ model = hdf5.Hdf5TreeModel()
+ h5 = _mock.File("/foo/bar/1.mock")
+ h5.create_NXentry("a").create_dataset("start_time", numpy.string_("2015"))
+ h5.create_NXentry("b").create_dataset("start_time", numpy.string_("2013"))
+ h5.create_NXentry("c").create_dataset("start_time", numpy.string_("2014"))
+ model.insertH5pyObject(h5)
+
+ proxy = hdf5.NexusSortFilterProxyModel()
+ proxy.setSourceModel(model)
+ proxy.sort(0, qt.Qt.DescendingOrder)
+ names = self.getChildNames(proxy, proxy.index(0, 0, qt.QModelIndex()))
+ self.assertListEqual(names, ["a", "c", "b"])
+
+ def testNXentryStartTimeInArray(self):
+ """Test NXentry with start_time"""
+ model = hdf5.Hdf5TreeModel()
+ h5 = _mock.File("/foo/bar/1.mock")
+ h5.create_NXentry("a").create_dataset("start_time", numpy.array([numpy.string_("2015")]))
+ h5.create_NXentry("b").create_dataset("start_time", numpy.array([numpy.string_("2013")]))
+ h5.create_NXentry("c").create_dataset("start_time", numpy.array([numpy.string_("2014")]))
+ model.insertH5pyObject(h5)
+
+ proxy = hdf5.NexusSortFilterProxyModel()
+ proxy.setSourceModel(model)
+ proxy.sort(0, qt.Qt.DescendingOrder)
+ names = self.getChildNames(proxy, proxy.index(0, 0, qt.QModelIndex()))
+ self.assertListEqual(names, ["a", "c", "b"])
+
+ def testNXentryEndTimeInArray(self):
+ """Test NXentry with end_time"""
+ model = hdf5.Hdf5TreeModel()
+ h5 = _mock.File("/foo/bar/1.mock")
+ h5.create_NXentry("a").create_dataset("end_time", numpy.array([numpy.string_("2015")]))
+ h5.create_NXentry("b").create_dataset("end_time", numpy.array([numpy.string_("2013")]))
+ h5.create_NXentry("c").create_dataset("end_time", numpy.array([numpy.string_("2014")]))
+ model.insertH5pyObject(h5)
+
+ proxy = hdf5.NexusSortFilterProxyModel()
+ proxy.setSourceModel(model)
+ proxy.sort(0, qt.Qt.DescendingOrder)
+ names = self.getChildNames(proxy, proxy.index(0, 0, qt.QModelIndex()))
+ self.assertListEqual(names, ["a", "c", "b"])
+
+ def testNXentryName(self):
+ """Test NXentry without start_time or end_time"""
+ model = hdf5.Hdf5TreeModel()
+ h5 = _mock.File("/foo/bar/1.mock")
+ h5.create_NXentry("a")
+ h5.create_NXentry("c")
+ h5.create_NXentry("b")
+ model.insertH5pyObject(h5)
+
+ proxy = hdf5.NexusSortFilterProxyModel()
+ proxy.setSourceModel(model)
+ proxy.sort(0, qt.Qt.AscendingOrder)
+ names = self.getChildNames(proxy, proxy.index(0, 0, qt.QModelIndex()))
+ self.assertListEqual(names, ["a", "b", "c"])
+
+ def testStartTime(self):
+ """If it is not NXentry, start_time is not used"""
+ model = hdf5.Hdf5TreeModel()
+ h5 = _mock.File("/foo/bar/1.mock")
+ h5.create_group("a").create_dataset("start_time", numpy.string_("2015"))
+ h5.create_group("b").create_dataset("start_time", numpy.string_("2013"))
+ h5.create_group("c").create_dataset("start_time", numpy.string_("2014"))
+ model.insertH5pyObject(h5)
+
+ proxy = hdf5.NexusSortFilterProxyModel()
+ proxy.setSourceModel(model)
+ proxy.sort(0, qt.Qt.AscendingOrder)
+ names = self.getChildNames(proxy, proxy.index(0, 0, qt.QModelIndex()))
+ self.assertListEqual(names, ["a", "b", "c"])
+
+ def testName(self):
+ model = hdf5.Hdf5TreeModel()
+ h5 = _mock.File("/foo/bar/1.mock")
+ h5.create_group("a")
+ h5.create_group("c")
+ h5.create_group("b")
+ model.insertH5pyObject(h5)
+
+ proxy = hdf5.NexusSortFilterProxyModel()
+ proxy.setSourceModel(model)
+ proxy.sort(0, qt.Qt.AscendingOrder)
+ names = self.getChildNames(proxy, proxy.index(0, 0, qt.QModelIndex()))
+ self.assertListEqual(names, ["a", "b", "c"])
+
+ def testNumber(self):
+ model = hdf5.Hdf5TreeModel()
+ h5 = _mock.File("/foo/bar/1.mock")
+ h5.create_group("a1")
+ h5.create_group("a20")
+ h5.create_group("a3")
+ model.insertH5pyObject(h5)
+
+ proxy = hdf5.NexusSortFilterProxyModel()
+ proxy.setSourceModel(model)
+ proxy.sort(0, qt.Qt.AscendingOrder)
+ names = self.getChildNames(proxy, proxy.index(0, 0, qt.QModelIndex()))
+ self.assertListEqual(names, ["a1", "a3", "a20"])
+
+ def testMultiNumber(self):
+ model = hdf5.Hdf5TreeModel()
+ h5 = _mock.File("/foo/bar/1.mock")
+ h5.create_group("a1-1")
+ h5.create_group("a20-1")
+ h5.create_group("a3-1")
+ h5.create_group("a3-20")
+ h5.create_group("a3-3")
+ model.insertH5pyObject(h5)
+
+ proxy = hdf5.NexusSortFilterProxyModel()
+ proxy.setSourceModel(model)
+ proxy.sort(0, qt.Qt.AscendingOrder)
+ names = self.getChildNames(proxy, proxy.index(0, 0, qt.QModelIndex()))
+ self.assertListEqual(names, ["a1-1", "a3-1", "a3-3", "a3-20", "a20-1"])
+
+ def testUnconsistantTypes(self):
+ model = hdf5.Hdf5TreeModel()
+ h5 = _mock.File("/foo/bar/1.mock")
+ h5.create_group("aaa100")
+ h5.create_group("100aaa")
+ model.insertH5pyObject(h5)
+
+ proxy = hdf5.NexusSortFilterProxyModel()
+ proxy.setSourceModel(model)
+ proxy.sort(0, qt.Qt.AscendingOrder)
+ names = self.getChildNames(proxy, proxy.index(0, 0, qt.QModelIndex()))
+ self.assertListEqual(names, ["100aaa", "aaa100"])
+
+
+class TestHdf5(TestCaseQt):
+ """Test to check that icons module."""
+
+ def setUp(self):
+ super(TestHdf5, self).setUp()
+ if h5py is None:
+ self.skipTest("h5py is not available")
+
+ def testCreate(self):
+ view = hdf5.Hdf5TreeView()
+ self.assertIsNotNone(view)
+
+ def testContextMenu(self):
+ view = hdf5.Hdf5TreeView()
+ view._createContextMenu(qt.QPoint(0, 0))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestHdf5TreeModel))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestNexusSortFilterProxyModel))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestHdf5))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/icons.py b/silx/gui/icons.py
new file mode 100644
index 0000000..eaf83b8
--- /dev/null
+++ b/silx/gui/icons.py
@@ -0,0 +1,360 @@
+# 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.
+#
+# ###########################################################################*/
+"""Set of icons for buttons.
+
+Use :func:`getQIcon` to create Qt QIcon from the name identifying an icon.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/04/2017"
+
+
+import logging
+import weakref
+from . import qt
+from silx.resources import resource_filename
+from silx.utils import weakref as silxweakref
+from silx.utils.decorators import deprecated
+
+
+_logger = logging.getLogger(__name__)
+"""Module logger"""
+
+
+_cached_icons = weakref.WeakValueDictionary()
+"""Cache loaded icons in a weak structure"""
+
+
+_supported_formats = None
+"""Order of file format extension to check"""
+
+
+class AbstractAnimatedIcon(qt.QObject):
+ """Store an animated icon.
+
+ It provides an event containing the new icon everytime it is updated."""
+
+ def __init__(self, parent=None):
+ """Constructor
+
+ :param qt.QObject parent: Parent of the QObject
+ :raises: ValueError when name is not known
+ """
+ qt.QObject.__init__(self, parent)
+
+ self.__targets = silxweakref.WeakList()
+ self.__currentIcon = None
+
+ iconChanged = qt.Signal(qt.QIcon)
+ """Signal sent with a QIcon everytime the animation changed."""
+
+ def register(self, obj):
+ """Register an object to the AnimatedIcon.
+ If no object are registred, the animation is paused.
+ Object are stored in a weaked list.
+
+ :param object obj: An object
+ """
+ if obj not in self.__targets:
+ self.__targets.append(obj)
+ self._updateState()
+
+ def unregister(self, obj):
+ """Remove the object from the registration.
+ If no object are registred the animation is paused.
+
+ :param object obj: A registered object
+ """
+ if obj in self.__targets:
+ self.__targets.remove(obj)
+ self._updateState()
+
+ def hasRegistredObjects(self):
+ """Returns true if any object is registred.
+
+ :rtype: bool
+ """
+ return len(self.__targets)
+
+ def isRegistered(self, obj):
+ """Returns true if the object is registred in the AnimatedIcon.
+
+ :param object obj: An object
+ :rtype: bool
+ """
+ return obj in self.__targets
+
+ def currentIcon(self):
+ """Returns the icon of the current frame.
+
+ :rtype: qt.QIcon
+ """
+ return self.__currentIcon
+
+ def _updateState(self):
+ """Update the object according to the connected objects."""
+ pass
+
+ def _setCurrentIcon(self, icon):
+ """Store the current icon and emit a `iconChanged` event.
+
+ :param qt.QIcon icon: The current icon
+ """
+ self.__currentIcon = icon
+ self.iconChanged.emit(self.__currentIcon)
+
+
+class MovieAnimatedIcon(AbstractAnimatedIcon):
+ """Store a looping QMovie to provide icons for each frames.
+ Provides an event with the new icon everytime the movie frame
+ is updated."""
+
+ def __init__(self, filename, parent=None):
+ """Constructor
+
+ :param str filename: An icon name to an animated format
+ :param qt.QObject parent: Parent of the QObject
+ :raises: ValueError when name is not known
+ """
+ AbstractAnimatedIcon.__init__(self, parent)
+
+ qfile = getQFile(filename)
+ self.__movie = qt.QMovie(qfile.fileName(), qt.QByteArray(), parent)
+ self.__movie.setCacheMode(qt.QMovie.CacheAll)
+ self.__movie.frameChanged.connect(self.__frameChanged)
+ self.__cacheIcons = {}
+
+ self.__movie.jumpToFrame(0)
+ self.__updateIconAtFrame(0)
+
+ def __frameChanged(self, frameId):
+ """Callback everytime the QMovie frame change
+ :param int frameId: Current frame id
+ """
+ self.__updateIconAtFrame(frameId)
+
+ def __updateIconAtFrame(self, frameId):
+ """
+ Update the current stored QIcon
+
+ :param int frameId: Current frame id
+ """
+ if frameId in self.__cacheIcons:
+ icon = self.__cacheIcons[frameId]
+ else:
+ icon = qt.QIcon(self.__movie.currentPixmap())
+ self.__cacheIcons[frameId] = icon
+ self._setCurrentIcon(icon)
+
+ def _updateState(self):
+ """Update the movie play according to internal stat of the
+ AnimatedIcon."""
+ self.__movie.setPaused(not self.hasRegistredObjects())
+
+
+class MultiImageAnimatedIcon(AbstractAnimatedIcon):
+ """Store a looping QMovie to provide icons for each frames.
+ Provides an event with the new icon everytime the movie frame
+ is updated."""
+
+ def __init__(self, filename, parent=None):
+ """Constructor
+
+ :param str filename: An icon name to an animated format
+ :param qt.QObject parent: Parent of the QObject
+ :raises: ValueError when name is not known
+ """
+ AbstractAnimatedIcon.__init__(self, parent)
+
+ self.__frames = []
+ for i in range(100):
+ try:
+ pixmap = getQPixmap("animated/%s-%02d" % (filename, i))
+ except ValueError:
+ break
+ icon = qt.QIcon(pixmap)
+ self.__frames.append(icon)
+
+ if len(self.__frames) == 0:
+ raise ValueError("Animated icon '%s' do not exists" % filename)
+
+ self.__frameId = -1
+ self.__timer = qt.QTimer(self)
+ self.__timer.timeout.connect(self.__increaseFrame)
+ self.__updateIconAtFrame(0)
+
+ def __increaseFrame(self):
+ """Callback called every timer timeout to change the current frame of
+ the animation
+ """
+ frameId = (self.__frameId + 1) % len(self.__frames)
+ self.__updateIconAtFrame(frameId)
+
+ def __updateIconAtFrame(self, frameId):
+ """
+ Update the current stored QIcon
+
+ :param int frameId: Current frame id
+ """
+ self.__frameId = frameId
+ icon = self.__frames[frameId]
+ self._setCurrentIcon(icon)
+
+ def _updateState(self):
+ """Update the object to wake up or sleep it according to its use."""
+ if self.hasRegistredObjects():
+ if not self.__timer.isActive():
+ self.__timer.start(100)
+ else:
+ if self.__timer.isActive():
+ self.__timer.stop()
+
+
+class AnimatedIcon(MovieAnimatedIcon):
+ """Store a looping QMovie to provide icons for each frames.
+ Provides an event with the new icon everytime the movie frame
+ is updated.
+
+ It may not be available anymore for the silx release 0.6.
+
+ .. deprecated:: 0.5
+ Use :class:`MovieAnimatedIcon` instead.
+ """
+
+ @deprecated
+ def __init__(self, filename, parent=None):
+ MovieAnimatedIcon.__init__(self, filename, parent=parent)
+
+
+def getWaitIcon():
+ """Returns a cached version of the waiting AbstractAnimatedIcon.
+
+ :rtype: AbstractAnimatedIcon
+ """
+ return getAnimatedIcon("process-working")
+
+
+def getAnimatedIcon(name):
+ """Create an AbstractAnimatedIcon from a name.
+
+ Try to load a mng or a gif file, then try to load a multi-image animated
+ icon.
+
+ In Qt5 mng or gif are not used. It does not take care very well of the
+ transparency.
+
+ :param str name: Name of the icon, in one of the defined icons
+ in this module.
+ :return: Corresponding AbstractAnimatedIcon
+ :raises: ValueError when name is not known
+ """
+ key = name + "__anim"
+ if key not in _cached_icons:
+
+ qtMajorVersion = int(qt.qVersion().split(".")[0])
+ icon = None
+
+ # ignore mng and gif in Qt5
+ if qtMajorVersion != 5:
+ try:
+ icon = MovieAnimatedIcon(name)
+ except ValueError:
+ icon = None
+
+ if icon is None:
+ try:
+ icon = MultiImageAnimatedIcon(name)
+ except ValueError:
+ icon = None
+
+ if icon is None:
+ raise ValueError("Not an animated icon name: %s", name)
+
+ _cached_icons[key] = icon
+ else:
+ icon = _cached_icons[key]
+ return icon
+
+
+def getQIcon(name):
+ """Create a QIcon from its name.
+
+ :param str name: Name of the icon, in one of the defined icons
+ in this module.
+ :return: Corresponding QIcon
+ :raises: ValueError when name is not known
+ """
+ if name not in _cached_icons:
+ qfile = getQFile(name)
+ icon = qt.QIcon(qfile.fileName())
+ _cached_icons[name] = icon
+ else:
+ icon = _cached_icons[name]
+ return icon
+
+
+def getQPixmap(name):
+ """Create a QPixmap from its name.
+
+ :param str name: Name of the icon, in one of the defined icons
+ in this module.
+ :return: Corresponding QPixmap
+ :raises: ValueError when name is not known
+ """
+ qfile = getQFile(name)
+ return qt.QPixmap(qfile.fileName())
+
+
+def getQFile(name):
+ """Create a QFile from an icon name. Filename is found
+ according to supported Qt formats.
+
+ :param str name: Name of the icon, in one of the defined icons
+ in this module.
+ :return: Corresponding QFile
+ :rtype: qt.QFile
+ :raises: ValueError when name is not known
+ """
+ global _supported_formats
+ if _supported_formats is None:
+ _supported_formats = []
+ supported_formats = qt.supportedImageFormats()
+ order = ["mng", "gif", "svg", "png", "jpg"]
+ for format_ in order:
+ if format_ in supported_formats:
+ _supported_formats.append(format_)
+ if len(_supported_formats) == 0:
+ _logger.error("No format supported for icons")
+ else:
+ _logger.debug("Format %s supported", ", ".join(_supported_formats))
+
+ for format_ in _supported_formats:
+ format_ = str(format_)
+ filename = resource_filename('gui/icons/%s.%s' % (name, format_))
+ qfile = qt.QFile(filename)
+ if qfile.exists():
+ return qfile
+ raise ValueError('Not an icon name: %s' % name)
diff --git a/silx/gui/plot/AlphaSlider.py b/silx/gui/plot/AlphaSlider.py
new file mode 100644
index 0000000..ab2e5aa
--- /dev/null
+++ b/silx/gui/plot/AlphaSlider.py
@@ -0,0 +1,300 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module defines slider widgets interacting with the transparency
+of an image on a :class:`PlotWidget`
+
+Classes:
+--------
+
+- :class:`BaseAlphaSlider` (abstract class)
+- :class:`NamedImageAlphaSlider`
+- :class:`ActiveImageAlphaSlider`
+
+Example:
+--------
+
+This widget can, for instance, be added to a plot toolbar.
+
+.. code-block:: python
+
+ import numpy
+ from silx.gui import qt
+ from silx.gui.plot import PlotWidget
+ from silx.gui.plot.ImageAlphaSlider import NamedImageAlphaSlider
+
+ app = qt.QApplication([])
+ pw = PlotWidget()
+
+ img0 = numpy.arange(200*150).reshape((200, 150))
+ pw.addImage(img0, legend="my background", z=0, origin=(50, 50))
+
+ x, y = numpy.meshgrid(numpy.linspace(-10, 10, 200),
+ numpy.linspace(-10, 5, 150),
+ indexing="ij")
+ img1 = numpy.asarray(numpy.sin(x * y) / (x * y),
+ dtype='float32')
+
+ pw.addImage(img1, legend="my data", z=1,
+ replace=False)
+
+ alpha_slider = NamedImageAlphaSlider(parent=pw,
+ plot=pw,
+ legend="my data")
+ alpha_slider.setOrientation(qt.Qt.Horizontal)
+
+ toolbar = qt.QToolBar("plot", pw)
+ toolbar.addWidget(alpha_slider)
+ pw.addToolBar(toolbar)
+
+ pw.show()
+ app.exec_()
+
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "24/03/2017"
+
+import logging
+
+from silx.gui import qt
+
+_logger = logging.getLogger(__name__)
+
+
+class BaseAlphaSlider(qt.QSlider):
+ """Slider widget to be used in a plot toolbar to control the
+ transparency of a plot primitive (image, scatter or curve).
+
+ Internally, the slider stores its state as an integer between
+ 0 and 255. This is the value emitted by the :attr:`valueChanged`
+ signal.
+
+ The method :meth:`getAlpha` returns the corresponding opacity/alpha
+ as a float between 0. and 1. (with a step of :math:`\frac{1}{255}`).
+
+ You must subclass this class and implement :meth:`getItem`.
+ """
+ sigAlphaChanged = qt.Signal(float)
+ """Emits the alpha value when the slider's value changes,
+ as a float between 0. and 1."""
+
+ def __init__(self, parent=None, plot=None):
+ """
+
+ :param parent: Parent QWidget
+ :param plot: Parent plot widget
+ """
+ assert plot is not None
+ super(BaseAlphaSlider, self).__init__(parent)
+
+ self.plot = plot
+
+ self.setRange(0, 255)
+
+ # if already connected to an item, use its alpha as initial value
+ if self.getItem() is None:
+ self.setValue(255)
+ self.setEnabled(False)
+ else:
+ alpha = self.getItem().getAlpha()
+ self.setValue(round(255*alpha))
+
+ self.valueChanged.connect(self._valueChanged)
+
+ def getItem(self):
+ """You must implement this class to define which item
+ to work on. It must return an item that inherits
+ :class:`silx.gui.plot.items.core.AlphaMixIn`.
+
+ :return: Item on which to operate, or None
+ :rtype: :class:`silx.plot.items.Item`
+ """
+ raise NotImplementedError(
+ "BaseAlphaSlider must be subclassed to " +
+ "implement getItem()")
+
+ def getAlpha(self):
+ """Get the opacity, as a float between 0. and 1.
+
+ :return: Alpha value in [0., 1.]
+ :rtype: float
+ """
+ return self.value() / 255.
+
+ def _valueChanged(self, value):
+ self._updateItem()
+ self.sigAlphaChanged.emit(value / 255.)
+
+ def _updateItem(self):
+ """Update the item's alpha channel.
+ """
+ item = self.getItem()
+ if item is not None:
+ item.setAlpha(self.getAlpha())
+
+
+class ActiveImageAlphaSlider(BaseAlphaSlider):
+ """Slider widget to be used in a plot toolbar to control the
+ transparency of the **active image**.
+
+ :param parent: Parent QWidget
+ :param plot: Plot on which to operate
+
+ See documentation of :class:`BaseAlphaSlider`
+ """
+ def __init__(self, parent=None, plot=None):
+ """
+
+ :param parent: Parent QWidget
+ :param plot: Plot widget on which to operate
+ """
+ super(ActiveImageAlphaSlider, self).__init__(parent, plot)
+ plot.sigActiveImageChanged.connect(self._activeImageChanged)
+
+ def getItem(self):
+ return self.plot.getActiveImage()
+
+ def _activeImageChanged(self, previous, new):
+ """Activate or deactivate slider depending on presence of a new
+ active image.
+ Apply transparency value to new active image.
+
+ :param previous: Legend of previous active image, or None
+ :param new: Legend of new active image, or None
+ """
+ if new is not None and not self.isEnabled():
+ self.setEnabled(True)
+ elif new is None and self.isEnabled():
+ self.setEnabled(False)
+
+ self._updateItem()
+
+
+class NamedItemAlphaSlider(BaseAlphaSlider):
+ """Slider widget to be used in a plot toolbar to control the
+ transparency of an item (defined by its kind and legend).
+
+ :param parent: Parent QWidget
+ :param plot: Plot on which to operate
+ :param str kind: Kind of item whose transparency is to be
+ controlled: "scatter", "image" or "curve".
+ :param str legend: Legend of item whose transparency is to be
+ controlled.
+ """
+ def __init__(self, parent=None, plot=None,
+ kind=None, legend=None):
+ self._item_legend = legend
+ self._item_kind = kind
+
+ super(NamedItemAlphaSlider, self).__init__(parent, plot)
+
+ self._updateState()
+ plot.sigContentChanged.connect(self._onContentChanged)
+
+ def _onContentChanged(self, action, kind, legend):
+ if legend == self._item_legend and kind == self._item_kind:
+ if action == "add":
+ self.setEnabled(True)
+ elif action == "remove":
+ self.setEnabled(False)
+
+ def _updateState(self):
+ """Enable or disable widget based on item's availability."""
+ if self.getItem() is not None:
+ self.setEnabled(True)
+ else:
+ self.setEnabled(False)
+
+ def getItem(self):
+ """Return plot item currently associated to this widget (can be
+ a curve, an image, a scatter...)
+
+ :rtype: subclass of :class:`silx.gui.plot.items.Item`"""
+ if self._item_legend is None or self._item_kind is None:
+ return None
+ return self.plot._getItem(kind=self._item_kind,
+ legend=self._item_legend)
+
+ def setLegend(self, legend):
+ """Associate a different item (of the same kind) to the slider.
+
+ :param legend: New legend of item whose transparency is to be
+ controlled.
+ """
+ self._item_legend = legend
+ self._updateState()
+
+ def getLegend(self):
+ """Return legend of the item currently controlled by this slider.
+
+ :return: Image legend associated to the slider
+ """
+ return self._item_kind
+
+ def setItemKind(self, legend):
+ """Associate a different item (of the same kind) to the slider.
+
+ :param legend: New legend of item whose transparency is to be
+ controlled.
+ """
+ self._item_legend = legend
+ self._updateState()
+
+ def getItemKind(self):
+ """Return kind of the item currently controlled by this slider.
+
+ :return: Item kind ("image", "scatter"...)
+ :rtype: str on None
+ """
+ return self._item_kind
+
+
+class NamedImageAlphaSlider(NamedItemAlphaSlider):
+ """Slider widget to be used in a plot toolbar to control the
+ transparency of an image (defined by its legend).
+
+ :param parent: Parent QWidget
+ :param plot: Plot on which to operate
+ :param str legend: Legend of image whose transparency is to be
+ controlled.
+ """
+ def __init__(self, parent=None, plot=None, legend=None):
+ NamedItemAlphaSlider.__init__(self, parent, plot,
+ kind="image", legend=legend)
+
+
+class NamedScatterAlphaSlider(NamedItemAlphaSlider):
+ """Slider widget to be used in a plot toolbar to control the
+ transparency of a scatter (defined by its legend).
+
+ :param parent: Parent QWidget
+ :param plot: Plot on which to operate
+ :param str legend: Legend of scatter whose transparency is to be
+ controlled.
+ """
+ def __init__(self, parent=None, plot=None, legend=None):
+ NamedItemAlphaSlider.__init__(self, parent, plot,
+ kind="scatter", legend=legend)
diff --git a/silx/gui/plot/ColorBar.py b/silx/gui/plot/ColorBar.py
new file mode 100644
index 0000000..93e3c36
--- /dev/null
+++ b/silx/gui/plot/ColorBar.py
@@ -0,0 +1,790 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Module containing several widgets associated to a colormap.
+"""
+
+__authors__ = ["H. Payno", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "11/04/2017"
+
+
+import logging
+import numpy
+from ._utils import ticklayout
+from ._utils import clipColormapLogRange
+
+
+from .. import qt
+from silx.gui.plot import Colors
+
+_logger = logging.getLogger(__name__)
+
+
+class ColorBarWidget(qt.QWidget):
+ """Colorbar widget displaying a colormap
+
+ It uses a description of colormap as dict compatible with :class:`Plot`.
+
+ .. image:: img/linearColorbar.png
+ :width: 80px
+ :align: center
+
+ To run the following sample code, a QApplication must be initialized.
+
+ >>> from silx.gui.plot import Plot2D
+ >>> from silx.gui.plot.ColorBar import ColorBarWidget
+
+ >>> plot = Plot2D() # Create a plot widget
+ >>> plot.show()
+
+ >>> colorbar = ColorBarWidget(plot=plot, legend='Colormap') # Associate the colorbar with it
+ >>> colorbar.show()
+
+ Initializer parameters:
+
+ :param parent: See :class:`QWidget`
+ :param plot: PlotWidget the colorbar is attached to (optional)
+ :param str legend: the label to set to the colormap
+ """
+
+ def __init__(self, parent=None, plot=None, legend=None):
+ super(ColorBarWidget, self).__init__(parent)
+ self._plot = None
+
+ self.__buildGUI()
+ self.setLegend(legend)
+ self.setPlot(plot)
+
+ def __buildGUI(self):
+ self.setLayout(qt.QHBoxLayout())
+
+ # create color scale widget
+ self._colorScale = ColorScaleBar(parent=self,
+ colormap=None)
+ self.layout().addWidget(self._colorScale)
+
+ # legend (is the right group)
+ self.legend = _VerticalLegend('', self)
+ self.layout().addWidget(self.legend)
+
+ self.layout().setSizeConstraint(qt.QLayout.SetMinAndMaxSize)
+ self.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
+ self.layout().setContentsMargins(0, 0, 0, 0)
+
+ def getPlot(self):
+ """Returns the :class:`Plot` associated to this widget or None"""
+ return self._plot
+
+ def setPlot(self, plot):
+ """Associate a plot to the ColorBar
+
+ :param plot: the plot to associate with the colorbar. If None will remove
+ any connection with a previous plot.
+ """
+ # removing previous plot if any
+ if self._plot is not None:
+ self._plot.sigActiveImageChanged.disconnect(self._activeImageChanged)
+
+ # setting the new plot
+ self._plot = plot
+ if self._plot is not None:
+ self._plot.sigActiveImageChanged.connect(self._activeImageChanged)
+ self._activeImageChanged(self._plot.getActiveImage(just_legend=True))
+
+ def getColormap(self):
+ """Return the colormap displayed in the colorbar as a dict.
+
+ It returns None if no colormap is set.
+ See :class:`silx.gui.plot.Plot` documentation for the description of the colormap
+ dict description.
+ """
+ return self._colormap.copy()
+
+ def setColormap(self, colormap):
+ """Set the colormap to be displayed.
+
+ :param dict colormap: The colormap to apply on the ColorBarWidget
+ """
+ self._colormap = colormap
+ if self._colormap is None:
+ return
+
+ if self._colormap['normalization'] not in ('log', 'linear'):
+ raise ValueError('Wrong normalization %s' % self._colormap['normalization'])
+
+ if self._colormap['normalization'] is 'log':
+ if self._colormap['vmin'] < 1. or self._colormap['vmax'] < 1.:
+ _logger.warning('Log colormap with bound <= 1: changing bounds.')
+ clipColormapLogRange(colormap)
+
+ self.getColorScaleBar().setColormap(self._colormap)
+
+ def setLegend(self, legend):
+ """Set the legend displayed along the colorbar
+
+ :param str legend: The label
+ """
+ if legend is None or legend == "":
+ self.legend.hide()
+ self.legend.setText("")
+ else:
+ assert(type(legend) is str)
+ self.legend.show()
+ self.legend.setText(legend)
+
+ def getLegend(self):
+ """
+ Returns the legend displayed along the colorbar
+
+ :return: return the legend displayed along the colorbar
+ :rtype: str
+ """
+ return self.legend.getText()
+
+ def _activeImageChanged(self, legend):
+ """Handle plot active curve changed"""
+ if legend is None: # No active image, display default colormap
+ self._syncWithDefaultColormap()
+ return
+
+ # Sync with active image
+ image = self._plot.getActiveImage().getData(copy=False)
+
+ # RGB(A) image, display default colormap
+ if image.ndim != 2:
+ self._syncWithDefaultColormap()
+ return
+
+ # data image, sync with image colormap
+ # do we need the copy here : used in the case we are changing
+ # vmin and vmax but should have already be done by the plot
+ cmap = self._plot.getActiveImage().getColormap().copy()
+ if cmap['autoscale']:
+ if cmap['normalization'] == 'log':
+ data = image[
+ numpy.logical_and(image > 0, numpy.isfinite(image))]
+ else:
+ data = image[numpy.isfinite(image)]
+ cmap['vmin'], cmap['vmax'] = data.min(), data.max()
+
+ self.setColormap(cmap)
+
+ def _defaultColormapChanged(self):
+ """Handle plot default colormap changed"""
+ if self._plot.getActiveImage() is None:
+ # No active image, take default colormap update into account
+ self._syncWithDefaultColormap()
+
+ def _syncWithDefaultColormap(self):
+ """Update colorbar according to plot default colormap"""
+ self.setColormap(self._plot.getDefaultColormap())
+
+ def getColorScaleBar(self):
+ """
+
+ :return: return the :class:`ColorScaleBar` used to display ColorScale
+ and ticks"""
+ return self._colorScale
+
+
+class _VerticalLegend(qt.QLabel):
+ """Display vertically the given text
+ """
+ def __init__(self, text, parent=None):
+ """
+
+ :param text: the legend
+ :param parent: the Qt parent if any
+ """
+ qt.QLabel.__init__(self, text, parent)
+ self.setLayout(qt.QVBoxLayout())
+ self.layout().setContentsMargins(0, 0, 0, 0)
+
+ def paintEvent(self, event):
+ painter = qt.QPainter(self)
+ painter.setFont(self.font())
+
+ painter.translate(0, self.rect().height())
+ painter.rotate(270)
+ newRect = qt.QRect(0, 0, self.rect().height(), self.rect().width())
+
+ painter.drawText(newRect, qt.Qt.AlignHCenter, self.text())
+
+ fm = qt.QFontMetrics(self.font())
+ preferedHeight = fm.width(self.text())
+ preferedWidth = fm.height()
+ self.setFixedWidth(preferedWidth)
+ self.setMinimumHeight(preferedHeight)
+
+
+class ColorScaleBar(qt.QWidget):
+ """This class is making the composition of a :class:`_ColorScale` and a
+ :class:`_TickBar`.
+
+ It is the simplest widget displaying ticks and colormap gradient.
+
+ .. image:: img/colorScaleBar.png
+ :width: 150px
+ :align: center
+
+ To run the following sample code, a QApplication must be initialized.
+
+ >>> colormap={'name':'gray',
+ ... 'normalization':'log',
+ ... 'vmin':1,
+ ... 'vmax':100000,
+ ... 'autoscale':False
+ ... }
+ >>> colorscale = ColorScaleBar(parent=None,
+ ... colormap=colormap )
+ >>> colorscale.show()
+
+ Initializer parameters :
+
+ :param colormap: the colormap to be displayed
+ :param parent: the Qt parent if any
+ :param displayTicksValues: display the ticks value or only the '-'
+ """
+
+ _TEXT_MARGIN = 5
+ """The tick bar need a margin to display all labels at the correct place.
+ So the ColorScale should have the same margin in order for both to fit"""
+
+ _MIN_LIM_SCI_FORM = -1000
+ """Used for the min and max label to know when we should display it under
+ the scientific form"""
+
+ _MAX_LIM_SCI_FORM = 1000
+ """Used for the min and max label to know when we should display it under
+ the scientific form"""
+
+ def __init__(self, parent=None, colormap=None, displayTicksValues=True):
+ super(ColorScaleBar, self).__init__(parent)
+
+ self.minVal = None
+ """Value set to the _minLabel"""
+ self.maxVal = None
+ """Value set to the _maxLabel"""
+
+ self.setLayout(qt.QGridLayout())
+
+ # create the left side group (ColorScale)
+ self.colorScale = _ColorScale(colormap=colormap,
+ parent=self,
+ margin=ColorScaleBar._TEXT_MARGIN)
+
+ self.tickbar = _TickBar(vmin=colormap['vmin'] if colormap else 0.0,
+ vmax=colormap['vmax'] if colormap else 1.0,
+ norm=colormap['normalization'] if colormap else 'linear',
+ parent=self,
+ displayValues=displayTicksValues,
+ margin=ColorScaleBar._TEXT_MARGIN)
+
+ self.layout().addWidget(self.tickbar, 1, 0)
+ self.layout().addWidget(self.colorScale, 1, 1)
+
+ self.layout().setContentsMargins(0, 0, 0, 0)
+ self.layout().setSpacing(0)
+
+ # max label
+ self._maxLabel = qt.QLabel(str(1.0), parent=self)
+ self._maxLabel.setAlignment(qt.Qt.AlignHCenter)
+ self._maxLabel.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum)
+ self.layout().addWidget(self._maxLabel, 0, 1)
+
+ # min label
+ self._minLabel = qt.QLabel(str(0.0), parent=self)
+ self._minLabel.setAlignment(qt.Qt.AlignHCenter)
+ self._minLabel.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum)
+ self.layout().addWidget(self._minLabel, 2, 1)
+
+ def getTickBar(self):
+ """
+
+ :return: the instanciation of the :class:`_TickBar`
+ """
+ return self.tickbar
+
+ def getColorScale(self):
+ """
+
+ :return: the instanciation of the :class:`_ColorScale`
+ """
+ return self.colorScale
+
+ def setColormap(self, colormap):
+ """Set the new colormap to be displayed
+
+ :param dict colormap: the colormap to set
+ """
+ if colormap is not None:
+ self.colorScale.setColormap(colormap)
+
+ self.tickbar.update(vmin=colormap['vmin'],
+ vmax=colormap['vmax'],
+ norm=colormap['normalization'])
+
+ self._setMinMaxLabels(colormap['vmin'], colormap['vmax'])
+
+ def setMinMaxVisible(self, val=True):
+ """Change visibility of the min label and the max label
+
+ :param val: if True, set the labels visible, otherwise set it not visible
+ """
+ self._maxLabel.show() if val is True else self._maxLabel.hide()
+ self._minLabel.show() if val is True else self._minLabel.hide()
+
+ def _updateMinMax(self):
+ """Update the min and max label if we are in the case of the
+ configuration 'minMaxValueOnly'"""
+ if self._minLabel is not None and self._maxLabel is not None:
+ if self.minVal is not None:
+ if ColorScaleBar._MIN_LIM_SCI_FORM <= self.minVal <= ColorScaleBar._MAX_LIM_SCI_FORM:
+ self._minLabel.setText(str(self.minVal))
+ else:
+ self._minLabel.setText("{0:.0e}".format(self.minVal))
+ if self.maxVal is not None:
+ if ColorScaleBar._MIN_LIM_SCI_FORM <= self.maxVal <= ColorScaleBar._MAX_LIM_SCI_FORM:
+ self._maxLabel.setText(str(self.maxVal))
+ else:
+ self._maxLabel.setText("{0:.0e}".format(self.maxVal))
+
+ def _setMinMaxLabels(self, minVal, maxVal):
+ """Change the value of the min and max labels to be displayed.
+
+ :param minVal: the minimal value of the TickBar (not str)
+ :param maxVal: the maximal value of the TickBar (not str)
+ """
+ # bad hack to try to display has much information as possible
+ self.minVal = minVal
+ self.maxVal = maxVal
+ self._updateMinMax()
+
+ def resizeEvent(self, event):
+ qt.QWidget.resizeEvent(self, event)
+ self._updateMinMax()
+
+
+class _ColorScale(qt.QWidget):
+ """Widget displaying the colormap colorScale.
+
+ Show matching value between the gradient color (from the colormap) at mouse
+ position and value.
+
+ .. image:: img/colorScale.png
+ :width: 20px
+ :align: center
+
+
+ To run the following sample code, a QApplication must be initialized.
+
+ >>> colormap={'name':'viridis',
+ ... 'normalization':'log',
+ ... 'vmin':1,
+ ... 'vmax':100000,
+ ... 'autoscale':False
+ ... }
+ >>> colorscale = ColorScale(parent=None,
+ ... colormap=colormap)
+ >>> colorscale.show()
+
+ Initializer parameters :
+
+ :param colormap: the colormap to be displayed
+ :param parent: the Qt parent if any
+ :param int margin: the top and left margin to apply.
+
+ .. warning:: Value drawing will be
+ done at the center of ticks. So if no margin is done your values
+ drawing might not be fully done for extrems values.
+ """
+
+ _NB_CONTROL_POINTS = 256
+
+ def __init__(self, colormap, parent=None, margin=5):
+ qt.QWidget.__init__(self, parent)
+ self.colormap = None
+ self.setColormap(colormap)
+
+ self.setLayout(qt.QVBoxLayout())
+ self.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding)
+ # needed to get the mouse event without waiting for button click
+ self.setMouseTracking(True)
+ self.setMargin(margin)
+ self.setContentsMargins(0, 0, 0, 0)
+
+ def setColormap(self, colormap):
+ """Set the new colormap to be displayed
+
+ :param dict colormap: the colormap to set
+ """
+ if colormap is None:
+ return
+
+ if colormap['normalization'] not in ('log', 'linear'):
+ raise ValueError("Unrecognized normalization, should be 'linear' or 'log'")
+
+ if colormap['normalization'] is 'log':
+ if not (colormap['vmin'] > 0 and colormap['vmax'] > 0):
+ raise ValueError('vmin and vmax should be positives')
+ self.colormap = colormap
+ self._computeColorPoints()
+
+ def _computeColorPoints(self):
+ """Compute the color points for the gradient
+ """
+ if self.colormap is None:
+ return
+
+ vmin = self.colormap['vmin']
+ vmax = self.colormap['vmax']
+ steps = (vmax - vmin)/float(_ColorScale._NB_CONTROL_POINTS)
+ self.ctrPoints = numpy.arange(vmin, vmax, steps)
+ self.colorsCtrPts = Colors.applyColormapToData(self.ctrPoints,
+ name=self.colormap['name'],
+ normalization='linear',
+ autoscale=self.colormap['autoscale'],
+ vmin=vmin,
+ vmax=vmax)
+
+ def paintEvent(self, event):
+ """"""
+ qt.QWidget.paintEvent(self, event)
+ if self.colormap is None:
+ return
+
+ vmin = self.colormap['vmin']
+ vmax = self.colormap['vmax']
+
+ painter = qt.QPainter(self)
+ gradient = qt.QLinearGradient(0, 0, 0, self.rect().height() - 2*self.margin)
+ for iPt, pt in enumerate(self.ctrPoints):
+ colormapPosition = 1 - (pt-vmin) / (vmax-vmin)
+ assert(colormapPosition >= 0.0)
+ assert(colormapPosition <= 1.0)
+ gradient.setColorAt(colormapPosition, qt.QColor(*(self.colorsCtrPts[iPt])))
+
+ painter.setBrush(gradient)
+ painter.drawRect(
+ qt.QRect(0, self.margin, self.width(), self.height() - 2.*self.margin))
+
+ def mouseMoveEvent(self, event):
+ """"""
+ self.setToolTip(str(self.getValueFromRelativePosition(self._getRelativePosition(event.y()))))
+ super(_ColorScale, self).mouseMoveEvent(event)
+
+ def _getRelativePosition(self, yPixel):
+ """yPixel : pixel position into _ColorScale widget reference
+ """
+ # widgets are bottom-top referencial but we display in top-bottom referential
+ return 1 - float(yPixel)/float(self.height() - 2*self.margin)
+
+ def getValueFromRelativePosition(self, value):
+ """Return the value in the colorMap from a relative position in the
+ ColorScaleBar (y)
+
+ :param value: float value in [0, 1]
+ :return: the value in [colormap['vmin'], colormap['vmax']]
+ """
+ value = max(0.0, value)
+ value = min(value, 1.0)
+ vmin = self.colormap['vmin']
+ vmax = self.colormap['vmax']
+ if self.colormap['normalization'] is 'linear':
+ return vmin + (vmax - vmin) * value
+ elif self.colormap['normalization'] is 'log':
+ rpos = (numpy.log10(vmax) - numpy.log10(vmin)) * value + numpy.log10(vmin)
+ return numpy.power(10., rpos)
+ else:
+ err = "normalization type (%s) is not managed by the _ColorScale Widget" % self.colormap['normalization']
+ raise ValueError(err)
+
+ def setMargin(self, margin):
+ """Define the margin to fit with a TickBar object.
+ This is needed since we can only paint on the viewport of the widget.
+ Didn't work with a simple setContentsMargins
+
+ :param int margin: the margin to apply on the top and bottom.
+ """
+ self.margin = margin
+
+
+class _TickBar(qt.QWidget):
+ """Bar grouping the ticks displayed
+
+ To run the following sample code, a QApplication must be initialized.
+
+ >>> bar = TickBar(1, 1000, norm='log', parent=None, displayValues=True)
+ >>> bar.show()
+
+ .. image:: img/tickbar.png
+ :width: 40px
+ :align: center
+
+ :param int vmin: smaller value of the range of values
+ :param int vmax: higher value of the range of values
+ :param str norm: normalization type to be displayed. Valid values are
+ 'linear' and 'log'
+ :param parent: the Qt parent if any
+ :param bool displayValues: if True display the values close to the tick,
+ Otherwise only signal it by '-'
+ :param int nticks: the number of tick we want to display. Should be an
+ unsigned int ot None. If None, let the Tick bar find the optimal
+ number of ticks from the tick density.
+ :param int margin: margin to set on the top and bottom
+ """
+ _WIDTH_DISP_VAL = 45
+ """widget width when displayed with ticks labels"""
+ _WIDTH_NO_DISP_VAL = 10
+ """widget width when displayed without ticks labels"""
+ _FONT_SIZE = 10
+ """font size for ticks labels"""
+ _LINE_WIDTH = 10
+ """width of the line to mark a tick"""
+
+ DEFAULT_TICK_DENSITY = 0.015
+
+ def __init__(self, vmin, vmax, norm, parent=None, displayValues=True,
+ nticks=None, margin=5):
+ super(_TickBar, self).__init__(parent)
+ self._forcedDisplayType = None
+ self.ticksDensity = _TickBar.DEFAULT_TICK_DENSITY
+
+ self._vmin = vmin
+ self._vmax = vmax
+ # TODO : should be grouped into a global function, called by all
+ # logScale displayer to make sure we have the same behavior everywhere
+ if self._vmin < 1. or self._vmax < 1.:
+ _logger.warning(
+ 'Log colormap with bound <= 1: changing bounds.')
+ self._vmin, self._vmax = 1., 10.
+
+ self._norm = norm
+ self.displayValues = displayValues
+ self.setTicksNumber(nticks)
+ self.setMargin(margin)
+
+ self.setLayout(qt.QVBoxLayout())
+ self.setMargin(margin)
+ self.setContentsMargins(0, 0, 0, 0)
+
+ self._resetWidth()
+
+ def setTicksValuesVisible(self, val):
+ self.displayValues = val
+ self._resetWidth()
+
+ def _resetWidth(self):
+ self.width = _TickBar._WIDTH_DISP_VAL if self.displayValues else _TickBar._WIDTH_NO_DISP_VAL
+ self.setFixedWidth(self.width)
+
+ def update(self, vmin, vmax, norm):
+ self._vmin = vmin
+ self._vmax = vmax
+ self._norm = norm
+ self.computeTicks()
+ qt.QWidget.update(self)
+
+ def setMargin(self, margin):
+ """Define the margin to fit with a _ColorScale object.
+ This is needed since we can only paint on the viewport of the widget
+
+ :param int margin: the margin to apply on the top and bottom.
+ """
+ self.margin = margin
+
+ def setTicksNumber(self, nticks):
+ """Set the number of ticks to display.
+
+ :param nticks: the number of tick to be display. Should be an
+ unsigned int ot None. If None, let the :class:`_TickBar` find the
+ optimal number of ticks from the tick density.
+ """
+ self._nticks = nticks
+ self.ticks = None
+ self.computeTicks()
+ qt.QWidget.update(self)
+
+ def setTicksDensity(self, density):
+ """If you let :class:`_TickBar` deal with the number of ticks
+ (nticks=None) then you can specify a ticks density to be displayed.
+ """
+ if density < 0.0:
+ raise ValueError('Density should be a positive value')
+ self.ticksDensity = density
+
+ def computeTicks(self):
+ """This function compute ticks values labels. It is called at each
+ update and each resize event.
+ Deal only with linear and log scale.
+ """
+ nticks = self._nticks
+ if nticks is None:
+ nticks = self._getOptimalNbTicks()
+
+ if self._norm == 'log':
+ self._computeTicksLog(nticks)
+ elif self._norm == 'linear':
+ self._computeTicksLin(nticks)
+ else:
+ err = 'TickBar - Wrong normalization %s' % self._norm
+ raise ValueError(err)
+ # update the form
+ font = qt.QFont()
+ font.setPixelSize(_TickBar._FONT_SIZE)
+
+ self.form = self._getFormat(font)
+
+ def _computeTicksLog(self, nticks):
+ logMin = numpy.log10(self._vmin)
+ logMax = numpy.log10(self._vmax)
+ lowBound, highBound, spacing, self._nfrac = ticklayout.niceNumbersForLog10(logMin,
+ logMax,
+ nticks)
+ self.ticks = numpy.power(10., numpy.arange(lowBound, highBound, spacing))
+ if spacing == 1:
+ self.subTicks = ticklayout.computeLogSubTicks(ticks=self.ticks,
+ lowBound=numpy.power(10., lowBound),
+ highBound=numpy.power(10., highBound))
+ else:
+ self.subTicks = []
+
+ def resizeEvent(self, event):
+ qt.QWidget.resizeEvent(self, event)
+ self.computeTicks()
+
+ def _computeTicksLin(self, nticks):
+ _min, _max, _spacing, self._nfrac = ticklayout.niceNumbers(self._vmin,
+ self._vmax,
+ nticks)
+
+ self.ticks = numpy.arange(_min, _max, _spacing)
+ self.subTicks = []
+
+ def _getOptimalNbTicks(self):
+ return max(2, int(round(self.ticksDensity * self.rect().height())))
+
+ def paintEvent(self, event):
+ painter = qt.QPainter(self)
+ font = painter.font()
+ font.setPixelSize(_TickBar._FONT_SIZE)
+ painter.setFont(font)
+
+ # paint ticks
+ if self.ticks is not None:
+ for val in self.ticks:
+ self._paintTick(val, painter, majorTick=True)
+
+ # paint subticks
+ for val in self.subTicks:
+ self._paintTick(val, painter, majorTick=False)
+
+ qt.QWidget.paintEvent(self, event)
+
+ def _getRelativePosition(self, val):
+ """Return the relative position of val according to min and max value
+ """
+ if self._norm == 'linear':
+ return 1 - (val - self._vmin) / (self._vmax - self._vmin)
+ elif self._norm == 'log':
+ return 1 - (numpy.log10(val) - numpy.log10(self._vmin))/(numpy.log10(self._vmax) - numpy.log(self._vmin))
+ else:
+ raise ValueError('Norm is not recognized')
+
+ def _paintTick(self, val, painter, majorTick=True):
+ """
+
+ :param bool majorTick: if False will never draw text and will set a line
+ with a smaller width
+ """
+ fm = qt.QFontMetrics(painter.font())
+ viewportHeight = self.rect().height() - self.margin * 2
+ relativePos = self._getRelativePosition(val)
+ height = viewportHeight * relativePos
+ height += self.margin
+ lineWidth = _TickBar._LINE_WIDTH
+ if majorTick is False:
+ lineWidth /= 2
+
+ painter.drawLine(qt.QLine(self.width - lineWidth,
+ height,
+ self.width,
+ height))
+
+ if self.displayValues and majorTick is True:
+ painter.drawText(qt.QPoint(0.0, height + (fm.height() / 2)),
+ self.form.format(val))
+
+ def setDisplayType(self, disType):
+ """Set the type of display we want to set for ticks labels
+
+ :param str disType: The type of display we want to set. disType values
+ can be :
+
+ - 'std' for standard, meaning only a formatting on the number of
+ digits is done
+ - 'e' for scientific display
+ - None to let the _TickBar guess the best display for this kind of data.
+ """
+ if disType not in (None, 'std', 'e'):
+ raise ValueError("display type not recognized, value should be in (None, 'std', 'e'")
+ self._forcedDisplayType = disType
+
+ def _getStandardFormat(self):
+ return "{0:.%sf}" % self._nfrac
+
+ def _getFormat(self, font):
+ if self._forcedDisplayType is None:
+ return self._guessType(font)
+ elif self._forcedDisplayType is 'std':
+ return self._getStandardFormat()
+ elif self._forcedDisplayType is 'e':
+ return self._getScientificForm()
+ else:
+ err = 'Forced type for display %s is not recognized' % self._forcedDisplayType
+ raise ValueError(err)
+
+ def _getScientificForm(self):
+ return "{0:.0e}"
+
+ def _guessType(self, font):
+ """Try fo find the better format to display the tick's labels
+
+ :param QFont font: the font we want want to use durint the painting
+ """
+ assert(type(self._vmin) == type(self._vmax))
+ form = self._getStandardFormat()
+
+ fm = qt.QFontMetrics(font)
+ width = 0
+ for tick in self.ticks:
+ width = max(fm.width(form.format(tick)), width)
+
+ # if the length of the string are too long we are mooving to scientific
+ # display
+ if width > _TickBar._WIDTH_DISP_VAL - _TickBar._LINE_WIDTH:
+ return self._getScientificForm()
+ else:
+ return form
diff --git a/silx/gui/plot/ColormapDialog.py b/silx/gui/plot/ColormapDialog.py
new file mode 100644
index 0000000..ad1425c
--- /dev/null
+++ b/silx/gui/plot/ColormapDialog.py
@@ -0,0 +1,506 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+# ###########################################################################*/
+"""A QDialog widget to set-up the colormap.
+
+It uses a description of colormaps as dict compatible with :class:`Plot`.
+
+To run the following sample code, a QApplication must be initialized.
+
+Create the colormap dialog and set the colormap description and data range:
+
+>>> from silx.gui.plot.ColormapDialog import ColormapDialog
+
+>>> dialog = ColormapDialog()
+
+>>> dialog.setColormap(name='red', normalization='log',
+... autoscale=False, vmin=1., vmax=2.)
+>>> dialog.setDataRange(1., 100.) # This scale the width of the plot area
+>>> dialog.show()
+
+Get the colormap description (compatible with :class:`Plot`) from the dialog:
+
+>>> cmap = dialog.getColormap()
+>>> cmap['name']
+'red'
+
+It is also possible to display an histogram of the image in the dialog.
+This updates the data range with the range of the bins.
+
+>>> import numpy
+>>> image = numpy.random.normal(size=512 * 512).reshape(512, -1)
+>>> hist, bin_edges = numpy.histogram(image, bins=10)
+>>> dialog.setHistogram(hist, bin_edges)
+
+The updates of the colormap description are also available through the signal:
+:attr:`ColormapDialog.sigColormapChanged`.
+""" # noqa
+
+from __future__ import division
+
+__authors__ = ["V.A. Sole", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "29/03/2016"
+
+
+import logging
+
+import numpy
+
+from .. import qt
+from . import PlotWidget
+
+
+_logger = logging.getLogger(__name__)
+
+
+class _FloatEdit(qt.QLineEdit):
+ """Field to edit a float value.
+
+ :param parent: See :class:`QLineEdit`
+ :param float value: The value to set the QLineEdit to.
+ """
+ def __init__(self, parent=None, value=None):
+ qt.QLineEdit.__init__(self, parent)
+ self.setValidator(qt.QDoubleValidator())
+ self.setAlignment(qt.Qt.AlignRight)
+ if value is not None:
+ self.setValue(value)
+
+ def value(self):
+ """Return the QLineEdit current value as a float."""
+ return float(self.text())
+
+ def setValue(self, value):
+ """Set the current value of the LineEdit
+
+ :param float value: The value to set the QLineEdit to.
+ """
+ self.setText('%g' % value)
+
+
+class ColormapDialog(qt.QDialog):
+ """A QDialog widget to set the colormap.
+
+ :param parent: See :class:`QDialog`
+ :param str title: The QDialog title
+ """
+
+ sigColormapChanged = qt.Signal(dict)
+ """Signal triggered when the colormap is changed.
+
+ It provides a dict describing the colormap to the slot.
+ This dict can be used with :class:`Plot`.
+ """
+
+ def __init__(self, parent=None, title="Colormap Dialog"):
+ qt.QDialog.__init__(self, parent)
+ self.setWindowTitle(title)
+
+ self._histogramData = None
+ self._dataRange = None
+ self._minMaxWasEdited = False
+
+ self._colormapList = (
+ 'gray', 'reversed gray',
+ 'temperature', 'red', 'green', 'blue', 'jet',
+ 'viridis', 'magma', 'inferno', 'plasma')
+
+ # Make the GUI
+ vLayout = qt.QVBoxLayout(self)
+
+ formWidget = qt.QWidget()
+ vLayout.addWidget(formWidget)
+ formLayout = qt.QFormLayout(formWidget)
+ formLayout.setContentsMargins(10, 10, 10, 10)
+ formLayout.setSpacing(0)
+
+ # Colormap row
+ self._comboBoxColormap = qt.QComboBox()
+ for cmap in self._colormapList:
+ # Capitalize first letters
+ cmap = ' '.join(w[0].upper() + w[1:] for w in cmap.split())
+ self._comboBoxColormap.addItem(cmap)
+ self._comboBoxColormap.activated[int].connect(self._notify)
+ formLayout.addRow('Colormap:', self._comboBoxColormap)
+
+ # Normalization row
+ self._normButtonLinear = qt.QRadioButton('Linear')
+ self._normButtonLinear.setChecked(True)
+ self._normButtonLog = qt.QRadioButton('Log')
+
+ normButtonGroup = qt.QButtonGroup(self)
+ normButtonGroup.setExclusive(True)
+ normButtonGroup.addButton(self._normButtonLinear)
+ normButtonGroup.addButton(self._normButtonLog)
+ normButtonGroup.buttonClicked[int].connect(self._notify)
+
+ normLayout = qt.QHBoxLayout()
+ normLayout.setContentsMargins(0, 0, 0, 0)
+ normLayout.setSpacing(10)
+ normLayout.addWidget(self._normButtonLinear)
+ normLayout.addWidget(self._normButtonLog)
+
+ formLayout.addRow('Normalization:', normLayout)
+
+ # Range row
+ self._rangeAutoscaleButton = qt.QCheckBox('Autoscale')
+ self._rangeAutoscaleButton.setChecked(True)
+ self._rangeAutoscaleButton.toggled.connect(self._autoscaleToggled)
+ self._rangeAutoscaleButton.clicked.connect(self._notify)
+ formLayout.addRow('Range:', self._rangeAutoscaleButton)
+
+ # Min row
+ self._minValue = _FloatEdit(value=1.)
+ self._minValue.setEnabled(False)
+ self._minValue.textEdited.connect(self._minMaxTextEdited)
+ self._minValue.editingFinished.connect(self._minEditingFinished)
+ formLayout.addRow('\tMin:', self._minValue)
+
+ # Max row
+ self._maxValue = _FloatEdit(value=10.)
+ self._maxValue.setEnabled(False)
+ self._maxValue.textEdited.connect(self._minMaxTextEdited)
+ self._maxValue.editingFinished.connect(self._maxEditingFinished)
+ formLayout.addRow('\tMax:', self._maxValue)
+
+ # Add plot for histogram
+ self._plotInit()
+ vLayout.addWidget(self._plot)
+
+ # Close button
+ buttonsWidget = qt.QWidget()
+ vLayout.addWidget(buttonsWidget)
+
+ buttonsLayout = qt.QHBoxLayout(buttonsWidget)
+
+ okButton = qt.QPushButton('OK')
+ okButton.clicked.connect(self.accept)
+ buttonsLayout.addWidget(okButton)
+
+ cancelButton = qt.QPushButton('Cancel')
+ cancelButton.clicked.connect(self.reject)
+ buttonsLayout.addWidget(cancelButton)
+
+ # colormap window can not be resized
+ self.setFixedSize(vLayout.minimumSize())
+
+ # Set the colormap to default values
+ self.setColormap(name='gray', normalization='linear',
+ autoscale=True, vmin=1., vmax=10.)
+
+ def _plotInit(self):
+ """Init the plot to display the range and the values"""
+ self._plot = PlotWidget()
+ self._plot.setDataMargins(yMinMargin=0.125, yMaxMargin=0.125)
+ self._plot.setGraphXLabel("Data Values")
+ self._plot.setGraphYLabel("")
+ self._plot.setInteractiveMode('select', zoomOnWheel=False)
+ self._plot.setActiveCurveHandling(False)
+ self._plot.setMinimumSize(qt.QSize(250, 200))
+ self._plot.sigPlotSignal.connect(self._plotSlot)
+ self._plot.hide()
+
+ self._plotUpdate()
+
+ def _plotUpdate(self, updateMarkers=True):
+ """Update the plot content
+
+ :param bool updateMarkers: True to update markers, False otherwith
+ """
+ dataRange = self.getDataRange()
+
+ if dataRange is None:
+ if self._plot.isVisibleTo(self):
+ self._plot.setVisible(False)
+ self.setFixedSize(self.layout().minimumSize())
+ return
+
+ if not self._plot.isVisibleTo(self):
+ self._plot.setVisible(True)
+ self.setFixedSize(self.layout().minimumSize())
+
+ dataMin, dataMax = dataRange
+ marge = (abs(dataMax) + abs(dataMin)) / 6.0
+ minmd = dataMin - marge
+ maxpd = dataMax + marge
+
+ start, end = self._minValue.value(), self._maxValue.value()
+
+ if start <= end:
+ x = [minmd, start, end, maxpd]
+ y = [0, 0, 1, 1]
+
+ else:
+ x = [minmd, end, start, maxpd]
+ y = [1, 1, 0, 0]
+
+ # Display the colormap on the side
+ # colormap = {'name': self.getColormap()['name'],
+ # 'normalization': self.getColormap()['normalization'],
+ # 'autoscale': True, 'vmin': 1., 'vmax': 256.}
+ # self._plot.addImage((1 + numpy.arange(256)).reshape(256, -1),
+ # xScale=(minmd - marge, marge),
+ # yScale=(1., 2./256.),
+ # legend='colormap',
+ # colormap=colormap)
+
+ self._plot.addCurve(x, y,
+ legend="ConstrainedCurve",
+ color='black',
+ symbol='o',
+ linestyle='-',
+ resetzoom=False)
+
+ draggable = not self._rangeAutoscaleButton.isChecked()
+
+ if updateMarkers:
+ self._plot.addXMarker(
+ self._minValue.value(),
+ legend='Min',
+ text='Min',
+ draggable=draggable,
+ color='blue',
+ constraint=self._plotMinMarkerConstraint)
+
+ self._plot.addXMarker(
+ self._maxValue.value(),
+ legend='Max',
+ text='Max',
+ draggable=draggable,
+ color='blue',
+ constraint=self._plotMaxMarkerConstraint)
+
+ self._plot.resetZoom()
+
+ def _plotMinMarkerConstraint(self, x, y):
+ """Constraint of the min marker"""
+ return min(x, self._maxValue.value()), y
+
+ def _plotMaxMarkerConstraint(self, x, y):
+ """Constraint of the max marker"""
+ return max(x, self._minValue.value()), y
+
+ def _plotSlot(self, event):
+ """Handle events from the plot"""
+ if event['event'] in ('markerMoving', 'markerMoved'):
+ value = float(str(event['xdata']))
+ if event['label'] == 'Min':
+ self._minValue.setValue(value)
+ elif event['label'] == 'Max':
+ self._maxValue.setValue(value)
+
+ # This will recreate the markers while interacting...
+ # It might break if marker interaction is changed
+ if event['event'] == 'markerMoved':
+ self._notify()
+ else:
+ self._plotUpdate(updateMarkers=False)
+
+ def getHistogram(self):
+ """Returns the counts and bin edges of the displayed histogram.
+
+ :return: (hist, bin_edges)
+ :rtype: 2-tuple of numpy arrays"""
+ if self._histogramData is None:
+ return None
+ else:
+ bins, counts = self._histogramData
+ return numpy.array(bins, copy=True), numpy.array(counts, copy=True)
+
+ def setHistogram(self, hist=None, bin_edges=None):
+ """Set the histogram to display.
+
+ This update the data range with the bounds of the bins.
+ See :meth:`setDataRange`.
+
+ :param hist: array-like of counts or None to hide histogram
+ :param bin_edges: array-like of bins edges or None to hide histogram
+ """
+ if hist is None or bin_edges is None:
+ self._histogramData = None
+ self._plot.remove(legend='Histogram', kind='curve')
+ self.setDataRange() # Remove data range
+
+ else:
+ hist = numpy.array(hist, copy=True)
+ bin_edges = numpy.array(bin_edges, copy=True)
+ self._histogramData = hist, bin_edges
+
+ # For now, draw the histogram as a curve
+ # using bin centers and normalised counts
+ bins_center = 0.5 * (bin_edges[:-1] + bin_edges[1:])
+ norm_hist = hist / max(hist)
+ self._plot.addCurve(bins_center, norm_hist,
+ legend="Histogram",
+ color='gray',
+ symbol='',
+ linestyle='-',
+ fill=True)
+
+ # Update the data range
+ self.setDataRange(bin_edges[0], bin_edges[-1])
+
+ def getDataRange(self):
+ """Returns the data range used for the histogram area.
+
+ :return: (dataMin, dataMax) or None if no data range is set
+ :rtype: 2-tuple of float
+ """
+ return self._dataRange
+
+ def setDataRange(self, min_=None, max_=None):
+ """Set the range of data to use for the range of the histogram area.
+
+ :param float min_: The min of the data or None to disable range.
+ :param float max_: The max of the data or None to disable range.
+ """
+ if min_ is None or max_ is None:
+ self._dataRange = None
+ self._plotUpdate()
+
+ else:
+ min_, max_ = float(min_), float(max_)
+ assert min_ <= max_
+ self._dataRange = min_, max_
+ if self._rangeAutoscaleButton.isChecked():
+ self._minValue.setValue(min_)
+ self._maxValue.setValue(max_)
+ self._notify()
+ else:
+ self._plotUpdate()
+
+ def getColormap(self):
+ """Return the colormap description as a dict.
+
+ See :class:`Plot` for documentation on the colormap dict.
+ """
+ isNormLinear = self._normButtonLinear.isChecked()
+ colormap = {
+ 'name': str(self._comboBoxColormap.currentText()).lower(),
+ 'normalization': 'linear' if isNormLinear else 'log',
+ 'autoscale': self._rangeAutoscaleButton.isChecked(),
+ 'vmin': self._minValue.value(),
+ 'vmax': self._maxValue.value()}
+ return colormap
+
+ def setColormap(self, name=None, normalization=None,
+ autoscale=None, vmin=None, vmax=None, colors=None):
+ """Set the colormap description
+
+ If some arguments are not provided, the current values are used.
+
+ :param str name: The name of the colormap
+ :param str normalization: 'linear' or 'log'
+ :param bool autoscale: Toggle colormap range autoscale
+ :param float vmin: The min value, ignored if autoscale is True
+ :param float vmax: The max value, ignored if autoscale is True
+ """
+ if name is not None:
+ assert name in self._colormapList
+ index = self._colormapList.index(name)
+ self._comboBoxColormap.setCurrentIndex(index)
+
+ if normalization is not None:
+ assert normalization in ('linear', 'log')
+ self._normButtonLinear.setChecked(normalization == 'linear')
+ self._normButtonLog.setChecked(normalization == 'log')
+
+ if vmin is not None:
+ self._minValue.setValue(vmin)
+
+ if vmax is not None:
+ self._maxValue.setValue(vmax)
+
+ if autoscale is not None:
+ self._rangeAutoscaleButton.setChecked(autoscale)
+ if autoscale:
+ dataRange = self.getDataRange()
+ if dataRange is not None:
+ self._minValue.setValue(dataRange[0])
+ self._maxValue.setValue(dataRange[1])
+
+ # Do it once for all the changes
+ self._notify()
+
+ def _notify(self, *args, **kwargs):
+ """Emit the signal for colormap change"""
+ self._plotUpdate()
+ self.sigColormapChanged.emit(self.getColormap())
+
+ def _autoscaleToggled(self, checked):
+ """Handle autoscale changes by enabling/disabling min/max fields"""
+ self._minValue.setEnabled(not checked)
+ self._maxValue.setEnabled(not checked)
+ if checked:
+ dataRange = self.getDataRange()
+ if dataRange is not None:
+ self._minValue.setValue(dataRange[0])
+ self._maxValue.setValue(dataRange[1])
+
+ def _minMaxTextEdited(self, text):
+ """Handle _minValue and _maxValue textEdited signal"""
+ self._minMaxWasEdited = True
+
+ def _minEditingFinished(self):
+ """Handle _minValue editingFinished signal
+
+ Together with :meth:`_minMaxTextEdited`, this avoids to notify
+ colormap change when the min and max value where not edited.
+ """
+ if self._minMaxWasEdited:
+ self._minMaxWasEdited = False
+
+ # Fix start value
+ if self._minValue.value() > self._maxValue.value():
+ self._minValue.setValue(self._maxValue.value())
+ self._notify()
+
+ def _maxEditingFinished(self):
+ """Handle _maxValue editingFinished signal
+
+ Together with :meth:`_minMaxTextEdited`, this avoids to notify
+ colormap change when the min and max value where not edited.
+ """
+ if self._minMaxWasEdited:
+ self._minMaxWasEdited = False
+
+ # Fix end value
+ if self._minValue.value() > self._maxValue.value():
+ self._maxValue.setValue(self._minValue.value())
+ self._notify()
+
+ def keyPressEvent(self, event):
+ """Override key handling.
+
+ It disables leaving the dialog when editing a text field.
+ """
+ if event.key() == qt.Qt.Key_Enter and (self._minValue.hasFocus() or
+ self._maxValue.hasFocus()):
+ # Bypass QDialog keyPressEvent
+ # To avoid leaving the dialog when pressing enter on a text field
+ super(qt.QDialog, self).keyPressEvent(event)
+ else:
+ # Use QDialog keyPressEvent
+ super(ColormapDialog, self).keyPressEvent(event)
diff --git a/silx/gui/plot/Colors.py b/silx/gui/plot/Colors.py
new file mode 100644
index 0000000..7a3cd97
--- /dev/null
+++ b/silx/gui/plot/Colors.py
@@ -0,0 +1,359 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Color conversion function, color dictionary and colormap tools."""
+
+__authors__ = ["V.A. Sole", "T. VINCENT"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+
+import logging
+
+import numpy
+
+import matplotlib
+import matplotlib.colors
+import matplotlib.cm
+
+from . import MPLColormap
+
+
+_logger = logging.getLogger(__name__)
+
+
+COLORDICT = {}
+"""Dictionary of common colors."""
+
+COLORDICT['b'] = COLORDICT['blue'] = '#0000ff'
+COLORDICT['r'] = COLORDICT['red'] = '#ff0000'
+COLORDICT['g'] = COLORDICT['green'] = '#00ff00'
+COLORDICT['k'] = COLORDICT['black'] = '#000000'
+COLORDICT['w'] = COLORDICT['white'] = '#ffffff'
+COLORDICT['pink'] = '#ff66ff'
+COLORDICT['brown'] = '#a52a2a'
+COLORDICT['orange'] = '#ff9900'
+COLORDICT['violet'] = '#6600ff'
+COLORDICT['gray'] = COLORDICT['grey'] = '#a0a0a4'
+# COLORDICT['darkGray'] = COLORDICT['darkGrey'] = '#808080'
+# COLORDICT['lightGray'] = COLORDICT['lightGrey'] = '#c0c0c0'
+COLORDICT['y'] = COLORDICT['yellow'] = '#ffff00'
+COLORDICT['m'] = COLORDICT['magenta'] = '#ff00ff'
+COLORDICT['c'] = COLORDICT['cyan'] = '#00ffff'
+COLORDICT['darkBlue'] = '#000080'
+COLORDICT['darkRed'] = '#800000'
+COLORDICT['darkGreen'] = '#008000'
+COLORDICT['darkBrown'] = '#660000'
+COLORDICT['darkCyan'] = '#008080'
+COLORDICT['darkYellow'] = '#808000'
+COLORDICT['darkMagenta'] = '#800080'
+
+
+def rgba(color, colorDict=None):
+ """Convert color code '#RRGGBB' and '#RRGGBBAA' to (R, G, B, A)
+
+ It also convert RGB(A) values from uint8 to float in [0, 1] and
+ accept a QColor as color argument.
+
+ :param str color: The color to convert
+ :param dict colorDict: A dictionary of color name conversion to color code
+ :returns: RGBA colors as floats in [0., 1.]
+ :rtype: tuple
+ """
+ if colorDict is None:
+ colorDict = COLORDICT
+
+ if hasattr(color, 'getRgbF'): # QColor support
+ color = color.getRgbF()
+
+ values = numpy.asarray(color).ravel()
+
+ if values.dtype.kind in 'iuf': # integer or float
+ # Color is an array
+ assert len(values) in (3, 4)
+
+ # Convert from integers in [0, 255] to float in [0, 1]
+ if values.dtype.kind in 'iu':
+ values = values / 255.
+
+ # Clip to [0, 1]
+ values[values < 0.] = 0.
+ values[values > 1.] = 1.
+
+ if len(values) == 3:
+ return values[0], values[1], values[2], 1.
+ else:
+ return tuple(values)
+
+ # We assume color is a string
+ if not color.startswith('#'):
+ color = colorDict[color]
+
+ assert len(color) in (7, 9) and color[0] == '#'
+ r = int(color[1:3], 16) / 255.
+ g = int(color[3:5], 16) / 255.
+ b = int(color[5:7], 16) / 255.
+ a = int(color[7:9], 16) / 255. if len(color) == 9 else 1.
+ return r, g, b, a
+
+
+_COLORMAP_CURSOR_COLORS = {
+ 'gray': 'pink',
+ 'reversed gray': 'pink',
+ 'temperature': 'pink',
+ 'red': 'green',
+ 'green': 'pink',
+ 'blue': 'yellow',
+ 'jet': 'pink',
+ 'viridis': 'pink',
+ 'magma': 'green',
+ 'inferno': 'green',
+ 'plasma': 'green',
+}
+
+
+def cursorColorForColormap(colormapName):
+ """Get a color suitable for overlay over a colormap.
+
+ :param str colormapName: The name of the colormap.
+ :return: Name of the color.
+ :rtype: str
+ """
+ return _COLORMAP_CURSOR_COLORS.get(colormapName, 'black')
+
+
+_CMAPS = {} # Store additional colormaps
+
+
+def getMPLColormap(name):
+ """Returns matplotlib colormap corresponding to given name
+
+ :param str name: The name of the colormap
+ :return: The corresponding colormap
+ :rtype: matplolib.colors.Colormap
+ """
+ if not _CMAPS: # Lazy initialization of own colormaps
+ cdict = {'red': ((0.0, 0.0, 0.0),
+ (1.0, 1.0, 1.0)),
+ 'green': ((0.0, 0.0, 0.0),
+ (1.0, 0.0, 0.0)),
+ 'blue': ((0.0, 0.0, 0.0),
+ (1.0, 0.0, 0.0))}
+ _CMAPS['red'] = matplotlib.colors.LinearSegmentedColormap(
+ 'red', cdict, 256)
+
+ cdict = {'red': ((0.0, 0.0, 0.0),
+ (1.0, 0.0, 0.0)),
+ 'green': ((0.0, 0.0, 0.0),
+ (1.0, 1.0, 1.0)),
+ 'blue': ((0.0, 0.0, 0.0),
+ (1.0, 0.0, 0.0))}
+ _CMAPS['green'] = matplotlib.colors.LinearSegmentedColormap(
+ 'green', cdict, 256)
+
+ cdict = {'red': ((0.0, 0.0, 0.0),
+ (1.0, 0.0, 0.0)),
+ 'green': ((0.0, 0.0, 0.0),
+ (1.0, 0.0, 0.0)),
+ 'blue': ((0.0, 0.0, 0.0),
+ (1.0, 1.0, 1.0))}
+ _CMAPS['blue'] = matplotlib.colors.LinearSegmentedColormap(
+ 'blue', cdict, 256)
+
+ # Temperature as defined in spslut
+ cdict = {'red': ((0.0, 0.0, 0.0),
+ (0.5, 0.0, 0.0),
+ (0.75, 1.0, 1.0),
+ (1.0, 1.0, 1.0)),
+ 'green': ((0.0, 0.0, 0.0),
+ (0.25, 1.0, 1.0),
+ (0.75, 1.0, 1.0),
+ (1.0, 0.0, 0.0)),
+ 'blue': ((0.0, 1.0, 1.0),
+ (0.25, 1.0, 1.0),
+ (0.5, 0.0, 0.0),
+ (1.0, 0.0, 0.0))}
+ # but limited to 256 colors for a faster display (of the colorbar)
+ _CMAPS['temperature'] = \
+ matplotlib.colors.LinearSegmentedColormap(
+ 'temperature', cdict, 256)
+
+ # reversed gray
+ cdict = {'red': ((0.0, 1.0, 1.0),
+ (1.0, 0.0, 0.0)),
+ 'green': ((0.0, 1.0, 1.0),
+ (1.0, 0.0, 0.0)),
+ 'blue': ((0.0, 1.0, 1.0),
+ (1.0, 0.0, 0.0))}
+
+ _CMAPS['reversed gray'] = \
+ matplotlib.colors.LinearSegmentedColormap(
+ 'yerg', cdict, 256)
+
+ if name in _CMAPS:
+ return _CMAPS[name]
+ elif hasattr(MPLColormap, name): # viridis and sister colormaps
+ return getattr(MPLColormap, name)
+ else:
+ # matplotlib built-in
+ return matplotlib.cm.get_cmap(name)
+
+
+def getMPLScalarMappable(colormap, data=None):
+ """Returns matplotlib ScalarMappable corresponding to colormap
+
+ :param dict colormap: The colormap to convert
+ :param numpy.ndarray data:
+ The data on which the colormap is applied.
+ If provided, it is used to compute autoscale.
+ :return: matplotlib object corresponding to colormap
+ :rtype: matplotlib.cm.ScalarMappable
+ """
+ assert colormap is not None
+
+ if colormap['name'] is not None:
+ cmap = getMPLColormap(colormap['name'])
+
+ else: # No name, use custom colors
+ if 'colors' not in colormap:
+ raise ValueError(
+ 'addImage: colormap no name nor list of colors.')
+ colors = numpy.array(colormap['colors'], copy=True)
+ assert len(colors.shape) == 2
+ assert colors.shape[-1] in (3, 4)
+ if colors.dtype == numpy.uint8:
+ # Convert to float in [0., 1.]
+ colors = colors.astype(numpy.float32) / 255.
+ cmap = matplotlib.colors.ListedColormap(colors)
+
+ if colormap['normalization'].startswith('log'):
+ vmin, vmax = None, None
+ if not colormap['autoscale']:
+ if colormap['vmin'] > 0.:
+ vmin = colormap['vmin']
+ if colormap['vmax'] > 0.:
+ vmax = colormap['vmax']
+
+ if vmin is None or vmax is None:
+ _logger.warning('Log colormap with negative bounds, ' +
+ 'changing bounds to positive ones.')
+ elif vmin > vmax:
+ _logger.warning('Colormap bounds are inverted.')
+ vmin, vmax = vmax, vmin
+
+ # Set unset/negative bounds to positive bounds
+ if (vmin is None or vmax is None) and data is not None:
+ finiteData = data[numpy.isfinite(data)]
+ posData = finiteData[finiteData > 0]
+ if vmax is None:
+ # 1. as an ultimate fallback
+ vmax = posData.max() if posData.size > 0 else 1.
+ if vmin is None:
+ vmin = posData.min() if posData.size > 0 else vmax
+ if vmin > vmax:
+ vmin = vmax
+
+ norm = matplotlib.colors.LogNorm(vmin, vmax)
+
+ else: # Linear normalization
+ if colormap['autoscale']:
+ if data is None:
+ vmin, vmax = None, None
+ else:
+ finiteData = data[numpy.isfinite(data)]
+ vmin = finiteData.min()
+ vmax = finiteData.max()
+ else:
+ vmin = colormap['vmin']
+ vmax = colormap['vmax']
+ if vmin > vmax:
+ _logger.warning('Colormap bounds are inverted.')
+ vmin, vmax = vmax, vmin
+
+ norm = matplotlib.colors.Normalize(vmin, vmax)
+
+ return matplotlib.cm.ScalarMappable(norm=norm, cmap=cmap)
+
+
+def applyColormapToData(data,
+ name='gray',
+ normalization='linear',
+ autoscale=True,
+ vmin=0.,
+ vmax=1.,
+ colors=None):
+ """Apply a colormap to the data and returns the RGBA image
+
+ This supports data of any dimensions (not only of dimension 2).
+ The returned array will have one more dimension (with 4 entries)
+ than the input data to store the RGBA channels
+ corresponding to each bin in the array.
+
+ :param numpy.ndarray data: The data to convert.
+ :param str name: Name of the colormap (default: 'gray').
+ :param str normalization: Colormap mapping: 'linear' or 'log'.
+ :param bool autoscale: Whether to use data min/max (True, default)
+ or [vmin, vmax] range (False).
+ :param float vmin: The minimum value of the range to use if
+ 'autoscale' is False.
+ :param float vmax: The maximum value of the range to use if
+ 'autoscale' is False.
+ :param numpy.ndarray colors: Only used if name is None.
+ Custom colormap colors as Nx3 or Nx4 RGB or RGBA arrays
+ :return: The computed RGBA image
+ :rtype: numpy.ndarray of uint8
+ """
+ # Debian 7 specific support
+ # No transparent colormap with matplotlib < 1.2.0
+ # Add support for transparent colormap for uint8 data with
+ # colormap with 256 colors, linear norm, [0, 255] range
+ if matplotlib.__version__ < '1.2.0':
+ if name is None and colors is not None:
+ colors = numpy.array(colors, copy=False)
+ if (colors.shape[-1] == 4 and
+ not numpy.all(numpy.equal(colors[3], 255))):
+ # This is a transparent colormap
+ if (colors.shape == (256, 4) and
+ normalization == 'linear' and
+ not autoscale and
+ vmin == 0 and vmax == 255 and
+ data.dtype == numpy.uint8):
+ # Supported case, convert data to RGBA
+ return colors[data.reshape(-1)].reshape(
+ data.shape + (4,))
+ else:
+ _logger.warning(
+ 'matplotlib %s does not support transparent '
+ 'colormap.', matplotlib.__version__)
+
+ colormap = dict(name=name,
+ normalization=normalization,
+ autoscale=autoscale,
+ vmin=vmin,
+ vmax=vmax,
+ colors=colors)
+ scalarMappable = getMPLScalarMappable(colormap, data)
+ rgbaImage = scalarMappable.to_rgba(data, bytes=True)
+
+ return rgbaImage
diff --git a/silx/gui/plot/CurvesROIWidget.py b/silx/gui/plot/CurvesROIWidget.py
new file mode 100644
index 0000000..13c3de0
--- /dev/null
+++ b/silx/gui/plot/CurvesROIWidget.py
@@ -0,0 +1,975 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Widget to handle regions of interest (ROI) on curves displayed in a PlotWindow.
+
+This widget is meant to work with :class:`PlotWindow`.
+
+ROI are defined by :
+
+- A name (`ROI` column)
+- A type. The type is the label of the x axis.
+ This can be used to apply or not some ROI to a curve and do some post processing.
+- The x coordinate of the left limit (`from` column)
+- The x coordinate of the right limit (`to` column)
+- Raw counts: integral of the curve between the
+ min ROI point and the max ROI point to the y = 0 line
+
+ .. image:: img/rawCounts.png
+
+- Net counts: the integral of the curve between the
+ min ROI point and the max ROI point to [ROI min point, ROI max point] segment
+
+ .. image:: img/netCounts.png
+"""
+
+__authors__ = ["V.A. Sole", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+from collections import OrderedDict
+
+import logging
+import os
+import sys
+
+import numpy
+
+from silx.io import dictdump
+from .. import icons, qt
+
+
+_logger = logging.getLogger(__name__)
+
+
+class CurvesROIWidget(qt.QWidget):
+ """Widget displaying a table of ROI information.
+
+ :param parent: See :class:`QWidget`
+ :param str name: The title of this widget
+ """
+
+ sigROIWidgetSignal = qt.Signal(object)
+ """Signal of ROIs modifications.
+
+ Modification information if given as a dict with an 'event' key
+ providing the type of events.
+
+ Type of events:
+
+ - AddROI, DelROI, LoadROI and ResetROI with keys: 'roilist', 'roidict'
+
+ - selectionChanged with keys: 'row', 'col' 'roi', 'key', 'colheader',
+ 'rowheader'
+ """
+
+ def __init__(self, parent=None, name=None):
+ super(CurvesROIWidget, self).__init__(parent)
+ if name is not None:
+ self.setWindowTitle(name)
+ layout = qt.QVBoxLayout(self)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setSpacing(0)
+ ##############
+ self.headerLabel = qt.QLabel(self)
+ self.headerLabel.setAlignment(qt.Qt.AlignHCenter)
+ self.setHeader()
+ layout.addWidget(self.headerLabel)
+ ##############
+ self.roiTable = ROITable(self)
+ rheight = self.roiTable.horizontalHeader().sizeHint().height()
+ self.roiTable.setMinimumHeight(4 * rheight)
+ self.fillFromROIDict = self.roiTable.fillFromROIDict
+ self.getROIListAndDict = self.roiTable.getROIListAndDict
+ layout.addWidget(self.roiTable)
+ self._roiFileDir = qt.QDir.home().absolutePath()
+ #################
+
+ hbox = qt.QWidget(self)
+ hboxlayout = qt.QHBoxLayout(hbox)
+ hboxlayout.setContentsMargins(0, 0, 0, 0)
+ hboxlayout.setSpacing(0)
+
+ hboxlayout.addStretch(0)
+
+ self.addButton = qt.QPushButton(hbox)
+ self.addButton.setText("Add ROI")
+ self.addButton.setToolTip('Create a new ROI')
+ self.delButton = qt.QPushButton(hbox)
+ self.delButton.setText("Delete ROI")
+ self.addButton.setToolTip('Remove the selected ROI')
+ self.resetButton = qt.QPushButton(hbox)
+ self.resetButton.setText("Reset")
+ self.addButton.setToolTip('Clear all created ROIs. We only let the default ROI')
+
+ hboxlayout.addWidget(self.addButton)
+ hboxlayout.addWidget(self.delButton)
+ hboxlayout.addWidget(self.resetButton)
+
+ hboxlayout.addStretch(0)
+
+ self.loadButton = qt.QPushButton(hbox)
+ self.loadButton.setText("Load")
+ self.loadButton.setToolTip('Load ROIs from a .ini file')
+ self.saveButton = qt.QPushButton(hbox)
+ self.saveButton.setText("Save")
+ self.loadButton.setToolTip('Save ROIs to a .ini file')
+ hboxlayout.addWidget(self.loadButton)
+ hboxlayout.addWidget(self.saveButton)
+ layout.setStretchFactor(self.headerLabel, 0)
+ layout.setStretchFactor(self.roiTable, 1)
+ layout.setStretchFactor(hbox, 0)
+
+ layout.addWidget(hbox)
+
+ self.addButton.clicked.connect(self._add)
+ self.delButton.clicked.connect(self._del)
+ self.resetButton.clicked.connect(self._reset)
+
+ self.loadButton.clicked.connect(self._load)
+ self.saveButton.clicked.connect(self._save)
+ self.roiTable.sigROITableSignal.connect(self._forward)
+
+ @property
+ def roiFileDir(self):
+ """The directory from which to load/save ROI from/to files."""
+ if not os.path.isdir(self._roiFileDir):
+ self._roiFileDir = qt.QDir.home().absolutePath()
+ return self._roiFileDir
+
+ @roiFileDir.setter
+ def roiFileDir(self, roiFileDir):
+ self._roiFileDir = str(roiFileDir)
+
+ def setRois(self, roidict, order=None):
+ """Set the ROIs by providing a dictionary of ROI information.
+
+ The dictionary keys are the ROI names.
+ Each value is a sub-dictionary of ROI info with the following fields:
+
+ - ``"from"``: x coordinate of the left limit, as a float
+ - ``"to"``: x coordinate of the right limit, as a float
+ - ``"type"``: type of ROI, as a string (e.g "channels", "energy")
+
+
+ :param roidict: Dictionary of ROIs
+ :param str order: Field used for ordering the ROIs.
+ One of "from", "to", "type".
+ None (default) for no ordering, or same order as specified
+ in parameter ``roidict`` if provided as an OrderedDict.
+ """
+ if order is None or order.lower() == "none":
+ roilist = list(roidict.keys())
+ else:
+ assert order in ["from", "to", "type"]
+ roilist = sorted(roidict.keys(),
+ key=lambda roi_name: roidict[roi_name].get(order))
+
+ return self.roiTable.fillFromROIDict(roilist, roidict)
+
+ def getRois(self, order=None):
+ """Return the currently defined ROIs, as an ordered dict.
+
+ The dictionary keys are the ROI names.
+ Each value is a sub-dictionary of ROI info with the following fields:
+
+ - ``"from"``: x coordinate of the left limit, as a float
+ - ``"to"``: x coordinate of the right limit, as a float
+ - ``"type"``: type of ROI, as a string (e.g "channels", "energy")
+ :param order: Field used for ordering the ROIs.
+ One of "from", "to", "type", "netcounts", "rawcounts".
+ None (default) to get the same order as displayed in the widget.
+ :return: Ordered dictionary of ROI information
+ """
+ roilist, roidict = self.roiTable.getROIListAndDict()
+ if order is None or order.lower() == "none":
+ ordered_roilist = roilist
+ else:
+ assert order in ["from", "to", "type", "netcounts", "rawcounts"]
+ ordered_roilist = sorted(roidict.keys(),
+ key=lambda roi_name: roidict[roi_name].get(order))
+
+ return OrderedDict([(name, roidict[name]) for name in ordered_roilist])
+
+ def _add(self):
+ """Add button clicked handler"""
+ ddict = {}
+ ddict['event'] = "AddROI"
+ roilist, roidict = self.roiTable.getROIListAndDict()
+ ddict['roilist'] = roilist
+ ddict['roidict'] = roidict
+ self.sigROIWidgetSignal.emit(ddict)
+
+ def _del(self):
+ """Delete button clicked handler"""
+ row = self.roiTable.currentRow()
+ if row >= 0:
+ index = self.roiTable.labels.index('Type')
+ text = str(self.roiTable.item(row, index).text())
+ if text.upper() != 'DEFAULT':
+ index = self.roiTable.labels.index('ROI')
+ key = str(self.roiTable.item(row, index).text())
+ else:
+ # This is to prevent deleting ICR ROI, that is
+ # usually initialized as "Default" type.
+ return
+ roilist, roidict = self.roiTable.getROIListAndDict()
+ row = roilist.index(key)
+ del roilist[row]
+ del roidict[key]
+ if len(roilist) > 0:
+ currentroi = roilist[0]
+ else:
+ currentroi = None
+
+ self.roiTable.fillFromROIDict(roilist=roilist,
+ roidict=roidict,
+ currentroi=currentroi)
+ ddict = {}
+ ddict['event'] = "DelROI"
+ ddict['roilist'] = roilist
+ ddict['roidict'] = roidict
+ self.sigROIWidgetSignal.emit(ddict)
+
+ def _forward(self, ddict):
+ """Broadcast events from ROITable signal"""
+ self.sigROIWidgetSignal.emit(ddict)
+
+ def _reset(self):
+ """Reset button clicked handler"""
+ ddict = {}
+ ddict['event'] = "ResetROI"
+ roilist0, roidict0 = self.roiTable.getROIListAndDict()
+ index = 0
+ for key in roilist0:
+ if roidict0[key]['type'].upper() == 'DEFAULT':
+ index = roilist0.index(key)
+ break
+ roilist = []
+ roidict = {}
+ if len(roilist0):
+ roilist.append(roilist0[index])
+ roidict[roilist[0]] = {}
+ roidict[roilist[0]].update(roidict0[roilist[0]])
+ self.roiTable.fillFromROIDict(roilist=roilist, roidict=roidict)
+ ddict['roilist'] = roilist
+ ddict['roidict'] = roidict
+ self.sigROIWidgetSignal.emit(ddict)
+
+ def _load(self):
+ """Load button clicked handler"""
+ dialog = qt.QFileDialog(self)
+ dialog.setNameFilters(
+ ['INI File *.ini', 'JSON File *.json', 'All *.*'])
+ dialog.setFileMode(qt.QFileDialog.ExistingFile)
+ dialog.setDirectory(self.roiFileDir)
+ if not dialog.exec_():
+ dialog.close()
+ return
+
+ # pyflakes bug http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666494
+ outputFile = dialog.selectedFiles()[0]
+ dialog.close()
+
+ self.roiFileDir = os.path.dirname(outputFile)
+ self.load(outputFile)
+
+ def load(self, filename):
+ """Load ROI widget information from a file storing a dict of ROI.
+
+ :param str filename: The file from which to load ROI
+ """
+ rois = dictdump.load(filename)
+ currentROI = None
+ if self.roiTable.rowCount():
+ item = self.roiTable.item(self.roiTable.currentRow(), 0)
+ if item is not None:
+ currentROI = str(item.text())
+
+ # Remove rawcounts and netcounts from ROIs
+ for roi in rois['ROI']['roidict'].values():
+ roi.pop('rawcounts', None)
+ roi.pop('netcounts', None)
+
+ self.roiTable.fillFromROIDict(roilist=rois['ROI']['roilist'],
+ roidict=rois['ROI']['roidict'],
+ currentroi=currentROI)
+
+ roilist, roidict = self.roiTable.getROIListAndDict()
+ event = {'event': 'LoadROI', 'roilist': roilist, 'roidict': roidict}
+ self.sigROIWidgetSignal.emit(event)
+
+ def _save(self):
+ """Save button clicked handler"""
+ dialog = qt.QFileDialog(self)
+ dialog.setNameFilters(['INI File *.ini', 'JSON File *.json'])
+ dialog.setFileMode(qt.QFileDialog.AnyFile)
+ dialog.setAcceptMode(qt.QFileDialog.AcceptSave)
+ dialog.setDirectory(self.roiFileDir)
+ if not dialog.exec_():
+ dialog.close()
+ return
+
+ outputFile = dialog.selectedFiles()[0]
+ extension = '.' + dialog.selectedNameFilter().split('.')[-1]
+ dialog.close()
+
+ if not outputFile.endswith(extension):
+ outputFile += extension
+
+ if os.path.exists(outputFile):
+ try:
+ os.remove(outputFile)
+ except IOError:
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setText("Input Output Error: %s" % (sys.exc_info()[1]))
+ msg.exec_()
+ return
+ self.roiFileDir = os.path.dirname(outputFile)
+ self.save(outputFile)
+
+ def save(self, filename):
+ """Save current ROIs of the widget as a dict of ROI to a file.
+
+ :param str filename: The file to which to save the ROIs
+ """
+ roilist, roidict = self.roiTable.getROIListAndDict()
+ datadict = {'ROI': {'roilist': roilist, 'roidict': roidict}}
+ dictdump.dump(datadict, filename)
+
+ def setHeader(self, text='ROIs'):
+ """Set the header text of this widget"""
+ self.headerLabel.setText("<b>%s<\b>" % text)
+
+
+class ROITable(qt.QTableWidget):
+ """Table widget displaying ROI information.
+
+ See :class:`QTableWidget` for constructor arguments.
+ """
+
+ sigROITableSignal = qt.Signal(object)
+ """Signal of ROI table modifications.
+ """
+
+ def __init__(self, *args, **kwargs):
+ super(ROITable, self).__init__(*args, **kwargs)
+ self.setRowCount(1)
+ self.labels = 'ROI', 'Type', 'From', 'To', 'Raw Counts', 'Net Counts'
+ self.setColumnCount(len(self.labels))
+ self.setSortingEnabled(False)
+
+ for index, label in enumerate(self.labels):
+ item = self.horizontalHeaderItem(index)
+ if item is None:
+ item = qt.QTableWidgetItem(label,
+ qt.QTableWidgetItem.Type)
+ item.setText(label)
+ self.setHorizontalHeaderItem(index, item)
+
+ self.roidict = {}
+ self.roilist = []
+
+ self.building = False
+ self.fillFromROIDict(roilist=self.roilist, roidict=self.roidict)
+
+ self.cellClicked[(int, int)].connect(self._cellClickedSlot)
+ self.cellChanged[(int, int)].connect(self._cellChangedSlot)
+ verticalHeader = self.verticalHeader()
+ verticalHeader.sectionClicked[int].connect(self._rowChangedSlot)
+
+ self.__setTooltip()
+
+ def __setTooltip(self):
+ assert(self.labels[0] == 'ROI')
+ self.horizontalHeaderItem(0).setToolTip('Region of interest identifier')
+ assert(self.labels[1] == 'Type')
+ self.horizontalHeaderItem(1).setToolTip('Type of the ROI')
+ assert(self.labels[2] == 'From')
+ self.horizontalHeaderItem(2).setToolTip('X-value of the min point')
+ assert(self.labels[3] == 'To')
+ self.horizontalHeaderItem(3).setToolTip('X-value of the max point')
+ assert(self.labels[4] == 'Raw Counts')
+ self.horizontalHeaderItem(4).setToolTip('Estimation of the integral \
+ between y=0 and the selected curve')
+ assert(self.labels[5] == 'Net Counts')
+ self.horizontalHeaderItem(5).setToolTip('Estimation of the integral \
+ between the segment [maxPt, minPt] and the selected curve')
+
+ def fillFromROIDict(self, roilist=(), roidict=None, currentroi=None):
+ """Set the ROIs by providing a list of ROI names and a dictionary
+ of ROI information for each ROI.
+
+ The ROI names must match an existing dictionary key.
+ The name list is used to provide an order for the ROIs.
+
+ The dictionary's values are sub-dictionaries containing 3
+ mandatory fields:
+
+ - ``"from"``: x coordinate of the left limit, as a float
+ - ``"to"``: x coordinate of the right limit, as a float
+ - ``"type"``: type of ROI, as a string (e.g "channels", "energy")
+
+ :param roilist: List of ROI names (keys of roidict)
+ :type roilist: List
+ :param dict roidict: Dict of ROI information
+ :param currentroi: Name of the selected ROI or None (no selection)
+ """
+ if roidict is None:
+ roidict = {}
+
+ self.building = True
+ line0 = 0
+ self.roilist = []
+ self.roidict = {}
+ for key in roilist:
+ if key in roidict.keys():
+ roi = roidict[key]
+ self.roilist.append(key)
+ self.roidict[key] = {}
+ self.roidict[key].update(roi)
+ line0 = line0 + 1
+ nlines = self.rowCount()
+ if (line0 > nlines):
+ self.setRowCount(line0)
+ line = line0 - 1
+ self.roidict[key]['line'] = line
+ ROI = key
+ roitype = "%s" % roi['type']
+ fromdata = "%6g" % (roi['from'])
+ todata = "%6g" % (roi['to'])
+ if 'rawcounts' in roi:
+ rawcounts = "%6g" % (roi['rawcounts'])
+ else:
+ rawcounts = " ?????? "
+ if 'netcounts' in roi:
+ netcounts = "%6g" % (roi['netcounts'])
+ else:
+ netcounts = " ?????? "
+ fields = [ROI, roitype, fromdata, todata, rawcounts, netcounts]
+ col = 0
+ for field in fields:
+ key2 = self.item(line, col)
+ if key2 is None:
+ key2 = qt.QTableWidgetItem(field,
+ qt.QTableWidgetItem.Type)
+ self.setItem(line, col, key2)
+ else:
+ key2.setText(field)
+ if (ROI.upper() == 'ICR') or (ROI.upper() == 'DEFAULT'):
+ key2.setFlags(qt.Qt.ItemIsSelectable |
+ qt.Qt.ItemIsEnabled)
+ else:
+ if col in [0, 2, 3]:
+ key2.setFlags(qt.Qt.ItemIsSelectable |
+ qt.Qt.ItemIsEnabled |
+ qt.Qt.ItemIsEditable)
+ else:
+ key2.setFlags(qt.Qt.ItemIsSelectable |
+ qt.Qt.ItemIsEnabled)
+ col = col + 1
+ self.setRowCount(line0)
+ i = 0
+ for _label in self.labels:
+ self.resizeColumnToContents(i)
+ i = i + 1
+ self.sortByColumn(2, qt.Qt.AscendingOrder)
+ for i in range(len(self.roilist)):
+ key = str(self.item(i, 0).text())
+ self.roilist[i] = key
+ self.roidict[key]['line'] = i
+ if len(self.roilist) == 1:
+ self.selectRow(0)
+ else:
+ if currentroi in self.roidict.keys():
+ self.selectRow(self.roidict[currentroi]['line'])
+ _logger.debug("Qt4 ensureCellVisible to be implemented")
+ self.building = False
+
+ def getROIListAndDict(self):
+ """Return the currently defined ROIs, as a 2-tuple
+ ``(roiList, roiDict)``
+
+ ``roiList`` is a list of ROI names.
+ ``roiDict`` is a dictionary of ROI info.
+
+ The ROI names must match an existing dictionary key.
+ The name list is used to provide an order for the ROIs.
+
+ The dictionary's values are sub-dictionaries containing 3
+ fields:
+
+ - ``"from"``: x coordinate of the left limit, as a float
+ - ``"to"``: x coordinate of the right limit, as a float
+ - ``"type"``: type of ROI, as a string (e.g "channels", "energy")
+
+
+ :return: ordered dict as a tuple of (list of ROI names, dict of info)
+ """
+ return self.roilist, self.roidict
+
+ def _cellClickedSlot(self, *var, **kw):
+ # selection changed event, get the current selection
+ row = self.currentRow()
+ col = self.currentColumn()
+ if row >= 0 and row < len(self.roilist):
+ item = self.item(row, 0)
+ text = '' if item is None else str(item.text())
+ self.roilist[row] = text
+ self._emitSelectionChangedSignal(row, col)
+
+ def _rowChangedSlot(self, row):
+ self._emitSelectionChangedSignal(row, 0)
+
+ def _cellChangedSlot(self, row, col):
+ _logger.debug("_cellChangedSlot(%d, %d)", row, col)
+ if self.building:
+ return
+ if col == 0:
+ self.nameSlot(row, col)
+ else:
+ self._valueChanged(row, col)
+
+ def _valueChanged(self, row, col):
+ if col not in [2, 3]:
+ return
+ item = self.item(row, col)
+ if item is None:
+ return
+ text = str(item.text())
+ try:
+ value = float(text)
+ except:
+ return
+ if row >= len(self.roilist):
+ _logger.debug("deleting???")
+ return
+ item = self.item(row, 0)
+ if item is None:
+ text = ""
+ else:
+ text = str(item.text())
+ if not len(text):
+ return
+ if col == 2:
+ self.roidict[text]['from'] = value
+ elif col == 3:
+ self.roidict[text]['to'] = value
+ self._emitSelectionChangedSignal(row, col)
+
+ def nameSlot(self, row, col):
+ if col != 0:
+ return
+ if row >= len(self.roilist):
+ _logger.debug("deleting???")
+ return
+ item = self.item(row, col)
+ if item is None:
+ text = ""
+ else:
+ text = str(item.text())
+ if len(text) and (text not in self.roilist):
+ old = self.roilist[row]
+ self.roilist[row] = text
+ self.roidict[text] = {}
+ self.roidict[text].update(self.roidict[old])
+ del self.roidict[old]
+ self._emitSelectionChangedSignal(row, col)
+
+ def _emitSelectionChangedSignal(self, row, col):
+ ddict = {}
+ ddict['event'] = "selectionChanged"
+ ddict['row'] = row
+ ddict['col'] = col
+ ddict['roi'] = self.roidict[self.roilist[row]]
+ ddict['key'] = self.roilist[row]
+ ddict['colheader'] = self.labels[col]
+ ddict['rowheader'] = "%d" % row
+ self.sigROITableSignal.emit(ddict)
+
+
+class CurvesROIDockWidget(qt.QDockWidget):
+ """QDockWidget with a :class:`CurvesROIWidget` connected to a PlotWindow.
+
+ It makes the link between the :class:`CurvesROIWidget` and the PlotWindow.
+
+ :param parent: See :class:`QDockWidget`
+ :param plot: :class:`.PlotWindow` instance on which to operate
+ :param name: See :class:`QDockWidget`
+ """
+ sigROISignal = qt.Signal(object)
+
+ def __init__(self, parent=None, plot=None, name=None):
+ super(CurvesROIDockWidget, self).__init__(name, parent)
+
+ assert plot is not None
+ self.plot = plot
+
+ self.currentROI = None
+ self._middleROIMarkerFlag = False
+
+ self._isConnected = False # True if connected to plot signals
+ self._isInit = False
+
+ self.roiWidget = CurvesROIWidget(self, name)
+ """Main widget of type :class:`CurvesROIWidget`"""
+
+ # convenience methods to offer a simpler API allowing to ignore
+ # the details of the underlying implementation
+ self.calculateROIs = self.calculateRois
+ self.setRois = self.roiWidget.setRois
+ self.getRois = self.roiWidget.getRois
+
+ self.layout().setContentsMargins(0, 0, 0, 0)
+ self.setWidget(self.roiWidget)
+
+ self.visibilityChanged.connect(self._visibilityChangedHandler)
+
+ def toggleViewAction(self):
+ """Returns a checkable action that shows or closes this widget.
+
+ See :class:`QMainWindow`.
+ """
+ action = super(CurvesROIDockWidget, self).toggleViewAction()
+ action.setIcon(icons.getQIcon('plot-roi'))
+ return action
+
+ def _visibilityChangedHandler(self, visible):
+ """Handle widget's visibilty updates.
+
+ It is connected to plot signals only when visible.
+ """
+ if visible:
+ if not self._isInit:
+ # Deferred ROI widget init finalization
+ self._isInit = True
+ self.roiWidget.sigROIWidgetSignal.connect(self._roiSignal)
+ # initialize with the ICR
+ self._roiSignal({'event': "AddROI"})
+
+ if not self._isConnected:
+ self.plot.sigPlotSignal.connect(self._handleROIMarkerEvent)
+ self.plot.sigActiveCurveChanged.connect(
+ self._activeCurveChanged)
+ self._isConnected = True
+
+ self.calculateROIs()
+ else:
+ if self._isConnected:
+ self.plot.sigPlotSignal.disconnect(self._handleROIMarkerEvent)
+ self.plot.sigActiveCurveChanged.disconnect(
+ self._activeCurveChanged)
+ self._isConnected = False
+
+ def _handleROIMarkerEvent(self, ddict):
+ """Handle plot signals related to marker events."""
+ if ddict['event'] == 'markerMoved':
+
+ label = ddict['label']
+ if label not in ['ROI min', 'ROI max', 'ROI middle']:
+ return
+
+ roiList, roiDict = self.roiWidget.getROIListAndDict()
+ if self.currentROI is None:
+ return
+ if self.currentROI not in roiDict:
+ return
+ x = ddict['x']
+
+ if label == 'ROI min':
+ roiDict[self.currentROI]['from'] = x
+ if self._middleROIMarkerFlag:
+ pos = 0.5 * (roiDict[self.currentROI]['to'] +
+ roiDict[self.currentROI]['from'])
+ self.plot.addXMarker(pos,
+ legend='ROI middle',
+ text='',
+ color='yellow',
+ draggable=True)
+ elif label == 'ROI max':
+ roiDict[self.currentROI]['to'] = x
+ if self._middleROIMarkerFlag:
+ pos = 0.5 * (roiDict[self.currentROI]['to'] +
+ roiDict[self.currentROI]['from'])
+ self.plot.addXMarker(pos,
+ legend='ROI middle',
+ text='',
+ color='yellow',
+ draggable=True)
+ elif label == 'ROI middle':
+ delta = x - 0.5 * (roiDict[self.currentROI]['from'] +
+ roiDict[self.currentROI]['to'])
+ roiDict[self.currentROI]['from'] += delta
+ roiDict[self.currentROI]['to'] += delta
+ self.plot.addXMarker(roiDict[self.currentROI]['from'],
+ legend='ROI min',
+ text='ROI min',
+ color='blue',
+ draggable=True)
+ self.plot.addXMarker(roiDict[self.currentROI]['to'],
+ legend='ROI max',
+ text='ROI max',
+ color='blue',
+ draggable=True)
+ else:
+ return
+ self.calculateROIs(roiList, roiDict)
+ self._emitCurrentROISignal()
+
+ def _roiSignal(self, ddict):
+ """Handle ROI widget signal"""
+ _logger.debug("PlotWindow._roiSignal %s", str(ddict))
+ if ddict['event'] == "AddROI":
+ xmin, xmax = self.plot.getGraphXLimits()
+ fromdata = xmin + 0.25 * (xmax - xmin)
+ todata = xmin + 0.75 * (xmax - xmin)
+ self.plot.remove('ROI min', kind='marker')
+ self.plot.remove('ROI max', kind='marker')
+ if self._middleROIMarkerFlag:
+ self.remove('ROI middle', kind='marker')
+ roiList, roiDict = self.roiWidget.getROIListAndDict()
+ nrois = len(roiList)
+ if nrois == 0:
+ newroi = "ICR"
+ fromdata, dummy0, todata, dummy1 = self._getAllLimits()
+ draggable = False
+ color = 'black'
+ else:
+ for i in range(nrois):
+ i += 1
+ newroi = "newroi %d" % i
+ if newroi not in roiList:
+ break
+ color = 'blue'
+ draggable = True
+ self.plot.addXMarker(fromdata,
+ legend='ROI min',
+ text='ROI min',
+ color=color,
+ draggable=draggable)
+ self.plot.addXMarker(todata,
+ legend='ROI max',
+ text='ROI max',
+ color=color,
+ draggable=draggable)
+ if draggable and self._middleROIMarkerFlag:
+ pos = 0.5 * (fromdata + todata)
+ self.plot.addXMarker(pos,
+ legend='ROI middle',
+ text="",
+ color='yellow',
+ draggable=draggable)
+ roiList.append(newroi)
+ roiDict[newroi] = {}
+ if newroi == "ICR":
+ roiDict[newroi]['type'] = "Default"
+ else:
+ roiDict[newroi]['type'] = self.plot.getGraphXLabel()
+ roiDict[newroi]['from'] = fromdata
+ roiDict[newroi]['to'] = todata
+ self.roiWidget.fillFromROIDict(roilist=roiList,
+ roidict=roiDict,
+ currentroi=newroi)
+ self.currentROI = newroi
+ self.calculateROIs()
+ elif ddict['event'] in ['DelROI', "ResetROI"]:
+ self.plot.remove('ROI min', kind='marker')
+ self.plot.remove('ROI max', kind='marker')
+ if self._middleROIMarkerFlag:
+ self.plot.remove('ROI middle', kind='marker')
+ roiList, roiDict = self.roiWidget.getROIListAndDict()
+ roiDictKeys = list(roiDict.keys())
+ if len(roiDictKeys):
+ currentroi = roiDictKeys[0]
+ else:
+ # create again the ICR
+ ddict = {"event": "AddROI"}
+ return self._roiSignal(ddict)
+
+ self.roiWidget.fillFromROIDict(roilist=roiList,
+ roidict=roiDict,
+ currentroi=currentroi)
+ self.currentROI = currentroi
+
+ elif ddict['event'] == 'LoadROI':
+ self.calculateROIs()
+
+ elif ddict['event'] == 'selectionChanged':
+ _logger.debug("Selection changed")
+ self.roilist, self.roidict = self.roiWidget.getROIListAndDict()
+ fromdata = ddict['roi']['from']
+ todata = ddict['roi']['to']
+ self.plot.remove('ROI min', kind='marker')
+ self.plot.remove('ROI max', kind='marker')
+ if ddict['key'] == 'ICR':
+ draggable = False
+ color = 'black'
+ else:
+ draggable = True
+ color = 'blue'
+ self.plot.addXMarker(fromdata,
+ legend='ROI min',
+ text='ROI min',
+ color=color,
+ draggable=draggable)
+ self.plot.addXMarker(todata,
+ legend='ROI max',
+ text='ROI max',
+ color=color,
+ draggable=draggable)
+ if draggable and self._middleROIMarkerFlag:
+ pos = 0.5 * (fromdata + todata)
+ self.plot.addXMarker(pos,
+ legend='ROI middle',
+ text="",
+ color='yellow',
+ draggable=True)
+ self.currentROI = ddict['key']
+ if ddict['colheader'] in ['From', 'To']:
+ dict0 = {}
+ dict0['event'] = "SetActiveCurveEvent"
+ dict0['legend'] = self.plot.getActiveCurve(just_legend=1)
+ self.plot.setActiveCurve(dict0['legend'])
+ elif ddict['colheader'] == 'Raw Counts':
+ pass
+ elif ddict['colheader'] == 'Net Counts':
+ pass
+ else:
+ self._emitCurrentROISignal()
+
+ else:
+ _logger.debug("Unknown or ignored event %s", ddict['event'])
+
+ def _activeCurveChanged(self, *args):
+ """Recompute ROIs when active curve changed."""
+ self.calculateROIs()
+
+ def calculateRois(self, roiList=None, roiDict=None):
+ """Compute ROI information"""
+ if roiList is None or roiDict is None:
+ roiList, roiDict = self.roiWidget.getROIListAndDict()
+
+ activeCurve = self.plot.getActiveCurve(just_legend=False)
+ if activeCurve is None:
+ xproc = None
+ yproc = None
+ self.roiWidget.setHeader()
+ else:
+ x = activeCurve.getXData(copy=False)
+ y = activeCurve.getYData(copy=False)
+ legend = activeCurve.getLegend()
+ idx = numpy.argsort(x, kind='mergesort')
+ xproc = numpy.take(x, idx)
+ yproc = numpy.take(y, idx)
+ self.roiWidget.setHeader('ROIs of %s' % legend)
+
+ for key in roiList:
+ if key == 'ICR':
+ if xproc is not None:
+ roiDict[key]['from'] = xproc.min()
+ roiDict[key]['to'] = xproc.max()
+ else:
+ roiDict[key]['from'] = 0
+ roiDict[key]['to'] = -1
+ fromData = roiDict[key]['from']
+ toData = roiDict[key]['to']
+ if xproc is not None:
+ idx = numpy.nonzero((fromData <= xproc) &
+ (xproc <= toData))[0]
+ if len(idx):
+ xw = xproc[idx]
+ yw = yproc[idx]
+ rawCounts = yw.sum(dtype=numpy.float)
+ deltaX = xw[-1] - xw[0]
+ deltaY = yw[-1] - yw[0]
+ if deltaX > 0.0:
+ slope = (deltaY / deltaX)
+ background = yw[0] + slope * (xw - xw[0])
+ netCounts = (rawCounts -
+ background.sum(dtype=numpy.float))
+ else:
+ netCounts = 0.0
+ else:
+ rawCounts = 0.0
+ netCounts = 0.0
+ roiDict[key]['rawcounts'] = rawCounts
+ roiDict[key]['netcounts'] = netCounts
+ else:
+ roiDict[key].pop('rawcounts', None)
+ roiDict[key].pop('netcounts', None)
+
+ self.roiWidget.fillFromROIDict(
+ roilist=roiList,
+ roidict=roiDict,
+ currentroi=self.currentROI if self.currentROI in roiList else None)
+
+ def _emitCurrentROISignal(self):
+ ddict = {}
+ ddict['event'] = "currentROISignal"
+ _roiList, roiDict = self.roiWidget.getROIListAndDict()
+ if self.currentROI in roiDict:
+ ddict['ROI'] = roiDict[self.currentROI]
+ else:
+ self.currentROI = None
+ ddict['current'] = self.currentROI
+ self.sigROISignal.emit(ddict)
+
+ def _getAllLimits(self):
+ """Retrieve the limits based on the curves."""
+ curves = self.plot.getAllCurves()
+ if not curves:
+ return 1.0, 1.0, 100., 100.
+
+ xmin, ymin = None, None
+ xmax, ymax = None, None
+
+ for curve in curves:
+ x = curve.getXData(copy=False)
+ y = curve.getYData(copy=False)
+ if xmin is None:
+ xmin = x.min()
+ else:
+ xmin = min(xmin, x.min())
+ if xmax is None:
+ xmax = x.max()
+ else:
+ xmax = max(xmax, x.max())
+ if ymin is None:
+ ymin = y.min()
+ else:
+ ymin = min(ymin, y.min())
+ if ymax is None:
+ ymax = y.max()
+ else:
+ ymax = max(ymax, y.max())
+
+ return xmin, ymin, xmax, ymax
+
+ def showEvent(self, event):
+ """Make sure this widget is raised when it is shown
+ (when it is first created as a tab in PlotWindow or when it is shown
+ again after hiding).
+ """
+ self.raise_()
diff --git a/silx/gui/plot/ImageView.py b/silx/gui/plot/ImageView.py
new file mode 100644
index 0000000..780215e
--- /dev/null
+++ b/silx/gui/plot/ImageView.py
@@ -0,0 +1,860 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""QWidget displaying a 2D image with histograms on its sides.
+
+The :class:`ImageView` implements this widget, and
+:class:`ImageViewMainWindow` provides a main window with additional toolbar
+and status bar.
+
+Basic usage of :class:`ImageView` is through the following methods:
+
+- :meth:`ImageView.getColormap`, :meth:`ImageView.setColormap` to update the
+ default colormap to use and update the currently displayed image.
+- :meth:`ImageView.setImage` to update the displayed image.
+
+The :class:`ImageView` uses :class:`PlotWindow` and also
+exposes :class:`silx.gui.plot.Plot` API for further control
+(plot title, axes labels, adding other images, ...).
+
+For an example of use, see the implementation of :class:`ImageViewMainWindow`,
+and `example/imageview.py`.
+"""
+
+from __future__ import division
+
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "13/10/2016"
+
+
+import logging
+import numpy
+
+from .. import qt
+
+from . import items, PlotWindow, PlotWidget, PlotActions
+from .Colors import cursorColorForColormap
+from .PlotTools import LimitsToolBar
+from .Profile import ProfileToolBar
+
+
+_logger = logging.getLogger(__name__)
+
+
+# RadarView ###################################################################
+
+class RadarView(qt.QGraphicsView):
+ """Widget presenting a synthetic view of a 2D area and
+ the current visible area.
+
+ Coordinates are as in QGraphicsView:
+ x goes from left to right and y goes from top to bottom.
+ This widget preserves the aspect ratio of the areas.
+
+ The 2D area and the visible area can be set with :meth:`setDataRect`
+ and :meth:`setVisibleRect`.
+ When the visible area has been dragged by the user, its new position
+ is signaled by the *visibleRectDragged* signal.
+
+ It is possible to invert the direction of the axes by using the
+ :meth:`scale` method of QGraphicsView.
+ """
+
+ visibleRectDragged = qt.Signal(float, float, float, float)
+ """Signals that the visible rectangle has been dragged.
+
+ It provides: left, top, width, height in data coordinates.
+ """
+
+ _DATA_PEN = qt.QPen(qt.QColor('white'))
+ _DATA_BRUSH = qt.QBrush(qt.QColor('light gray'))
+ _VISIBLE_PEN = qt.QPen(qt.QColor('red'))
+ _VISIBLE_PEN.setWidth(2)
+ _VISIBLE_PEN.setCosmetic(True)
+ _VISIBLE_BRUSH = qt.QBrush(qt.QColor(0, 0, 0, 0))
+ _TOOLTIP = 'Radar View:\nRed contour: Visible area\nGray area: The image'
+
+ _PIXMAP_SIZE = 256
+
+ class _DraggableRectItem(qt.QGraphicsRectItem):
+ """RectItem which signals its change through visibleRectDragged."""
+ def __init__(self, *args, **kwargs):
+ super(RadarView._DraggableRectItem, self).__init__(
+ *args, **kwargs)
+
+ self._previousCursor = None
+ self.setFlag(qt.QGraphicsItem.ItemIsMovable)
+ self.setFlag(qt.QGraphicsItem.ItemSendsGeometryChanges)
+ self.setAcceptHoverEvents(True)
+ self._ignoreChange = False
+ self._constraint = 0, 0, 0, 0
+
+ def setConstraintRect(self, left, top, width, height):
+ """Set the constraint rectangle for dragging.
+
+ The coordinates are in the _DraggableRectItem coordinate system.
+
+ This constraint only applies to modification through interaction
+ (i.e., this constraint is not applied to change through API).
+
+ If the _DraggableRectItem is smaller than the constraint rectangle,
+ the _DraggableRectItem remains within the constraint rectangle.
+ If the _DraggableRectItem is wider than the constraint rectangle,
+ the constraint rectangle remains within the _DraggableRectItem.
+ """
+ self._constraint = left, left + width, top, top + height
+
+ def setPos(self, *args, **kwargs):
+ """Overridden to ignore changes from API in itemChange."""
+ self._ignoreChange = True
+ super(RadarView._DraggableRectItem, self).setPos(*args, **kwargs)
+ self._ignoreChange = False
+
+ def moveBy(self, *args, **kwargs):
+ """Overridden to ignore changes from API in itemChange."""
+ self._ignoreChange = True
+ super(RadarView._DraggableRectItem, self).moveBy(*args, **kwargs)
+ self._ignoreChange = False
+
+ def itemChange(self, change, value):
+ """Callback called before applying changes to the item."""
+ if (change == qt.QGraphicsItem.ItemPositionChange and
+ not self._ignoreChange):
+ # Makes sure that the visible area is in the data
+ # or that data is in the visible area if area is too wide
+ x, y = value.x(), value.y()
+ xMin, xMax, yMin, yMax = self._constraint
+
+ if self.rect().width() <= (xMax - xMin):
+ if x < xMin:
+ value.setX(xMin)
+ elif x > xMax - self.rect().width():
+ value.setX(xMax - self.rect().width())
+ else:
+ if x > xMin:
+ value.setX(xMin)
+ elif x < xMax - self.rect().width():
+ value.setX(xMax - self.rect().width())
+
+ if self.rect().height() <= (yMax - yMin):
+ if y < yMin:
+ value.setY(yMin)
+ elif y > yMax - self.rect().height():
+ value.setY(yMax - self.rect().height())
+ else:
+ if y > yMin:
+ value.setY(yMin)
+ elif y < yMax - self.rect().height():
+ value.setY(yMax - self.rect().height())
+
+ if self.pos() != value:
+ # Notify change through signal
+ views = self.scene().views()
+ assert len(views) == 1
+ views[0].visibleRectDragged.emit(
+ value.x() + self.rect().left(),
+ value.y() + self.rect().top(),
+ self.rect().width(),
+ self.rect().height())
+
+ return value
+
+ return super(RadarView._DraggableRectItem, self).itemChange(
+ change, value)
+
+ def hoverEnterEvent(self, event):
+ """Called when the mouse enters the rectangle area"""
+ self._previousCursor = self.cursor()
+ self.setCursor(qt.Qt.OpenHandCursor)
+
+ def hoverLeaveEvent(self, event):
+ """Called when the mouse leaves the rectangle area"""
+ if self._previousCursor is not None:
+ self.setCursor(self._previousCursor)
+ self._previousCursor = None
+
+ def __init__(self, parent=None):
+ self._scene = qt.QGraphicsScene()
+ self._dataRect = self._scene.addRect(0, 0, 1, 1,
+ self._DATA_PEN,
+ self._DATA_BRUSH)
+ self._visibleRect = self._DraggableRectItem(0, 0, 1, 1)
+ self._visibleRect.setPen(self._VISIBLE_PEN)
+ self._visibleRect.setBrush(self._VISIBLE_BRUSH)
+ self._scene.addItem(self._visibleRect)
+
+ super(RadarView, self).__init__(self._scene, parent)
+ self.setHorizontalScrollBarPolicy(qt.Qt.ScrollBarAlwaysOff)
+ self.setVerticalScrollBarPolicy(qt.Qt.ScrollBarAlwaysOff)
+ self.setFocusPolicy(qt.Qt.NoFocus)
+ self.setStyleSheet('border: 0px')
+ self.setToolTip(self._TOOLTIP)
+
+ def sizeHint(self):
+ # """Overridden to avoid sizeHint to depend on content size."""
+ return self.minimumSizeHint()
+
+ def wheelEvent(self, event):
+ # """Overridden to disable vertical scrolling with wheel."""
+ event.ignore()
+
+ def resizeEvent(self, event):
+ # """Overridden to fit current content to new size."""
+ self.fitInView(self._scene.itemsBoundingRect(), qt.Qt.KeepAspectRatio)
+ super(RadarView, self).resizeEvent(event)
+
+ def setDataRect(self, left, top, width, height):
+ """Set the bounds of the data rectangular area.
+
+ This sets the coordinate system.
+ """
+ self._dataRect.setRect(left, top, width, height)
+ self._visibleRect.setConstraintRect(left, top, width, height)
+ self.fitInView(self._scene.itemsBoundingRect(), qt.Qt.KeepAspectRatio)
+
+ def setVisibleRect(self, left, top, width, height):
+ """Set the visible rectangular area.
+
+ The coordinates are relative to the data rect.
+ """
+ self._visibleRect.setRect(0, 0, width, height)
+ self._visibleRect.setPos(left, top)
+ self.fitInView(self._scene.itemsBoundingRect(), qt.Qt.KeepAspectRatio)
+
+
+# ImageView ###################################################################
+
+class ImageView(PlotWindow):
+ """Display a single image with horizontal and vertical histograms.
+
+ Use :meth:`setImage` to control the displayed image.
+ This class also provides the :class:`silx.gui.plot.Plot` API.
+
+ :param parent: The parent of this widget or None.
+ :param backend: The backend to use for the plot (default: matplotlib).
+ See :class:`.Plot` for the list of supported backend.
+ :type backend: str or :class:`BackendBase.BackendBase`
+ """
+
+ HISTOGRAMS_COLOR = 'blue'
+ """Color to use for the side histograms."""
+
+ HISTOGRAMS_HEIGHT = 200
+ """Height in pixels of the side histograms."""
+
+ IMAGE_MIN_SIZE = 200
+ """Minimum size in pixels of the image area."""
+
+ # Qt signals
+ valueChanged = qt.Signal(float, float, float)
+ """Signals that the data value under the cursor has changed.
+
+ It provides: row, column, data value.
+
+ When the cursor is over an histogram, either row or column is Nan
+ and the provided data value is the histogram value
+ (i.e., the sum along the corresponding row/column).
+ Row and columns are either Nan or integer values.
+ """
+
+ def __init__(self, parent=None, backend=None):
+ self._imageLegend = '__ImageView__image' + str(id(self))
+ self._cache = None # Store currently visible data information
+ self._updatingLimits = False
+
+ super(ImageView, self).__init__(parent=parent, backend=backend,
+ resetzoom=True, autoScale=False,
+ logScale=False, grid=False,
+ curveStyle=False, colormap=True,
+ aspectRatio=True, yInverted=True,
+ copy=True, save=True, print_=True,
+ control=False, position=False,
+ roi=False, mask=True)
+ if parent is None:
+ self.setWindowTitle('ImageView')
+
+ self._initWidgets(backend)
+
+ self.profile = ProfileToolBar(plot=self)
+ """"Profile tools attached to this plot.
+
+ See :class:`silx.gui.plot.PlotTools.ProfileToolBar`
+ """
+
+ self.addToolBar(self.profile)
+
+ # Sync PlotBackend and ImageView
+ self._updateYAxisInverted()
+
+ def _initWidgets(self, backend):
+ """Set-up layout and plots."""
+ # Monkey-patch for histogram size
+ # alternative: create a layout that does not use widget size hints
+ def sizeHint():
+ return qt.QSize(self.HISTOGRAMS_HEIGHT, self.HISTOGRAMS_HEIGHT)
+
+ self._histoHPlot = PlotWidget(backend=backend)
+ self._histoHPlot.setInteractiveMode('zoom')
+ self._histoHPlot.setCallback(self._histoHPlotCB)
+ self._histoHPlot.getWidgetHandle().sizeHint = sizeHint
+ self._histoHPlot.getWidgetHandle().minimumSizeHint = sizeHint
+
+ self.setPanWithArrowKeys(True)
+
+ self.setInteractiveMode('zoom') # Color set in setColormap
+ self.sigPlotSignal.connect(self._imagePlotCB)
+ self.sigSetYAxisInverted.connect(self._updateYAxisInverted)
+ self.sigActiveImageChanged.connect(self._activeImageChangedSlot)
+
+ self._histoVPlot = PlotWidget(backend=backend)
+ self._histoVPlot.setInteractiveMode('zoom')
+ self._histoVPlot.setCallback(self._histoVPlotCB)
+ self._histoVPlot.getWidgetHandle().sizeHint = sizeHint
+ self._histoVPlot.getWidgetHandle().minimumSizeHint = sizeHint
+
+ self._radarView = RadarView()
+ self._radarView.visibleRectDragged.connect(self._radarViewCB)
+
+ self._layout = qt.QGridLayout()
+ self._layout.addWidget(self.getWidgetHandle(), 0, 0)
+ self._layout.addWidget(self._histoVPlot.getWidgetHandle(), 0, 1)
+ self._layout.addWidget(self._histoHPlot.getWidgetHandle(), 1, 0)
+ self._layout.addWidget(self._radarView, 1, 1)
+
+ self._layout.setColumnMinimumWidth(0, self.IMAGE_MIN_SIZE)
+ self._layout.setColumnStretch(0, 1)
+ self._layout.setColumnMinimumWidth(1, self.HISTOGRAMS_HEIGHT)
+ self._layout.setColumnStretch(1, 0)
+
+ self._layout.setRowMinimumHeight(0, self.IMAGE_MIN_SIZE)
+ self._layout.setRowStretch(0, 1)
+ self._layout.setRowMinimumHeight(1, self.HISTOGRAMS_HEIGHT)
+ self._layout.setRowStretch(1, 0)
+
+ self._layout.setSpacing(0)
+ self._layout.setContentsMargins(0, 0, 0, 0)
+
+ centralWidget = qt.QWidget()
+ centralWidget.setLayout(self._layout)
+ self.setCentralWidget(centralWidget)
+
+ def _dirtyCache(self):
+ self._cache = None
+
+ def _updateHistograms(self):
+ """Update histograms content using current active image."""
+ activeImage = self.getActiveImage()
+ if activeImage is not None:
+ wasUpdatingLimits = self._updatingLimits
+ self._updatingLimits = True
+
+ data = activeImage.getData(copy=False)
+ origin = activeImage.getOrigin()
+ scale = activeImage.getScale()
+ height, width = data.shape
+
+ xMin, xMax = self.getGraphXLimits()
+ yMin, yMax = self.getGraphYLimits()
+
+ # Convert plot area limits to image coordinates
+ # and work in image coordinates (i.e., in pixels)
+ xMin = int((xMin - origin[0]) / scale[0])
+ xMax = int((xMax - origin[0]) / scale[0])
+ yMin = int((yMin - origin[1]) / scale[1])
+ yMax = int((yMax - origin[1]) / scale[1])
+
+ if (xMin < width and xMax >= 0 and
+ yMin < height and yMax >= 0):
+ # The image is at least partly in the plot area
+ # Get the visible bounds in image coords (i.e., in pixels)
+ subsetXMin = 0 if xMin < 0 else xMin
+ subsetXMax = (width if xMax >= width else xMax) + 1
+ subsetYMin = 0 if yMin < 0 else yMin
+ subsetYMax = (height if yMax >= height else yMax) + 1
+
+ if (self._cache is None or
+ subsetXMin != self._cache['dataXMin'] or
+ subsetXMax != self._cache['dataXMax'] or
+ subsetYMin != self._cache['dataYMin'] or
+ subsetYMax != self._cache['dataYMax']):
+ # The visible area of data has changed, update histograms
+
+ # Rebuild histograms for visible area
+ visibleData = data[subsetYMin:subsetYMax,
+ subsetXMin:subsetXMax]
+ histoHVisibleData = numpy.sum(visibleData, axis=0)
+ histoVVisibleData = numpy.sum(visibleData, axis=1)
+
+ self._cache = {
+ 'dataXMin': subsetXMin,
+ 'dataXMax': subsetXMax,
+ 'dataYMin': subsetYMin,
+ 'dataYMax': subsetYMax,
+
+ 'histoH': histoHVisibleData,
+ 'histoHMin': numpy.min(histoHVisibleData),
+ 'histoHMax': numpy.max(histoHVisibleData),
+
+ 'histoV': histoVVisibleData,
+ 'histoVMin': numpy.min(histoVVisibleData),
+ 'histoVMax': numpy.max(histoVVisibleData)
+ }
+
+ # Convert to histogram curve and update plots
+ # Taking into account origin and scale
+ coords = numpy.arange(2 * histoHVisibleData.size)
+ xCoords = (coords + 1) // 2 + subsetXMin
+ xCoords = origin[0] + scale[0] * xCoords
+ xData = numpy.take(histoHVisibleData, coords // 2)
+ self._histoHPlot.addCurve(xCoords, xData,
+ xlabel='', ylabel='',
+ replace=False,
+ color=self.HISTOGRAMS_COLOR,
+ linestyle='-',
+ selectable=False)
+ vMin = self._cache['histoHMin']
+ vMax = self._cache['histoHMax']
+ vOffset = 0.1 * (vMax - vMin)
+ if vOffset == 0.:
+ vOffset = 1.
+ self._histoHPlot.setGraphYLimits(vMin - vOffset,
+ vMax + vOffset)
+
+ coords = numpy.arange(2 * histoVVisibleData.size)
+ yCoords = (coords + 1) // 2 + subsetYMin
+ yCoords = origin[1] + scale[1] * yCoords
+ yData = numpy.take(histoVVisibleData, coords // 2)
+ self._histoVPlot.addCurve(yData, yCoords,
+ xlabel='', ylabel='',
+ replace=False,
+ color=self.HISTOGRAMS_COLOR,
+ linestyle='-',
+ selectable=False)
+ vMin = self._cache['histoVMin']
+ vMax = self._cache['histoVMax']
+ vOffset = 0.1 * (vMax - vMin)
+ if vOffset == 0.:
+ vOffset = 1.
+ self._histoVPlot.setGraphXLimits(vMin - vOffset,
+ vMax + vOffset)
+ else:
+ self._dirtyCache()
+ self._histoHPlot.remove(kind='curve')
+ self._histoVPlot.remove(kind='curve')
+
+ self._updatingLimits = wasUpdatingLimits
+
+ def _updateRadarView(self):
+ """Update radar view visible area.
+
+ Takes care of y coordinate conversion.
+ """
+ xMin, xMax = self.getGraphXLimits()
+ yMin, yMax = self.getGraphYLimits()
+ self._radarView.setVisibleRect(xMin, yMin, xMax - xMin, yMax - yMin)
+
+ # Plots event listeners
+
+ def _imagePlotCB(self, eventDict):
+ """Callback for imageView plot events."""
+ if eventDict['event'] == 'mouseMoved':
+ activeImage = self.getActiveImage()
+ if activeImage is not None:
+ data = activeImage.getData(copy=False)
+ height, width = data.shape
+
+ # Get corresponding coordinate in image
+ origin = activeImage.getOrigin()
+ scale = activeImage.getScale()
+ if (eventDict['x'] >= origin[0] and
+ eventDict['y'] >= origin[1]):
+ x = int((eventDict['x'] - origin[0]) / scale[0])
+ y = int((eventDict['y'] - origin[1]) / scale[1])
+
+ if x >= 0 and x < width and y >= 0 and y < height:
+ self.valueChanged.emit(float(x), float(y),
+ data[y][x])
+
+ elif eventDict['event'] == 'limitsChanged':
+ # Do not handle histograms limitsChanged while
+ # updating their limits from here.
+ self._updatingLimits = True
+
+ # Refresh histograms
+ self._updateHistograms()
+
+ # could use eventDict['xdata'], eventDict['ydata'] instead
+ xMin, xMax = self.getGraphXLimits()
+ yMin, yMax = self.getGraphYLimits()
+
+ # Set horizontal histo limits
+ self._histoHPlot.setGraphXLimits(xMin, xMax)
+
+ # Set vertical histo limits
+ self._histoVPlot.setGraphYLimits(yMin, yMax)
+
+ self._updateRadarView()
+
+ self._updatingLimits = False
+
+ def _histoHPlotCB(self, eventDict):
+ """Callback for horizontal histogram plot events."""
+ if eventDict['event'] == 'mouseMoved':
+ if self._cache is not None:
+ activeImage = self.getActiveImage()
+ if activeImage is not None:
+ xOrigin = activeImage.getOrigin()[0]
+ xScale = activeImage.getScale()[0]
+
+ minValue = xOrigin + xScale * self._cache['dataXMin']
+
+ if eventDict['x'] >= minValue:
+ data = self._cache['histoH']
+ column = int((eventDict['x'] - minValue) / xScale)
+ if column >= 0 and column < data.shape[0]:
+ self.valueChanged.emit(
+ float('nan'),
+ float(column + self._cache['dataXMin']),
+ data[column])
+
+ elif eventDict['event'] == 'limitsChanged':
+ if (not self._updatingLimits and
+ eventDict['xdata'] != self.getGraphXLimits()):
+ xMin, xMax = eventDict['xdata']
+ self.setGraphXLimits(xMin, xMax)
+
+ def _histoVPlotCB(self, eventDict):
+ """Callback for vertical histogram plot events."""
+ if eventDict['event'] == 'mouseMoved':
+ if self._cache is not None:
+ activeImage = self.getActiveImage()
+ if activeImage is not None:
+ yOrigin = activeImage.getOrigin()[1]
+ yScale = activeImage.getScale()[1]
+
+ minValue = yOrigin + yScale * self._cache['dataYMin']
+
+ if eventDict['y'] >= minValue:
+ data = self._cache['histoV']
+ row = int((eventDict['y'] - minValue) / yScale)
+ if row >= 0 and row < data.shape[0]:
+ self.valueChanged.emit(
+ float(row + self._cache['dataYMin']),
+ float('nan'),
+ data[row])
+
+ elif eventDict['event'] == 'limitsChanged':
+ if (not self._updatingLimits and
+ eventDict['ydata'] != self.getGraphYLimits()):
+ yMin, yMax = eventDict['ydata']
+ self.setGraphYLimits(yMin, yMax)
+
+ def _radarViewCB(self, left, top, width, height):
+ """Slot for radar view visible rectangle changes."""
+ if not self._updatingLimits:
+ # Takes care of Y axis conversion
+ self.setLimits(left, left + width, top, top + height)
+
+ def _updateYAxisInverted(self, inverted=None):
+ """Sync image, vertical histogram and radar view axis orientation."""
+ if inverted is None:
+ # Do not perform this when called from plot signal
+ inverted = self.isYAxisInverted()
+
+ self._histoVPlot.setYAxisInverted(inverted)
+
+ # Use scale to invert radarView
+ # RadarView default Y direction is from top to bottom
+ # As opposed to Plot. So invert RadarView when Plot is NOT inverted.
+ self._radarView.resetTransform()
+ if not inverted:
+ self._radarView.scale(1., -1.)
+ self._updateRadarView()
+
+ self._radarView.update()
+
+ def _activeImageChangedSlot(self, previous, legend):
+ """Handle Plot active image change.
+
+ Resets side histograms cache
+ """
+ self._dirtyCache()
+ self._updateHistograms()
+
+ def getHistogram(self, axis):
+ """Return the histogram and corresponding row or column extent.
+
+ The returned value when an histogram is available is a dict with keys:
+
+ - 'data': numpy array of the histogram values.
+ - 'extent': (start, end) row or column index.
+ end index is not included in the histogram.
+
+ :param str axis: 'x' for horizontal, 'y' for vertical
+ :return: The histogram and its extent as a dict or None.
+ :rtype: dict
+ """
+ assert axis in ('x', 'y')
+ if self._cache is None:
+ return None
+ else:
+ if axis == 'x':
+ return dict(
+ data=numpy.array(self._cache['histoH'], copy=True),
+ extent=(self._cache['dataXMin'], self._cache['dataXMax']))
+ else:
+ return dict(
+ data=numpy.array(self._cache['histoV'], copy=True),
+ extent=(self._cache['dataYMin'], self._cache['dataYMax']))
+
+ def radarView(self):
+ """Get the lower right radarView widget."""
+ return self._radarView
+
+ def setRadarView(self, radarView):
+ """Change the lower right radarView widget.
+
+ :param RadarView radarView: Widget subclassing RadarView to replace
+ the lower right corner widget.
+ """
+ self._radarView.visibleRectDragged.disconnect(self._radarViewCB)
+ self._radarView = radarView
+ self._radarView.visibleRectDragged.connect(self._radarViewCB)
+ self._layout.addWidget(self._radarView, 1, 1)
+
+ self._updateYAxisInverted()
+
+ # High-level API
+
+ def getColormap(self):
+ """Get the default colormap description.
+
+ :return: A description of the current colormap.
+ See :meth:`setColormap` for details.
+ :rtype: dict
+ """
+ return self.getDefaultColormap()
+
+ def setColormap(self, colormap=None, normalization=None,
+ autoscale=None, vmin=None, vmax=None, colors=None):
+ """Set the default colormap and update active image.
+
+ Parameters that are not provided are taken from the current colormap.
+
+ The colormap parameter can also be a dict with the following keys:
+
+ - *name*: string. The colormap to use:
+ 'gray', 'reversed gray', 'temperature', 'red', 'green', 'blue'.
+ - *normalization*: string. The mapping to use for the colormap:
+ either 'linear' or 'log'.
+ - *autoscale*: bool. Whether to use autoscale (True)
+ or range provided by keys 'vmin' and 'vmax' (False).
+ - *vmin*: float. The minimum value of the range to use if 'autoscale'
+ is False.
+ - *vmax*: float. The maximum value of the range to use if 'autoscale'
+ is False.
+ - *colors*: optional. Nx3 or Nx4 array of float in [0, 1] or uint8.
+ List of RGB or RGBA colors to use (only if name is None)
+
+ :param colormap: Name of the colormap in
+ 'gray', 'reversed gray', 'temperature', 'red', 'green', 'blue'.
+ Or the description of the colormap as a dict.
+ :type colormap: dict or str.
+ :param str normalization: Colormap mapping: 'linear' or 'log'.
+ :param bool autoscale: Whether to use autoscale (True)
+ or [vmin, vmax] range (False).
+ :param float vmin: The minimum value of the range to use if
+ 'autoscale' is False.
+ :param float vmax: The maximum value of the range to use if
+ 'autoscale' is False.
+ :param numpy.ndarray colors: Only used if name is None.
+ Custom colormap colors as Nx3 or Nx4 RGB or RGBA arrays
+ """
+ cmapDict = self.getDefaultColormap()
+
+ if isinstance(colormap, dict):
+ # Support colormap parameter as a dict
+ assert normalization is None
+ assert autoscale is None
+ assert vmin is None
+ assert vmax is None
+ assert colors is None
+ for key, value in colormap.items():
+ cmapDict[key] = value
+
+ else:
+ if colormap is not None:
+ cmapDict['name'] = colormap
+ if normalization is not None:
+ cmapDict['normalization'] = normalization
+ if autoscale is not None:
+ cmapDict['autoscale'] = autoscale
+ if vmin is not None:
+ cmapDict['vmin'] = vmin
+ if vmax is not None:
+ cmapDict['vmax'] = vmax
+ if colors is not None:
+ cmapDict['colors'] = colors
+
+ cursorColor = cursorColorForColormap(cmapDict['name'])
+ self.setInteractiveMode('zoom', color=cursorColor)
+
+ self.setDefaultColormap(cmapDict)
+
+ # Update active image colormap
+ activeImage = self.getActiveImage()
+ if isinstance(activeImage, items.ColormapMixIn):
+ activeImage.setColormap(self.getColormap())
+
+ def setImage(self, image, origin=(0, 0), scale=(1., 1.),
+ copy=True, reset=True):
+ """Set the image to display.
+
+ :param image: A 2D array representing the image or None to empty plot.
+ :type image: numpy.ndarray-like with 2 dimensions or None.
+ :param origin: The (x, y) position of the origin of the image.
+ Default: (0, 0).
+ The origin is the lower left corner of the image when
+ the Y axis is not inverted.
+ :type origin: Tuple of 2 floats: (origin x, origin y).
+ :param scale: The scale factor to apply to the image on X and Y axes.
+ Default: (1, 1).
+ It is the size of a pixel in the coordinates of the axes.
+ Scales must be positive numbers.
+ :type scale: Tuple of 2 floats: (scale x, scale y).
+ :param bool copy: Whether to copy image data (default) or not.
+ :param bool reset: Whether to reset zoom and ROI (default) or not.
+ """
+ self._dirtyCache()
+
+ assert len(origin) == 2
+ assert len(scale) == 2
+ assert scale[0] > 0
+ assert scale[1] > 0
+
+ if image is None:
+ self.remove(self._imageLegend, kind='image')
+ return
+
+ data = numpy.array(image, order='C', copy=copy)
+ assert data.size != 0
+ assert len(data.shape) == 2
+ height, width = data.shape
+
+ self.addImage(data,
+ legend=self._imageLegend,
+ origin=origin, scale=scale,
+ colormap=self.getColormap(),
+ replace=False)
+ self.setActiveImage(self._imageLegend)
+ self._updateHistograms()
+
+ self._radarView.setDataRect(origin[0],
+ origin[1],
+ width * scale[0],
+ height * scale[1])
+
+ if reset:
+ self.resetZoom()
+
+
+# ImageViewMainWindow #########################################################
+
+class ImageViewMainWindow(ImageView):
+ """:class:`ImageView` with additional toolbars
+
+ Adds extra toolbar and a status bar to :class:`ImageView`.
+ """
+ def __init__(self, parent=None, backend=None):
+ self._dataInfo = None
+ super(ImageViewMainWindow, self).__init__(parent, backend)
+ self.setWindowFlags(qt.Qt.Window)
+
+ self.setGraphXLabel('X')
+ self.setGraphYLabel('Y')
+ self.setGraphTitle('Image')
+
+ # Add toolbars and status bar
+ self.addToolBar(qt.Qt.BottomToolBarArea, LimitsToolBar(plot=self))
+
+ self.statusBar()
+
+ menu = self.menuBar().addMenu('File')
+ menu.addAction(self.saveAction)
+ menu.addAction(self.printAction)
+ menu.addSeparator()
+ action = menu.addAction('Quit')
+ action.triggered[bool].connect(qt.QApplication.instance().quit)
+
+ menu = self.menuBar().addMenu('Edit')
+ menu.addAction(self.copyAction)
+ menu.addSeparator()
+ menu.addAction(self.resetZoomAction)
+ menu.addAction(self.colormapAction)
+ menu.addAction(PlotActions.KeepAspectRatioAction(self, self))
+ menu.addAction(PlotActions.YAxisInvertedAction(self, self))
+
+ menu = self.menuBar().addMenu('Profile')
+ menu.addAction(self.profile.browseAction)
+ menu.addAction(self.profile.hLineAction)
+ menu.addAction(self.profile.vLineAction)
+ menu.addAction(self.profile.lineAction)
+ menu.addAction(self.profile.clearAction)
+
+ # Connect to ImageView's signal
+ self.valueChanged.connect(self._statusBarSlot)
+
+ def _statusBarSlot(self, row, column, value):
+ """Update status bar with coordinates/value from plots."""
+ if numpy.isnan(row):
+ msg = 'Column: %d, Sum: %g' % (int(column), value)
+ elif numpy.isnan(column):
+ msg = 'Row: %d, Sum: %g' % (int(row), value)
+ else:
+ msg = 'Position: (%d, %d), Value: %g' % (int(row), int(column),
+ value)
+ if self._dataInfo is not None:
+ msg = self._dataInfo + ', ' + msg
+
+ self.statusBar().showMessage(msg)
+
+ def setImage(self, image, *args, **kwargs):
+ """Set the displayed image.
+
+ See :meth:`ImageView.setImage` for details.
+ """
+ if hasattr(image, 'dtype') and hasattr(image, 'shape'):
+ assert len(image.shape) == 2
+ height, width = image.shape
+ self._dataInfo = 'Data: %dx%d (%s)' % (width, height,
+ str(image.dtype))
+ self.statusBar().showMessage(self._dataInfo)
+ else:
+ self._dataInfo = None
+
+ # Set the new image in ImageView widget
+ super(ImageViewMainWindow, self).setImage(image, *args, **kwargs)
+ self.setStatusBar(None)
diff --git a/silx/gui/plot/Interaction.py b/silx/gui/plot/Interaction.py
new file mode 100644
index 0000000..f09b9bc
--- /dev/null
+++ b/silx/gui/plot/Interaction.py
@@ -0,0 +1,300 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-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.
+#
+# ###########################################################################*/
+"""This module provides an implementation of state machines for interaction.
+
+Sample code of a state machine with two states ('idle' and 'active')
+with transitions on left button press/release:
+
+.. code-block:: python
+
+ from silx.gui.plot.Interaction import *
+
+ class SampleStateMachine(StateMachine):
+
+ class Idle(State):
+ def onPress(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.goto('active')
+
+ class Active(State):
+ def enterState(self):
+ print('Enabled') # Handle enter active state here
+
+ def leaveState(self):
+ print('Disabled') # Handle leave active state here
+
+ def onRelease(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.goto('idle')
+
+ def __init__(self):
+ # State machine has 2 states
+ states = {
+ 'idle': SampleStateMachine.Idle,
+ 'active': SampleStateMachine.Active
+ }
+ super(TwoStates, self).__init__(states, 'idle')
+ # idle is the initial state
+
+ stateMachine = SampleStateMachine()
+
+ # Triggers a transition to the Active state:
+ stateMachine.handleEvent('press', 0, 0, LEFT_BTN)
+
+ # Triggers a transition to the Idle state:
+ stateMachine.handleEvent('release', 0, 0, LEFT_BTN)
+
+See :class:`ClickOrDrag` for another example of a state machine.
+
+See `Renaud Blanch, Michel Beaudouin-Lafon.
+Programming Rich Interactions using the Hierarchical State Machine Toolkit.
+In Proceedings of AVI 2006. p 51-58.
+<http://iihm.imag.fr/en/publication/BB06a/>`_
+for a discussion of using (hierarchical) state machines for interaction.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/02/2016"
+
+
+import weakref
+
+
+# state machine ###############################################################
+
+class State(object):
+ """Base class for the states of a state machine.
+
+ This class is meant to be subclassed.
+ """
+
+ def __init__(self, machine):
+ """State instances should be created by the :class:`StateMachine`.
+
+ They are not intended to be used outside this context.
+
+ :param machine: The state machine instance this state belongs to.
+ :type machine: StateMachine
+ """
+ self._machineRef = weakref.ref(machine) # Prevent cyclic reference
+
+ @property
+ def machine(self):
+ """The state machine this state belongs to.
+
+ Useful to access data or methods that are shared across states.
+ """
+ machine = self._machineRef()
+ if machine is not None:
+ return machine
+ else:
+ raise RuntimeError("Associated StateMachine is not valid")
+
+ def goto(self, state, *args, **kwargs):
+ """Performs a transition to a new state.
+
+ Extra arguments are passed to the :meth:`enterState` method of the
+ new state.
+
+ :param str state: The name of the state to go to.
+ """
+ self.machine._goto(state, *args, **kwargs)
+
+ def enterState(self, *args, **kwargs):
+ """Called when the state machine enters this state.
+
+ Arguments are those provided to the :meth:`goto` method that
+ triggered the transition to this state.
+ """
+ pass
+
+ def leaveState(self):
+ """Called when the state machine leaves this state
+ (i.e., when :meth:`goto` is called).
+ """
+ pass
+
+
+class StateMachine(object):
+ """State machine controller.
+
+ This is the entry point of a state machine.
+ It is in charge of dispatching received event and handling the
+ current active state.
+ """
+
+ def __init__(self, states, initState, *args, **kwargs):
+ """Create a state machine controller with an initial state.
+
+ Extra arguments are passed to the :meth:`enterState` method
+ of the initState.
+
+ :param states: All states of the state machine
+ :type states: dict of: {str name: State subclass}
+ :param str initState: Key of the initial state in states
+ """
+ self.states = states
+
+ self.state = self.states[initState](self)
+ self.state.enterState(*args, **kwargs)
+
+ def _goto(self, state, *args, **kwargs):
+ self.state.leaveState()
+ self.state = self.states[state](self)
+ self.state.enterState(*args, **kwargs)
+
+ def handleEvent(self, eventName, *args, **kwargs):
+ """Process an event with the state machine.
+
+ This method looks up for an event handler in the current state
+ and then in the :class:`StateMachine` instance.
+ Handler are looked up as 'onEventName' method.
+ If a handler is found, it is called with the provided extra
+ arguments, and this method returns the return value of the
+ handler.
+ If no handler is found, this method returns None.
+
+ :param str eventName: Name of the event to handle
+ :returns: The return value of the handler or None
+ """
+ handlerName = 'on' + eventName[0].upper() + eventName[1:]
+ try:
+ handler = getattr(self.state, handlerName)
+ except AttributeError:
+ try:
+ handler = getattr(self, handlerName)
+ except AttributeError:
+ handler = None
+ if handler is not None:
+ return handler(*args, **kwargs)
+
+
+# clickOrDrag #################################################################
+
+LEFT_BTN = 'left'
+"""Left mouse button."""
+
+RIGHT_BTN = 'right'
+"""Right mouse button."""
+
+MIDDLE_BTN = 'middle'
+"""Middle mouse button."""
+
+
+class ClickOrDrag(StateMachine):
+ """State machine for left and right click and left drag interaction.
+
+ It is intended to be used through subclassing by overriding
+ :meth:`click`, :meth:`beginDrag`, :meth:`drag` and :meth:`endDrag`.
+ """
+
+ DRAG_THRESHOLD_SQUARE_DIST = 5 ** 2
+
+ class Idle(State):
+ def onPress(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.goto('clickOrDrag', x, y)
+ return True
+ elif btn == RIGHT_BTN:
+ self.goto('rightClick', x, y)
+ return True
+
+ class RightClick(State):
+ def onMove(self, x, y):
+ self.goto('idle')
+
+ def onRelease(self, x, y, btn):
+ if btn == RIGHT_BTN:
+ self.machine.click(x, y, btn)
+ self.goto('idle')
+
+ class ClickOrDrag(State):
+ def enterState(self, x, y):
+ self.initPos = x, y
+
+ def onMove(self, x, y):
+ dx2 = (x - self.initPos[0]) ** 2
+ dy2 = (y - self.initPos[1]) ** 2
+ if (dx2 + dy2) >= self.machine.DRAG_THRESHOLD_SQUARE_DIST:
+ self.goto('drag', self.initPos, (x, y))
+
+ def onRelease(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.machine.click(x, y, btn)
+ self.goto('idle')
+
+ class Drag(State):
+ def enterState(self, initPos, curPos):
+ self.initPos = initPos
+ self.machine.beginDrag(*initPos)
+ self.machine.drag(*curPos)
+
+ def onMove(self, x, y):
+ self.machine.drag(x, y)
+
+ def onRelease(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.machine.endDrag(self.initPos, (x, y))
+ self.goto('idle')
+
+ def __init__(self):
+ states = {
+ 'idle': ClickOrDrag.Idle,
+ 'rightClick': ClickOrDrag.RightClick,
+ 'clickOrDrag': ClickOrDrag.ClickOrDrag,
+ 'drag': ClickOrDrag.Drag
+ }
+ super(ClickOrDrag, self).__init__(states, 'idle')
+
+ def click(self, x, y, btn):
+ """Called upon a left or right button click.
+
+ To override in a subclass.
+ """
+ pass
+
+ def beginDrag(self, x, y):
+ """Called at the beginning of a drag gesture with left button
+ pressed.
+
+ To override in a subclass.
+ """
+ pass
+
+ def drag(self, x, y):
+ """Called on mouse moved during a drag gesture.
+
+ To override in a subclass.
+ """
+ pass
+
+ def endDrag(self, startPoint, endPoint):
+ """Called at the end of a drag gesture when the left button is
+ released.
+
+ To override in a subclass.
+ """
+ pass
diff --git a/silx/gui/plot/LegendSelector.py b/silx/gui/plot/LegendSelector.py
new file mode 100644
index 0000000..3af9050
--- /dev/null
+++ b/silx/gui/plot/LegendSelector.py
@@ -0,0 +1,1087 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Widget displaying curves legends and allowing to operate on curves.
+
+This widget is meant to work with :class:`PlotWindow`.
+"""
+
+__authors__ = ["V.A. Sole", "T. Rueter", "T. Vincent"]
+__license__ = "MIT"
+__data__ = "28/04/2016"
+
+
+import logging
+import weakref
+
+from .. import qt
+
+
+_logger = logging.getLogger(__name__)
+
+# Build all symbols
+# Courtesy of the pyqtgraph project
+Symbols = dict([(name, qt.QPainterPath())
+ for name in ['o', 's', 't', 'd', '+', 'x', '.', ',']])
+Symbols['o'].addEllipse(qt.QRectF(.1, .1, .8, .8))
+Symbols['.'].addEllipse(qt.QRectF(.3, .3, .4, .4))
+Symbols[','].addEllipse(qt.QRectF(.4, .4, .2, .2))
+Symbols['s'].addRect(qt.QRectF(.1, .1, .8, .8))
+
+coords = {
+ 't': [(0.5, 0.), (.1, .8), (.9, .8)],
+ 'd': [(0.1, 0.5), (0.5, 0.), (0.9, 0.5), (0.5, 1.)],
+ '+': [(0.0, 0.40), (0.40, 0.40), (0.40, 0.), (0.60, 0.),
+ (0.60, 0.40), (1., 0.40), (1., 0.60), (0.60, 0.60),
+ (0.60, 1.), (0.40, 1.), (0.40, 0.60), (0., 0.60)],
+ 'x': [(0.0, 0.40), (0.40, 0.40), (0.40, 0.), (0.60, 0.),
+ (0.60, 0.40), (1., 0.40), (1., 0.60), (0.60, 0.60),
+ (0.60, 1.), (0.40, 1.), (0.40, 0.60), (0., 0.60)]
+}
+for s, c in coords.items():
+ Symbols[s].moveTo(*c[0])
+ for x, y in c[1:]:
+ Symbols[s].lineTo(x, y)
+ Symbols[s].closeSubpath()
+tr = qt.QTransform()
+tr.rotate(45)
+Symbols['x'].translate(qt.QPointF(-0.5, -0.5))
+Symbols['x'] = tr.map(Symbols['x'])
+Symbols['x'].translate(qt.QPointF(0.5, 0.5))
+
+NoSymbols = (None, 'None', 'none', '', ' ')
+"""List of values resulting in no symbol being displayed for a curve"""
+
+
+LineStyles = {
+ None: qt.Qt.NoPen,
+ 'None': qt.Qt.NoPen,
+ 'none': qt.Qt.NoPen,
+ '': qt.Qt.NoPen,
+ ' ': qt.Qt.NoPen,
+ '-': qt.Qt.SolidLine,
+ '--': qt.Qt.DashLine,
+ ':': qt.Qt.DotLine,
+ '-.': qt.Qt.DashDotLine
+}
+"""Conversion from matplotlib-like linestyle to Qt"""
+
+NoLineStyle = (None, 'None', 'none', '', ' ')
+"""List of style values resulting in no line being displayed for a curve"""
+
+
+class LegendIcon(qt.QWidget):
+ """Object displaying a curve linestyle and symbol."""
+
+ def __init__(self, parent=None):
+ super(LegendIcon, self).__init__(parent)
+
+ # Visibilities
+ self.showLine = True
+ self.showSymbol = True
+
+ # Line attributes
+ self.lineStyle = qt.Qt.NoPen
+ self.lineWidth = 1.
+ self.lineColor = qt.Qt.green
+
+ self.symbol = ''
+ # Symbol attributes
+ self.symbolStyle = qt.Qt.SolidPattern
+ self.symbolColor = qt.Qt.green
+ self.symbolOutlineBrush = qt.QBrush(qt.Qt.white)
+
+ # Control widget size: sizeHint "is the only acceptable
+ # alternative, so the widget can never grow or shrink"
+ # (c.f. Qt Doc, enum QSizePolicy::Policy)
+ self.setSizePolicy(qt.QSizePolicy.Fixed,
+ qt.QSizePolicy.Fixed)
+
+ def sizeHint(self):
+ return qt.QSize(50, 15)
+
+ # Modify Symbol
+ def setSymbol(self, symbol):
+ symbol = str(symbol)
+ if symbol not in NoSymbols:
+ if symbol not in Symbols:
+ raise ValueError("Unknown symbol: <%s>" % symbol)
+ self.symbol = symbol
+ # self.update() after set...?
+ # Does not seem necessary
+
+ def setSymbolColor(self, color):
+ """
+ :param color: determines the symbol color
+ :type style: qt.QColor
+ """
+ self.symbolColor = qt.QColor(color)
+
+ # Modify Line
+
+ def setLineColor(self, color):
+ self.lineColor = qt.QColor(color)
+
+ def setLineWidth(self, width):
+ self.lineWidth = float(width)
+
+ def setLineStyle(self, style):
+ """Set the linestyle.
+
+ Possible line styles:
+
+ - '', ' ', 'None': No line
+ - '-': solid
+ - '--': dashed
+ - ':': dotted
+ - '-.': dash and dot
+
+ :param str style: The linestyle to use
+ """
+ if style not in LineStyles:
+ raise ValueError('Unknown style: %s', style)
+ self.lineStyle = LineStyles[style]
+
+ # Paint
+
+ def paintEvent(self, event):
+ """
+ :param event: event
+ :type event: QPaintEvent
+ """
+ painter = qt.QPainter(self)
+ self.paint(painter, event.rect(), self.palette())
+
+ def paint(self, painter, rect, palette):
+ painter.save()
+ painter.setRenderHint(qt.QPainter.Antialiasing)
+ # Scale painter to the icon height
+ # current -> width = 2.5, height = 1.0
+ scale = float(self.height())
+ ratio = float(self.width()) / scale
+ painter.scale(scale,
+ scale)
+ symbolOffset = qt.QPointF(.5 * (ratio - 1.), 0.)
+ # Determine and scale offset
+ offset = qt.QPointF(float(rect.left()) / scale, float(rect.top()) / scale)
+ # Draw BG rectangle (for debugging)
+ # bottomRight = qt.QPointF(
+ # float(rect.right())/scale,
+ # float(rect.bottom())/scale)
+ # painter.fillRect(qt.QRectF(offset, bottomRight),
+ # qt.QBrush(qt.Qt.green))
+ llist = []
+ if self.showLine:
+ linePath = qt.QPainterPath()
+ linePath.moveTo(0., 0.5)
+ linePath.lineTo(ratio, 0.5)
+ # linePath.lineTo(2.5, 0.5)
+ linePen = qt.QPen(
+ qt.QBrush(self.lineColor),
+ (self.lineWidth / self.height()),
+ self.lineStyle,
+ qt.Qt.FlatCap
+ )
+ llist.append((linePath,
+ linePen,
+ qt.QBrush(self.lineColor)))
+ if (self.showSymbol and len(self.symbol) and
+ self.symbol not in NoSymbols):
+ # PITFALL ahead: Let this be a warning to others
+ # symbolPath = Symbols[self.symbol]
+ # Copy before translate! Dict is a mutable type
+ symbolPath = qt.QPainterPath(Symbols[self.symbol])
+ symbolPath.translate(symbolOffset)
+ symbolBrush = qt.QBrush(
+ self.symbolColor,
+ self.symbolStyle
+ )
+ symbolPen = qt.QPen(
+ self.symbolOutlineBrush, # Brush
+ 1. / self.height(), # Width
+ qt.Qt.SolidLine # Style
+ )
+ llist.append((symbolPath,
+ symbolPen,
+ symbolBrush))
+ # Draw
+ for path, pen, brush in llist:
+ path.translate(offset)
+ painter.setPen(pen)
+ painter.setBrush(brush)
+ painter.drawPath(path)
+ painter.restore()
+
+
+class LegendModel(qt.QAbstractListModel):
+ """Data model of curve legends.
+
+ It holds the information of the curve:
+
+ - color
+ - line width
+ - line style
+ - visibility of the lines
+ - symbol
+ - visibility of the symbols
+ """
+ iconColorRole = qt.Qt.UserRole + 0
+ iconLineWidthRole = qt.Qt.UserRole + 1
+ iconLineStyleRole = qt.Qt.UserRole + 2
+ showLineRole = qt.Qt.UserRole + 3
+ iconSymbolRole = qt.Qt.UserRole + 4
+ showSymbolRole = qt.Qt.UserRole + 5
+
+ def __init__(self, legendList=None, parent=None):
+ super(LegendModel, self).__init__(parent)
+ if legendList is None:
+ legendList = []
+ self.legendList = []
+ self.insertLegendList(0, legendList)
+
+ def __getitem__(self, idx):
+ if idx >= len(self.legendList):
+ raise IndexError('list index out of range')
+ return self.legendList[idx]
+
+ def rowCount(self, modelIndex=None):
+ return len(self.legendList)
+
+ def flags(self, index):
+ return (qt.Qt.ItemIsEditable |
+ qt.Qt.ItemIsEnabled |
+ qt.Qt.ItemIsSelectable)
+
+ def data(self, modelIndex, role):
+ if modelIndex.isValid:
+ idx = modelIndex.row()
+ else:
+ return None
+ if idx >= len(self.legendList):
+ raise IndexError('list index out of range')
+
+ item = self.legendList[idx]
+ if role == qt.Qt.DisplayRole:
+ # Data to be rendered in the form of text
+ legend = str(item[0])
+ return legend
+ elif role == qt.Qt.SizeHintRole:
+ # size = qt.QSize(200,50)
+ _logger.warning('LegendModel -- size hint role not implemented')
+ return qt.QSize()
+ elif role == qt.Qt.TextAlignmentRole:
+ alignment = qt.Qt.AlignVCenter | qt.Qt.AlignLeft
+ return alignment
+ elif role == qt.Qt.BackgroundRole:
+ # Background color, must be QBrush
+ if idx % 2:
+ brush = qt.QBrush(qt.QColor(240, 240, 240))
+ else:
+ brush = qt.QBrush(qt.Qt.white)
+ return brush
+ elif role == qt.Qt.ForegroundRole:
+ # ForegroundRole color, must be QBrush
+ brush = qt.QBrush(qt.Qt.blue)
+ return brush
+ elif role == qt.Qt.CheckStateRole:
+ return bool(item[2]) # item[2] == True
+ elif role == qt.Qt.ToolTipRole or role == qt.Qt.StatusTipRole:
+ return ''
+ elif role == self.iconColorRole:
+ return item[1]['color']
+ elif role == self.iconLineWidthRole:
+ return item[1]['linewidth']
+ elif role == self.iconLineStyleRole:
+ return item[1]['linestyle']
+ elif role == self.iconSymbolRole:
+ return item[1]['symbol']
+ elif role == self.showLineRole:
+ return item[3]
+ elif role == self.showSymbolRole:
+ return item[4]
+ else:
+ _logger.info('Unkown role requested: %s', str(role))
+ return None
+
+ def setData(self, modelIndex, value, role):
+ if modelIndex.isValid:
+ idx = modelIndex.row()
+ else:
+ return None
+ if idx >= len(self.legendList):
+ # raise IndexError('list index out of range')
+ _logger.warning(
+ 'setData -- List index out of range, idx: %d', idx)
+ return None
+
+ item = self.legendList[idx]
+ try:
+ if role == qt.Qt.DisplayRole:
+ # Set legend
+ item[0] = str(value)
+ elif role == self.iconColorRole:
+ item[1]['color'] = qt.QColor(value)
+ elif role == self.iconLineWidthRole:
+ item[1]['linewidth'] = int(value)
+ elif role == self.iconLineStyleRole:
+ item[1]['linestyle'] = str(value)
+ elif role == self.iconSymbolRole:
+ item[1]['symbol'] = str(value)
+ elif role == qt.Qt.CheckStateRole:
+ item[2] = value
+ elif role == self.showLineRole:
+ item[3] = value
+ elif role == self.showSymbolRole:
+ item[4] = value
+ except ValueError:
+ _logger.warning('Conversion failed:\n\tvalue: %s\n\trole: %s',
+ str(value), str(role))
+ # Can that be right? Read docs again..
+ self.dataChanged.emit(modelIndex, modelIndex)
+ return True
+
+ def insertLegendList(self, row, llist):
+ """
+ :param int row: Determines after which row the items are inserted
+ :param llist: Carries the new legend information
+ :type llist: List
+ """
+ modelIndex = self.createIndex(row, 0)
+ count = len(llist)
+ super(LegendModel, self).beginInsertRows(modelIndex,
+ row,
+ row + count)
+ head = self.legendList[0:row]
+ tail = self.legendList[row:]
+ new = []
+ for (legend, icon) in llist:
+ linestyle = icon.get('linestyle', None)
+ if linestyle in NoLineStyle:
+ # Curve had no line, give it one and hide it
+ # So when toggle line, it will display a solid line
+ showLine = False
+ icon['linestyle'] = '-'
+ else:
+ showLine = True
+
+ symbol = icon.get('symbol', None)
+ if symbol in NoSymbols:
+ # Curve had no symbol, give it one and hide it
+ # So when toggle symbol, it will display 'o'
+ showSymbol = False
+ icon['symbol'] = 'o'
+ else:
+ showSymbol = True
+
+ selected = icon.get('selected', True)
+ item = [legend,
+ icon,
+ selected,
+ showLine,
+ showSymbol]
+ new.append(item)
+ self.legendList = head + new + tail
+ super(LegendModel, self).endInsertRows()
+ return True
+
+ def insertRows(self, row, count, modelIndex=qt.QModelIndex()):
+ raise NotImplementedError('Use LegendModel.insertLegendList instead')
+
+ def removeRow(self, row):
+ return self.removeRows(row, 1)
+
+ def removeRows(self, row, count, modelIndex=qt.QModelIndex()):
+ length = len(self.legendList)
+ if length == 0:
+ # Nothing to do..
+ return True
+ if row < 0 or row >= length:
+ raise IndexError('Index out of range -- ' +
+ 'idx: %d, len: %d' % (row, length))
+ if count == 0:
+ return False
+ super(LegendModel, self).beginRemoveRows(modelIndex,
+ row,
+ row + count)
+ del(self.legendList[row:row + count])
+ super(LegendModel, self).endRemoveRows()
+ return True
+
+ def setEditor(self, event, editor):
+ """
+ :param str event: String that identifies the editor
+ :param editor: Widget used to change data in the underlying model
+ :type editor: QWidget
+ """
+ if event not in self.eventList:
+ raise ValueError('setEditor -- Event must be in %s' %
+ str(self.eventList))
+ self.editorDict[event] = editor
+
+
+class LegendListItemWidget(qt.QItemDelegate):
+ """Object displaying a single item (i.e., a row) in the list."""
+
+ # Notice: LegendListItem does NOT inherit
+ # from QObject, it cannot emit signals!
+
+ def __init__(self, parent=None, itemType=0):
+ super(LegendListItemWidget, self).__init__(parent)
+
+ # Dictionary to render checkboxes
+ self.cbDict = {}
+ self.labelDict = {}
+ self.iconDict = {}
+
+ # Keep checkbox and legend to get sizeHint
+ self.checkbox = qt.QCheckBox()
+ self.legend = qt.QLabel()
+ self.icon = LegendIcon()
+
+ # Context Menu and Editors
+ self.contextMenu = None
+
+ def paint(self, painter, option, modelIndex):
+ """
+ Here be docs..
+
+ :param QPainter painter:
+ :param QStyleOptionViewItem option:
+ :param QModelIndex modelIndex:
+ """
+ painter.save()
+ rect = option.rect
+
+ # Calculate the icon rectangle
+ iconSize = self.icon.sizeHint()
+ # Calculate icon position
+ x = rect.left() + 2
+ y = rect.top() + int(.5 * (rect.height() - iconSize.height()))
+ iconRect = qt.QRect(qt.QPoint(x, y), iconSize)
+
+ # Calculate label rectangle
+ legendSize = qt.QSize(rect.width() - iconSize.width() - 30,
+ rect.height())
+ # Calculate label position
+ x = rect.left() + iconRect.width()
+ y = rect.top()
+ labelRect = qt.QRect(qt.QPoint(x, y), legendSize)
+ labelRect.translate(qt.QPoint(10, 0))
+
+ # Calculate the checkbox rectangle
+ x = rect.right() - 30
+ y = rect.top()
+ chBoxRect = qt.QRect(qt.QPoint(x, y), rect.bottomRight())
+
+ # Remember the rectangles
+ idx = modelIndex.row()
+ self.cbDict[idx] = chBoxRect
+ self.iconDict[idx] = iconRect
+ self.labelDict[idx] = labelRect
+
+ # Draw background first!
+ if option.state & qt.QStyle.State_MouseOver:
+ backgroundBrush = option.palette.highlight()
+ else:
+ backgroundBrush = modelIndex.data(qt.Qt.BackgroundRole)
+ painter.fillRect(rect, backgroundBrush)
+
+ # Draw label
+ legendText = modelIndex.data(qt.Qt.DisplayRole)
+ textBrush = modelIndex.data(qt.Qt.ForegroundRole)
+ textAlign = modelIndex.data(qt.Qt.TextAlignmentRole)
+ painter.setBrush(textBrush)
+ painter.setFont(self.legend.font())
+ painter.drawText(labelRect, textAlign, legendText)
+
+ # Draw icon
+ iconColor = modelIndex.data(LegendModel.iconColorRole)
+ iconLineWidth = modelIndex.data(LegendModel.iconLineWidthRole)
+ iconLineStyle = modelIndex.data(LegendModel.iconLineStyleRole)
+ iconSymbol = modelIndex.data(LegendModel.iconSymbolRole)
+ icon = LegendIcon()
+ icon.resize(iconRect.size())
+ icon.move(iconRect.topRight())
+ icon.showSymbol = modelIndex.data(LegendModel.showSymbolRole)
+ icon.showLine = modelIndex.data(LegendModel.showLineRole)
+ icon.setSymbolColor(iconColor)
+ icon.setLineColor(iconColor)
+ icon.setLineWidth(iconLineWidth)
+ icon.setLineStyle(iconLineStyle)
+ icon.setSymbol(iconSymbol)
+ icon.symbolOutlineBrush = backgroundBrush
+ icon.paint(painter, iconRect, option.palette)
+
+ # Draw the checkbox
+ if modelIndex.data(qt.Qt.CheckStateRole):
+ checkState = qt.Qt.Checked
+ else:
+ checkState = qt.Qt.Unchecked
+
+ self.drawCheck(
+ painter, qt.QStyleOptionViewItem(), chBoxRect, checkState)
+
+ painter.restore()
+
+ def editorEvent(self, event, model, option, modelIndex):
+ # From the docs:
+ # Mouse events are sent to editorEvent()
+ # even if they don't start editing of the item.
+ if event.button() == qt.Qt.RightButton and self.contextMenu:
+ self.contextMenu.exec_(event.globalPos(), modelIndex)
+ return True
+ elif event.button() == qt.Qt.LeftButton:
+ # Check if checkbox was clicked
+ idx = modelIndex.row()
+ cbRect = self.cbDict[idx]
+ if cbRect.contains(event.pos()):
+ # Toggle checkbox
+ model.setData(modelIndex,
+ not modelIndex.data(qt.Qt.CheckStateRole),
+ qt.Qt.CheckStateRole)
+ event.ignore()
+ return True
+ else:
+ return super(LegendListItemWidget, self).editorEvent(
+ event, model, option, modelIndex)
+
+ def createEditor(self, parent, option, idx):
+ _logger.info('### Editor request ###')
+
+ def sizeHint(self, option, idx):
+ # return qt.QSize(68,24)
+ iconSize = self.icon.sizeHint()
+ legendSize = self.legend.sizeHint()
+ checkboxSize = self.checkbox.sizeHint()
+ height = max([iconSize.height(),
+ legendSize.height(),
+ checkboxSize.height()]) + 4
+ width = iconSize.width() + legendSize.width() + checkboxSize.width()
+ return qt.QSize(width, height)
+
+
+class LegendListView(qt.QListView):
+ """Widget displaying a list of curve legends, line style and symbol."""
+
+ sigLegendSignal = qt.Signal(object)
+ """Signal emitting a dict when an action is triggered by the user."""
+
+ __mouseClickedEvent = 'mouseClicked'
+ __checkBoxClickedEvent = 'checkBoxClicked'
+ __legendClickedEvent = 'legendClicked'
+
+ def __init__(self, parent=None, model=None, contextMenu=None):
+ super(LegendListView, self).__init__(parent)
+ self.__lastButton = None
+ self.__lastClickPos = None
+ self.__lastModelIdx = None
+ # Set default delegate
+ self.setItemDelegate(LegendListItemWidget())
+ # Set default editors
+ # self.setSizePolicy(qt.QSizePolicy.MinimumExpanding,
+ # qt.QSizePolicy.MinimumExpanding)
+ # Set edit triggers by hand using self.edit(QModelIndex)
+ # in mousePressEvent (better to control than signals)
+ self.setEditTriggers(qt.QAbstractItemView.NoEditTriggers)
+
+ # Control layout
+ # self.setBatchSize(2)
+ # self.setLayoutMode(qt.QListView.Batched)
+ # self.setFlow(qt.QListView.LeftToRight)
+
+ # Control selection
+ self.setSelectionMode(qt.QAbstractItemView.NoSelection)
+
+ if model is None:
+ model = LegendModel()
+ self.setModel(model)
+ self.setContextMenu(contextMenu)
+
+ def setLegendList(self, legendList, row=None):
+ self.clear()
+ if row is None:
+ row = 0
+ model = self.model()
+ model.insertLegendList(row, legendList)
+ _logger.debug('LegendListView.setLegendList(legendList) finished')
+
+ def clear(self):
+ model = self.model()
+ model.removeRows(0, model.rowCount())
+ _logger.debug('LegendListView.clear() finished')
+
+ def setContextMenu(self, contextMenu=None):
+ delegate = self.itemDelegate()
+ if isinstance(delegate, LegendListItemWidget) and self.model():
+ if contextMenu is None:
+ delegate.contextMenu = LegendListContextMenu(self.model())
+ delegate.contextMenu.sigContextMenu.connect(
+ self._contextMenuSlot)
+ else:
+ delegate.contextMenu = contextMenu
+
+ def __getitem__(self, idx):
+ model = self.model()
+ try:
+ item = model[idx]
+ except ValueError:
+ item = None
+ return item
+
+ def _contextMenuSlot(self, ddict):
+ self.sigLegendSignal.emit(ddict)
+
+ def mousePressEvent(self, event):
+ self.__lastButton = event.button()
+ self.__lastPosition = event.pos()
+ super(LegendListView, self).mousePressEvent(event)
+ # call _handleMouseClick after editing was handled
+ # If right click (context menu) is aborted, no
+ # signal is emitted..
+ self._handleMouseClick(self.indexAt(self.__lastPosition))
+
+ def mouseDoubleClickEvent(self, event):
+ self.__lastButton = event.button()
+ self.__lastPosition = event.pos()
+ super(LegendListView, self).mouseDoubleClickEvent(event)
+ # call _handleMouseClick after editing was handled
+ # If right click (context menu) is aborted, no
+ # signal is emitted..
+ self._handleMouseClick(self.indexAt(self.__lastPosition))
+
+ def mouseMoveEvent(self, event):
+ # LegendListView.mouseMoveEvent is overwritten
+ # to suppress unwanted behavior in the delegate.
+ pass
+
+ def mouseReleaseEvent(self, event):
+ # LegendListView.mouseReleaseEvent is overwritten
+ # to subpress unwanted behavior in the delegate.
+ pass
+
+ def _handleMouseClick(self, modelIndex):
+ """
+ Distinguish between mouse click on Legend
+ and mouse click on CheckBox by setting the
+ currentCheckState attribute in LegendListItem.
+
+ Emits signal sigLegendSignal(ddict)
+
+ :param QModelIndex modelIndex: index of the clicked item
+ """
+ _logger.debug('self._handleMouseClick called')
+ if self.__lastButton not in [qt.Qt.LeftButton,
+ qt.Qt.RightButton]:
+ return
+ if not modelIndex.isValid():
+ _logger.debug('_handleMouseClick -- Invalid QModelIndex')
+ return
+ # model = self.model()
+ idx = modelIndex.row()
+
+ delegate = self.itemDelegate()
+ cbClicked = False
+ if isinstance(delegate, LegendListItemWidget):
+ for cbRect in delegate.cbDict.values():
+ if cbRect.contains(self.__lastPosition):
+ cbClicked = True
+ break
+
+ # TODO: Check for doubleclicks on legend/icon and spawn editors
+
+ ddict = {
+ 'legend': str(modelIndex.data(qt.Qt.DisplayRole)),
+ 'icon': {
+ 'linewidth': str(modelIndex.data(
+ LegendModel.iconLineWidthRole)),
+ 'linestyle': str(modelIndex.data(
+ LegendModel.iconLineStyleRole)),
+ 'symbol': str(modelIndex.data(LegendModel.iconSymbolRole))
+ },
+ 'selected': modelIndex.data(qt.Qt.CheckStateRole),
+ 'type': str(modelIndex.data())
+ }
+ if self.__lastButton == qt.Qt.RightButton:
+ _logger.debug('Right clicked')
+ ddict['button'] = "right"
+ ddict['event'] = self.__mouseClickedEvent
+ elif cbClicked:
+ _logger.debug('CheckBox clicked')
+ ddict['button'] = "left"
+ ddict['event'] = self.__checkBoxClickedEvent
+ else:
+ _logger.debug('Legend clicked')
+ ddict['button'] = "left"
+ ddict['event'] = self.__legendClickedEvent
+ _logger.debug(' idx: %d\n ddict: %s', idx, str(ddict))
+ self.sigLegendSignal.emit(ddict)
+
+
+class LegendListContextMenu(qt.QMenu):
+ """Contextual menu associated to items in a :class:`LegendListView`."""
+
+ sigContextMenu = qt.Signal(object)
+ """Signal emitting a dict upon contextual menu actions."""
+
+ def __init__(self, model):
+ super(LegendListContextMenu, self).__init__(parent=None)
+ self.model = model
+
+ self.addAction('Set Active', self.setActiveAction)
+ self.addAction('Map to left', self.mapToLeftAction)
+ self.addAction('Map to right', self.mapToRightAction)
+
+ self._pointsAction = self.addAction(
+ 'Points', self.togglePointsAction)
+ self._pointsAction.setCheckable(True)
+
+ self._linesAction = self.addAction('Lines', self.toggleLinesAction)
+ self._linesAction.setCheckable(True)
+
+ self.addAction('Remove curve', self.removeItemAction)
+ self.addAction('Rename curve', self.renameItemAction)
+
+ def exec_(self, pos, idx):
+ self.__currentIdx = idx
+
+ # Set checkable action state
+ modelIndex = self.currentIdx()
+ self._pointsAction.setChecked(
+ modelIndex.data(LegendModel.showSymbolRole))
+ self._linesAction.setChecked(
+ modelIndex.data(LegendModel.showLineRole))
+
+ super(LegendListContextMenu, self).popup(pos)
+
+ def currentIdx(self):
+ return self.__currentIdx
+
+ def mapToLeftAction(self):
+ _logger.debug('LegendListContextMenu.mapToLeftAction called')
+ modelIndex = self.currentIdx()
+ legend = str(modelIndex.data(qt.Qt.DisplayRole))
+ ddict = {
+ 'legend': legend,
+ 'label': legend,
+ 'selected': modelIndex.data(qt.Qt.CheckStateRole),
+ 'type': str(modelIndex.data()),
+ 'event': "mapToLeft"
+ }
+ self.sigContextMenu.emit(ddict)
+
+ def mapToRightAction(self):
+ _logger.debug('LegendListContextMenu.mapToRightAction called')
+ modelIndex = self.currentIdx()
+ legend = str(modelIndex.data(qt.Qt.DisplayRole))
+ ddict = {
+ 'legend': legend,
+ 'label': legend,
+ 'selected': modelIndex.data(qt.Qt.CheckStateRole),
+ 'type': str(modelIndex.data()),
+ 'event': "mapToRight"
+ }
+ self.sigContextMenu.emit(ddict)
+
+ def removeItemAction(self):
+ _logger.debug('LegendListContextMenu.removeCurveAction called')
+ modelIndex = self.currentIdx()
+ legend = str(modelIndex.data(qt.Qt.DisplayRole))
+ ddict = {
+ 'legend': legend,
+ 'label': legend,
+ 'selected': modelIndex.data(qt.Qt.CheckStateRole),
+ 'type': str(modelIndex.data()),
+ 'event': "removeCurve"
+ }
+ self.model.removeRow(modelIndex.row())
+ self.sigContextMenu.emit(ddict)
+
+ def renameItemAction(self):
+ _logger.debug('LegendListContextMenu.renameCurveAction called')
+ modelIndex = self.currentIdx()
+ legend = str(modelIndex.data(qt.Qt.DisplayRole))
+ ddict = {
+ 'legend': legend,
+ 'label': legend,
+ 'selected': modelIndex.data(qt.Qt.CheckStateRole),
+ 'type': str(modelIndex.data()),
+ 'event': "renameCurve"
+ }
+ self.sigContextMenu.emit(ddict)
+
+ def toggleLinesAction(self):
+ modelIndex = self.currentIdx()
+ legend = str(modelIndex.data(qt.Qt.DisplayRole))
+ ddict = {
+ 'legend': legend,
+ 'label': legend,
+ 'selected': modelIndex.data(qt.Qt.CheckStateRole),
+ 'type': str(modelIndex.data()),
+ }
+ linestyle = modelIndex.data(LegendModel.iconLineStyleRole)
+ visible = not modelIndex.data(LegendModel.showLineRole)
+ _logger.debug('toggleLinesAction -- lines visible: %s', str(visible))
+ ddict['event'] = "toggleLine"
+ ddict['line'] = visible
+ ddict['linestyle'] = linestyle if visible else ''
+ self.model.setData(modelIndex, visible, LegendModel.showLineRole)
+ self.sigContextMenu.emit(ddict)
+
+ def togglePointsAction(self):
+ modelIndex = self.currentIdx()
+ legend = str(modelIndex.data(qt.Qt.DisplayRole))
+ ddict = {
+ 'legend': legend,
+ 'label': legend,
+ 'selected': modelIndex.data(qt.Qt.CheckStateRole),
+ 'type': str(modelIndex.data()),
+ }
+ flag = modelIndex.data(LegendModel.showSymbolRole)
+ symbol = modelIndex.data(LegendModel.iconSymbolRole)
+ visible = not flag or symbol in NoSymbols
+ _logger.debug(
+ 'togglePointsAction -- Symbols visible: %s', str(visible))
+
+ ddict['event'] = "togglePoints"
+ ddict['points'] = visible
+ ddict['symbol'] = symbol if visible else ''
+ self.model.setData(modelIndex, visible, LegendModel.showSymbolRole)
+ self.sigContextMenu.emit(ddict)
+
+ def setActiveAction(self):
+ modelIndex = self.currentIdx()
+ legend = str(modelIndex.data(qt.Qt.DisplayRole))
+ _logger.debug('setActiveAction -- active curve: %s', legend)
+ ddict = {
+ 'legend': legend,
+ 'label': legend,
+ 'selected': modelIndex.data(qt.Qt.CheckStateRole),
+ 'type': str(modelIndex.data()),
+ 'event': "setActiveCurve",
+ }
+ self.sigContextMenu.emit(ddict)
+
+
+class RenameCurveDialog(qt.QDialog):
+ """Dialog box to input the name of a curve."""
+
+ def __init__(self, parent=None, current="", curves=()):
+ super(RenameCurveDialog, self).__init__(parent)
+ self.setWindowTitle("Rename Curve %s" % current)
+ self.curves = curves
+ layout = qt.QVBoxLayout(self)
+ self.lineEdit = qt.QLineEdit(self)
+ self.lineEdit.setText(current)
+ self.hbox = qt.QWidget(self)
+ self.hboxLayout = qt.QHBoxLayout(self.hbox)
+ self.hboxLayout.addStretch(1)
+ self.okButton = qt.QPushButton(self.hbox)
+ self.okButton.setText('OK')
+ self.hboxLayout.addWidget(self.okButton)
+ self.cancelButton = qt.QPushButton(self.hbox)
+ self.cancelButton.setText('Cancel')
+ self.hboxLayout.addWidget(self.cancelButton)
+ self.hboxLayout.addStretch(1)
+ layout.addWidget(self.lineEdit)
+ layout.addWidget(self.hbox)
+ self.okButton.clicked.connect(self.preAccept)
+ self.cancelButton.clicked.connect(self.reject)
+
+ def preAccept(self):
+ text = str(self.lineEdit.text())
+ addedText = ""
+ if len(text):
+ if text not in self.curves:
+ self.accept()
+ return
+ else:
+ addedText = "Curve already exists."
+ text = "Invalid Curve Name"
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setWindowTitle(text)
+ text += "\n%s" % addedText
+ msg.setText(text)
+ msg.exec_()
+
+ def getText(self):
+ return str(self.lineEdit.text())
+
+
+class LegendsDockWidget(qt.QDockWidget):
+ """QDockWidget with a :class:`LegendSelector` connected to a PlotWindow.
+
+ It makes the link between the LegendListView widget and the PlotWindow.
+
+ :param parent: See :class:`QDockWidget`
+ :param plot: :class:`.PlotWindow` instance on which to operate
+ """
+
+ def __init__(self, parent=None, plot=None):
+ assert plot is not None
+ self._plotRef = weakref.ref(plot)
+ self._isConnected = False # True if widget connected to plot signals
+
+ super(LegendsDockWidget, self).__init__("Legends", parent)
+
+ self._legendWidget = LegendListView()
+
+ self.layout().setContentsMargins(0, 0, 0, 0)
+ self.setWidget(self._legendWidget)
+
+ self.visibilityChanged.connect(
+ self._visibilityChangedHandler)
+
+ self._legendWidget.sigLegendSignal.connect(self._legendSignalHandler)
+
+ @property
+ def plot(self):
+ """The :class:`.PlotWindow` this widget is attached to."""
+ return self._plotRef()
+
+ def renameCurve(self, oldLegend, newLegend):
+ """Change the name of a curve using remove and addCurve
+
+ :param str oldLegend: The legend of the curve to be change
+ :param str newLegend: The new legend of the curve
+ """
+ curve = self.plot.getCurve(oldLegend)
+ self.plot.remove(oldLegend, kind='curve')
+ self.plot.addCurve(curve.getXData(copy=False),
+ curve.getYData(copy=False),
+ legend=newLegend,
+ info=curve.getInfo(),
+ color=curve.getColor(),
+ symbol=curve.getSymbol(),
+ linewidth=curve.getLineWidth(),
+ linestyle=curve.getLineStyle(),
+ xlabel=curve.getXLabel(),
+ ylabel=curve.getYLabel(),
+ xerror=curve.getXErrorData(copy=False),
+ yerror=curve.getYErrorData(copy=False),
+ z=curve.getZValue(),
+ selectable=curve.isSelectable(),
+ fill=curve.isFill(),
+ resetzoom=False)
+
+ def _legendSignalHandler(self, ddict):
+ """Handles events from the LegendListView signal"""
+ _logger.debug("Legend signal ddict = %s", str(ddict))
+
+ if ddict['event'] == "legendClicked":
+ if ddict['button'] == "left":
+ self.plot.setActiveCurve(ddict['legend'])
+
+ elif ddict['event'] == "removeCurve":
+ self.plot.removeCurve(ddict['legend'])
+
+ elif ddict['event'] == "renameCurve":
+ curveList = self.plot.getAllCurves(just_legend=True)
+ oldLegend = ddict['legend']
+ dialog = RenameCurveDialog(self.plot, oldLegend, curveList)
+ ret = dialog.exec_()
+ if ret:
+ newLegend = dialog.getText()
+ self.renameCurve(oldLegend, newLegend)
+
+ elif ddict['event'] == "setActiveCurve":
+ self.plot.setActiveCurve(ddict['legend'])
+
+ elif ddict['event'] == "checkBoxClicked":
+ self.plot.hideCurve(ddict['legend'], not ddict['selected'])
+
+ elif ddict['event'] in ["mapToRight", "mapToLeft"]:
+ legend = ddict['legend']
+ curve = self.plot.getCurve(legend)
+ yaxis = 'right' if ddict['event'] == 'mapToRight' else 'left'
+ self.plot.addCurve(x=curve.getXData(copy=False),
+ y=curve.getYData(copy=False),
+ legend=curve.getLegend(),
+ info=curve.getInfo(),
+ yaxis=yaxis)
+
+ elif ddict['event'] == "togglePoints":
+ legend = ddict['legend']
+ curve = self.plot.getCurve(legend)
+ symbol = ddict['symbol'] if ddict['points'] else ''
+ self.plot.addCurve(x=curve.getXData(copy=False),
+ y=curve.getYData(copy=False),
+ legend=curve.getLegend(),
+ info=curve.getInfo(),
+ symbol=symbol)
+
+ elif ddict['event'] == "toggleLine":
+ legend = ddict['legend']
+ curve = self.plot.getCurve(legend)
+ linestyle = ddict['linestyle'] if ddict['line'] else ''
+ self.plot.addCurve(x=curve.getXData(copy=False),
+ y=curve.getYData(copy=False),
+ legend=curve.getLegend(),
+ info=curve.getInfo(),
+ linestyle=linestyle)
+
+ else:
+ _logger.debug("unhandled event %s", str(ddict['event']))
+
+ def updateLegends(self, *args):
+ """Sync the LegendSelector widget displayed info with the plot.
+ """
+ legendList = []
+ for curve in self.plot.getAllCurves(withhidden=True):
+ legend = curve.getLegend()
+ # Use active color if curve is active
+ if legend == self.plot.getActiveCurve(just_legend=True):
+ color = qt.QColor(self.plot.getActiveCurveColor())
+ else:
+ color = qt.QColor.fromRgbF(*curve.getColor())
+
+ curveInfo = {
+ 'color': color,
+ 'linewidth': curve.getLineWidth(),
+ 'linestyle': curve.getLineStyle(),
+ 'symbol': curve.getSymbol(),
+ 'selected': not self.plot.isCurveHidden(legend)}
+ legendList.append((legend, curveInfo))
+
+ self._legendWidget.setLegendList(legendList)
+
+ def _visibilityChangedHandler(self, visible):
+ if visible:
+ self.updateLegends()
+ if not self._isConnected:
+ self.plot.sigContentChanged.connect(self.updateLegends)
+ self.plot.sigActiveCurveChanged.connect(self.updateLegends)
+ self._isConnected = True
+ else:
+ if self._isConnected:
+ self.plot.sigContentChanged.disconnect(self.updateLegends)
+ self.plot.sigActiveCurveChanged.disconnect(self.updateLegends)
+ self._isConnected = False
+
+ def showEvent(self, event):
+ """Make sure this widget is raised when it is shown
+ (when it is first created as a tab in PlotWindow or when it is shown
+ again after hiding).
+ """
+ self.raise_()
diff --git a/silx/gui/plot/MPLColormap.py b/silx/gui/plot/MPLColormap.py
new file mode 100644
index 0000000..49b11d7
--- /dev/null
+++ b/silx/gui/plot/MPLColormap.py
@@ -0,0 +1,1062 @@
+# New matplotlib colormaps by Nathaniel J. Smith, Stefan van der Walt,
+# and (in the case of viridis) Eric Firing.
+#
+# This file and the colormaps in it are released under the CC0 license /
+# public domain dedication. We would appreciate credit if you use or
+# redistribute these colormaps, but do not impose any legal restrictions.
+#
+# To the extent possible under law, the persons who associated CC0 with
+# mpl-colormaps have waived all copyright and related or neighboring rights
+# to mpl-colormaps.
+#
+# You should have received a copy of the CC0 legalcode along with this
+# work. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
+"""Matplotlib's new colormaps"""
+
+
+from matplotlib.colors import ListedColormap
+
+
+__all__ = ['magma', 'inferno', 'plasma', 'viridis']
+
+_magma_data = [[0.001462, 0.000466, 0.013866],
+ [0.002258, 0.001295, 0.018331],
+ [0.003279, 0.002305, 0.023708],
+ [0.004512, 0.003490, 0.029965],
+ [0.005950, 0.004843, 0.037130],
+ [0.007588, 0.006356, 0.044973],
+ [0.009426, 0.008022, 0.052844],
+ [0.011465, 0.009828, 0.060750],
+ [0.013708, 0.011771, 0.068667],
+ [0.016156, 0.013840, 0.076603],
+ [0.018815, 0.016026, 0.084584],
+ [0.021692, 0.018320, 0.092610],
+ [0.024792, 0.020715, 0.100676],
+ [0.028123, 0.023201, 0.108787],
+ [0.031696, 0.025765, 0.116965],
+ [0.035520, 0.028397, 0.125209],
+ [0.039608, 0.031090, 0.133515],
+ [0.043830, 0.033830, 0.141886],
+ [0.048062, 0.036607, 0.150327],
+ [0.052320, 0.039407, 0.158841],
+ [0.056615, 0.042160, 0.167446],
+ [0.060949, 0.044794, 0.176129],
+ [0.065330, 0.047318, 0.184892],
+ [0.069764, 0.049726, 0.193735],
+ [0.074257, 0.052017, 0.202660],
+ [0.078815, 0.054184, 0.211667],
+ [0.083446, 0.056225, 0.220755],
+ [0.088155, 0.058133, 0.229922],
+ [0.092949, 0.059904, 0.239164],
+ [0.097833, 0.061531, 0.248477],
+ [0.102815, 0.063010, 0.257854],
+ [0.107899, 0.064335, 0.267289],
+ [0.113094, 0.065492, 0.276784],
+ [0.118405, 0.066479, 0.286321],
+ [0.123833, 0.067295, 0.295879],
+ [0.129380, 0.067935, 0.305443],
+ [0.135053, 0.068391, 0.315000],
+ [0.140858, 0.068654, 0.324538],
+ [0.146785, 0.068738, 0.334011],
+ [0.152839, 0.068637, 0.343404],
+ [0.159018, 0.068354, 0.352688],
+ [0.165308, 0.067911, 0.361816],
+ [0.171713, 0.067305, 0.370771],
+ [0.178212, 0.066576, 0.379497],
+ [0.184801, 0.065732, 0.387973],
+ [0.191460, 0.064818, 0.396152],
+ [0.198177, 0.063862, 0.404009],
+ [0.204935, 0.062907, 0.411514],
+ [0.211718, 0.061992, 0.418647],
+ [0.218512, 0.061158, 0.425392],
+ [0.225302, 0.060445, 0.431742],
+ [0.232077, 0.059889, 0.437695],
+ [0.238826, 0.059517, 0.443256],
+ [0.245543, 0.059352, 0.448436],
+ [0.252220, 0.059415, 0.453248],
+ [0.258857, 0.059706, 0.457710],
+ [0.265447, 0.060237, 0.461840],
+ [0.271994, 0.060994, 0.465660],
+ [0.278493, 0.061978, 0.469190],
+ [0.284951, 0.063168, 0.472451],
+ [0.291366, 0.064553, 0.475462],
+ [0.297740, 0.066117, 0.478243],
+ [0.304081, 0.067835, 0.480812],
+ [0.310382, 0.069702, 0.483186],
+ [0.316654, 0.071690, 0.485380],
+ [0.322899, 0.073782, 0.487408],
+ [0.329114, 0.075972, 0.489287],
+ [0.335308, 0.078236, 0.491024],
+ [0.341482, 0.080564, 0.492631],
+ [0.347636, 0.082946, 0.494121],
+ [0.353773, 0.085373, 0.495501],
+ [0.359898, 0.087831, 0.496778],
+ [0.366012, 0.090314, 0.497960],
+ [0.372116, 0.092816, 0.499053],
+ [0.378211, 0.095332, 0.500067],
+ [0.384299, 0.097855, 0.501002],
+ [0.390384, 0.100379, 0.501864],
+ [0.396467, 0.102902, 0.502658],
+ [0.402548, 0.105420, 0.503386],
+ [0.408629, 0.107930, 0.504052],
+ [0.414709, 0.110431, 0.504662],
+ [0.420791, 0.112920, 0.505215],
+ [0.426877, 0.115395, 0.505714],
+ [0.432967, 0.117855, 0.506160],
+ [0.439062, 0.120298, 0.506555],
+ [0.445163, 0.122724, 0.506901],
+ [0.451271, 0.125132, 0.507198],
+ [0.457386, 0.127522, 0.507448],
+ [0.463508, 0.129893, 0.507652],
+ [0.469640, 0.132245, 0.507809],
+ [0.475780, 0.134577, 0.507921],
+ [0.481929, 0.136891, 0.507989],
+ [0.488088, 0.139186, 0.508011],
+ [0.494258, 0.141462, 0.507988],
+ [0.500438, 0.143719, 0.507920],
+ [0.506629, 0.145958, 0.507806],
+ [0.512831, 0.148179, 0.507648],
+ [0.519045, 0.150383, 0.507443],
+ [0.525270, 0.152569, 0.507192],
+ [0.531507, 0.154739, 0.506895],
+ [0.537755, 0.156894, 0.506551],
+ [0.544015, 0.159033, 0.506159],
+ [0.550287, 0.161158, 0.505719],
+ [0.556571, 0.163269, 0.505230],
+ [0.562866, 0.165368, 0.504692],
+ [0.569172, 0.167454, 0.504105],
+ [0.575490, 0.169530, 0.503466],
+ [0.581819, 0.171596, 0.502777],
+ [0.588158, 0.173652, 0.502035],
+ [0.594508, 0.175701, 0.501241],
+ [0.600868, 0.177743, 0.500394],
+ [0.607238, 0.179779, 0.499492],
+ [0.613617, 0.181811, 0.498536],
+ [0.620005, 0.183840, 0.497524],
+ [0.626401, 0.185867, 0.496456],
+ [0.632805, 0.187893, 0.495332],
+ [0.639216, 0.189921, 0.494150],
+ [0.645633, 0.191952, 0.492910],
+ [0.652056, 0.193986, 0.491611],
+ [0.658483, 0.196027, 0.490253],
+ [0.664915, 0.198075, 0.488836],
+ [0.671349, 0.200133, 0.487358],
+ [0.677786, 0.202203, 0.485819],
+ [0.684224, 0.204286, 0.484219],
+ [0.690661, 0.206384, 0.482558],
+ [0.697098, 0.208501, 0.480835],
+ [0.703532, 0.210638, 0.479049],
+ [0.709962, 0.212797, 0.477201],
+ [0.716387, 0.214982, 0.475290],
+ [0.722805, 0.217194, 0.473316],
+ [0.729216, 0.219437, 0.471279],
+ [0.735616, 0.221713, 0.469180],
+ [0.742004, 0.224025, 0.467018],
+ [0.748378, 0.226377, 0.464794],
+ [0.754737, 0.228772, 0.462509],
+ [0.761077, 0.231214, 0.460162],
+ [0.767398, 0.233705, 0.457755],
+ [0.773695, 0.236249, 0.455289],
+ [0.779968, 0.238851, 0.452765],
+ [0.786212, 0.241514, 0.450184],
+ [0.792427, 0.244242, 0.447543],
+ [0.798608, 0.247040, 0.444848],
+ [0.804752, 0.249911, 0.442102],
+ [0.810855, 0.252861, 0.439305],
+ [0.816914, 0.255895, 0.436461],
+ [0.822926, 0.259016, 0.433573],
+ [0.828886, 0.262229, 0.430644],
+ [0.834791, 0.265540, 0.427671],
+ [0.840636, 0.268953, 0.424666],
+ [0.846416, 0.272473, 0.421631],
+ [0.852126, 0.276106, 0.418573],
+ [0.857763, 0.279857, 0.415496],
+ [0.863320, 0.283729, 0.412403],
+ [0.868793, 0.287728, 0.409303],
+ [0.874176, 0.291859, 0.406205],
+ [0.879464, 0.296125, 0.403118],
+ [0.884651, 0.300530, 0.400047],
+ [0.889731, 0.305079, 0.397002],
+ [0.894700, 0.309773, 0.393995],
+ [0.899552, 0.314616, 0.391037],
+ [0.904281, 0.319610, 0.388137],
+ [0.908884, 0.324755, 0.385308],
+ [0.913354, 0.330052, 0.382563],
+ [0.917689, 0.335500, 0.379915],
+ [0.921884, 0.341098, 0.377376],
+ [0.925937, 0.346844, 0.374959],
+ [0.929845, 0.352734, 0.372677],
+ [0.933606, 0.358764, 0.370541],
+ [0.937221, 0.364929, 0.368567],
+ [0.940687, 0.371224, 0.366762],
+ [0.944006, 0.377643, 0.365136],
+ [0.947180, 0.384178, 0.363701],
+ [0.950210, 0.390820, 0.362468],
+ [0.953099, 0.397563, 0.361438],
+ [0.955849, 0.404400, 0.360619],
+ [0.958464, 0.411324, 0.360014],
+ [0.960949, 0.418323, 0.359630],
+ [0.963310, 0.425390, 0.359469],
+ [0.965549, 0.432519, 0.359529],
+ [0.967671, 0.439703, 0.359810],
+ [0.969680, 0.446936, 0.360311],
+ [0.971582, 0.454210, 0.361030],
+ [0.973381, 0.461520, 0.361965],
+ [0.975082, 0.468861, 0.363111],
+ [0.976690, 0.476226, 0.364466],
+ [0.978210, 0.483612, 0.366025],
+ [0.979645, 0.491014, 0.367783],
+ [0.981000, 0.498428, 0.369734],
+ [0.982279, 0.505851, 0.371874],
+ [0.983485, 0.513280, 0.374198],
+ [0.984622, 0.520713, 0.376698],
+ [0.985693, 0.528148, 0.379371],
+ [0.986700, 0.535582, 0.382210],
+ [0.987646, 0.543015, 0.385210],
+ [0.988533, 0.550446, 0.388365],
+ [0.989363, 0.557873, 0.391671],
+ [0.990138, 0.565296, 0.395122],
+ [0.990871, 0.572706, 0.398714],
+ [0.991558, 0.580107, 0.402441],
+ [0.992196, 0.587502, 0.406299],
+ [0.992785, 0.594891, 0.410283],
+ [0.993326, 0.602275, 0.414390],
+ [0.993834, 0.609644, 0.418613],
+ [0.994309, 0.616999, 0.422950],
+ [0.994738, 0.624350, 0.427397],
+ [0.995122, 0.631696, 0.431951],
+ [0.995480, 0.639027, 0.436607],
+ [0.995810, 0.646344, 0.441361],
+ [0.996096, 0.653659, 0.446213],
+ [0.996341, 0.660969, 0.451160],
+ [0.996580, 0.668256, 0.456192],
+ [0.996775, 0.675541, 0.461314],
+ [0.996925, 0.682828, 0.466526],
+ [0.997077, 0.690088, 0.471811],
+ [0.997186, 0.697349, 0.477182],
+ [0.997254, 0.704611, 0.482635],
+ [0.997325, 0.711848, 0.488154],
+ [0.997351, 0.719089, 0.493755],
+ [0.997351, 0.726324, 0.499428],
+ [0.997341, 0.733545, 0.505167],
+ [0.997285, 0.740772, 0.510983],
+ [0.997228, 0.747981, 0.516859],
+ [0.997138, 0.755190, 0.522806],
+ [0.997019, 0.762398, 0.528821],
+ [0.996898, 0.769591, 0.534892],
+ [0.996727, 0.776795, 0.541039],
+ [0.996571, 0.783977, 0.547233],
+ [0.996369, 0.791167, 0.553499],
+ [0.996162, 0.798348, 0.559820],
+ [0.995932, 0.805527, 0.566202],
+ [0.995680, 0.812706, 0.572645],
+ [0.995424, 0.819875, 0.579140],
+ [0.995131, 0.827052, 0.585701],
+ [0.994851, 0.834213, 0.592307],
+ [0.994524, 0.841387, 0.598983],
+ [0.994222, 0.848540, 0.605696],
+ [0.993866, 0.855711, 0.612482],
+ [0.993545, 0.862859, 0.619299],
+ [0.993170, 0.870024, 0.626189],
+ [0.992831, 0.877168, 0.633109],
+ [0.992440, 0.884330, 0.640099],
+ [0.992089, 0.891470, 0.647116],
+ [0.991688, 0.898627, 0.654202],
+ [0.991332, 0.905763, 0.661309],
+ [0.990930, 0.912915, 0.668481],
+ [0.990570, 0.920049, 0.675675],
+ [0.990175, 0.927196, 0.682926],
+ [0.989815, 0.934329, 0.690198],
+ [0.989434, 0.941470, 0.697519],
+ [0.989077, 0.948604, 0.704863],
+ [0.988717, 0.955742, 0.712242],
+ [0.988367, 0.962878, 0.719649],
+ [0.988033, 0.970012, 0.727077],
+ [0.987691, 0.977154, 0.734536],
+ [0.987387, 0.984288, 0.742002],
+ [0.987053, 0.991438, 0.749504]]
+
+_inferno_data = [[0.001462, 0.000466, 0.013866],
+ [0.002267, 0.001270, 0.018570],
+ [0.003299, 0.002249, 0.024239],
+ [0.004547, 0.003392, 0.030909],
+ [0.006006, 0.004692, 0.038558],
+ [0.007676, 0.006136, 0.046836],
+ [0.009561, 0.007713, 0.055143],
+ [0.011663, 0.009417, 0.063460],
+ [0.013995, 0.011225, 0.071862],
+ [0.016561, 0.013136, 0.080282],
+ [0.019373, 0.015133, 0.088767],
+ [0.022447, 0.017199, 0.097327],
+ [0.025793, 0.019331, 0.105930],
+ [0.029432, 0.021503, 0.114621],
+ [0.033385, 0.023702, 0.123397],
+ [0.037668, 0.025921, 0.132232],
+ [0.042253, 0.028139, 0.141141],
+ [0.046915, 0.030324, 0.150164],
+ [0.051644, 0.032474, 0.159254],
+ [0.056449, 0.034569, 0.168414],
+ [0.061340, 0.036590, 0.177642],
+ [0.066331, 0.038504, 0.186962],
+ [0.071429, 0.040294, 0.196354],
+ [0.076637, 0.041905, 0.205799],
+ [0.081962, 0.043328, 0.215289],
+ [0.087411, 0.044556, 0.224813],
+ [0.092990, 0.045583, 0.234358],
+ [0.098702, 0.046402, 0.243904],
+ [0.104551, 0.047008, 0.253430],
+ [0.110536, 0.047399, 0.262912],
+ [0.116656, 0.047574, 0.272321],
+ [0.122908, 0.047536, 0.281624],
+ [0.129285, 0.047293, 0.290788],
+ [0.135778, 0.046856, 0.299776],
+ [0.142378, 0.046242, 0.308553],
+ [0.149073, 0.045468, 0.317085],
+ [0.155850, 0.044559, 0.325338],
+ [0.162689, 0.043554, 0.333277],
+ [0.169575, 0.042489, 0.340874],
+ [0.176493, 0.041402, 0.348111],
+ [0.183429, 0.040329, 0.354971],
+ [0.190367, 0.039309, 0.361447],
+ [0.197297, 0.038400, 0.367535],
+ [0.204209, 0.037632, 0.373238],
+ [0.211095, 0.037030, 0.378563],
+ [0.217949, 0.036615, 0.383522],
+ [0.224763, 0.036405, 0.388129],
+ [0.231538, 0.036405, 0.392400],
+ [0.238273, 0.036621, 0.396353],
+ [0.244967, 0.037055, 0.400007],
+ [0.251620, 0.037705, 0.403378],
+ [0.258234, 0.038571, 0.406485],
+ [0.264810, 0.039647, 0.409345],
+ [0.271347, 0.040922, 0.411976],
+ [0.277850, 0.042353, 0.414392],
+ [0.284321, 0.043933, 0.416608],
+ [0.290763, 0.045644, 0.418637],
+ [0.297178, 0.047470, 0.420491],
+ [0.303568, 0.049396, 0.422182],
+ [0.309935, 0.051407, 0.423721],
+ [0.316282, 0.053490, 0.425116],
+ [0.322610, 0.055634, 0.426377],
+ [0.328921, 0.057827, 0.427511],
+ [0.335217, 0.060060, 0.428524],
+ [0.341500, 0.062325, 0.429425],
+ [0.347771, 0.064616, 0.430217],
+ [0.354032, 0.066925, 0.430906],
+ [0.360284, 0.069247, 0.431497],
+ [0.366529, 0.071579, 0.431994],
+ [0.372768, 0.073915, 0.432400],
+ [0.379001, 0.076253, 0.432719],
+ [0.385228, 0.078591, 0.432955],
+ [0.391453, 0.080927, 0.433109],
+ [0.397674, 0.083257, 0.433183],
+ [0.403894, 0.085580, 0.433179],
+ [0.410113, 0.087896, 0.433098],
+ [0.416331, 0.090203, 0.432943],
+ [0.422549, 0.092501, 0.432714],
+ [0.428768, 0.094790, 0.432412],
+ [0.434987, 0.097069, 0.432039],
+ [0.441207, 0.099338, 0.431594],
+ [0.447428, 0.101597, 0.431080],
+ [0.453651, 0.103848, 0.430498],
+ [0.459875, 0.106089, 0.429846],
+ [0.466100, 0.108322, 0.429125],
+ [0.472328, 0.110547, 0.428334],
+ [0.478558, 0.112764, 0.427475],
+ [0.484789, 0.114974, 0.426548],
+ [0.491022, 0.117179, 0.425552],
+ [0.497257, 0.119379, 0.424488],
+ [0.503493, 0.121575, 0.423356],
+ [0.509730, 0.123769, 0.422156],
+ [0.515967, 0.125960, 0.420887],
+ [0.522206, 0.128150, 0.419549],
+ [0.528444, 0.130341, 0.418142],
+ [0.534683, 0.132534, 0.416667],
+ [0.540920, 0.134729, 0.415123],
+ [0.547157, 0.136929, 0.413511],
+ [0.553392, 0.139134, 0.411829],
+ [0.559624, 0.141346, 0.410078],
+ [0.565854, 0.143567, 0.408258],
+ [0.572081, 0.145797, 0.406369],
+ [0.578304, 0.148039, 0.404411],
+ [0.584521, 0.150294, 0.402385],
+ [0.590734, 0.152563, 0.400290],
+ [0.596940, 0.154848, 0.398125],
+ [0.603139, 0.157151, 0.395891],
+ [0.609330, 0.159474, 0.393589],
+ [0.615513, 0.161817, 0.391219],
+ [0.621685, 0.164184, 0.388781],
+ [0.627847, 0.166575, 0.386276],
+ [0.633998, 0.168992, 0.383704],
+ [0.640135, 0.171438, 0.381065],
+ [0.646260, 0.173914, 0.378359],
+ [0.652369, 0.176421, 0.375586],
+ [0.658463, 0.178962, 0.372748],
+ [0.664540, 0.181539, 0.369846],
+ [0.670599, 0.184153, 0.366879],
+ [0.676638, 0.186807, 0.363849],
+ [0.682656, 0.189501, 0.360757],
+ [0.688653, 0.192239, 0.357603],
+ [0.694627, 0.195021, 0.354388],
+ [0.700576, 0.197851, 0.351113],
+ [0.706500, 0.200728, 0.347777],
+ [0.712396, 0.203656, 0.344383],
+ [0.718264, 0.206636, 0.340931],
+ [0.724103, 0.209670, 0.337424],
+ [0.729909, 0.212759, 0.333861],
+ [0.735683, 0.215906, 0.330245],
+ [0.741423, 0.219112, 0.326576],
+ [0.747127, 0.222378, 0.322856],
+ [0.752794, 0.225706, 0.319085],
+ [0.758422, 0.229097, 0.315266],
+ [0.764010, 0.232554, 0.311399],
+ [0.769556, 0.236077, 0.307485],
+ [0.775059, 0.239667, 0.303526],
+ [0.780517, 0.243327, 0.299523],
+ [0.785929, 0.247056, 0.295477],
+ [0.791293, 0.250856, 0.291390],
+ [0.796607, 0.254728, 0.287264],
+ [0.801871, 0.258674, 0.283099],
+ [0.807082, 0.262692, 0.278898],
+ [0.812239, 0.266786, 0.274661],
+ [0.817341, 0.270954, 0.270390],
+ [0.822386, 0.275197, 0.266085],
+ [0.827372, 0.279517, 0.261750],
+ [0.832299, 0.283913, 0.257383],
+ [0.837165, 0.288385, 0.252988],
+ [0.841969, 0.292933, 0.248564],
+ [0.846709, 0.297559, 0.244113],
+ [0.851384, 0.302260, 0.239636],
+ [0.855992, 0.307038, 0.235133],
+ [0.860533, 0.311892, 0.230606],
+ [0.865006, 0.316822, 0.226055],
+ [0.869409, 0.321827, 0.221482],
+ [0.873741, 0.326906, 0.216886],
+ [0.878001, 0.332060, 0.212268],
+ [0.882188, 0.337287, 0.207628],
+ [0.886302, 0.342586, 0.202968],
+ [0.890341, 0.347957, 0.198286],
+ [0.894305, 0.353399, 0.193584],
+ [0.898192, 0.358911, 0.188860],
+ [0.902003, 0.364492, 0.184116],
+ [0.905735, 0.370140, 0.179350],
+ [0.909390, 0.375856, 0.174563],
+ [0.912966, 0.381636, 0.169755],
+ [0.916462, 0.387481, 0.164924],
+ [0.919879, 0.393389, 0.160070],
+ [0.923215, 0.399359, 0.155193],
+ [0.926470, 0.405389, 0.150292],
+ [0.929644, 0.411479, 0.145367],
+ [0.932737, 0.417627, 0.140417],
+ [0.935747, 0.423831, 0.135440],
+ [0.938675, 0.430091, 0.130438],
+ [0.941521, 0.436405, 0.125409],
+ [0.944285, 0.442772, 0.120354],
+ [0.946965, 0.449191, 0.115272],
+ [0.949562, 0.455660, 0.110164],
+ [0.952075, 0.462178, 0.105031],
+ [0.954506, 0.468744, 0.099874],
+ [0.956852, 0.475356, 0.094695],
+ [0.959114, 0.482014, 0.089499],
+ [0.961293, 0.488716, 0.084289],
+ [0.963387, 0.495462, 0.079073],
+ [0.965397, 0.502249, 0.073859],
+ [0.967322, 0.509078, 0.068659],
+ [0.969163, 0.515946, 0.063488],
+ [0.970919, 0.522853, 0.058367],
+ [0.972590, 0.529798, 0.053324],
+ [0.974176, 0.536780, 0.048392],
+ [0.975677, 0.543798, 0.043618],
+ [0.977092, 0.550850, 0.039050],
+ [0.978422, 0.557937, 0.034931],
+ [0.979666, 0.565057, 0.031409],
+ [0.980824, 0.572209, 0.028508],
+ [0.981895, 0.579392, 0.026250],
+ [0.982881, 0.586606, 0.024661],
+ [0.983779, 0.593849, 0.023770],
+ [0.984591, 0.601122, 0.023606],
+ [0.985315, 0.608422, 0.024202],
+ [0.985952, 0.615750, 0.025592],
+ [0.986502, 0.623105, 0.027814],
+ [0.986964, 0.630485, 0.030908],
+ [0.987337, 0.637890, 0.034916],
+ [0.987622, 0.645320, 0.039886],
+ [0.987819, 0.652773, 0.045581],
+ [0.987926, 0.660250, 0.051750],
+ [0.987945, 0.667748, 0.058329],
+ [0.987874, 0.675267, 0.065257],
+ [0.987714, 0.682807, 0.072489],
+ [0.987464, 0.690366, 0.079990],
+ [0.987124, 0.697944, 0.087731],
+ [0.986694, 0.705540, 0.095694],
+ [0.986175, 0.713153, 0.103863],
+ [0.985566, 0.720782, 0.112229],
+ [0.984865, 0.728427, 0.120785],
+ [0.984075, 0.736087, 0.129527],
+ [0.983196, 0.743758, 0.138453],
+ [0.982228, 0.751442, 0.147565],
+ [0.981173, 0.759135, 0.156863],
+ [0.980032, 0.766837, 0.166353],
+ [0.978806, 0.774545, 0.176037],
+ [0.977497, 0.782258, 0.185923],
+ [0.976108, 0.789974, 0.196018],
+ [0.974638, 0.797692, 0.206332],
+ [0.973088, 0.805409, 0.216877],
+ [0.971468, 0.813122, 0.227658],
+ [0.969783, 0.820825, 0.238686],
+ [0.968041, 0.828515, 0.249972],
+ [0.966243, 0.836191, 0.261534],
+ [0.964394, 0.843848, 0.273391],
+ [0.962517, 0.851476, 0.285546],
+ [0.960626, 0.859069, 0.298010],
+ [0.958720, 0.866624, 0.310820],
+ [0.956834, 0.874129, 0.323974],
+ [0.954997, 0.881569, 0.337475],
+ [0.953215, 0.888942, 0.351369],
+ [0.951546, 0.896226, 0.365627],
+ [0.950018, 0.903409, 0.380271],
+ [0.948683, 0.910473, 0.395289],
+ [0.947594, 0.917399, 0.410665],
+ [0.946809, 0.924168, 0.426373],
+ [0.946392, 0.930761, 0.442367],
+ [0.946403, 0.937159, 0.458592],
+ [0.946903, 0.943348, 0.474970],
+ [0.947937, 0.949318, 0.491426],
+ [0.949545, 0.955063, 0.507860],
+ [0.951740, 0.960587, 0.524203],
+ [0.954529, 0.965896, 0.540361],
+ [0.957896, 0.971003, 0.556275],
+ [0.961812, 0.975924, 0.571925],
+ [0.966249, 0.980678, 0.587206],
+ [0.971162, 0.985282, 0.602154],
+ [0.976511, 0.989753, 0.616760],
+ [0.982257, 0.994109, 0.631017],
+ [0.988362, 0.998364, 0.644924]]
+
+_plasma_data = [[0.050383, 0.029803, 0.527975],
+ [0.063536, 0.028426, 0.533124],
+ [0.075353, 0.027206, 0.538007],
+ [0.086222, 0.026125, 0.542658],
+ [0.096379, 0.025165, 0.547103],
+ [0.105980, 0.024309, 0.551368],
+ [0.115124, 0.023556, 0.555468],
+ [0.123903, 0.022878, 0.559423],
+ [0.132381, 0.022258, 0.563250],
+ [0.140603, 0.021687, 0.566959],
+ [0.148607, 0.021154, 0.570562],
+ [0.156421, 0.020651, 0.574065],
+ [0.164070, 0.020171, 0.577478],
+ [0.171574, 0.019706, 0.580806],
+ [0.178950, 0.019252, 0.584054],
+ [0.186213, 0.018803, 0.587228],
+ [0.193374, 0.018354, 0.590330],
+ [0.200445, 0.017902, 0.593364],
+ [0.207435, 0.017442, 0.596333],
+ [0.214350, 0.016973, 0.599239],
+ [0.221197, 0.016497, 0.602083],
+ [0.227983, 0.016007, 0.604867],
+ [0.234715, 0.015502, 0.607592],
+ [0.241396, 0.014979, 0.610259],
+ [0.248032, 0.014439, 0.612868],
+ [0.254627, 0.013882, 0.615419],
+ [0.261183, 0.013308, 0.617911],
+ [0.267703, 0.012716, 0.620346],
+ [0.274191, 0.012109, 0.622722],
+ [0.280648, 0.011488, 0.625038],
+ [0.287076, 0.010855, 0.627295],
+ [0.293478, 0.010213, 0.629490],
+ [0.299855, 0.009561, 0.631624],
+ [0.306210, 0.008902, 0.633694],
+ [0.312543, 0.008239, 0.635700],
+ [0.318856, 0.007576, 0.637640],
+ [0.325150, 0.006915, 0.639512],
+ [0.331426, 0.006261, 0.641316],
+ [0.337683, 0.005618, 0.643049],
+ [0.343925, 0.004991, 0.644710],
+ [0.350150, 0.004382, 0.646298],
+ [0.356359, 0.003798, 0.647810],
+ [0.362553, 0.003243, 0.649245],
+ [0.368733, 0.002724, 0.650601],
+ [0.374897, 0.002245, 0.651876],
+ [0.381047, 0.001814, 0.653068],
+ [0.387183, 0.001434, 0.654177],
+ [0.393304, 0.001114, 0.655199],
+ [0.399411, 0.000859, 0.656133],
+ [0.405503, 0.000678, 0.656977],
+ [0.411580, 0.000577, 0.657730],
+ [0.417642, 0.000564, 0.658390],
+ [0.423689, 0.000646, 0.658956],
+ [0.429719, 0.000831, 0.659425],
+ [0.435734, 0.001127, 0.659797],
+ [0.441732, 0.001540, 0.660069],
+ [0.447714, 0.002080, 0.660240],
+ [0.453677, 0.002755, 0.660310],
+ [0.459623, 0.003574, 0.660277],
+ [0.465550, 0.004545, 0.660139],
+ [0.471457, 0.005678, 0.659897],
+ [0.477344, 0.006980, 0.659549],
+ [0.483210, 0.008460, 0.659095],
+ [0.489055, 0.010127, 0.658534],
+ [0.494877, 0.011990, 0.657865],
+ [0.500678, 0.014055, 0.657088],
+ [0.506454, 0.016333, 0.656202],
+ [0.512206, 0.018833, 0.655209],
+ [0.517933, 0.021563, 0.654109],
+ [0.523633, 0.024532, 0.652901],
+ [0.529306, 0.027747, 0.651586],
+ [0.534952, 0.031217, 0.650165],
+ [0.540570, 0.034950, 0.648640],
+ [0.546157, 0.038954, 0.647010],
+ [0.551715, 0.043136, 0.645277],
+ [0.557243, 0.047331, 0.643443],
+ [0.562738, 0.051545, 0.641509],
+ [0.568201, 0.055778, 0.639477],
+ [0.573632, 0.060028, 0.637349],
+ [0.579029, 0.064296, 0.635126],
+ [0.584391, 0.068579, 0.632812],
+ [0.589719, 0.072878, 0.630408],
+ [0.595011, 0.077190, 0.627917],
+ [0.600266, 0.081516, 0.625342],
+ [0.605485, 0.085854, 0.622686],
+ [0.610667, 0.090204, 0.619951],
+ [0.615812, 0.094564, 0.617140],
+ [0.620919, 0.098934, 0.614257],
+ [0.625987, 0.103312, 0.611305],
+ [0.631017, 0.107699, 0.608287],
+ [0.636008, 0.112092, 0.605205],
+ [0.640959, 0.116492, 0.602065],
+ [0.645872, 0.120898, 0.598867],
+ [0.650746, 0.125309, 0.595617],
+ [0.655580, 0.129725, 0.592317],
+ [0.660374, 0.134144, 0.588971],
+ [0.665129, 0.138566, 0.585582],
+ [0.669845, 0.142992, 0.582154],
+ [0.674522, 0.147419, 0.578688],
+ [0.679160, 0.151848, 0.575189],
+ [0.683758, 0.156278, 0.571660],
+ [0.688318, 0.160709, 0.568103],
+ [0.692840, 0.165141, 0.564522],
+ [0.697324, 0.169573, 0.560919],
+ [0.701769, 0.174005, 0.557296],
+ [0.706178, 0.178437, 0.553657],
+ [0.710549, 0.182868, 0.550004],
+ [0.714883, 0.187299, 0.546338],
+ [0.719181, 0.191729, 0.542663],
+ [0.723444, 0.196158, 0.538981],
+ [0.727670, 0.200586, 0.535293],
+ [0.731862, 0.205013, 0.531601],
+ [0.736019, 0.209439, 0.527908],
+ [0.740143, 0.213864, 0.524216],
+ [0.744232, 0.218288, 0.520524],
+ [0.748289, 0.222711, 0.516834],
+ [0.752312, 0.227133, 0.513149],
+ [0.756304, 0.231555, 0.509468],
+ [0.760264, 0.235976, 0.505794],
+ [0.764193, 0.240396, 0.502126],
+ [0.768090, 0.244817, 0.498465],
+ [0.771958, 0.249237, 0.494813],
+ [0.775796, 0.253658, 0.491171],
+ [0.779604, 0.258078, 0.487539],
+ [0.783383, 0.262500, 0.483918],
+ [0.787133, 0.266922, 0.480307],
+ [0.790855, 0.271345, 0.476706],
+ [0.794549, 0.275770, 0.473117],
+ [0.798216, 0.280197, 0.469538],
+ [0.801855, 0.284626, 0.465971],
+ [0.805467, 0.289057, 0.462415],
+ [0.809052, 0.293491, 0.458870],
+ [0.812612, 0.297928, 0.455338],
+ [0.816144, 0.302368, 0.451816],
+ [0.819651, 0.306812, 0.448306],
+ [0.823132, 0.311261, 0.444806],
+ [0.826588, 0.315714, 0.441316],
+ [0.830018, 0.320172, 0.437836],
+ [0.833422, 0.324635, 0.434366],
+ [0.836801, 0.329105, 0.430905],
+ [0.840155, 0.333580, 0.427455],
+ [0.843484, 0.338062, 0.424013],
+ [0.846788, 0.342551, 0.420579],
+ [0.850066, 0.347048, 0.417153],
+ [0.853319, 0.351553, 0.413734],
+ [0.856547, 0.356066, 0.410322],
+ [0.859750, 0.360588, 0.406917],
+ [0.862927, 0.365119, 0.403519],
+ [0.866078, 0.369660, 0.400126],
+ [0.869203, 0.374212, 0.396738],
+ [0.872303, 0.378774, 0.393355],
+ [0.875376, 0.383347, 0.389976],
+ [0.878423, 0.387932, 0.386600],
+ [0.881443, 0.392529, 0.383229],
+ [0.884436, 0.397139, 0.379860],
+ [0.887402, 0.401762, 0.376494],
+ [0.890340, 0.406398, 0.373130],
+ [0.893250, 0.411048, 0.369768],
+ [0.896131, 0.415712, 0.366407],
+ [0.898984, 0.420392, 0.363047],
+ [0.901807, 0.425087, 0.359688],
+ [0.904601, 0.429797, 0.356329],
+ [0.907365, 0.434524, 0.352970],
+ [0.910098, 0.439268, 0.349610],
+ [0.912800, 0.444029, 0.346251],
+ [0.915471, 0.448807, 0.342890],
+ [0.918109, 0.453603, 0.339529],
+ [0.920714, 0.458417, 0.336166],
+ [0.923287, 0.463251, 0.332801],
+ [0.925825, 0.468103, 0.329435],
+ [0.928329, 0.472975, 0.326067],
+ [0.930798, 0.477867, 0.322697],
+ [0.933232, 0.482780, 0.319325],
+ [0.935630, 0.487712, 0.315952],
+ [0.937990, 0.492667, 0.312575],
+ [0.940313, 0.497642, 0.309197],
+ [0.942598, 0.502639, 0.305816],
+ [0.944844, 0.507658, 0.302433],
+ [0.947051, 0.512699, 0.299049],
+ [0.949217, 0.517763, 0.295662],
+ [0.951344, 0.522850, 0.292275],
+ [0.953428, 0.527960, 0.288883],
+ [0.955470, 0.533093, 0.285490],
+ [0.957469, 0.538250, 0.282096],
+ [0.959424, 0.543431, 0.278701],
+ [0.961336, 0.548636, 0.275305],
+ [0.963203, 0.553865, 0.271909],
+ [0.965024, 0.559118, 0.268513],
+ [0.966798, 0.564396, 0.265118],
+ [0.968526, 0.569700, 0.261721],
+ [0.970205, 0.575028, 0.258325],
+ [0.971835, 0.580382, 0.254931],
+ [0.973416, 0.585761, 0.251540],
+ [0.974947, 0.591165, 0.248151],
+ [0.976428, 0.596595, 0.244767],
+ [0.977856, 0.602051, 0.241387],
+ [0.979233, 0.607532, 0.238013],
+ [0.980556, 0.613039, 0.234646],
+ [0.981826, 0.618572, 0.231287],
+ [0.983041, 0.624131, 0.227937],
+ [0.984199, 0.629718, 0.224595],
+ [0.985301, 0.635330, 0.221265],
+ [0.986345, 0.640969, 0.217948],
+ [0.987332, 0.646633, 0.214648],
+ [0.988260, 0.652325, 0.211364],
+ [0.989128, 0.658043, 0.208100],
+ [0.989935, 0.663787, 0.204859],
+ [0.990681, 0.669558, 0.201642],
+ [0.991365, 0.675355, 0.198453],
+ [0.991985, 0.681179, 0.195295],
+ [0.992541, 0.687030, 0.192170],
+ [0.993032, 0.692907, 0.189084],
+ [0.993456, 0.698810, 0.186041],
+ [0.993814, 0.704741, 0.183043],
+ [0.994103, 0.710698, 0.180097],
+ [0.994324, 0.716681, 0.177208],
+ [0.994474, 0.722691, 0.174381],
+ [0.994553, 0.728728, 0.171622],
+ [0.994561, 0.734791, 0.168938],
+ [0.994495, 0.740880, 0.166335],
+ [0.994355, 0.746995, 0.163821],
+ [0.994141, 0.753137, 0.161404],
+ [0.993851, 0.759304, 0.159092],
+ [0.993482, 0.765499, 0.156891],
+ [0.993033, 0.771720, 0.154808],
+ [0.992505, 0.777967, 0.152855],
+ [0.991897, 0.784239, 0.151042],
+ [0.991209, 0.790537, 0.149377],
+ [0.990439, 0.796859, 0.147870],
+ [0.989587, 0.803205, 0.146529],
+ [0.988648, 0.809579, 0.145357],
+ [0.987621, 0.815978, 0.144363],
+ [0.986509, 0.822401, 0.143557],
+ [0.985314, 0.828846, 0.142945],
+ [0.984031, 0.835315, 0.142528],
+ [0.982653, 0.841812, 0.142303],
+ [0.981190, 0.848329, 0.142279],
+ [0.979644, 0.854866, 0.142453],
+ [0.977995, 0.861432, 0.142808],
+ [0.976265, 0.868016, 0.143351],
+ [0.974443, 0.874622, 0.144061],
+ [0.972530, 0.881250, 0.144923],
+ [0.970533, 0.887896, 0.145919],
+ [0.968443, 0.894564, 0.147014],
+ [0.966271, 0.901249, 0.148180],
+ [0.964021, 0.907950, 0.149370],
+ [0.961681, 0.914672, 0.150520],
+ [0.959276, 0.921407, 0.151566],
+ [0.956808, 0.928152, 0.152409],
+ [0.954287, 0.934908, 0.152921],
+ [0.951726, 0.941671, 0.152925],
+ [0.949151, 0.948435, 0.152178],
+ [0.946602, 0.955190, 0.150328],
+ [0.944152, 0.961916, 0.146861],
+ [0.941896, 0.968590, 0.140956],
+ [0.940015, 0.975158, 0.131326]]
+
+_viridis_data = [[0.267004, 0.004874, 0.329415],
+ [0.268510, 0.009605, 0.335427],
+ [0.269944, 0.014625, 0.341379],
+ [0.271305, 0.019942, 0.347269],
+ [0.272594, 0.025563, 0.353093],
+ [0.273809, 0.031497, 0.358853],
+ [0.274952, 0.037752, 0.364543],
+ [0.276022, 0.044167, 0.370164],
+ [0.277018, 0.050344, 0.375715],
+ [0.277941, 0.056324, 0.381191],
+ [0.278791, 0.062145, 0.386592],
+ [0.279566, 0.067836, 0.391917],
+ [0.280267, 0.073417, 0.397163],
+ [0.280894, 0.078907, 0.402329],
+ [0.281446, 0.084320, 0.407414],
+ [0.281924, 0.089666, 0.412415],
+ [0.282327, 0.094955, 0.417331],
+ [0.282656, 0.100196, 0.422160],
+ [0.282910, 0.105393, 0.426902],
+ [0.283091, 0.110553, 0.431554],
+ [0.283197, 0.115680, 0.436115],
+ [0.283229, 0.120777, 0.440584],
+ [0.283187, 0.125848, 0.444960],
+ [0.283072, 0.130895, 0.449241],
+ [0.282884, 0.135920, 0.453427],
+ [0.282623, 0.140926, 0.457517],
+ [0.282290, 0.145912, 0.461510],
+ [0.281887, 0.150881, 0.465405],
+ [0.281412, 0.155834, 0.469201],
+ [0.280868, 0.160771, 0.472899],
+ [0.280255, 0.165693, 0.476498],
+ [0.279574, 0.170599, 0.479997],
+ [0.278826, 0.175490, 0.483397],
+ [0.278012, 0.180367, 0.486697],
+ [0.277134, 0.185228, 0.489898],
+ [0.276194, 0.190074, 0.493001],
+ [0.275191, 0.194905, 0.496005],
+ [0.274128, 0.199721, 0.498911],
+ [0.273006, 0.204520, 0.501721],
+ [0.271828, 0.209303, 0.504434],
+ [0.270595, 0.214069, 0.507052],
+ [0.269308, 0.218818, 0.509577],
+ [0.267968, 0.223549, 0.512008],
+ [0.266580, 0.228262, 0.514349],
+ [0.265145, 0.232956, 0.516599],
+ [0.263663, 0.237631, 0.518762],
+ [0.262138, 0.242286, 0.520837],
+ [0.260571, 0.246922, 0.522828],
+ [0.258965, 0.251537, 0.524736],
+ [0.257322, 0.256130, 0.526563],
+ [0.255645, 0.260703, 0.528312],
+ [0.253935, 0.265254, 0.529983],
+ [0.252194, 0.269783, 0.531579],
+ [0.250425, 0.274290, 0.533103],
+ [0.248629, 0.278775, 0.534556],
+ [0.246811, 0.283237, 0.535941],
+ [0.244972, 0.287675, 0.537260],
+ [0.243113, 0.292092, 0.538516],
+ [0.241237, 0.296485, 0.539709],
+ [0.239346, 0.300855, 0.540844],
+ [0.237441, 0.305202, 0.541921],
+ [0.235526, 0.309527, 0.542944],
+ [0.233603, 0.313828, 0.543914],
+ [0.231674, 0.318106, 0.544834],
+ [0.229739, 0.322361, 0.545706],
+ [0.227802, 0.326594, 0.546532],
+ [0.225863, 0.330805, 0.547314],
+ [0.223925, 0.334994, 0.548053],
+ [0.221989, 0.339161, 0.548752],
+ [0.220057, 0.343307, 0.549413],
+ [0.218130, 0.347432, 0.550038],
+ [0.216210, 0.351535, 0.550627],
+ [0.214298, 0.355619, 0.551184],
+ [0.212395, 0.359683, 0.551710],
+ [0.210503, 0.363727, 0.552206],
+ [0.208623, 0.367752, 0.552675],
+ [0.206756, 0.371758, 0.553117],
+ [0.204903, 0.375746, 0.553533],
+ [0.203063, 0.379716, 0.553925],
+ [0.201239, 0.383670, 0.554294],
+ [0.199430, 0.387607, 0.554642],
+ [0.197636, 0.391528, 0.554969],
+ [0.195860, 0.395433, 0.555276],
+ [0.194100, 0.399323, 0.555565],
+ [0.192357, 0.403199, 0.555836],
+ [0.190631, 0.407061, 0.556089],
+ [0.188923, 0.410910, 0.556326],
+ [0.187231, 0.414746, 0.556547],
+ [0.185556, 0.418570, 0.556753],
+ [0.183898, 0.422383, 0.556944],
+ [0.182256, 0.426184, 0.557120],
+ [0.180629, 0.429975, 0.557282],
+ [0.179019, 0.433756, 0.557430],
+ [0.177423, 0.437527, 0.557565],
+ [0.175841, 0.441290, 0.557685],
+ [0.174274, 0.445044, 0.557792],
+ [0.172719, 0.448791, 0.557885],
+ [0.171176, 0.452530, 0.557965],
+ [0.169646, 0.456262, 0.558030],
+ [0.168126, 0.459988, 0.558082],
+ [0.166617, 0.463708, 0.558119],
+ [0.165117, 0.467423, 0.558141],
+ [0.163625, 0.471133, 0.558148],
+ [0.162142, 0.474838, 0.558140],
+ [0.160665, 0.478540, 0.558115],
+ [0.159194, 0.482237, 0.558073],
+ [0.157729, 0.485932, 0.558013],
+ [0.156270, 0.489624, 0.557936],
+ [0.154815, 0.493313, 0.557840],
+ [0.153364, 0.497000, 0.557724],
+ [0.151918, 0.500685, 0.557587],
+ [0.150476, 0.504369, 0.557430],
+ [0.149039, 0.508051, 0.557250],
+ [0.147607, 0.511733, 0.557049],
+ [0.146180, 0.515413, 0.556823],
+ [0.144759, 0.519093, 0.556572],
+ [0.143343, 0.522773, 0.556295],
+ [0.141935, 0.526453, 0.555991],
+ [0.140536, 0.530132, 0.555659],
+ [0.139147, 0.533812, 0.555298],
+ [0.137770, 0.537492, 0.554906],
+ [0.136408, 0.541173, 0.554483],
+ [0.135066, 0.544853, 0.554029],
+ [0.133743, 0.548535, 0.553541],
+ [0.132444, 0.552216, 0.553018],
+ [0.131172, 0.555899, 0.552459],
+ [0.129933, 0.559582, 0.551864],
+ [0.128729, 0.563265, 0.551229],
+ [0.127568, 0.566949, 0.550556],
+ [0.126453, 0.570633, 0.549841],
+ [0.125394, 0.574318, 0.549086],
+ [0.124395, 0.578002, 0.548287],
+ [0.123463, 0.581687, 0.547445],
+ [0.122606, 0.585371, 0.546557],
+ [0.121831, 0.589055, 0.545623],
+ [0.121148, 0.592739, 0.544641],
+ [0.120565, 0.596422, 0.543611],
+ [0.120092, 0.600104, 0.542530],
+ [0.119738, 0.603785, 0.541400],
+ [0.119512, 0.607464, 0.540218],
+ [0.119423, 0.611141, 0.538982],
+ [0.119483, 0.614817, 0.537692],
+ [0.119699, 0.618490, 0.536347],
+ [0.120081, 0.622161, 0.534946],
+ [0.120638, 0.625828, 0.533488],
+ [0.121380, 0.629492, 0.531973],
+ [0.122312, 0.633153, 0.530398],
+ [0.123444, 0.636809, 0.528763],
+ [0.124780, 0.640461, 0.527068],
+ [0.126326, 0.644107, 0.525311],
+ [0.128087, 0.647749, 0.523491],
+ [0.130067, 0.651384, 0.521608],
+ [0.132268, 0.655014, 0.519661],
+ [0.134692, 0.658636, 0.517649],
+ [0.137339, 0.662252, 0.515571],
+ [0.140210, 0.665859, 0.513427],
+ [0.143303, 0.669459, 0.511215],
+ [0.146616, 0.673050, 0.508936],
+ [0.150148, 0.676631, 0.506589],
+ [0.153894, 0.680203, 0.504172],
+ [0.157851, 0.683765, 0.501686],
+ [0.162016, 0.687316, 0.499129],
+ [0.166383, 0.690856, 0.496502],
+ [0.170948, 0.694384, 0.493803],
+ [0.175707, 0.697900, 0.491033],
+ [0.180653, 0.701402, 0.488189],
+ [0.185783, 0.704891, 0.485273],
+ [0.191090, 0.708366, 0.482284],
+ [0.196571, 0.711827, 0.479221],
+ [0.202219, 0.715272, 0.476084],
+ [0.208030, 0.718701, 0.472873],
+ [0.214000, 0.722114, 0.469588],
+ [0.220124, 0.725509, 0.466226],
+ [0.226397, 0.728888, 0.462789],
+ [0.232815, 0.732247, 0.459277],
+ [0.239374, 0.735588, 0.455688],
+ [0.246070, 0.738910, 0.452024],
+ [0.252899, 0.742211, 0.448284],
+ [0.259857, 0.745492, 0.444467],
+ [0.266941, 0.748751, 0.440573],
+ [0.274149, 0.751988, 0.436601],
+ [0.281477, 0.755203, 0.432552],
+ [0.288921, 0.758394, 0.428426],
+ [0.296479, 0.761561, 0.424223],
+ [0.304148, 0.764704, 0.419943],
+ [0.311925, 0.767822, 0.415586],
+ [0.319809, 0.770914, 0.411152],
+ [0.327796, 0.773980, 0.406640],
+ [0.335885, 0.777018, 0.402049],
+ [0.344074, 0.780029, 0.397381],
+ [0.352360, 0.783011, 0.392636],
+ [0.360741, 0.785964, 0.387814],
+ [0.369214, 0.788888, 0.382914],
+ [0.377779, 0.791781, 0.377939],
+ [0.386433, 0.794644, 0.372886],
+ [0.395174, 0.797475, 0.367757],
+ [0.404001, 0.800275, 0.362552],
+ [0.412913, 0.803041, 0.357269],
+ [0.421908, 0.805774, 0.351910],
+ [0.430983, 0.808473, 0.346476],
+ [0.440137, 0.811138, 0.340967],
+ [0.449368, 0.813768, 0.335384],
+ [0.458674, 0.816363, 0.329727],
+ [0.468053, 0.818921, 0.323998],
+ [0.477504, 0.821444, 0.318195],
+ [0.487026, 0.823929, 0.312321],
+ [0.496615, 0.826376, 0.306377],
+ [0.506271, 0.828786, 0.300362],
+ [0.515992, 0.831158, 0.294279],
+ [0.525776, 0.833491, 0.288127],
+ [0.535621, 0.835785, 0.281908],
+ [0.545524, 0.838039, 0.275626],
+ [0.555484, 0.840254, 0.269281],
+ [0.565498, 0.842430, 0.262877],
+ [0.575563, 0.844566, 0.256415],
+ [0.585678, 0.846661, 0.249897],
+ [0.595839, 0.848717, 0.243329],
+ [0.606045, 0.850733, 0.236712],
+ [0.616293, 0.852709, 0.230052],
+ [0.626579, 0.854645, 0.223353],
+ [0.636902, 0.856542, 0.216620],
+ [0.647257, 0.858400, 0.209861],
+ [0.657642, 0.860219, 0.203082],
+ [0.668054, 0.861999, 0.196293],
+ [0.678489, 0.863742, 0.189503],
+ [0.688944, 0.865448, 0.182725],
+ [0.699415, 0.867117, 0.175971],
+ [0.709898, 0.868751, 0.169257],
+ [0.720391, 0.870350, 0.162603],
+ [0.730889, 0.871916, 0.156029],
+ [0.741388, 0.873449, 0.149561],
+ [0.751884, 0.874951, 0.143228],
+ [0.762373, 0.876424, 0.137064],
+ [0.772852, 0.877868, 0.131109],
+ [0.783315, 0.879285, 0.125405],
+ [0.793760, 0.880678, 0.120005],
+ [0.804182, 0.882046, 0.114965],
+ [0.814576, 0.883393, 0.110347],
+ [0.824940, 0.884720, 0.106217],
+ [0.835270, 0.886029, 0.102646],
+ [0.845561, 0.887322, 0.099702],
+ [0.855810, 0.888601, 0.097452],
+ [0.866013, 0.889868, 0.095953],
+ [0.876168, 0.891125, 0.095250],
+ [0.886271, 0.892374, 0.095374],
+ [0.896320, 0.893616, 0.096335],
+ [0.906311, 0.894855, 0.098125],
+ [0.916242, 0.896091, 0.100717],
+ [0.926106, 0.897330, 0.104071],
+ [0.935904, 0.898570, 0.108131],
+ [0.945636, 0.899815, 0.112838],
+ [0.955300, 0.901065, 0.118128],
+ [0.964894, 0.902323, 0.123941],
+ [0.974417, 0.903590, 0.130215],
+ [0.983868, 0.904867, 0.136897],
+ [0.993248, 0.906157, 0.143936]]
+
+
+cmaps = {}
+for (name, data) in (('magma', _magma_data),
+ ('inferno', _inferno_data),
+ ('plasma', _plasma_data),
+ ('viridis', _viridis_data)):
+
+ cmaps[name] = ListedColormap(data, name=name)
+
+magma = cmaps['magma']
+inferno = cmaps['inferno']
+plasma = cmaps['plasma']
+viridis = cmaps['viridis']
diff --git a/silx/gui/plot/MaskToolsWidget.py b/silx/gui/plot/MaskToolsWidget.py
new file mode 100644
index 0000000..6407d44
--- /dev/null
+++ b/silx/gui/plot/MaskToolsWidget.py
@@ -0,0 +1,615 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""Widget providing a set of tools to draw masks on a PlotWidget.
+
+This widget is meant to work with :class:`silx.gui.plot.PlotWidget`.
+
+- :class:`ImageMask`: Handle mask bitmap update and history
+- :class:`MaskToolsWidget`: GUI for :class:`Mask`
+- :class:`MaskToolsDockWidget`: DockWidget to integrate in :class:`PlotWindow`
+"""
+from __future__ import division
+
+
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "20/04/2017"
+
+
+import os
+import sys
+import numpy
+import logging
+
+from silx.image import shapes
+
+from ._BaseMaskToolsWidget import BaseMask, BaseMaskToolsWidget, BaseMaskToolsDockWidget
+from . import items
+from .Colors import cursorColorForColormap, rgba
+from .. import qt
+
+from silx.third_party.EdfFile import EdfFile
+from silx.third_party.TiffIO import TiffIO
+
+try:
+ import fabio
+except ImportError:
+ fabio = None
+
+
+_logger = logging.getLogger(__name__)
+
+
+class ImageMask(BaseMask):
+ """A 2D mask field with update operations.
+
+ Coords follows (row, column) convention and are in mask array coords.
+
+ This is meant for internal use by :class:`MaskToolsWidget`.
+ """
+ def __init__(self, image=None):
+ """
+
+ :param image: :class:`silx.gui.plot.items.ImageBase` instance
+ """
+ BaseMask.__init__(self, image)
+
+ def getDataValues(self):
+ """Return image data as a 2D or 3D array (if it is a RGBA image).
+
+ :rtype: 2D or 3D numpy.ndarray
+ """
+ return self._dataItem.getData(copy=False)
+
+ def save(self, filename, kind):
+ """Save current mask in a file
+
+ :param str filename: The file where to save to mask
+ :param str kind: The kind of file to save in 'edf', 'tif', 'npy',
+ or 'msk' (if FabIO is installed)
+ :raise Exception: Raised if the file writing fail
+ """
+ if kind == 'edf':
+ edfFile = EdfFile(filename, access="w+")
+ edfFile.WriteImage({}, self.getMask(copy=False), Append=0)
+
+ elif kind == 'tif':
+ tiffFile = TiffIO(filename, mode='w')
+ tiffFile.writeImage(self.getMask(copy=False), software='silx')
+
+ elif kind == 'npy':
+ try:
+ numpy.save(filename, self.getMask(copy=False))
+ except IOError:
+ raise RuntimeError("Mask file can't be written")
+
+ elif kind == 'msk':
+ if fabio is None:
+ raise ImportError("Fit2d mask files can't be written: Fabio module is not available")
+ try:
+ data = self.getMask(copy=False)
+ image = fabio.fabioimage.FabioImage(data=data)
+ image = image.convert(fabio.fit2dmaskimage.Fit2dMaskImage)
+ image.save(filename)
+ except Exception:
+ _logger.debug("Backtrace", exc_info=True)
+ raise RuntimeError("Mask file can't be written")
+
+ else:
+ raise ValueError("Format '%s' is not supported" % kind)
+
+ # Drawing operations
+ def updateRectangle(self, level, row, col, height, width, mask=True):
+ """Mask/Unmask a rectangle of the given mask level.
+
+ :param int level: Mask level to update.
+ :param int row: Starting row of the rectangle
+ :param int col: Starting column of the rectangle
+ :param int height:
+ :param int width:
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ assert 0 < level < 256
+ selection = self._mask[max(0, row):row + height + 1,
+ max(0, col):col + width + 1]
+ if mask:
+ selection[:, :] = level
+ else:
+ selection[selection == level] = 0
+ self._notify()
+
+ def updatePolygon(self, level, vertices, mask=True):
+ """Mask/Unmask a polygon of the given mask level.
+
+ :param int level: Mask level to update.
+ :param vertices: Nx2 array of polygon corners as (row, col)
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ fill = shapes.polygon_fill_mask(vertices, self._mask.shape)
+ if mask:
+ self._mask[fill != 0] = level
+ else:
+ self._mask[numpy.logical_and(fill != 0,
+ self._mask == level)] = 0
+ self._notify()
+
+ def updatePoints(self, level, rows, cols, mask=True):
+ """Mask/Unmask points with given coordinates.
+
+ :param int level: Mask level to update.
+ :param rows: Rows of selected points
+ :type rows: 1D numpy.ndarray
+ :param cols: Columns of selected points
+ :type cols: 1D numpy.ndarray
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ valid = numpy.logical_and(
+ numpy.logical_and(rows >= 0, cols >= 0),
+ numpy.logical_and(rows < self._mask.shape[0],
+ cols < self._mask.shape[1]))
+ rows, cols = rows[valid], cols[valid]
+
+ if mask:
+ self._mask[rows, cols] = level
+ else:
+ inMask = self._mask[rows, cols] == level
+ self._mask[rows[inMask], cols[inMask]] = 0
+ self._notify()
+
+ def updateDisk(self, level, crow, ccol, radius, mask=True):
+ """Mask/Unmask a disk of the given mask level.
+
+ :param int level: Mask level to update.
+ :param int crow: Disk center row.
+ :param int ccol: Disk center column.
+ :param float radius: Radius of the disk in mask array unit
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ rows, cols = shapes.circle_fill(crow, ccol, radius)
+ self.updatePoints(level, rows, cols, mask)
+
+ def updateLine(self, level, row0, col0, row1, col1, width, mask=True):
+ """Mask/Unmask a line of the given mask level.
+
+ :param int level: Mask level to update.
+ :param int row0: Row of the starting point.
+ :param int col0: Column of the starting point.
+ :param int row1: Row of the end point.
+ :param int col1: Column of the end point.
+ :param int width: Width of the line in mask array unit.
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ rows, cols = shapes.draw_line(row0, col0, row1, col1, width)
+ self.updatePoints(level, rows, cols, mask)
+
+
+class MaskToolsWidget(BaseMaskToolsWidget):
+ """Widget with tools for drawing mask on an image in a PlotWidget."""
+
+ _maxLevelNumber = 255
+
+ def __init__(self, parent=None, plot=None):
+ self._origin = (0., 0.) # Mask origin in plot
+ self._scale = (1., 1.) # Mask scale in plot
+ self._z = 1 # Mask layer in plot
+ self._data = numpy.zeros((0, 0), dtype=numpy.uint8) # Store image
+
+ self._mask = ImageMask()
+
+ super(MaskToolsWidget, self).__init__(parent, plot)
+
+ self._initWidgets()
+
+ def setSelectionMask(self, mask, copy=True):
+ """Set the mask to a new array.
+
+ :param numpy.ndarray mask: The array to use for the mask.
+ :type mask: numpy.ndarray of uint8 of dimension 2, C-contiguous.
+ Array of other types are converted.
+ :param bool copy: True (the default) to copy the array,
+ False to use it as is if possible.
+ :return: None if failed, shape of mask as 2-tuple if successful.
+ The mask can be cropped or padded to fit active image,
+ the returned shape is that of the active image.
+ """
+ mask = numpy.array(mask, copy=False, dtype=numpy.uint8)
+ if len(mask.shape) != 2:
+ _logger.error('Not an image, shape: %d', len(mask.shape))
+ return None
+
+ if self._data.shape[0:2] == (0, 0) or mask.shape == self._data.shape[0:2]:
+ self._mask.setMask(mask, copy=copy)
+ self._mask.commit()
+ return mask.shape
+ else:
+ _logger.warning('Mask has not the same size as current image.'
+ ' Mask will be cropped or padded to fit image'
+ ' dimensions. %s != %s',
+ str(mask.shape), str(self._data.shape))
+ resizedMask = numpy.zeros(self._data.shape[0:2],
+ dtype=numpy.uint8)
+ height = min(self._data.shape[0], mask.shape[0])
+ width = min(self._data.shape[1], mask.shape[1])
+ resizedMask[:height, :width] = mask[:height, :width]
+ self._mask.setMask(resizedMask, copy=False)
+ self._mask.commit()
+ return resizedMask.shape
+
+ # Handle mask refresh on the plot
+ def _updatePlotMask(self):
+ """Update mask image in plot"""
+ mask = self.getSelectionMask(copy=False)
+ if len(mask):
+ self.plot.addImage(mask, legend=self._maskName,
+ colormap=self._colormap,
+ origin=self._origin,
+ scale=self._scale,
+ z=self._z,
+ replace=False, resetzoom=False)
+ elif self.plot.getImage(self._maskName):
+ self.plot.remove(self._maskName, kind='image')
+
+ def showEvent(self, event):
+ try:
+ self.plot.sigActiveImageChanged.disconnect(
+ self._activeImageChangedAfterCare)
+ except (RuntimeError, TypeError):
+ pass
+ self._activeImageChanged() # Init mask + enable/disable widget
+ self.plot.sigActiveImageChanged.connect(self._activeImageChanged)
+
+ def hideEvent(self, event):
+ self.plot.sigActiveImageChanged.disconnect(self._activeImageChanged)
+ if not self.browseAction.isChecked():
+ self.browseAction.trigger() # Disable drawing tool
+
+ if len(self.getSelectionMask(copy=False)):
+ self.plot.sigActiveImageChanged.connect(
+ self._activeImageChangedAfterCare)
+
+ def _setOverlayColorForImage(self, image):
+ """Set the color of overlay adapted to image
+
+ :param image: :class:`.items.ImageBase` object to set color for.
+ """
+ if isinstance(image, items.ColormapMixIn):
+ colormap = image.getColormap()
+ self._defaultOverlayColor = rgba(
+ cursorColorForColormap(colormap['name']))
+ else:
+ self._defaultOverlayColor = rgba('black')
+
+ def _activeImageChangedAfterCare(self, *args):
+ """Check synchro of active image and mask when mask widget is hidden.
+
+ If active image has no more the same size as the mask, the mask is
+ removed, otherwise it is adjusted to origin, scale and z.
+ """
+ activeImage = self.plot.getActiveImage()
+ if activeImage is None or activeImage.getLegend() == self._maskName:
+ # No active image or active image is the mask...
+ self.plot.sigActiveImageChanged.disconnect(
+ self._activeImageChangedAfterCare)
+ else:
+ self._setOverlayColorForImage(activeImage)
+ self._setMaskColors(self.levelSpinBox.value(),
+ self.transparencySlider.value() /
+ self.transparencySlider.maximum())
+
+ self._origin = activeImage.getOrigin()
+ self._scale = activeImage.getScale()
+ self._z = activeImage.getZValue() + 1
+ self._data = activeImage.getData(copy=False)
+ if self._data.shape[:2] != self.getSelectionMask(copy=False).shape:
+ # Image has not the same size, remove mask and stop listening
+ if self.plot.getImage(self._maskName):
+ self.plot.remove(self._maskName, kind='image')
+
+ self.plot.sigActiveImageChanged.disconnect(
+ self._activeImageChangedAfterCare)
+ else:
+ # Refresh in case origin, scale, z changed
+ self._mask.setDataItem(activeImage)
+ self._updatePlotMask()
+
+ def _activeImageChanged(self, *args):
+ """Update widget and mask according to active image changes"""
+ activeImage = self.plot.getActiveImage()
+ if activeImage is None or activeImage.getLegend() == self._maskName:
+ # No active image or active image is the mask...
+ self.setEnabled(False)
+
+ self._data = numpy.zeros((0, 0), dtype=numpy.uint8)
+ self._mask.reset()
+ self._mask.commit()
+
+ else: # There is an active image
+ self.setEnabled(True)
+
+ self._setOverlayColorForImage(activeImage)
+
+ self._setMaskColors(self.levelSpinBox.value(),
+ self.transparencySlider.value() /
+ self.transparencySlider.maximum())
+
+ self._origin = activeImage.getOrigin()
+ self._scale = activeImage.getScale()
+ self._z = activeImage.getZValue() + 1
+ self._data = activeImage.getData(copy=False)
+ self._mask.setDataItem(activeImage)
+ if self._data.shape[:2] != self.getSelectionMask(copy=False).shape:
+ self._mask.reset(self._data.shape[:2])
+ self._mask.commit()
+ else:
+ # Refresh in case origin, scale, z changed
+ self._updatePlotMask()
+
+ # Threshold tools only available for data with colormap
+ self.thresholdGroup.setEnabled(self._data.ndim == 2)
+
+ self._updateInteractiveMode()
+
+ # Handle whole mask operations
+ def load(self, filename):
+ """Load a mask from an image file.
+
+ :param str filename: File name from which to load the mask
+ :raise Exception: An exception in case of failure
+ :raise RuntimeWarning: In case the mask was applied but with some
+ import changes to notice
+ """
+ _, extension = os.path.splitext(filename)
+ extension = extension.lower()[1:]
+
+ if extension == "npy":
+ try:
+ mask = numpy.load(filename)
+ except IOError:
+ _logger.error("Can't load filename '%s'", filename)
+ _logger.debug("Backtrace", exc_info=True)
+ raise RuntimeError('File "%s" is not a numpy file.', filename)
+ elif extension == "edf":
+ try:
+ mask = EdfFile(filename, access='r').GetData(0)
+ except Exception as e:
+ _logger.error("Can't load filename %s", filename)
+ _logger.debug("Backtrace", exc_info=True)
+ raise e
+ elif extension == "msk":
+ if fabio is None:
+ raise ImportError("Fit2d mask files can't be read: Fabio module is not available")
+ try:
+ mask = fabio.open(filename).data
+ except Exception as e:
+ _logger.error("Can't load fit2d mask file")
+ _logger.debug("Backtrace", exc_info=True)
+ raise e
+ else:
+ msg = "Extension '%s' is not supported."
+ raise RuntimeError(msg % extension)
+
+ effectiveMaskShape = self.setSelectionMask(mask, copy=False)
+ if effectiveMaskShape is None:
+ return
+ if mask.shape != effectiveMaskShape:
+ msg = 'Mask was resized from %s to %s'
+ msg = msg % (str(mask.shape), str(effectiveMaskShape))
+ raise RuntimeWarning(msg)
+
+ def _loadMask(self):
+ """Open load mask dialog"""
+ dialog = qt.QFileDialog(self)
+ dialog.setWindowTitle("Load Mask")
+ dialog.setModal(1)
+ filters = [
+ 'EDF (*.edf)',
+ 'TIFF (*.tif)',
+ 'NumPy binary file (*.npy)',
+ # Fit2D mask is displayed anyway fabio is here or not
+ # to show to the user that the option exists
+ 'Fit2D mask (*.msk)',
+ ]
+ dialog.setNameFilters(filters)
+ dialog.setFileMode(qt.QFileDialog.ExistingFile)
+ dialog.setDirectory(self.maskFileDir)
+ if not dialog.exec_():
+ dialog.close()
+ return
+
+ filename = dialog.selectedFiles()[0]
+ dialog.close()
+
+ self.maskFileDir = os.path.dirname(filename)
+ try:
+ self.load(filename)
+ except RuntimeWarning as e:
+ message = e.args[0]
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Warning)
+ msg.setText("Mask loaded but an operation was applied.\n" + message)
+ msg.exec_()
+ except Exception as e:
+ message = e.args[0]
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setText("Cannot load mask from file. " + message)
+ msg.exec_()
+
+ def _saveMask(self):
+ """Open Save mask dialog"""
+ dialog = qt.QFileDialog(self)
+ dialog.setWindowTitle("Save Mask")
+ dialog.setModal(1)
+ filters = [
+ 'EDF (*.edf)',
+ 'TIFF (*.tif)',
+ 'NumPy binary file (*.npy)',
+ # Fit2D mask is displayed anyway fabio is here or not
+ # to show to the user that the option exists
+ 'Fit2D mask (*.msk)',
+ ]
+ dialog.setNameFilters(filters)
+ dialog.setFileMode(qt.QFileDialog.AnyFile)
+ dialog.setAcceptMode(qt.QFileDialog.AcceptSave)
+ dialog.setDirectory(self.maskFileDir)
+ if not dialog.exec_():
+ dialog.close()
+ return
+
+ # convert filter name to extension name with the .
+ extension = dialog.selectedNameFilter().split()[-1][2:-1]
+ filename = dialog.selectedFiles()[0]
+ dialog.close()
+
+ if not filename.lower().endswith(extension):
+ filename += extension
+
+ if os.path.exists(filename):
+ try:
+ os.remove(filename)
+ except IOError:
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setText("Cannot save.\n"
+ "Input Output Error: %s" % (sys.exc_info()[1]))
+ msg.exec_()
+ return
+
+ self.maskFileDir = os.path.dirname(filename)
+ try:
+ self.save(filename, extension[1:])
+ except Exception as e:
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setText("Cannot save file %s\n%s" % (filename, e.args[0]))
+ msg.exec_()
+
+ def resetSelectionMask(self):
+ """Reset the mask"""
+ self._mask.reset(shape=self._data.shape[:2])
+ self._mask.commit()
+
+ def _plotDrawEvent(self, event):
+ """Handle draw events from the plot"""
+ if (self._drawingMode is None or
+ event['event'] not in ('drawingProgress', 'drawingFinished')):
+ return
+
+ if not len(self._data):
+ return
+
+ level = self.levelSpinBox.value()
+
+ if (self._drawingMode == 'rectangle' and
+ event['event'] == 'drawingFinished'):
+ # Convert from plot to array coords
+ doMask = self._isMasking()
+ ox, oy = self._origin
+ sx, sy = self._scale
+
+ height = int(abs(event['height'] / sy))
+ width = int(abs(event['width'] / sx))
+
+ row = int((event['y'] - oy) / sy)
+ if sy < 0:
+ row -= height
+
+ col = int((event['x'] - ox) / sx)
+ if sx < 0:
+ col -= width
+
+ self._mask.updateRectangle(
+ level,
+ row=row,
+ col=col,
+ height=height,
+ width=width,
+ mask=doMask)
+ self._mask.commit()
+
+ elif (self._drawingMode == 'polygon' and
+ event['event'] == 'drawingFinished'):
+ doMask = self._isMasking()
+ # Convert from plot to array coords
+ vertices = (event['points'] - self._origin) / self._scale
+ vertices = vertices.astype(numpy.int)[:, (1, 0)] # (row, col)
+ self._mask.updatePolygon(level, vertices, doMask)
+ self._mask.commit()
+
+ elif self._drawingMode == 'pencil':
+ doMask = self._isMasking()
+ # convert from plot to array coords
+ col, row = (event['points'][-1] - self._origin) / self._scale
+ col, row = int(col), int(row)
+ brushSize = self.pencilSpinBox.value()
+
+ if self._lastPencilPos != (row, col):
+ if self._lastPencilPos is not None:
+ # Draw the line
+ self._mask.updateLine(
+ level,
+ self._lastPencilPos[0], self._lastPencilPos[1],
+ row, col,
+ brushSize,
+ doMask)
+
+ # Draw the very first, or last point
+ self._mask.updateDisk(level, row, col, brushSize / 2., doMask)
+
+ if event['event'] == 'drawingFinished':
+ self._mask.commit()
+ self._lastPencilPos = None
+ else:
+ self._lastPencilPos = row, col
+
+ def _loadRangeFromColormapTriggered(self):
+ """Set range from active image colormap range"""
+ activeImage = self.plot.getActiveImage()
+ if (isinstance(activeImage, items.ColormapMixIn) and
+ activeImage.getLegend() != self._maskName):
+ # Update thresholds according to colormap
+ colormap = activeImage.getColormap()
+ if colormap['autoscale']:
+ min_ = numpy.nanmin(activeImage.getData(copy=False))
+ max_ = numpy.nanmax(activeImage.getData(copy=False))
+ else:
+ min_, max_ = colormap['vmin'], colormap['vmax']
+ self.minLineEdit.setText(str(min_))
+ self.maxLineEdit.setText(str(max_))
+
+
+class MaskToolsDockWidget(BaseMaskToolsDockWidget):
+ """:class:`MaskToolsWidget` embedded in a QDockWidget.
+
+ For integration in a :class:`PlotWindow`.
+
+ :param parent: See :class:`QDockWidget`
+ :param plot: The PlotWidget this widget is operating on
+ :paran str name: The title of this widget
+ """
+ def __init__(self, parent=None, plot=None, name='Mask'):
+ super(MaskToolsDockWidget, self).__init__(parent, name)
+ self.setWidget(MaskToolsWidget(plot=plot))
+ self.widget().sigMaskChanged.connect(self._emitSigMaskChanged)
diff --git a/silx/gui/plot/Plot.py b/silx/gui/plot/Plot.py
new file mode 100644
index 0000000..fe0a7b8
--- /dev/null
+++ b/silx/gui/plot/Plot.py
@@ -0,0 +1,2925 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+# ###########################################################################*/
+"""Plot API for 1D and 2D data.
+
+The :class:`Plot` implements the plot API initially provided in PyMca.
+
+
+Colormap
+--------
+
+The :class:`Plot` uses a dictionary to describe a colormap.
+This dictionary has the following keys:
+
+- 'name': str, name of the colormap. Available colormap are returned by
+ :meth:`Plot.getSupportedColormaps`.
+ At least 'gray', 'reversed gray', 'temperature',
+ 'red', 'green', 'blue' are supported.
+- 'normalization': Either 'linear' or 'log'
+- 'autoscale': bool, True to get bounds from the min and max of the
+ data, False to use [vmin, vmax]
+- 'vmin': float, min value, ignored if autoscale is True
+- 'vmax': float, max value, ignored if autoscale is True
+- 'colors': optional, custom colormap.
+ Nx3 or Nx4 numpy array of RGB(A) colors,
+ either uint8 or float in [0, 1].
+ If 'name' is None, then this array is used as the colormap.
+
+
+Plot Events
+-----------
+
+The Plot sends some event to the registered callback
+(See :meth:`Plot.setCallback`).
+Those events are sent as a dictionary with a key 'event' describing the kind
+of event.
+
+Drawing events
+..............
+
+'drawingProgress' and 'drawingFinished' events are sent during drawing
+interaction (See :meth:`Plot.setInteractiveMode`).
+
+- 'event': 'drawingProgress' or 'drawingFinished'
+- 'parameters': dict of parameters used by the drawing mode.
+ It has the following keys: 'shape', 'label', 'color'.
+ See :meth:`Plot.setInteractiveMode`.
+- 'points': Points (x, y) in data coordinates of the drawn shape.
+ For 'hline' and 'vline', it is the 2 points defining the line.
+ For 'line' and 'rectangle', it is the coordinates of the start
+ drawing point and the latest drawing point.
+ For 'polygon', it is the coordinates of all points of the shape.
+- 'type': The type of drawing in 'line', 'hline', 'polygon', 'rectangle',
+ 'vline'.
+- 'xdata' and 'ydata': X coords and Y coords of shape points in data
+ coordinates (as in 'points').
+
+When the type is 'rectangle', the following additional keys are provided:
+
+- 'x' and 'y': The origin of the rectangle in data coordinates
+- 'widht' and 'height': The size of the rectangle in data coordinates
+
+
+Mouse events
+............
+
+'mouseMoved', 'mouseClicked' and 'mouseDoubleClicked' events are sent for
+mouse events.
+
+They provide the following keys:
+
+- 'event': 'mouseMoved', 'mouseClicked' or 'mouseDoubleClicked'
+- 'button': the mouse button that was pressed in 'left', 'middle', 'right'
+- 'x' and 'y': The mouse position in data coordinates
+- 'xpixel' and 'ypixel': The mouse position in pixels
+
+
+Marker events
+.............
+
+'hover', 'markerClicked', 'markerMoving' and 'markerMoved' events are
+sent during interaction with markers.
+
+'hover' is sent when the mouse cursor is over a marker.
+'markerClicker' is sent when the user click on a selectable marker.
+'markerMoving' and 'markerMoved' are sent when a draggable marker is moved.
+
+They provide the following keys:
+
+- 'event': 'hover', 'markerClicked', 'markerMoving' or 'markerMoved'
+- 'button': the mouse button that is pressed in 'left', 'middle', 'right'
+- 'draggable': True if the marker is draggable, False otherwise
+- 'label': The legend associated with the clicked image or curve
+- 'selectable': True if the marker is selectable, False otherwise
+- 'type': 'marker'
+- 'x' and 'y': The mouse position in data coordinates
+- 'xdata' and 'ydata': The marker position in data coordinates
+
+'markerClicked' and 'markerMoving' events have a 'xpixel' and a 'ypixel'
+additional keys, that provide the mouse position in pixels.
+
+
+Image and curve events
+......................
+
+'curveClicked' and 'imageClicked' events are sent when a selectable curve
+or image is clicked.
+
+Both share the following keys:
+
+- 'event': 'curveClicked' or 'imageClicked'
+- 'button': the mouse button that was pressed in 'left', 'middle', 'right'
+- 'label': The legend associated with the clicked image or curve
+- 'type': The type of item in 'curve', 'image'
+- 'x' and 'y': The clicked position in data coordinates
+- 'xpixel' and 'ypixel': The clicked position in pixels
+
+'curveClicked' events have a 'xdata' and a 'ydata' additional keys, that
+provide the coordinates of the picked points of the curve.
+There can be more than one point of the curve being picked, and if a line of
+the curve is picked, only the first point of the line is included in the list.
+
+'imageClicked' have a 'col' and a 'row' additional keys, that provide
+the column and row index in the image array that was clicked.
+
+
+Limits changed events
+.....................
+
+'limitsChanged' events are sent when the limits of the plot are changed.
+This can results from user interaction or API calls.
+
+It provides the following keys:
+
+- 'event': 'limitsChanged'
+- 'source': id of the widget that emitted this event.
+- 'xdata': Range of X in graph coordinates: (xMin, xMax).
+- 'ydata': Range of Y in graph coordinates: (yMin, yMax).
+- 'y2data': Range of right axis in graph coordinates (y2Min, y2Max) or None.
+
+Plot state change events
+........................
+
+The following events are emitted when the plot is modified.
+They provide the new state:
+
+- 'setGraphCursor' event with a 'state' key (bool)
+- 'setGraphGrid' event with a 'which' key (str), see :meth:`setGraphGrid`
+- 'setKeepDataAspectRatio' event with a 'state' key (bool)
+- 'setXAxisAutoScale' event with a 'state' key (bool)
+- 'setXAxisLogarithmic' event with a 'state' key (bool)
+- 'setYAxisAutoScale' event with a 'state' key (bool)
+- 'setYAxisInverted' event with a 'state' key (bool)
+- 'setYAxisLogarithmic' event with a 'state' key (bool)
+
+A 'contentChanged' event is triggered when the content of the plot is updated.
+It provides the following keys:
+
+- 'action': The change of the plot: 'add' or 'remove'
+- 'kind': The kind of primitive changed: 'curve', 'image', 'item' or 'marker'
+- 'legend': The legend of the primitive changed.
+
+'activeCurveChanged' and 'activeImageChanged' events with the following keys:
+
+- 'legend': Name (str) of the current active item or None if no active item.
+- 'previous': Name (str) of the previous active item or None if no item was
+ active. It is the same as 'legend' if 'updated' == True
+- 'updated': (bool) True if active item name did not changed,
+ but active item data or style was updated.
+
+'interactiveModeChanged' event with a 'source' key identifying the object
+setting the interactive mode.
+"""
+
+from __future__ import division
+
+
+__authors__ = ["V.A. Sole", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "16/02/2017"
+
+
+from collections import OrderedDict, namedtuple
+import itertools
+import logging
+
+import numpy
+
+# Import matplotlib backend here to init matplotlib our way
+from .backends.BackendMatplotlib import BackendMatplotlibQt
+
+try:
+ from matplotlib import cm as matplotlib_cm
+except ImportError:
+ matplotlib_cm = None
+
+from . import Colors
+from . import PlotInteraction
+from . import PlotEvents
+from . import _utils
+
+from . import items
+
+
+_logger = logging.getLogger(__name__)
+
+
+_COLORDICT = Colors.COLORDICT
+_COLORLIST = [_COLORDICT['black'],
+ _COLORDICT['blue'],
+ _COLORDICT['red'],
+ _COLORDICT['green'],
+ _COLORDICT['pink'],
+ _COLORDICT['yellow'],
+ _COLORDICT['brown'],
+ _COLORDICT['cyan'],
+ _COLORDICT['magenta'],
+ _COLORDICT['orange'],
+ _COLORDICT['violet'],
+ # _COLORDICT['bluegreen'],
+ _COLORDICT['grey'],
+ _COLORDICT['darkBlue'],
+ _COLORDICT['darkRed'],
+ _COLORDICT['darkGreen'],
+ _COLORDICT['darkCyan'],
+ _COLORDICT['darkMagenta'],
+ _COLORDICT['darkYellow'],
+ _COLORDICT['darkBrown']]
+
+
+"""
+Object returned when requesting the data range.
+"""
+_PlotDataRange = namedtuple('PlotDataRange',
+ ['x', 'y', 'yright'])
+
+
+class Plot(object):
+ """This class implements the plot API initially provided in PyMca.
+
+ Supported backends:
+
+ - 'matplotlib' and 'mpl': Matplotlib with Qt.
+ - 'opengl' and 'gl': OpenGL backend (requires PyOpenGL and OpenGL >= 2.1)
+ - 'none': No backend, to run headless for testing purpose.
+
+ :param parent: The parent widget of the plot (Default: None)
+ :param backend: The backend to use. A str in:
+ 'matplotlib', 'mpl', 'opengl', 'gl', 'none'
+ or a :class:`BackendBase.BackendBase` class
+ """
+
+ DEFAULT_BACKEND = 'matplotlib'
+ """Class attribute setting the default backend for all instances."""
+
+ colorList = _COLORLIST
+ colorDict = _COLORDICT
+
+ def __init__(self, parent=None, backend=None):
+ self._autoreplot = False
+ self._dirty = False
+ self._cursorInPlot = False
+
+ if backend is None:
+ backend = self.DEFAULT_BACKEND
+
+ if hasattr(backend, "__call__"):
+ self._backend = backend(self, parent)
+
+ elif hasattr(backend, "lower"):
+ lowerCaseString = backend.lower()
+ if lowerCaseString in ("matplotlib", "mpl"):
+ backendClass = BackendMatplotlibQt
+ elif lowerCaseString in ('gl', 'opengl'):
+ from .backends.BackendOpenGL import BackendOpenGL
+ backendClass = BackendOpenGL
+ elif lowerCaseString == 'none':
+ from .backends.BackendBase import BackendBase as backendClass
+ else:
+ raise ValueError("Backend not supported %s" % backend)
+ self._backend = backendClass(self, parent)
+
+ else:
+ raise ValueError("Backend not supported %s" % str(backend))
+
+ super(Plot, self).__init__()
+
+ self.setCallback() # set _callback
+
+ # Items handling
+ self._content = OrderedDict()
+ self._contentToUpdate = set()
+
+ self._dataRange = None
+
+ # line types
+ self._styleList = ['-', '--', '-.', ':']
+ self._colorIndex = 0
+ self._styleIndex = 0
+
+ self._activeCurveHandling = True
+ self._activeCurveColor = "#000000"
+ self._activeLegend = {'curve': None, 'image': None,
+ 'scatter': None}
+
+ # default properties
+ self._cursorConfiguration = None
+
+ self._logY = False
+ self._logX = False
+ self._xAutoScale = True
+ self._yAutoScale = True
+ self._grid = None
+
+ # Store default labels provided to setGraph[X|Y]Label
+ self._defaultLabels = {'x': '', 'y': '', 'yright': ''}
+ # Store currently displayed labels
+ # Current label can differ from input one with active curve handling
+ self._currentLabels = {'x': '', 'y': '', 'yright': ''}
+
+ self._graphTitle = ''
+
+ self.setGraphTitle()
+ self.setGraphXLabel()
+ self.setGraphYLabel()
+ self.setGraphYLabel('', axis='right')
+
+ self.setDefaultColormap() # Init default colormap
+
+ self.setDefaultPlotPoints(False)
+ self.setDefaultPlotLines(True)
+
+ self._eventHandler = PlotInteraction.PlotInteraction(self)
+ self._eventHandler.setInteractiveMode('zoom', color=(0., 0., 0., 1.))
+
+ self._pressedButtons = [] # Currently pressed mouse buttons
+
+ self._defaultDataMargins = (0., 0., 0., 0.)
+
+ # Only activate autoreplot at the end
+ # This avoids errors when loaded in Qt designer
+ self._dirty = False
+ self._autoreplot = True
+
+ def _getDirtyPlot(self):
+ """Return the plot dirty flag.
+
+ If False, the plot has not changed since last replot.
+ If True, the full plot need to be redrawn.
+ If 'overlay', only the overlay has changed since last replot.
+
+ It can be accessed by backend to check the dirty state.
+
+ :return: False, True, 'overlay'
+ """
+ return self._dirty
+
+ def _setDirtyPlot(self, overlayOnly=False):
+ """Mark the plot as needing redraw
+
+ :param bool overlayOnly: True to redraw only the overlay,
+ False to redraw everything
+ """
+ wasDirty = self._dirty
+
+ if not self._dirty and overlayOnly:
+ self._dirty = 'overlay'
+ else:
+ self._dirty = True
+
+ if self._autoreplot and not wasDirty:
+ self._backend.postRedisplay()
+
+ def _invalidateDataRange(self):
+ """
+ Notifies this Plot instance that the range has changed and will have
+ to be recomputed.
+ """
+ self._dataRange = None
+
+ def _updateDataRange(self):
+ """
+ Recomputes the range of the data displayed on this Plot.
+ """
+ xMin = yMinLeft = yMinRight = float('nan')
+ xMax = yMaxLeft = yMaxRight = float('nan')
+
+ for item in self._content.values():
+ if item.isVisible():
+ bounds = item.getBounds()
+ if bounds is not None:
+ xMin = numpy.nanmin([xMin, bounds[0]])
+ xMax = numpy.nanmax([xMax, bounds[1]])
+ # Take care of right axis
+ if (isinstance(item, items.YAxisMixIn) and
+ item.getYAxis() == 'right'):
+ yMinRight = numpy.nanmin([yMinRight, bounds[2]])
+ yMaxRight = numpy.nanmax([yMaxRight, bounds[3]])
+ else:
+ yMinLeft = numpy.nanmin([yMinLeft, bounds[2]])
+ yMaxLeft = numpy.nanmax([yMaxLeft, bounds[3]])
+
+ def lGetRange(x, y):
+ return None if numpy.isnan(x) and numpy.isnan(y) else (x, y)
+ xRange = lGetRange(xMin, xMax)
+ yLeftRange = lGetRange(yMinLeft, yMaxLeft)
+ yRightRange = lGetRange(yMinRight, yMaxRight)
+
+ self._dataRange = _PlotDataRange(x=xRange,
+ y=yLeftRange,
+ yright=yRightRange)
+
+ def getDataRange(self):
+ """
+ Returns this Plot's data range.
+
+ :return: a namedtuple with the following members :
+ x, y (left y axis), yright. Each member is a tuple (min, max)
+ or None if no data is associated with the axis.
+ :rtype: namedtuple
+ """
+ if self._dataRange is None:
+ self._updateDataRange()
+ return self._dataRange
+
+ # Content management
+
+ @staticmethod
+ def _itemKey(item):
+ """Build the key of given :class:`Item` in the plot
+
+ :param Item item: The item to make the key from
+ :return: (legend, kind)
+ :rtype: (str, str)
+ """
+ if isinstance(item, items.Curve):
+ kind = 'curve'
+ elif isinstance(item, items.ImageBase):
+ kind = 'image'
+ elif isinstance(item, items.Scatter):
+ kind = 'scatter'
+ elif isinstance(item, (items.Marker,
+ items.XMarker, items.YMarker)):
+ kind = 'marker'
+ elif isinstance(item, items.Shape):
+ kind = 'item'
+ elif isinstance(item, items.Histogram):
+ kind = 'histogram'
+ else:
+ raise ValueError('Unsupported item type %s' % type(item))
+
+ return item.getLegend(), kind
+
+ def _add(self, item):
+ """Add the given :class:`Item` to the plot.
+
+ :param Item item: The item to append to the plot content
+ """
+ key = self._itemKey(item)
+ if key in self._content:
+ raise RuntimeError('Item already in the plot')
+
+ # Add item to plot
+ self._content[key] = item
+ item._setPlot(self)
+ if item.isVisible():
+ self._itemRequiresUpdate(item)
+ if isinstance(item, (items.Curve, items.ImageBase)):
+ self._invalidateDataRange() # TODO handle this automatically
+
+ def _remove(self, item):
+ """Remove the given :class:`Item` from the plot.
+
+ :param Item item: The item to remove from the plot content
+ """
+ key = self._itemKey(item)
+ if key not in self._content:
+ raise RuntimeError('Item not in the plot')
+
+ # Remove item from plot
+ self._content.pop(key)
+ self._contentToUpdate.discard(item)
+ if item.isVisible():
+ self._setDirtyPlot(overlayOnly=item.isOverlay())
+ if item.getBounds() is not None:
+ self._invalidateDataRange()
+ item._removeBackendRenderer(self._backend)
+ item._setPlot(None)
+
+ def _itemRequiresUpdate(self, item):
+ """Called by items in the plot for asynchronous update
+
+ :param Item item: The item that required update
+ """
+ assert item.getPlot() == self
+ self._contentToUpdate.add(item)
+ self._setDirtyPlot(overlayOnly=item.isOverlay())
+
+ # Add
+
+ # add * input arguments management:
+ # If an arg is set, then use it.
+ # Else:
+ # If a curve with the same legend exists, then use its arg value
+ # Else, use a default value.
+ # Store used value.
+ # This value is used when curve is updated either internally or by user.
+
+ def addCurve(self, x, y, legend=None, info=None,
+ replace=False, replot=None,
+ color=None, symbol=None,
+ linewidth=None, linestyle=None,
+ xlabel=None, ylabel=None, yaxis=None,
+ xerror=None, yerror=None, z=None, selectable=None,
+ fill=None, resetzoom=True,
+ histogram=None, copy=True, **kw):
+ """Add a 1D curve given by x an y to the graph.
+
+ Curves are uniquely identified by their legend.
+ To add multiple curves, call :meth:`addCurve` multiple times with
+ different legend argument.
+ To replace an existing curve, call :meth:`addCurve` with the
+ existing curve legend.
+ If you want to display the curve values as an histogram see the
+ histogram parameter or :meth:`addHistogram`.
+
+ When curve parameters are not provided, if a curve with the
+ same legend is displayed in the plot, its parameters are used.
+
+ :param numpy.ndarray x: The data corresponding to the x coordinates.
+ If you attempt to plot an histogram you can set edges values in x.
+ In this case len(x) = len(y) + 1
+ :param numpy.ndarray y: The data corresponding to the y coordinates
+ :param str legend: The legend to be associated to the curve (or None)
+ :param info: User-defined information associated to the curve
+ :param bool replace: True (the default) to delete already existing
+ curves
+ :param color: color(s) to be used
+ :type color: str ("#RRGGBB") or (npoints, 4) unsigned byte array or
+ one of the predefined color names defined in Colors.py
+ :param str symbol: Symbol to be drawn at each (x, y) position::
+
+ - 'o' circle
+ - '.' point
+ - ',' pixel
+ - '+' cross
+ - 'x' x-cross
+ - 'd' diamond
+ - 's' square
+ - None (the default) to use default symbol
+
+ :param float linewidth: The width of the curve in pixels (Default: 1).
+ :param str linestyle: Type of line::
+
+ - ' ' no line
+ - '-' solid line
+ - '--' dashed line
+ - '-.' dash-dot line
+ - ':' dotted line
+ - None (the default) to use default line style
+
+ :param str xlabel: Label to show on the X axis when the curve is active
+ or None to keep default axis label.
+ :param str ylabel: Label to show on the Y axis when the curve is active
+ or None to keep default axis label.
+ :param str yaxis: The Y axis this curve is attached to.
+ Either 'left' (the default) or 'right'
+ :param xerror: Values with the uncertainties on the x values
+ :type xerror: A float, or a numpy.ndarray of float32.
+ If it is an array, it can either be a 1D array of
+ same length as the data or a 2D array with 2 rows
+ of same length as the data: row 0 for positive errors,
+ row 1 for negative errors.
+ :param yerror: Values with the uncertainties on the y values
+ :type yerror: A float, or a numpy.ndarray of float32. See xerror.
+ :param int z: Layer on which to draw the curve (default: 1)
+ This allows to control the overlay.
+ :param bool selectable: Indicate if the curve can be selected.
+ (Default: True)
+ :param bool fill: True to fill the curve, False otherwise (default).
+ :param bool resetzoom: True (the default) to reset the zoom.
+ :param str histogram: if not None then the curve will be draw as an
+ histogram. The step for each values of the curve can be set to the
+ left, center or right of the original x curve values.
+ If histogram is not None and len(x) == len(y)+1 then x is directly
+ take as edges of the histogram.
+ Type of histogram::
+
+ - None (default)
+ - 'left'
+ - 'right'
+ - 'center'
+ :param bool copy: True make a copy of the data (default),
+ False to use provided arrays.
+ :returns: The key string identify this curve
+ """
+ # Deprecation warnings
+ if replot is not None:
+ _logger.warning(
+ 'addCurve deprecated replot argument, use resetzoom instead')
+ resetzoom = replot and resetzoom
+
+ if kw:
+ _logger.warning('addCurve: deprecated extra arguments')
+
+ # This is an histogram, use addHistogram
+ if histogram is not None:
+ histoLegend = self.addHistogram(histogram=y,
+ edges=x,
+ legend=legend,
+ color=color,
+ fill=fill,
+ align=histogram,
+ copy=copy)
+ histo = self.getHistogram(histoLegend)
+
+ histo.setInfo(info)
+ if linewidth is not None:
+ histo.setLineWidth(linewidth)
+ if linestyle is not None:
+ histo.setLineStyle(linestyle)
+ if xlabel is not None:
+ _logger.warning(
+ 'addCurve: Histogram does not support xlabel argument')
+ if ylabel is not None:
+ _logger.warning(
+ 'addCurve: Histogram does not support ylabel argument')
+ if yaxis is not None:
+ histo.setYAxis(yaxis)
+ if z is not None:
+ histo.setZValue(z)
+ if selectable is not None:
+ _logger.warning(
+ 'addCurve: Histogram does not support selectable argument')
+
+ return
+
+ legend = 'Unnamed curve 1.1' if legend is None else str(legend)
+
+ # Check if curve was previously active
+ wasActive = self.getActiveCurve(just_legend=True) == legend
+
+ # Create/Update curve object
+ curve = self.getCurve(legend)
+ if curve is None:
+ # No previous curve, create a default one and add it to the plot
+ curve = items.Curve() if histogram is None else items.Histogram()
+ curve._setLegend(legend)
+ # Set default color, linestyle and symbol
+ default_color, default_linestyle = self._getColorAndStyle()
+ curve.setColor(default_color)
+ curve.setLineStyle(default_linestyle)
+ curve.setSymbol(self._defaultPlotPoints)
+ self._add(curve)
+
+ # Override previous/default values with provided ones
+ curve.setInfo(info)
+ if color is not None:
+ curve.setColor(color)
+ if symbol is not None:
+ curve.setSymbol(symbol)
+ if linewidth is not None:
+ curve.setLineWidth(linewidth)
+ if linestyle is not None:
+ curve.setLineStyle(linestyle)
+ if xlabel is not None:
+ curve._setXLabel(xlabel)
+ if ylabel is not None:
+ curve._setYLabel(ylabel)
+ if yaxis is not None:
+ curve.setYAxis(yaxis)
+ if z is not None:
+ curve.setZValue(z)
+ if selectable is not None:
+ curve._setSelectable(selectable)
+ if fill is not None:
+ curve.setFill(fill)
+
+ # Set curve data
+ # If errors not provided, reuse previous ones
+ # TODO: Issue if size of data change but not that of errors
+ if xerror is None:
+ xerror = curve.getXErrorData(copy=False)
+ if yerror is None:
+ yerror = curve.getYErrorData(copy=False)
+
+ curve.setData(x, y, xerror, yerror, copy=copy)
+
+ if replace: # Then remove all other curves
+ for c in self.getAllCurves(withhidden=True):
+ if c is not curve:
+ self._remove(c)
+
+ self.notify(
+ 'contentChanged', action='add', kind='curve', legend=legend)
+
+ if wasActive:
+ self.setActiveCurve(curve.getLegend())
+
+ if resetzoom:
+ # We ask for a zoom reset in order to handle the plot scaling
+ # if the user does not want that, autoscale of the different
+ # axes has to be set to off.
+ self.resetZoom()
+
+ return legend
+
+ def addHistogram(self,
+ histogram,
+ edges,
+ legend=None,
+ color=None,
+ fill=None,
+ align='center',
+ resetzoom=True,
+ copy=True):
+ """Add an histogram to the graph.
+
+ This is NOT computing the histogram, this method takes as parameter
+ already computed histogram values.
+
+ Histogram are uniquely identified by their legend.
+ To add multiple histograms, call :meth:`addHistogram` multiple times
+ with different legend argument.
+
+ When histogram parameters are not provided, if an histogram with the
+ same legend is displayed in the plot, its parameters are used.
+
+ :param numpy.ndarray histogram: The values of the histogram.
+ :param numpy.ndarray edges:
+ The bin edges of the histogram.
+ If histogram and edges have the same length, the bin edges
+ are computed according to the align parameter.
+ :param str legend:
+ The legend to be associated to the histogram (or None)
+ :param color: color to be used
+ :type color: str ("#RRGGBB") or RGB unsigned byte array or
+ one of the predefined color names defined in Colors.py
+ :param bool fill: True to fill the curve, False otherwise (default).
+ :param str align:
+ In case histogram values and edges have the same length N,
+ the N+1 bin edges are computed according to the alignment in:
+ 'center' (default), 'left', 'right'.
+ :param bool resetzoom: True (the default) to reset the zoom.
+ :param bool copy: True make a copy of the data (default),
+ False to use provided arrays.
+ :returns: The key string identify this histogram
+ """
+ legend = 'Unnamed histogram' if legend is None else str(legend)
+
+ # Create/Update histogram object
+ histo = self.getHistogram(legend)
+ if histo is None:
+ # No previous histogram, create a default one and
+ # add it to the plot
+ histo = items.Histogram()
+ histo._setLegend(legend)
+ histo.setColor(self._getColorAndStyle()[0])
+ self._add(histo)
+
+ # Override previous/default values with provided ones
+ if color is not None:
+ histo.setColor(color)
+ if fill is not None:
+ histo.setFill(fill)
+
+ # Set histogram data
+ histo.setData(histogram, edges, align=align, copy=copy)
+
+ self.notify(
+ 'contentChanged', action='add', kind='histogram', legend=legend)
+
+ if resetzoom:
+ # We ask for a zoom reset in order to handle the plot scaling
+ # if the user does not want that, autoscale of the different
+ # axes has to be set to off.
+ self.resetZoom()
+
+ return legend
+
+ def addImage(self, data, legend=None, info=None,
+ replace=True, replot=None,
+ xScale=None, yScale=None, z=None,
+ selectable=None, draggable=None,
+ colormap=None, pixmap=None,
+ xlabel=None, ylabel=None,
+ origin=None, scale=None,
+ resetzoom=True, copy=True, **kw):
+ """Add a 2D dataset or an image to the plot.
+
+ It displays either an array of data using a colormap or a RGB(A) image.
+
+ Images are uniquely identified by their legend.
+ To add multiple images, call :meth:`addImage` multiple times with
+ different legend argument.
+ To replace/update an existing image, call :meth:`addImage` with the
+ existing image legend.
+
+ When image parameters are not provided, if an image with the
+ same legend is displayed in the plot, its parameters are used.
+
+ :param numpy.ndarray data: (nrows, ncolumns) data or
+ (nrows, ncolumns, RGBA) ubyte array
+ :param str legend: The legend to be associated to the image (or None)
+ :param info: User-defined information associated to the image
+ :param bool replace: True (default) to delete already existing images
+ :param int z: Layer on which to draw the image (default: 0)
+ This allows to control the overlay.
+ :param bool selectable: Indicate if the image can be selected.
+ (default: False)
+ :param bool draggable: Indicate if the image can be moved.
+ (default: False)
+ :param dict colormap: Description of the colormap to use (or None)
+ This is ignored if data is a RGB(A) image.
+ See :mod:`Plot` for the documentation
+ of the colormap dict.
+ :param pixmap: Pixmap representation of the data (if any)
+ :type pixmap: (nrows, ncolumns, RGBA) ubyte array or None (default)
+ :param str xlabel: X axis label to show when this curve is active,
+ or None to keep default axis label.
+ :param str ylabel: Y axis label to show when this curve is active,
+ or None to keep default axis label.
+ :param origin: (origin X, origin Y) of the data.
+ It is possible to pass a single float if both
+ coordinates are equal.
+ Default: (0., 0.)
+ :type origin: float or 2-tuple of float
+ :param scale: (scale X, scale Y) of the data.
+ It is possible to pass a single float if both
+ coordinates are equal.
+ Default: (1., 1.)
+ :type scale: float or 2-tuple of float
+ :param bool resetzoom: True (the default) to reset the zoom.
+ :param bool copy: True make a copy of the data (default),
+ False to use provided arrays.
+ :returns: The key string identify this image
+ """
+ # Deprecation warnings
+ if xScale is not None or yScale is not None:
+ _logger.warning(
+ 'addImage deprecated xScale and yScale arguments,'
+ 'use origin, scale arguments instead.')
+ if origin is None and scale is None:
+ origin = xScale[0], yScale[0]
+ scale = xScale[1], yScale[1]
+ else:
+ _logger.warning(
+ 'addCurve: xScale, yScale and origin, scale arguments'
+ ' are conflicting. xScale and yScale are ignored.'
+ ' Use only origin, scale arguments.')
+
+ if replot is not None:
+ _logger.warning(
+ 'addImage deprecated replot argument, use resetzoom instead')
+ resetzoom = replot and resetzoom
+
+ if kw:
+ _logger.warning('addImage: deprecated extra arguments')
+
+ legend = "Unnamed Image 1.1" if legend is None else str(legend)
+
+ # Check if image was previously active
+ wasActive = self.getActiveImage(just_legend=True) == legend
+
+ data = numpy.array(data, copy=False)
+ assert data.ndim in (2, 3)
+
+ image = self.getImage(legend)
+ if image is not None and image.getData(copy=False).ndim != data.ndim:
+ # Update a data image with RGBA image or the other way around:
+ # Remove previous image
+ # In this case, we don't retrieve defaults from the previous image
+ self._remove(image)
+ image = None
+
+ if image is None:
+ # No previous image, create a default one and add it to the plot
+ if data.ndim == 2:
+ image = items.ImageData()
+ image.setColormap(self.getDefaultColormap())
+ else:
+ image = items.ImageRgba()
+ image._setLegend(legend)
+ self._add(image)
+
+ # Override previous/default values with provided ones
+ image.setInfo(info)
+ if origin is not None:
+ image.setOrigin(origin)
+ if scale is not None:
+ image.setScale(scale)
+ if z is not None:
+ image.setZValue(z)
+ if selectable is not None:
+ image._setSelectable(selectable)
+ if draggable is not None:
+ image._setDraggable(draggable)
+ if colormap is not None and isinstance(image, items.ColormapMixIn):
+ image.setColormap(colormap)
+ if xlabel is not None:
+ image._setXLabel(xlabel)
+ if ylabel is not None:
+ image._setYLabel(ylabel)
+
+ if data.ndim == 2:
+ image.setData(data, alternative=pixmap, copy=copy)
+ else: # RGB(A) image
+ if pixmap is not None:
+ _logger.warning(
+ 'addImage: pixmap argument ignored when data is RGB(A)')
+ image.setData(data, copy=copy)
+
+ if replace:
+ for img in self.getAllImages():
+ if img is not image:
+ self._remove(img)
+
+ if len(self.getAllImages()) == 1 or wasActive:
+ self.setActiveImage(legend)
+
+ self.notify(
+ 'contentChanged', action='add', kind='image', legend=legend)
+
+ if resetzoom:
+ # We ask for a zoom reset in order to handle the plot scaling
+ # if the user does not want that, autoscale of the different
+ # axes has to be set to off.
+ self.resetZoom()
+
+ return legend
+
+ def addScatter(self, x, y, value, legend=None, colormap=None,
+ info=None, symbol=None, xerror=None, yerror=None,
+ z=None, copy=True):
+ """Add a (x, y, value) scatter to the graph.
+
+ Scatters are uniquely identified by their legend.
+ To add multiple scatters, call :meth:`addScatter` multiple times with
+ different legend argument.
+ To replace/update an existing scatter, call :meth:`addScatter` with the
+ existing scatter legend.
+
+ When scatter parameters are not provided, if a scatter with the
+ same legend is displayed in the plot, its parameters are used.
+
+ :param numpy.ndarray x: The data corresponding to the x coordinates.
+ :param numpy.ndarray y: The data corresponding to the y coordinates
+ :param numpy.ndarray value: The data value associated with each point
+ :param str legend: The legend to be associated to the scatter (or None)
+ :param dict colormap: The colormap to be used for the scatter (or None)
+ See :mod:`Plot` for the documentation
+ of the colormap dict.
+ :param info: User-defined information associated to the curve
+ :param str symbol: Symbol to be drawn at each (x, y) position::
+
+ - 'o' circle
+ - '.' point
+ - ',' pixel
+ - '+' cross
+ - 'x' x-cross
+ - 'd' diamond
+ - 's' square
+ - None (the default) to use default symbol
+
+ :param xerror: Values with the uncertainties on the x values
+ :type xerror: A float, or a numpy.ndarray of float32.
+ If it is an array, it can either be a 1D array of
+ same length as the data or a 2D array with 2 rows
+ of same length as the data: row 0 for positive errors,
+ row 1 for negative errors.
+ :param yerror: Values with the uncertainties on the y values
+ :type yerror: A float, or a numpy.ndarray of float32. See xerror.
+ :param int z: Layer on which to draw the scatter (default: 1)
+ This allows to control the overlay.
+
+ :param bool copy: True make a copy of the data (default),
+ False to use provided arrays.
+ :returns: The key string identify this scatter
+ """
+ legend = 'Unnamed scatter 1.1' if legend is None else str(legend)
+
+ # Check if scatter was previously active
+ wasActive = self._getActiveItem(kind='scatter',
+ just_legend=True) == legend
+
+ # Create/Update curve object
+ scatter = self._getItem(kind='scatter', legend=legend)
+ if scatter is None:
+ # No previous scatter, create a default one and add it to the plot
+ scatter = items.Scatter()
+ scatter._setLegend(legend)
+ scatter.setColormap(self.getDefaultColormap())
+ self._add(scatter)
+
+ # Override previous/default values with provided ones
+ scatter.setInfo(info)
+ if symbol is not None:
+ scatter.setSymbol(symbol)
+ if z is not None:
+ scatter.setZValue(z)
+ if colormap is not None:
+ scatter.setColormap(colormap)
+
+ # Set scatter data
+ # If errors not provided, reuse previous ones
+ if xerror is None:
+ xerror = scatter.getXErrorData(copy=False)
+ if xerror is not None and len(xerror) != len(x):
+ xerror = None
+ if yerror is None:
+ yerror = scatter.getYErrorData(copy=False)
+ if yerror is not None and len(yerror) != len(y):
+ yerror = None
+
+ scatter.setData(x, y, value, xerror, yerror, copy=copy)
+
+ self.notify(
+ 'contentChanged', action='add', kind='scatter', legend=legend)
+
+ if len(self._getItems(kind="scatter")) == 1 or wasActive:
+ self._setActiveItem('scatter', scatter.getLegend())
+
+ return legend
+
+ def addItem(self, xdata, ydata, legend=None, info=None,
+ replace=False,
+ shape="polygon", color='black', fill=True,
+ overlay=False, z=None, **kw):
+ """Add an item (i.e. a shape) to the plot.
+
+ Items are uniquely identified by their legend.
+ To add multiple items, call :meth:`addItem` multiple times with
+ different legend argument.
+ To replace/update an existing item, call :meth:`addItem` with the
+ existing item legend.
+
+ :param numpy.ndarray xdata: The X coords of the points of the shape
+ :param numpy.ndarray ydata: The Y coords of the points of the shape
+ :param str legend: The legend to be associated to the item
+ :param info: User-defined information associated to the item
+ :param bool replace: True (default) to delete already existing images
+ :param str shape: Type of item to be drawn in
+ hline, polygon (the default), rectangle, vline,
+ polylines
+ :param str color: Color of the item, e.g., 'blue', 'b', '#FF0000'
+ (Default: 'black')
+ :param bool fill: True (the default) to fill the shape
+ :param bool overlay: True if item is an overlay (Default: False).
+ This allows for rendering optimization if this
+ item is changed often.
+ :param int z: Layer on which to draw the item (default: 2)
+ :returns: The key string identify this item
+ """
+ # expected to receive the same parameters as the signal
+
+ if kw:
+ _logger.warning('addItem deprecated parameters: %s', str(kw))
+
+ legend = "Unnamed Item 1.1" if legend is None else str(legend)
+
+ z = int(z) if z is not None else 2
+
+ if replace:
+ self.remove(kind='item')
+ else:
+ self.remove(legend, kind='item')
+
+ item = items.Shape(shape)
+ item._setLegend(legend)
+ item.setInfo(info)
+ item.setColor(color)
+ item.setFill(fill)
+ item.setOverlay(overlay)
+ item.setZValue(z)
+ item.setPoints(numpy.array((xdata, ydata)).T)
+
+ self._add(item)
+
+ self.notify('contentChanged', action='add', kind='item', legend=legend)
+
+ return legend
+
+ def addXMarker(self, x, legend=None,
+ text=None,
+ color=None,
+ selectable=False,
+ draggable=False,
+ constraint=None,
+ **kw):
+ """Add a vertical line marker to the plot.
+
+ Markers are uniquely identified by their legend.
+ As opposed to curves, images and items, two calls to
+ :meth:`addXMarker` without legend argument adds two markers with
+ different identifying legends.
+
+ :param float x: Position of the marker on the X axis in data
+ coordinates
+ :param str legend: Legend associated to the marker to identify it
+ :param str text: Text to display on the marker.
+ :param str color: Color of the marker, e.g., 'blue', 'b', '#FF0000'
+ (Default: 'black')
+ :param bool selectable: Indicate if the marker can be selected.
+ (default: False)
+ :param bool draggable: Indicate if the marker can be moved.
+ (default: False)
+ :param constraint: A function filtering marker displacement by
+ dragging operations or None for no filter.
+ This function is called each time a marker is
+ moved.
+ This parameter is only used if draggable is True.
+ :type constraint: None or a callable that takes the coordinates of
+ the current cursor position in the plot as input
+ and that returns the filtered coordinates.
+ :return: The key string identify this marker
+ """
+ if kw:
+ _logger.warning(
+ 'addXMarker deprecated extra parameters: %s', str(kw))
+
+ return self._addMarker(x=x, y=None, legend=legend,
+ text=text, color=color,
+ selectable=selectable, draggable=draggable,
+ symbol=None, constraint=constraint)
+
+ def addYMarker(self, y,
+ legend=None,
+ text=None,
+ color=None,
+ selectable=False,
+ draggable=False,
+ constraint=None,
+ **kw):
+ """Add a horizontal line marker to the plot.
+
+ Markers are uniquely identified by their legend.
+ As opposed to curves, images and items, two calls to
+ :meth:`addYMarker` without legend argument adds two markers with
+ different identifying legends.
+
+ :param float y: Position of the marker on the Y axis in data
+ coordinates
+ :param str legend: Legend associated to the marker to identify it
+ :param str text: Text to display next to the marker.
+ :param str color: Color of the marker, e.g., 'blue', 'b', '#FF0000'
+ (Default: 'black')
+ :param bool selectable: Indicate if the marker can be selected.
+ (default: False)
+ :param bool draggable: Indicate if the marker can be moved.
+ (default: False)
+ :param constraint: A function filtering marker displacement by
+ dragging operations or None for no filter.
+ This function is called each time a marker is
+ moved.
+ This parameter is only used if draggable is True.
+ :type constraint: None or a callable that takes the coordinates of
+ the current cursor position in the plot as input
+ and that returns the filtered coordinates.
+ :return: The key string identify this marker
+ """
+ if kw:
+ _logger.warning(
+ 'addYMarker deprecated extra parameters: %s', str(kw))
+
+ return self._addMarker(x=None, y=y, legend=legend,
+ text=text, color=color,
+ selectable=selectable, draggable=draggable,
+ symbol=None, constraint=constraint)
+
+ def addMarker(self, x, y, legend=None,
+ text=None,
+ color=None,
+ selectable=False,
+ draggable=False,
+ symbol='+',
+ constraint=None,
+ **kw):
+ """Add a point marker to the plot.
+
+ Markers are uniquely identified by their legend.
+ As opposed to curves, images and items, two calls to
+ :meth:`addMarker` without legend argument adds two markers with
+ different identifying legends.
+
+ :param float x: Position of the marker on the X axis in data
+ coordinates
+ :param float y: Position of the marker on the Y axis in data
+ coordinates
+ :param str legend: Legend associated to the marker to identify it
+ :param str text: Text to display next to the marker
+ :param str color: Color of the marker, e.g., 'blue', 'b', '#FF0000'
+ (Default: 'black')
+ :param bool selectable: Indicate if the marker can be selected.
+ (default: False)
+ :param bool draggable: Indicate if the marker can be moved.
+ (default: False)
+ :param str symbol: Symbol representing the marker in::
+
+ - 'o' circle
+ - '.' point
+ - ',' pixel
+ - '+' cross (the default)
+ - 'x' x-cross
+ - 'd' diamond
+ - 's' square
+
+ :param constraint: A function filtering marker displacement by
+ dragging operations or None for no filter.
+ This function is called each time a marker is
+ moved.
+ This parameter is only used if draggable is True.
+ :type constraint: None or a callable that takes the coordinates of
+ the current cursor position in the plot as input
+ and that returns the filtered coordinates.
+ :return: The key string identify this marker
+ """
+ if kw:
+ _logger.warning(
+ 'addMarker deprecated extra parameters: %s', str(kw))
+
+ if x is None:
+ xmin, xmax = self.getGraphXLimits()
+ x = 0.5 * (xmax + xmin)
+
+ if y is None:
+ ymin, ymax = self.getGraphYLimits()
+ y = 0.5 * (ymax + ymin)
+
+ return self._addMarker(x=x, y=y, legend=legend,
+ text=text, color=color,
+ selectable=selectable, draggable=draggable,
+ symbol=symbol, constraint=constraint)
+
+ def _addMarker(self, x, y, legend,
+ text, color,
+ selectable, draggable,
+ symbol, constraint):
+ """Common method for adding point, vline and hline marker.
+
+ See :meth:`addMarker` for argument documentation.
+ """
+ assert (x, y) != (None, None)
+
+ if legend is None: # Find an unused legend
+ markerLegends = self._getAllMarkers(just_legend=True)
+ for index in itertools.count():
+ legend = "Unnamed Marker %d" % index
+ if legend not in markerLegends:
+ break # Keep this legend
+ legend = str(legend)
+
+ if x is None:
+ markerClass = items.YMarker
+ elif y is None:
+ markerClass = items.XMarker
+ else:
+ markerClass = items.Marker
+
+ # Create/Update marker object
+ marker = self._getMarker(legend)
+ if marker is not None and not isinstance(marker, markerClass):
+ _logger.warning('Adding marker with same legend'
+ ' but different type replaces it')
+ self._remove(marker)
+ marker = None
+
+ if marker is None:
+ # No previous marker, create one
+ marker = markerClass()
+ marker._setLegend(legend)
+ self._add(marker)
+
+ if text is not None:
+ marker.setText(text)
+ if color is not None:
+ marker.setColor(color)
+ if selectable is not None:
+ marker._setSelectable(selectable)
+ if draggable is not None:
+ marker._setDraggable(draggable)
+ if symbol is not None:
+ marker.setSymbol(symbol)
+
+ # TODO to improve, but this ensure constraint is applied
+ marker.setPosition(x, y)
+ if constraint is not None:
+ marker._setConstraint(constraint)
+ marker.setPosition(x, y)
+
+ self.notify(
+ 'contentChanged', action='add', kind='marker', legend=legend)
+
+ return legend
+
+ # Hide
+
+ def isCurveHidden(self, legend):
+ """Returns True if the curve associated to legend is hidden, else False
+
+ :param str legend: The legend key identifying the curve
+ :return: True if the associated curve is hidden, False otherwise
+ """
+ curve = self._getItem('curve', legend)
+ return curve is not None and not curve.isVisible()
+
+ def hideCurve(self, legend, flag=True, replot=None):
+ """Show/Hide the curve associated to legend.
+
+ Even when hidden, the curve is kept in the list of curves.
+
+ :param str legend: The legend associated to the curve to be hidden
+ :param bool flag: True (default) to hide the curve, False to show it
+ """
+ if replot is not None:
+ _logger.warning('hideCurve deprecated replot parameter')
+
+ curve = self._getItem('curve', legend)
+ if curve is None:
+ _logger.warning('Curve not in plot: %s', legend)
+ return
+
+ isVisible = not flag
+ if isVisible != curve.isVisible():
+ curve.setVisible(isVisible)
+
+ # Remove
+
+ ITEM_KINDS = 'curve', 'image', 'scatter', 'item', 'marker', 'histogram'
+
+ def remove(self, legend=None, kind=ITEM_KINDS):
+ """Remove one or all element(s) of the given legend and kind.
+
+ Examples:
+
+ - ``remove()`` clears the plot
+ - ``remove(kind='curve')`` removes all curves from the plot
+ - ``remove('myCurve', kind='curve')`` removes the curve with
+ legend 'myCurve' from the plot.
+ - ``remove('myImage, kind='image')`` removes the image with
+ legend 'myImage' from the plot.
+ - ``remove('myImage')`` removes elements (for instance curve, image,
+ item and marker) with legend 'myImage'.
+
+ :param str legend: The legend associated to the element to remove,
+ or None to remove
+ :param kind: The kind of elements to remove from the plot.
+ In: 'all', 'curve', 'image', 'item', 'marker'.
+ By default, it removes all kind of elements.
+ :type kind: str or tuple of str to specify multiple kinds.
+ """
+ if kind is 'all': # Replace all by tuple of all kinds
+ kind = self.ITEM_KINDS
+
+ if kind in self.ITEM_KINDS: # Kind is a str, make it a tuple
+ kind = (kind,)
+
+ for aKind in kind:
+ assert aKind in self.ITEM_KINDS
+
+ if legend is None: # This is a clear
+ # Clear each given kind
+ for aKind in kind:
+ for legend in self._getItems(
+ kind=aKind, just_legend=True, withhidden=True):
+ self.remove(legend=legend, kind=aKind)
+
+ else: # This is removing a single element
+ # Remove each given kind
+ for aKind in kind:
+ item = self._getItem(aKind, legend)
+ if item is not None:
+ if aKind in ('curve', 'image'):
+ if self._getActiveItem(aKind) == item:
+ # Reset active item
+ self._setActiveItem(aKind, None)
+
+ self._remove(item)
+
+ if (aKind == 'curve' and
+ not self.getAllCurves(just_legend=True,
+ withhidden=True)):
+ self._colorIndex = 0
+ self._styleIndex = 0
+
+ self.notify('contentChanged', action='remove',
+ kind=aKind, legend=legend)
+
+ def removeCurve(self, legend):
+ """Remove the curve associated to legend from the graph.
+
+ :param str legend: The legend associated to the curve to be deleted
+ """
+ if legend is None:
+ return
+ self.remove(legend, kind='curve')
+
+ def removeImage(self, legend):
+ """Remove the image associated to legend from the graph.
+
+ :param str legend: The legend associated to the image to be deleted
+ """
+ if legend is None:
+ return
+ self.remove(legend, kind='image')
+
+ def removeItem(self, legend):
+ """Remove the item associated to legend from the graph.
+
+ :param str legend: The legend associated to the item to be deleted
+ """
+ if legend is None:
+ return
+ self.remove(legend, kind='item')
+
+ def removeMarker(self, legend):
+ """Remove the marker associated to legend from the graph.
+
+ :param str legend: The legend associated to the marker to be deleted
+ """
+ if legend is None:
+ return
+ self.remove(legend, kind='marker')
+
+ # Clear
+
+ def clear(self):
+ """Remove everything from the plot."""
+ self.remove()
+
+ def clearCurves(self):
+ """Remove all the curves from the plot."""
+ self.remove(kind='curve')
+
+ def clearImages(self):
+ """Remove all the images from the plot."""
+ self.remove(kind='image')
+
+ def clearItems(self):
+ """Remove all the items from the plot. """
+ self.remove(kind='item')
+
+ def clearMarkers(self):
+ """Remove all the markers from the plot."""
+ self.remove(kind='marker')
+
+ # Interaction
+
+ def getGraphCursor(self):
+ """Returns the state of the crosshair cursor.
+
+ See :meth:`setGraphCursor`.
+
+ :return: None if the crosshair cursor is not active,
+ else a tuple (color, linewidth, linestyle).
+ """
+ return self._cursorConfiguration
+
+ def setGraphCursor(self, flag=False, color='black',
+ linewidth=1, linestyle='-'):
+ """Toggle the display of a crosshair cursor and set its attributes.
+
+ :param bool flag: Toggle the display of a crosshair cursor.
+ The crosshair cursor is hidden by default.
+ :param color: The color to use for the crosshair.
+ :type color: A string (either a predefined color name in Colors.py
+ or "#RRGGBB")) or a 4 columns unsigned byte array
+ (Default: black).
+ :param int linewidth: The width of the lines of the crosshair
+ (Default: 1).
+ :param str linestyle: Type of line::
+
+ - ' ' no line
+ - '-' solid line (the default)
+ - '--' dashed line
+ - '-.' dash-dot line
+ - ':' dotted line
+ """
+ if flag:
+ self._cursorConfiguration = color, linewidth, linestyle
+ else:
+ self._cursorConfiguration = None
+
+ self._backend.setGraphCursor(flag=flag, color=color,
+ linewidth=linewidth, linestyle=linestyle)
+ self._setDirtyPlot()
+ self.notify('setGraphCursor',
+ state=self._cursorConfiguration is not None)
+
+ def pan(self, direction, factor=0.1):
+ """Pan the graph in the given direction by the given factor.
+
+ Warning: Pan of right Y axis not implemented!
+
+ :param str direction: One of 'up', 'down', 'left', 'right'.
+ :param float factor: Proportion of the range used to pan the graph.
+ Must be strictly positive.
+ """
+ assert direction in ('up', 'down', 'left', 'right')
+ assert factor > 0.
+
+ if direction in ('left', 'right'):
+ xFactor = factor if direction == 'right' else - factor
+ xMin, xMax = self.getGraphXLimits()
+
+ xMin, xMax = _utils.applyPan(xMin, xMax, xFactor,
+ self.isXAxisLogarithmic())
+ self.setGraphXLimits(xMin, xMax)
+
+ else: # direction in ('up', 'down')
+ sign = -1. if self.isYAxisInverted() else 1.
+ yFactor = sign * (factor if direction == 'up' else -factor)
+ yMin, yMax = self.getGraphYLimits()
+ yIsLog = self.isYAxisLogarithmic()
+
+ yMin, yMax = _utils.applyPan(yMin, yMax, yFactor, yIsLog)
+ self.setGraphYLimits(yMin, yMax, axis='left')
+
+ y2Min, y2Max = self.getGraphYLimits(axis='right')
+
+ y2Min, y2Max = _utils.applyPan(y2Min, y2Max, yFactor, yIsLog)
+ self.setGraphYLimits(y2Min, y2Max, axis='right')
+
+ # Active Curve/Image
+
+ def isActiveCurveHandling(self):
+ """Returns True if active curve selection is enabled."""
+ return self._activeCurveHandling
+
+ def setActiveCurveHandling(self, flag=True):
+ """Enable/Disable active curve selection.
+
+ :param bool flag: True (the default) to enable active curve selection.
+ """
+ if not flag:
+ self.setActiveCurve(None) # Reset active curve
+
+ self._activeCurveHandling = bool(flag)
+
+ def getActiveCurveColor(self):
+ """Get the color used to display the currently active curve.
+
+ See :meth:`setActiveCurveColor`.
+ """
+ return self._activeCurveColor
+
+ def setActiveCurveColor(self, color="#000000"):
+ """Set the color to use to display the currently active curve.
+
+ :param str color: Color of the active curve,
+ e.g., 'blue', 'b', '#FF0000' (Default: 'black')
+ """
+ if color is None:
+ color = "black"
+ if color in self.colorDict:
+ color = self.colorDict[color]
+ self._activeCurveColor = color
+
+ def getActiveCurve(self, just_legend=False):
+ """Return the currently active curve.
+
+ It returns None in case of not having an active curve.
+
+ :param bool just_legend: True to get the legend of the curve,
+ False (the default) to get the curve data
+ and info.
+ :return: Active curve's legend or corresponding
+ :class:`.items.Curve`
+ :rtype: str or :class:`.items.Curve` or None
+ """
+ if not self.isActiveCurveHandling():
+ return None
+
+ return self._getActiveItem(kind='curve', just_legend=just_legend)
+
+ def setActiveCurve(self, legend, replot=None):
+ """Make the curve associated to legend the active curve.
+
+ :param legend: The legend associated to the curve
+ or None to have no active curve.
+ :type legend: str or None
+ """
+ if replot is not None:
+ _logger.warning('setActiveCurve deprecated replot parameter')
+
+ if not self.isActiveCurveHandling():
+ return
+
+ return self._setActiveItem(kind='curve', legend=legend)
+
+ def getActiveImage(self, just_legend=False):
+ """Returns the currently active image.
+
+ It returns None in case of not having an active image.
+
+ :param bool just_legend: True to get the legend of the image,
+ False (the default) to get the image data
+ and info.
+ :return: Active image's legend or corresponding image object
+ :rtype: str, :class:`.items.ImageData`, :class:`.items.ImageRgba`
+ or None
+ """
+ return self._getActiveItem(kind='image', just_legend=just_legend)
+
+ def setActiveImage(self, legend, replot=None):
+ """Make the image associated to legend the active image.
+
+ :param str legend: The legend associated to the image
+ or None to have no active image.
+ """
+ if replot is not None:
+ _logger.warning('setActiveImage deprecated replot parameter')
+
+ return self._setActiveItem(kind='image', legend=legend)
+
+ def _getActiveItem(self, kind, just_legend=False):
+ """Return the currently active item of that kind if any
+
+ :param str kind: Type of item: 'curve', 'scatter' or 'image'
+ :param bool just_legend: True to get the legend,
+ False (default) to get the item
+ :return: legend or item or None if no active item
+ """
+ assert kind in ('curve', 'scatter', 'image')
+
+ if self._activeLegend[kind] is None:
+ return None
+
+ if (self._activeLegend[kind], kind) not in self._content:
+ self._activeLegend[kind] = None
+ return None
+
+ if just_legend:
+ return self._activeLegend[kind]
+ else:
+ return self._getItem(kind, self._activeLegend[kind])
+
+ def _setActiveItem(self, kind, legend):
+ """Make the curve associated to legend the active curve.
+
+ :param str kind: Type of item: 'curve' or 'image'
+ :param legend: The legend associated to the curve
+ or None to have no active curve.
+ :type legend: str or None
+ """
+ assert kind in ('curve', 'image', 'scatter')
+
+ xLabel = self._defaultLabels['x']
+ yLabel = self._defaultLabels['y']
+ yRightLabel = self._defaultLabels['yright']
+
+ oldActiveItem = self._getActiveItem(kind=kind)
+
+ # Curve specific: Reset highlight of previous active curve
+ if kind == 'curve' and oldActiveItem is not None:
+ oldActiveItem.setHighlighted(False)
+
+ if legend is None:
+ self._activeLegend[kind] = None
+ else:
+ legend = str(legend)
+ item = self._getItem(kind, legend)
+ if item is None:
+ _logger.warning("This %s does not exist: %s", kind, legend)
+ self._activeLegend[kind] = None
+ else:
+ self._activeLegend[kind] = legend
+
+ # Curve specific: handle highlight
+ if kind == 'curve':
+ item.setHighlightedColor(self.getActiveCurveColor())
+ item.setHighlighted(True)
+
+ if isinstance(item, items.LabelsMixIn):
+ if item.getXLabel() is not None:
+ xLabel = item.getXLabel()
+ if item.getYLabel() is not None:
+ if (isinstance(item, items.YAxisMixIn) and
+ item.getYAxis() == 'right'):
+ yRightLabel = item.getYLabel()
+ else:
+ yLabel = item.getYLabel()
+
+ # Store current labels and update plot
+ self._currentLabels['x'] = xLabel
+ self._currentLabels['y'] = yLabel
+ self._currentLabels['yright'] = yRightLabel
+
+ self._backend.setGraphXLabel(xLabel)
+ self._backend.setGraphYLabel(yLabel, axis='left')
+ self._backend.setGraphYLabel(yRightLabel, axis='right')
+
+ self._setDirtyPlot()
+
+ activeLegend = self._activeLegend[kind]
+ if oldActiveItem is not None or activeLegend is not None:
+ if oldActiveItem is None:
+ oldActiveLegend = None
+ else:
+ oldActiveLegend = oldActiveItem.getLegend()
+ self.notify(
+ 'active' + kind[0].upper() + kind[1:] + 'Changed',
+ updated=oldActiveLegend != activeLegend,
+ previous=oldActiveLegend,
+ legend=activeLegend)
+
+ return activeLegend
+
+ # Getters
+
+ def getAllCurves(self, just_legend=False, withhidden=False):
+ """Returns all curves legend or info and data.
+
+ It returns an empty list in case of not having any curve.
+
+ If just_legend is False, it returns a list of :class:`items.Curve`
+ objects describing the curves.
+ If just_legend is True, it returns a list of curves' legend.
+
+ :param bool just_legend: True to get the legend of the curves,
+ False (the default) to get the curves' data
+ and info.
+ :param bool withhidden: False (default) to skip hidden curves.
+ :return: list of curves' legend or :class:`.items.Curve`
+ :rtype: list of str or list of :class:`.items.Curve`
+ """
+ return self._getItems(kind='curve',
+ just_legend=just_legend,
+ withhidden=withhidden)
+
+ def getCurve(self, legend=None):
+ """Get the object describing a specific curve.
+
+ It returns None in case no matching curve is found.
+
+ :param str legend:
+ The legend identifying the curve.
+ If not provided or None (the default), the active curve is returned
+ or if there is no active curve, the latest updated curve that is
+ not hidden is returned if there are curves in the plot.
+ :return: None or :class:`.items.Curve` object
+ """
+ return self._getItem(kind='curve', legend=legend)
+
+ def getAllImages(self, just_legend=False):
+ """Returns all images legend or objects.
+
+ It returns an empty list in case of not having any image.
+
+ If just_legend is False, it returns a list of :class:`items.ImageBase`
+ objects describing the images.
+ If just_legend is True, it returns a list of legends.
+
+ :param bool just_legend: True to get the legend of the images,
+ False (the default) to get the images'
+ object.
+ :return: list of images' legend or :class:`.items.ImageBase`
+ :rtype: list of str or list of :class:`.items.ImageBase`
+ """
+ return self._getItems(kind='image',
+ just_legend=just_legend,
+ withhidden=True)
+
+ def getImage(self, legend=None):
+ """Get the object describing a specific image.
+
+ It returns None in case no matching image is found.
+
+ :param str legend:
+ The legend identifying the image.
+ If not provided or None (the default), the active image is returned
+ or if there is no active image, the latest updated image
+ is returned if there are images in the plot.
+ :return: None or :class:`.items.ImageBase` object
+ """
+ return self._getItem(kind='image', legend=legend)
+
+ def getScatter(self, legend=None):
+ """Get the object describing a specific scatter.
+
+ It returns None in case no matching scatter is found.
+
+ :param str legend:
+ The legend identifying the scatter.
+ If not provided or None (the default), the active scatter is
+ returned or if there is no active scatter, the latest updated
+ scatter is returned if there are scatters in the plot.
+ :return: None or :class:`.items.Scatter` object
+ """
+ return self._getItem(kind='scatter', legend=legend)
+
+ def getHistogram(self, legend=None):
+ """Get the object describing a specific histogram.
+
+ It returns None in case no matching histogram is found.
+
+ :param str legend:
+ The legend identifying the histogram.
+ If not provided or None (the default), the latest updated scatter
+ is returned if there are histograms in the plot.
+ :return: None or :class:`.items.Histogram` object
+ """
+ return self._getItem(kind='histogram', legend=legend)
+
+ def _getItems(self, kind, just_legend=False, withhidden=False):
+ """Retrieve all items of a kind in the plot
+
+ :param str kind: Type of item: 'curve' or 'image'
+ :param bool just_legend: True to get the legend of the curves,
+ False (the default) to get the curves' data
+ and info.
+ :param bool withhidden: False (default) to skip hidden curves.
+ :return: list of legends or item objects
+ """
+ assert kind in self.ITEM_KINDS
+ output = []
+ for (legend, type_), item in self._content.items():
+ if type_ == kind and (withhidden or item.isVisible()):
+ output.append(legend if just_legend else item)
+ return output
+
+ def _getItem(self, kind, legend=None):
+ """Get an item from the plot: either an image or a curve.
+
+ Returns None if no match found
+
+ :param str kind: Type of item: 'curve' or 'image'
+ :param str legend: Legend of the item or
+ None to get active or last item
+ :return: Object describing the item or None
+ """
+ assert kind in self.ITEM_KINDS
+
+ if legend is not None:
+ return self._content.get((legend, kind), None)
+ else:
+ if kind in ('curve', 'image', 'scatter'):
+ item = self._getActiveItem(kind=kind)
+ if item is not None: # Return active item if available
+ return item
+ # Return last visible item if any
+ allItems = self._getItems(
+ kind=kind, just_legend=False, withhidden=False)
+ return allItems[-1] if allItems else None
+
+ # Limits
+
+ def _notifyLimitsChanged(self):
+ """Send an event when plot area limits are changed."""
+ xRange = self.getGraphXLimits()
+ yRange = self.getGraphYLimits(axis='left')
+ y2Range = self.getGraphYLimits(axis='right')
+ event = PlotEvents.prepareLimitsChangedSignal(
+ id(self.getWidgetHandle()), xRange, yRange, y2Range)
+ self.notify(**event)
+
+ def _checkLimits(self, min_, max_, axis):
+ """Makes sure axis range is not empty
+
+ :param float min_: Min axis value
+ :param float max_: Max axis value
+ :param str axis: 'x', 'y' or 'y2' the axis to deal with
+ :return: (min, max) making sure min < max
+ :rtype: 2-tuple of float
+ """
+ if max_ < min_:
+ _logger.info('%s axis: max < min, inverting limits.', axis)
+ min_, max_ = max_, min_
+ elif max_ == min_:
+ _logger.info('%s axis: max == min, expanding limits.', axis)
+ if min_ == 0.:
+ min_, max_ = -0.1, 0.1
+ elif min_ < 0:
+ min_, max_ = min_ * 1.1, min_ * 0.9
+ else: # xmin > 0
+ min_, max_ = min_ * 0.9, min_ * 1.1
+
+ return min_, max_
+
+ def getGraphXLimits(self):
+ """Get the graph X (bottom) limits.
+
+ :return: Minimum and maximum values of the X axis
+ """
+ return self._backend.getGraphXLimits()
+
+ def setGraphXLimits(self, xmin, xmax, replot=None):
+ """Set the graph X (bottom) limits.
+
+ :param float xmin: minimum bottom axis value
+ :param float xmax: maximum bottom axis value
+ """
+ if replot is not None:
+ _logger.warning('setGraphXLimits deprecated replot parameter')
+
+ xmin, xmax = self._checkLimits(xmin, xmax, axis='x')
+
+ self._backend.setGraphXLimits(xmin, xmax)
+ self._setDirtyPlot()
+
+ self._notifyLimitsChanged()
+
+ def getGraphYLimits(self, axis='left'):
+ """Get the graph Y limits.
+
+ :param str axis: The axis for which to get the limits:
+ Either 'left' or 'right'
+ :return: Minimum and maximum values of the X axis
+ """
+ assert axis in ('left', 'right')
+ return self._backend.getGraphYLimits(axis)
+
+ def setGraphYLimits(self, ymin, ymax, axis='left', replot=None):
+ """Set the graph Y limits.
+
+ :param float ymin: minimum bottom axis value
+ :param float ymax: maximum bottom axis value
+ :param str axis: The axis for which to get the limits:
+ Either 'left' or 'right'
+ """
+ if replot is not None:
+ _logger.warning('setGraphYLimits deprecated replot parameter')
+
+ assert axis in ('left', 'right')
+
+ ymin, ymax = self._checkLimits(ymin, ymax,
+ axis='y' if axis == 'left' else 'y2')
+
+ self._backend.setGraphYLimits(ymin, ymax, axis)
+ self._setDirtyPlot()
+
+ self._notifyLimitsChanged()
+
+ def setLimits(self, xmin, xmax, ymin, ymax, y2min=None, y2max=None):
+ """Set the limits of the X and Y axes at once.
+
+ If y2min or y2max is None, the right Y axis limits are not updated.
+
+ :param float xmin: minimum bottom axis value
+ :param float xmax: maximum bottom axis value
+ :param float ymin: minimum left axis value
+ :param float ymax: maximum left axis value
+ :param float y2min: minimum right axis value or None (the default)
+ :param float y2max: maximum right axis value or None (the default)
+ """
+ # Deal with incorrect values
+ xmin, xmax = self._checkLimits(xmin, xmax, axis='x')
+ ymin, ymax = self._checkLimits(ymin, ymax, axis='y')
+
+ if y2min is None or y2max is None:
+ # if one limit is None, both are ignored
+ y2min, y2max = None, None
+ else:
+ y2min, y2max = self._checkLimits(y2min, y2max, axis='y2')
+
+ self._backend.setLimits(xmin, xmax, ymin, ymax, y2min, y2max)
+ self._setDirtyPlot()
+ self._notifyLimitsChanged()
+
+ # Title and labels
+
+ def getGraphTitle(self):
+ """Return the plot main title as a str."""
+ return self._graphTitle
+
+ def setGraphTitle(self, title=""):
+ """Set the plot main title.
+
+ :param str title: Main title of the plot (default: '')
+ """
+ self._graphTitle = str(title)
+ self._backend.setGraphTitle(title)
+ self._setDirtyPlot()
+
+ def getGraphXLabel(self):
+ """Return the current X axis label as a str."""
+ return self._currentLabels['x']
+
+ def setGraphXLabel(self, label="X"):
+ """Set the plot X axis label.
+
+ The provided label can be temporarily replaced by the X label of the
+ active curve if any.
+
+ :param str label: The X axis label (default: 'X')
+ """
+ self._defaultLabels['x'] = label
+ self._currentLabels['x'] = label
+ self._backend.setGraphXLabel(label)
+ self._setDirtyPlot()
+
+ def getGraphYLabel(self, axis='left'):
+ """Return the current Y axis label as a str.
+
+ :param str axis: The Y axis for which to get the label (left or right)
+ """
+ assert axis in ('left', 'right')
+
+ return self._currentLabels['y' if axis == 'left' else 'yright']
+
+ def setGraphYLabel(self, label="Y", axis='left'):
+ """Set the plot Y axis label.
+
+ The provided label can be temporarily replaced by the Y label of the
+ active curve if any.
+
+ :param str label: The Y axis label (default: 'Y')
+ :param str axis: The Y axis for which to set the label (left or right)
+ """
+ assert axis in ('left', 'right')
+
+ if axis == 'left':
+ self._defaultLabels['y'] = label
+ self._currentLabels['y'] = label
+ else:
+ self._defaultLabels['yright'] = label
+ self._currentLabels['yright'] = label
+
+ self._backend.setGraphYLabel(label, axis=axis)
+ self._setDirtyPlot()
+
+ # Axes
+
+ def setYAxisInverted(self, flag=True):
+ """Set the Y axis orientation.
+
+ :param bool flag: True for Y axis going from top to bottom,
+ False for Y axis going from bottom to top
+ """
+ flag = bool(flag)
+ self._backend.setYAxisInverted(flag)
+ self._setDirtyPlot()
+ self.notify('setYAxisInverted', state=flag)
+
+ def isYAxisInverted(self):
+ """Return True if Y axis goes from top to bottom, False otherwise."""
+ return self._backend.isYAxisInverted()
+
+ def isXAxisLogarithmic(self):
+ """Return True if X axis scale is logarithmic, False if linear."""
+ return self._logX
+
+ def setXAxisLogarithmic(self, flag):
+ """Set the bottom X axis scale (either linear or logarithmic).
+
+ :param bool flag: True to use a logarithmic scale, False for linear.
+ """
+ if bool(flag) == self._logX:
+ return
+ self._logX = bool(flag)
+
+ self._backend.setXAxisLogarithmic(self._logX)
+
+ # TODO hackish way of forcing update of curves and images
+ for curve in self.getAllCurves():
+ curve._updated()
+ for image in self.getAllImages():
+ image._updated()
+ self._invalidateDataRange()
+
+ self.resetZoom()
+ self.notify('setXAxisLogarithmic', state=self._logX)
+
+ def isYAxisLogarithmic(self):
+ """Return True if Y axis scale is logarithmic, False if linear."""
+ return self._logY
+
+ def setYAxisLogarithmic(self, flag):
+ """Set the Y axes scale (either linear or logarithmic).
+
+ :param bool flag: True to use a logarithmic scale, False for linear.
+ """
+ if bool(flag) == self._logY:
+ return
+ self._logY = bool(flag)
+
+ self._backend.setYAxisLogarithmic(self._logY)
+
+ # TODO hackish way of forcing update of curves and images
+ for curve in self.getAllCurves():
+ curve._updated()
+ for image in self.getAllImages():
+ image._updated()
+ self._invalidateDataRange()
+
+ self.resetZoom()
+ self.notify('setYAxisLogarithmic', state=self._logY)
+
+ def isXAxisAutoScale(self):
+ """Return True if X axis is automatically adjusting its limits."""
+ return self._xAutoScale
+
+ def setXAxisAutoScale(self, flag=True):
+ """Set the X axis limits adjusting behavior of :meth:`resetZoom`.
+
+ :param bool flag: True to resize limits automatically,
+ False to disable it.
+ """
+ self._xAutoScale = bool(flag)
+ self.notify('setXAxisAutoScale', state=self._xAutoScale)
+
+ def isYAxisAutoScale(self):
+ """Return True if Y axes are automatically adjusting its limits."""
+ return self._yAutoScale
+
+ def setYAxisAutoScale(self, flag=True):
+ """Set the Y axis limits adjusting behavior of :meth:`resetZoom`.
+
+ :param bool flag: True to resize limits automatically,
+ False to disable it.
+ """
+ self._yAutoScale = bool(flag)
+ self.notify('setYAxisAutoScale', state=self._yAutoScale)
+
+ def isKeepDataAspectRatio(self):
+ """Returns whether the plot is keeping data aspect ratio or not."""
+ return self._backend.isKeepDataAspectRatio()
+
+ def setKeepDataAspectRatio(self, flag=True):
+ """Set whether the plot keeps data aspect ratio or not.
+
+ :param bool flag: True to respect data aspect ratio
+ """
+ flag = bool(flag)
+ self._backend.setKeepDataAspectRatio(flag=flag)
+ self._setDirtyPlot()
+ self.resetZoom()
+ self.notify('setKeepDataAspectRatio', state=flag)
+
+ def getGraphGrid(self):
+ """Return the current grid mode, either None, 'major' or 'both'.
+
+ See :meth:`setGraphGrid`.
+ """
+ return self._grid
+
+ def setGraphGrid(self, which=True):
+ """Set the type of grid to display.
+
+ :param which: None or False to disable the grid,
+ 'major' or True for grid on major ticks (the default),
+ 'both' for grid on both major and minor ticks.
+ :type which: str of bool
+ """
+ assert which in (None, True, False, 'both', 'major')
+ if not which:
+ which = None
+ elif which is True:
+ which = 'major'
+ self._grid = which
+ self._backend.setGraphGrid(which)
+ self._setDirtyPlot()
+ self.notify('setGraphGrid', which=str(which))
+
+ # Defaults
+
+ def isDefaultPlotPoints(self):
+ """Return True if default Curve symbol is 'o', False for no symbol."""
+ return self._defaultPlotPoints == 'o'
+
+ def setDefaultPlotPoints(self, flag):
+ """Set the default symbol of all curves.
+
+ When called, this reset the symbol of all existing curves.
+
+ :param bool flag: True to use 'o' as the default curve symbol,
+ False to use no symbol.
+ """
+ self._defaultPlotPoints = 'o' if flag else ''
+
+ # Reset symbol of all curves
+ curves = self.getAllCurves(just_legend=False, withhidden=True)
+
+ if curves:
+ for curve in curves:
+ curve.setSymbol(self._defaultPlotPoints)
+
+ def isDefaultPlotLines(self):
+ """Return True for line as default line style, False for no line."""
+ return self._plotLines
+
+ def setDefaultPlotLines(self, flag):
+ """Toggle the use of lines as the default curve line style.
+
+ :param bool flag: True to use a line as the default line style,
+ False to use no line as the default line style.
+ """
+ self._plotLines = bool(flag)
+
+ linestyle = '-' if self._plotLines else ' '
+
+ # Reset linestyle of all curves
+ curves = self.getAllCurves(withhidden=True)
+
+ if curves:
+ for curve in curves:
+ curve.setLineStyle(linestyle)
+
+ def getDefaultColormap(self):
+ """Return the default colormap used by :meth:`addImage` as a dict.
+
+ See :mod:`Plot` for the documentation of the colormap dict.
+ """
+ return self._defaultColormap.copy()
+
+ def setDefaultColormap(self, colormap=None):
+ """Set the default colormap used by :meth:`addImage`.
+
+ Setting the default colormap do not change any currently displayed
+ image.
+ It only affects future calls to :meth:`addImage` without the colormap
+ parameter.
+
+ :param dict colormap: The description of the default colormap, or
+ None to set the colormap to a linear autoscale
+ gray colormap.
+ See :mod:`Plot` for the documentation
+ of the colormap dict.
+ """
+ if colormap is None:
+ colormap = {'name': 'gray', 'normalization': 'linear',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0}
+ self._defaultColormap = colormap.copy()
+
+ def getSupportedColormaps(self):
+ """Get the supported colormap names as a tuple of str.
+
+ The list should at least contain and start by:
+ ('gray', 'reversed gray', 'temperature', 'red', 'green', 'blue')
+ """
+ default = ('gray', 'reversed gray',
+ 'temperature',
+ 'red', 'green', 'blue')
+ if matplotlib_cm is None:
+ return default
+ else:
+ maps = [m for m in matplotlib_cm.datad]
+ maps.sort()
+ return default + tuple(maps)
+
+ def _getColorAndStyle(self):
+ color = self.colorList[self._colorIndex]
+ style = self._styleList[self._styleIndex]
+
+ # Loop over color and then styles
+ self._colorIndex += 1
+ if self._colorIndex >= len(self.colorList):
+ self._colorIndex = 0
+ self._styleIndex = (self._styleIndex + 1) % len(self._styleList)
+
+ # If color is the one of active curve, take the next one
+ if color == self.getActiveCurveColor():
+ color, style = self._getColorAndStyle()
+
+ if not self._plotLines:
+ style = ' '
+
+ return color, style
+
+ # Misc.
+
+ def getWidgetHandle(self):
+ """Return the widget the plot is displayed in.
+
+ This widget is owned by the backend.
+ """
+ return self._backend.getWidgetHandle()
+
+ def notify(self, event, **kwargs):
+ """Send an event to the listeners.
+
+ Event are passed to the registered callback as a dict with an 'event'
+ key for backward compatibility with PyMca.
+
+ :param str event: The type of event
+ :param kwargs: The information of the event.
+ """
+ eventDict = kwargs.copy()
+ eventDict['event'] = event
+ self._callback(eventDict)
+
+ def setCallback(self, callbackFunction=None):
+ """Attach a listener to the backend.
+
+ Limitation: Only one listener at a time.
+
+ :param callbackFunction: function accepting a dictionary as input
+ to handle the graph events
+ If None (default), use a default listener.
+ """
+ # TODO allow multiple listeners, keep a weakref on it
+ # allow register listener by event type
+ if callbackFunction is None:
+ callbackFunction = self.graphCallback
+ self._callback = callbackFunction
+
+ def graphCallback(self, ddict=None):
+ """This callback is going to receive all the events from the plot.
+
+ Those events will consist on a dictionary and among the dictionary
+ keys the key 'event' is mandatory to describe the type of event.
+ This default implementation only handles setting the active curve.
+ """
+
+ if ddict is None:
+ ddict = {}
+ _logger.debug("Received dict keys = %s", str(ddict.keys()))
+ _logger.debug(str(ddict))
+ if ddict['event'] in ["legendClicked", "curveClicked"]:
+ if ddict['button'] == "left":
+ self.setActiveCurve(ddict['label'])
+
+ def saveGraph(self, filename, fileFormat=None, dpi=None, **kw):
+ """Save a snapshot of the plot.
+
+ Supported file formats: "png", "svg", "pdf", "ps", "eps",
+ "tif", "tiff", "jpeg", "jpg".
+
+ :param filename: Destination
+ :type filename: str, StringIO or BytesIO
+ :param str fileFormat: String specifying the format
+ :return: False if cannot save the plot, True otherwise
+ """
+ if kw:
+ _logger.warning('Extra parameters ignored: %s', str(kw))
+
+ if fileFormat is None:
+ if not hasattr(filename, 'lower'):
+ _logger.warning(
+ 'saveGraph cancelled, cannot define file format.')
+ return False
+ else:
+ fileFormat = (filename.split(".")[-1]).lower()
+
+ supportedFormats = ("png", "svg", "pdf", "ps", "eps",
+ "tif", "tiff", "jpeg", "jpg")
+
+ if fileFormat not in supportedFormats:
+ _logger.warning('Unsupported format %s', fileFormat)
+ return False
+ else:
+ self._backend.saveGraph(filename,
+ fileFormat=fileFormat,
+ dpi=dpi)
+ return True
+
+ def getDataMargins(self):
+ """Get the default data margin ratios, see :meth:`setDataMargins`.
+
+ :return: The margin ratios for each side (xMin, xMax, yMin, yMax).
+ :rtype: A 4-tuple of floats.
+ """
+ return self._defaultDataMargins
+
+ def setDataMargins(self, xMinMargin=0., xMaxMargin=0.,
+ yMinMargin=0., yMaxMargin=0.):
+ """Set the default data margins to use in :meth:`resetZoom`.
+
+ Set the default ratios of margins (as floats) to add around the data
+ inside the plot area for each side.
+ """
+ self._defaultDataMargins = (xMinMargin, xMaxMargin,
+ yMinMargin, yMaxMargin)
+
+ def getAutoReplot(self):
+ """Return True if replot is automatically handled, False otherwise.
+
+ See :meth`setAutoReplot`.
+ """
+ return self._autoreplot
+
+ def setAutoReplot(self, autoreplot=True):
+ """Set automatic replot mode.
+
+ When enabled, the plot is redrawn automatically when changed.
+ When disabled, the plot is not redrawn when its content change.
+ Instead, it :meth:`replot` must be called.
+
+ :param bool autoreplot: True to enable it (default),
+ False to disable it.
+ """
+ self._autoreplot = bool(autoreplot)
+
+ # If the plot is dirty before enabling autoreplot,
+ # then _backend.postRedisplay will never be called from _setDirtyPlot
+ if self._autoreplot and self._getDirtyPlot():
+ self._backend.postRedisplay()
+
+ def replot(self):
+ """Redraw the plot immediately."""
+ for item in self._contentToUpdate:
+ item._update(self._backend)
+ self._contentToUpdate.clear()
+ self._backend.replot()
+ self._dirty = False # reset dirty flag
+
+ def resetZoom(self, dataMargins=None):
+ """Reset the plot limits to the bounds of the data and redraw the plot.
+
+ It automatically scale limits of axes that are in autoscale mode
+ (See :meth:`setXAxisAutoScale`, :meth:`setYAxisAutoScale`).
+ It keeps current limits on axes that are not in autoscale mode.
+
+ Extra margins can be added around the data inside the plot area.
+ Margins are given as one ratio of the data range per limit of the
+ data (xMin, xMax, yMin and yMax limits).
+ For log scale, extra margins are applied in log10 of the data.
+
+ :param dataMargins: Ratios of margins to add around the data inside
+ the plot area for each side (Default: no margins).
+ :type dataMargins: A 4-tuple of float as (xMin, xMax, yMin, yMax).
+ """
+ if dataMargins is None:
+ dataMargins = self._defaultDataMargins
+
+ xLimits = self.getGraphXLimits()
+ yLimits = self.getGraphYLimits(axis='left')
+ y2Limits = self.getGraphYLimits(axis='right')
+
+ xAuto = self.isXAxisAutoScale()
+ yAuto = self.isYAxisAutoScale()
+
+ if not xAuto and not yAuto:
+ _logger.debug("Nothing to autoscale")
+ else: # Some axes to autoscale
+
+ # Get data range
+ ranges = self.getDataRange()
+ xmin, xmax = (1., 100.) if ranges.x is None else ranges.x
+ ymin, ymax = (1., 100.) if ranges.y is None else ranges.y
+ if ranges.yright is None:
+ ymin2, ymax2 = None, None
+ else:
+ ymin2, ymax2 = ranges.yright
+
+ # Add margins around data inside the plot area
+ newLimits = list(_utils.addMarginsToLimits(
+ dataMargins,
+ self.isXAxisLogarithmic(),
+ self.isYAxisLogarithmic(),
+ xmin, xmax, ymin, ymax, ymin2, ymax2))
+
+ if self.isKeepDataAspectRatio():
+ # Use limits with margins to keep ratio
+ xmin, xmax, ymin, ymax = newLimits[:4]
+
+ # Compute bbox wth figure aspect ratio
+ plotWidth, plotHeight = self.getPlotBoundsInPixels()[2:]
+ plotRatio = plotHeight / plotWidth
+
+ if plotRatio > 0.:
+ dataRatio = (ymax - ymin) / (xmax - xmin)
+ if dataRatio < plotRatio:
+ # Increase y range
+ ycenter = 0.5 * (ymax + ymin)
+ yrange = (xmax - xmin) * plotRatio
+ newLimits[2] = ycenter - 0.5 * yrange
+ newLimits[3] = ycenter + 0.5 * yrange
+
+ elif dataRatio > plotRatio:
+ # Increase x range
+ xcenter = 0.5 * (xmax + xmin)
+ xrange_ = (ymax - ymin) / plotRatio
+ newLimits[0] = xcenter - 0.5 * xrange_
+ newLimits[1] = xcenter + 0.5 * xrange_
+
+ self.setLimits(*newLimits)
+
+ if not xAuto and yAuto:
+ self.setGraphXLimits(*xLimits)
+ elif xAuto and not yAuto:
+ if y2Limits is not None:
+ self.setGraphYLimits(
+ y2Limits[0], y2Limits[1], axis='right')
+ if yLimits is not None:
+ self.setGraphYLimits(yLimits[0], yLimits[1], axis='left')
+
+ self._setDirtyPlot()
+
+ if (xLimits != self.getGraphXLimits() or
+ yLimits != self.getGraphYLimits(axis='left') or
+ y2Limits != self.getGraphYLimits(axis='right')):
+ self._notifyLimitsChanged()
+
+ # Coord conversion
+
+ def dataToPixel(self, x=None, y=None, axis="left", check=True):
+ """Convert a position in data coordinates to a position in pixels.
+
+ :param float x: The X coordinate in data space. If None (default)
+ the middle position of the displayed data is used.
+ :param float y: The Y coordinate in data space. If None (default)
+ the middle position of the displayed data is used.
+ :param str axis: The Y axis to use for the conversion
+ ('left' or 'right').
+ :param bool check: True to return None if outside displayed area,
+ False to convert to pixels anyway
+ :returns: The corresponding position in pixels or
+ None if the data position is not in the displayed area and
+ check is True.
+ :rtype: A tuple of 2 floats: (xPixel, yPixel) or None.
+ """
+ assert axis in ("left", "right")
+
+ xmin, xmax = self.getGraphXLimits()
+ ymin, ymax = self.getGraphYLimits(axis=axis)
+
+ if x is None:
+ x = 0.5 * (xmax + xmin)
+ if y is None:
+ y = 0.5 * (ymax + ymin)
+
+ if check:
+ if x > xmax or x < xmin:
+ return None
+
+ if y > ymax or y < ymin:
+ return None
+
+ return self._backend.dataToPixel(x, y, axis=axis)
+
+ def pixelToData(self, x, y, axis="left", check=False):
+ """Convert a position in pixels to a position in data coordinates.
+
+ :param float x: The X coordinate in pixels. If None (default)
+ the center of the widget is used.
+ :param float y: The Y coordinate in pixels. If None (default)
+ the center of the widget is used.
+ :param str axis: The Y axis to use for the conversion
+ ('left' or 'right').
+ :param bool check: Toggle checking if pixel is in plot area.
+ If False, this method never returns None.
+ :returns: The corresponding position in data space or
+ None if the pixel position is not in the plot area.
+ :rtype: A tuple of 2 floats: (xData, yData) or None.
+ """
+ assert axis in ("left", "right")
+ return self._backend.pixelToData(x, y, axis=axis, check=check)
+
+ def getPlotBoundsInPixels(self):
+ """Plot area bounds in widget coordinates in pixels.
+
+ :return: bounds as a 4-tuple of int: (left, top, width, height)
+ """
+ return self._backend.getPlotBoundsInPixels()
+
+ # Interaction support
+
+ def setGraphCursorShape(self, cursor=None):
+ """Set the cursor shape.
+
+ :param str cursor: Name of the cursor shape
+ """
+ self._backend.setGraphCursorShape(cursor)
+
+ def _pickMarker(self, x, y, test=None):
+ """Pick a marker at the given position.
+
+ To use for interaction implementation.
+
+ :param float x: X position in pixels.
+ :param float y: Y position in pixels.
+ :param test: A callable to call for each picked marker to filter
+ picked markers. If None (default), do not filter markers.
+ """
+ if test is None:
+ def test(mark):
+ return True
+
+ markers = self._backend.pickItems(x, y)
+ legends = [m['legend'] for m in markers if m['kind'] == 'marker']
+
+ for legend in reversed(legends):
+ marker = self._getMarker(legend)
+ if marker is not None and test(marker):
+ return marker
+ return None
+
+ def _getAllMarkers(self, just_legend=False):
+ """Returns all markers' legend or objects
+
+ :param bool just_legend: True to get the legend of the markers,
+ False (the default) to get marker objects.
+ :return: list of legend of list of marker objects
+ :rtype: list of str or list of marker objects
+ """
+ return self._getItems(
+ kind='marker', just_legend=just_legend, withhidden=True)
+
+ def _getMarker(self, legend=None):
+ """Get the object describing a specific marker.
+
+ It returns None in case no matching marker is found
+
+ :param str legend: The legend of the marker to retrieve
+ :rtype: None of marker object
+ """
+ return self._getItem(kind='marker', legend=legend)
+
+ def _pickImageOrCurve(self, x, y, test=None):
+ """Pick an image or a curve at the given position.
+
+ To use for interaction implementation.
+
+ :param float x: X position in pixelsparam float y: Y position in pixels
+ :param test: A callable to call for each picked item to filter
+ picked items. If None (default), do not filter items.
+ """
+ if test is None:
+ def test(i):
+ return True
+
+ allItems = self._backend.pickItems(x, y)
+ allItems = [item for item in allItems
+ if item['kind'] in ['curve', 'image']]
+
+ for item in reversed(allItems):
+ kind, legend = item['kind'], item['legend']
+ if kind == 'curve':
+ curve = self.getCurve(legend)
+ if curve is not None and test(curve):
+ return kind, curve, item['xdata'], item['ydata']
+
+ elif kind == 'image':
+ image = self.getImage(legend)
+ if image is not None and test(image):
+ return kind, image, None
+
+ else:
+ _logger.warning('Unsupported kind: %s', kind)
+
+ return None
+
+ # User event handling #
+
+ def _isPositionInPlotArea(self, x, y):
+ """Project position in pixel to the closest point in the plot area
+
+ :param float x: X coordinate in widget coordinate (in pixel)
+ :param float y: Y coordinate in widget coordinate (in pixel)
+ :return: (x, y) in widget coord (in pixel) in the plot area
+ """
+ left, top, width, height = self.getPlotBoundsInPixels()
+ xPlot = numpy.clip(x, left, left + width)
+ yPlot = numpy.clip(y, top, top + height)
+ return xPlot, yPlot
+
+ def onMousePress(self, xPixel, yPixel, btn):
+ """Handle mouse press event.
+
+ :param float xPixel: X mouse position in pixels
+ :param float yPixel: Y mouse position in pixels
+ :param str btn: Mouse button in 'left', 'middle', 'right'
+ """
+ if self._isPositionInPlotArea(xPixel, yPixel) == (xPixel, yPixel):
+ self._pressedButtons.append(btn)
+ self._eventHandler.handleEvent('press', xPixel, yPixel, btn)
+
+ def onMouseMove(self, xPixel, yPixel):
+ """Handle mouse move event.
+
+ :param float xPixel: X mouse position in pixels
+ :param float yPixel: Y mouse position in pixels
+ """
+ inXPixel, inYPixel = self._isPositionInPlotArea(xPixel, yPixel)
+ isCursorInPlot = inXPixel == xPixel and inYPixel == yPixel
+
+ if self._cursorInPlot != isCursorInPlot:
+ self._cursorInPlot = isCursorInPlot
+ self._eventHandler.handleEvent(
+ 'enter' if self._cursorInPlot else 'leave')
+
+ if isCursorInPlot:
+ # Signal mouse move event
+ dataPos = self.pixelToData(inXPixel, inYPixel)
+ assert dataPos is not None
+
+ btn = self._pressedButtons[-1] if self._pressedButtons else None
+ event = PlotEvents.prepareMouseSignal(
+ 'mouseMoved', btn, dataPos[0], dataPos[1], xPixel, yPixel)
+ self.notify(**event)
+
+ # Either button was pressed in the plot or cursor is in the plot
+ if isCursorInPlot or self._pressedButtons:
+ self._eventHandler.handleEvent('move', inXPixel, inYPixel)
+
+ def onMouseRelease(self, xPixel, yPixel, btn):
+ """Handle mouse release event.
+
+ :param float xPixel: X mouse position in pixels
+ :param float yPixel: Y mouse position in pixels
+ :param str btn: Mouse button in 'left', 'middle', 'right'
+ """
+ try:
+ self._pressedButtons.remove(btn)
+ except ValueError:
+ pass
+ else:
+ xPixel, yPixel = self._isPositionInPlotArea(xPixel, yPixel)
+ self._eventHandler.handleEvent('release', xPixel, yPixel, btn)
+
+ def onMouseWheel(self, xPixel, yPixel, angleInDegrees):
+ """Handle mouse wheel event.
+
+ :param float xPixel: X mouse position in pixels
+ :param float yPixel: Y mouse position in pixels
+ :param float angleInDegrees: Angle corresponding to wheel motion.
+ Positive for movement away from the user,
+ negative for movement toward the user.
+ """
+ if self._isPositionInPlotArea(xPixel, yPixel) == (xPixel, yPixel):
+ self._eventHandler.handleEvent(
+ 'wheel', xPixel, yPixel, angleInDegrees)
+
+ def onMouseLeaveWidget(self):
+ """Handle mouse leave widget event."""
+ if self._cursorInPlot:
+ self._cursorInPlot = False
+ self._eventHandler.handleEvent('leave')
+
+ # Interaction modes #
+
+ def getInteractiveMode(self):
+ """Returns the current interactive mode as a dict.
+
+ The returned dict contains at least the key 'mode'.
+ Mode can be: 'draw', 'pan', 'select', 'zoom'.
+ It can also contains extra keys (e.g., 'color') specific to a mode
+ as provided to :meth:`setInteractiveMode`.
+ """
+ return self._eventHandler.getInteractiveMode()
+
+ def setInteractiveMode(self, mode, color='black',
+ shape='polygon', label=None,
+ zoomOnWheel=True, source=None, width=None):
+ """Switch the interactive mode.
+
+ :param str mode: The name of the interactive mode.
+ In 'draw', 'pan', 'select', 'zoom'.
+ :param color: Only for 'draw' and 'zoom' modes.
+ Color to use for drawing selection area. Default black.
+ :type color: Color description: The name as a str or
+ a tuple of 4 floats.
+ :param str shape: Only for 'draw' mode. The kind of shape to draw.
+ In 'polygon', 'rectangle', 'line', 'vline', 'hline',
+ 'freeline'.
+ Default is 'polygon'.
+ :param str label: Only for 'draw' mode, sent in drawing events.
+ :param bool zoomOnWheel: Toggle zoom on wheel support
+ :param source: A user-defined object (typically the caller object)
+ that will be send in the interactiveModeChanged event,
+ to identify which object required a mode change.
+ Default: None
+ :param float width: Width of the pencil. Only for draw pencil mode.
+ """
+ self._eventHandler.setInteractiveMode(mode, color, shape, label, width)
+ self._eventHandler.zoomOnWheel = zoomOnWheel
+
+ self.notify(
+ 'interactiveModeChanged', source=source)
+
+ # Deprecated #
+
+ def isDrawModeEnabled(self):
+ """Deprecated, use :meth:`getInteractiveMode` instead.
+
+ Return True if the current interactive state is drawing."""
+ _logger.warning(
+ 'isDrawModeEnabled deprecated, use getInteractiveMode instead')
+ return self.getInteractiveMode()['mode'] == 'draw'
+
+ def setDrawModeEnabled(self, flag=True, shape='polygon', label=None,
+ color=None, **kwargs):
+ """Deprecated, use :meth:`setInteractiveMode` instead.
+
+ Set the drawing mode if flag is True and its parameters.
+
+ If flag is False, only item selection is enabled.
+
+ Warning: Zoom and drawing are not compatible and cannot be enabled
+ simultaneously.
+
+ :param bool flag: True to enable drawing and disable zoom and select.
+ :param str shape: Type of item to be drawn in:
+ hline, vline, rectangle, polygon (default)
+ :param str label: Associated text for identifying draw signals
+ :param color: The color to use to draw the selection area
+ :type color: string ("#RRGGBB") or 4 column unsigned byte array or
+ one of the predefined color names defined in Colors.py
+ """
+ _logger.warning(
+ 'setDrawModeEnabled deprecated, use setInteractiveMode instead')
+
+ if kwargs:
+ _logger.warning('setDrawModeEnabled ignores additional parameters')
+
+ if color is None:
+ color = 'black'
+
+ if flag:
+ self.setInteractiveMode('draw', shape=shape,
+ label=label, color=color)
+ elif self.getInteractiveMode()['mode'] == 'draw':
+ self.setInteractiveMode('select')
+
+ def getDrawMode(self):
+ """Deprecated, use :meth:`getInteractiveMode` instead.
+
+ Return the draw mode parameters as a dict of None.
+
+ It returns None if the interactive mode is not a drawing mode,
+ otherwise, it returns a dict containing the drawing mode parameters
+ as provided to :meth:`setDrawModeEnabled`.
+ """
+ _logger.warning(
+ 'getDrawMode deprecated, use getInteractiveMode instead')
+ mode = self.getInteractiveMode()
+ return mode if mode['mode'] == 'draw' else None
+
+ def isZoomModeEnabled(self):
+ """Deprecated, use :meth:`getInteractiveMode` instead.
+
+ Return True if the current interactive state is zooming."""
+ _logger.warning(
+ 'isZoomModeEnabled deprecated, use getInteractiveMode instead')
+ return self.getInteractiveMode()['mode'] == 'zoom'
+
+ def setZoomModeEnabled(self, flag=True, color=None):
+ """Deprecated, use :meth:`setInteractiveMode` instead.
+
+ Set the zoom mode if flag is True, else item selection is enabled.
+
+ Warning: Zoom and drawing are not compatible and cannot be enabled
+ simultaneously
+
+ :param bool flag: If True, enable zoom and select mode.
+ :param color: The color to use to draw the selection area.
+ (Default: 'black')
+ :param color: The color to use to draw the selection area
+ :type color: string ("#RRGGBB") or 4 column unsigned byte array or
+ one of the predefined color names defined in Colors.py
+ """
+ _logger.warning(
+ 'setZoomModeEnabled deprecated, use setInteractiveMode instead')
+ if color is None:
+ color = 'black'
+
+ if flag:
+ self.setInteractiveMode('zoom', color=color)
+ elif self.getInteractiveMode()['mode'] == 'zoom':
+ self.setInteractiveMode('select')
+
+ def insertMarker(self, *args, **kwargs):
+ """Deprecated, use :meth:`addMarker` instead."""
+ _logger.warning(
+ 'insertMarker deprecated, use addMarker instead.')
+ return self.addMarker(*args, **kwargs)
+
+ def insertXMarker(self, *args, **kwargs):
+ """Deprecated, use :meth:`addXMarker` instead."""
+ _logger.warning(
+ 'insertXMarker deprecated, use addXMarker instead.')
+ return self.addXMarker(*args, **kwargs)
+
+ def insertYMarker(self, *args, **kwargs):
+ """Deprecated, use :meth:`addYMarker` instead."""
+ _logger.warning(
+ 'insertYMarker deprecated, use addYMarker instead.')
+ return self.addYMarker(*args, **kwargs)
+
+ def isActiveCurveHandlingEnabled(self):
+ """Deprecated, use :meth:`isActiveCurveHandling` instead."""
+ _logger.warning(
+ 'isActiveCurveHandlingEnabled deprecated, '
+ 'use isActiveCurveHandling instead.')
+ return self.isActiveCurveHandling()
+
+ def enableActiveCurveHandling(self, *args, **kwargs):
+ """Deprecated, use :meth:`setActiveCurveHandling` instead."""
+ _logger.warning(
+ 'enableActiveCurveHandling deprecated, '
+ 'use setActiveCurveHandling instead.')
+ return self.setActiveCurveHandling(*args, **kwargs)
+
+ def invertYAxis(self, *args, **kwargs):
+ """Deprecated, use :meth:`setYAxisInverted` instead."""
+ _logger.warning('invertYAxis deprecated, '
+ 'use setYAxisInverted instead.')
+ return self.setYAxisInverted(*args, **kwargs)
+
+ def showGrid(self, flag=True):
+ """Deprecated, use :meth:`setGraphGrid` instead."""
+ _logger.warning("showGrid deprecated, use setGraphGrid instead")
+ if flag in (0, False):
+ flag = None
+ elif flag in (1, True):
+ flag = 'major'
+ else:
+ flag = 'both'
+ return self.setGraphGrid(flag)
+
+ def keepDataAspectRatio(self, *args, **kwargs):
+ """Deprecated, use :meth:`setKeepDataAspectRatio`."""
+ _logger.warning('keepDataAspectRatio deprecated,'
+ 'use setKeepDataAspectRatio instead')
+ return self.setKeepDataAspectRatio(*args, **kwargs)
diff --git a/silx/gui/plot/PlotActions.py b/silx/gui/plot/PlotActions.py
new file mode 100644
index 0000000..aad27d2
--- /dev/null
+++ b/silx/gui/plot/PlotActions.py
@@ -0,0 +1,1386 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a set of QAction to use with :class:`.PlotWidget`.
+
+The following QAction are available:
+
+- :class:`ColormapAction`
+- :class:`CopyAction`
+- :class:`CrosshairAction`
+- :class:`CurveStyleAction`
+- :class:`FitAction`
+- :class:`GridAction`
+- :class:`KeepAspectRatioAction`
+- :class:`PanWithArrowKeysAction`
+- :class:`PrintAction`
+- :class:`ResetZoomAction`
+- :class:`SaveAction`
+- :class:`XAxisLogarithmicAction`
+- :class:`XAxisAutoScaleAction`
+- :class:`YAxisInvertedAction`
+- :class:`YAxisLogarithmicAction`
+- :class:`YAxisAutoScaleAction`
+- :class:`ZoomInAction`
+- :class:`ZoomOutAction`
+"""
+
+from __future__ import division
+
+
+__authors__ = ["V.A. Sole", "T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "20/04/2017"
+
+
+from collections import OrderedDict
+import logging
+import sys
+import traceback
+import weakref
+
+if sys.version_info[0] == 3:
+ from io import BytesIO
+else:
+ import cStringIO as _StringIO
+ BytesIO = _StringIO.StringIO
+
+import numpy
+
+from .. import icons
+from .. import qt
+from .._utils import convertArrayToQImage
+from . import Colors, items
+from .ColormapDialog import ColormapDialog
+from ._utils import applyZoomToPlot as _applyZoomToPlot
+from silx.third_party.EdfFile import EdfFile
+from silx.third_party.TiffIO import TiffIO
+from silx.math.histogram import Histogramnd
+from silx.math.medianfilter import medfilt2d
+from silx.gui.widgets.MedianFilterDialog import MedianFilterDialog
+
+from silx.io.utils import save1D, savespec
+
+
+_logger = logging.getLogger(__name__)
+
+
+class PlotAction(qt.QAction):
+ """Base class for QAction that operates on a PlotWidget.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate.
+ :param icon: QIcon or str name of icon to use
+ :param str text: The name of this action to be used for menu label
+ :param str tooltip: The text of the tooltip
+ :param triggered: The callback to connect to the action's triggered
+ signal or None for no callback.
+ :param bool checkable: True for checkable action, False otherwise (default)
+ :param parent: See :class:`QAction`.
+ """
+
+ def __init__(self, plot, icon, text, tooltip=None,
+ triggered=None, checkable=False, parent=None):
+ assert plot is not None
+ self._plotRef = weakref.ref(plot)
+
+ if not isinstance(icon, qt.QIcon):
+ # Try with icon as a string and load corresponding icon
+ icon = icons.getQIcon(icon)
+
+ super(PlotAction, self).__init__(icon, text, parent)
+
+ if tooltip is not None:
+ self.setToolTip(tooltip)
+
+ self.setCheckable(checkable)
+
+ if triggered is not None:
+ self.triggered[bool].connect(triggered)
+
+ @property
+ def plot(self):
+ """The :class:`.PlotWidget` this action group is controlling."""
+ return self._plotRef()
+
+
+class ResetZoomAction(PlotAction):
+ """QAction controlling reset zoom on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ super(ResetZoomAction, self).__init__(
+ plot, icon='zoom-original', text='Reset Zoom',
+ tooltip='Auto-scale the graph',
+ triggered=self._actionTriggered,
+ checkable=False, parent=parent)
+ self._autoscaleChanged(True)
+ plot.sigSetXAxisAutoScale.connect(self._autoscaleChanged)
+ plot.sigSetYAxisAutoScale.connect(self._autoscaleChanged)
+
+ def _autoscaleChanged(self, enabled):
+ self.setEnabled(
+ self.plot.isXAxisAutoScale() or self.plot.isYAxisAutoScale())
+
+ if self.plot.isXAxisAutoScale() and self.plot.isYAxisAutoScale():
+ tooltip = 'Auto-scale the graph'
+ elif self.plot.isXAxisAutoScale(): # And not Y axis
+ tooltip = 'Auto-scale the x-axis of the graph only'
+ elif self.plot.isYAxisAutoScale(): # And not X axis
+ tooltip = 'Auto-scale the y-axis of the graph only'
+ else: # no axis in autoscale
+ tooltip = 'Auto-scale the graph'
+ self.setToolTip(tooltip)
+
+ def _actionTriggered(self, checked=False):
+ self.plot.resetZoom()
+
+
+class ZoomInAction(PlotAction):
+ """QAction performing a zoom-in on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ super(ZoomInAction, self).__init__(
+ plot, icon='zoom-in', text='Zoom In',
+ tooltip='Zoom in the plot',
+ triggered=self._actionTriggered,
+ checkable=False, parent=parent)
+ self.setShortcut(qt.QKeySequence.ZoomIn)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+
+ def _actionTriggered(self, checked=False):
+ _applyZoomToPlot(self.plot, 1.1)
+
+
+class ZoomOutAction(PlotAction):
+ """QAction performing a zoom-out on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ super(ZoomOutAction, self).__init__(
+ plot, icon='zoom-out', text='Zoom Out',
+ tooltip='Zoom out the plot',
+ triggered=self._actionTriggered,
+ checkable=False, parent=parent)
+ self.setShortcut(qt.QKeySequence.ZoomOut)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+
+ def _actionTriggered(self, checked=False):
+ _applyZoomToPlot(self.plot, 1. / 1.1)
+
+
+class XAxisAutoScaleAction(PlotAction):
+ """QAction controlling X axis autoscale on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ super(XAxisAutoScaleAction, self).__init__(
+ plot, icon='plot-xauto', text='X Autoscale',
+ tooltip='Enable x-axis auto-scale when checked.\n'
+ 'If unchecked, x-axis does not change when reseting zoom.',
+ triggered=self._actionTriggered,
+ checkable=True, parent=parent)
+ self.setChecked(plot.isXAxisAutoScale())
+ plot.sigSetXAxisAutoScale.connect(self.setChecked)
+
+ def _actionTriggered(self, checked=False):
+ self.plot.setXAxisAutoScale(checked)
+ if checked:
+ self.plot.resetZoom()
+
+
+class YAxisAutoScaleAction(PlotAction):
+ """QAction controlling Y axis autoscale on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ super(YAxisAutoScaleAction, self).__init__(
+ plot, icon='plot-yauto', text='Y Autoscale',
+ tooltip='Enable y-axis auto-scale when checked.\n'
+ 'If unchecked, y-axis does not change when reseting zoom.',
+ triggered=self._actionTriggered,
+ checkable=True, parent=parent)
+ self.setChecked(plot.isXAxisAutoScale())
+ plot.sigSetYAxisAutoScale.connect(self.setChecked)
+
+ def _actionTriggered(self, checked=False):
+ self.plot.setYAxisAutoScale(checked)
+ if checked:
+ self.plot.resetZoom()
+
+
+class XAxisLogarithmicAction(PlotAction):
+ """QAction controlling X axis log scale on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ super(XAxisLogarithmicAction, self).__init__(
+ plot, icon='plot-xlog', text='X Log. scale',
+ tooltip='Logarithmic x-axis when checked',
+ triggered=self._actionTriggered,
+ checkable=True, parent=parent)
+ self.setChecked(plot.isXAxisLogarithmic())
+ plot.sigSetXAxisLogarithmic.connect(self.setChecked)
+
+ def _actionTriggered(self, checked=False):
+ self.plot.setXAxisLogarithmic(checked)
+
+
+class YAxisLogarithmicAction(PlotAction):
+ """QAction controlling Y axis log scale on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ super(YAxisLogarithmicAction, self).__init__(
+ plot, icon='plot-ylog', text='Y Log. scale',
+ tooltip='Logarithmic y-axis when checked',
+ triggered=self._actionTriggered,
+ checkable=True, parent=parent)
+ self.setChecked(plot.isYAxisLogarithmic())
+ plot.sigSetYAxisLogarithmic.connect(self.setChecked)
+
+ def _actionTriggered(self, checked=False):
+ self.plot.setYAxisLogarithmic(checked)
+
+
+class GridAction(PlotAction):
+ """QAction controlling grid mode on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param str gridMode: The grid mode to use in 'both', 'major'.
+ See :meth:`.PlotWidget.setGraphGrid`
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, gridMode='both', parent=None):
+ assert gridMode in ('both', 'major')
+ self._gridMode = gridMode
+
+ super(GridAction, self).__init__(
+ plot, icon='plot-grid', text='Grid',
+ tooltip='Toggle grid (on/off)',
+ triggered=self._actionTriggered,
+ checkable=True, parent=parent)
+ self.setChecked(plot.getGraphGrid() is not None)
+ plot.sigSetGraphGrid.connect(self._gridChanged)
+
+ def _gridChanged(self, which):
+ """Slot listening for PlotWidget grid mode change."""
+ self.setChecked(which != 'None')
+
+ def _actionTriggered(self, checked=False):
+ self.plot.setGraphGrid(self._gridMode if checked else None)
+
+
+class CurveStyleAction(PlotAction):
+ """QAction controlling curve style on a :class:`.PlotWidget`.
+
+ It changes the default line and markers style which updates all
+ curves on the plot.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ super(CurveStyleAction, self).__init__(
+ plot, icon='plot-toggle-points', text='Curve style',
+ tooltip='Change curve line and markers style',
+ triggered=self._actionTriggered,
+ checkable=False, parent=parent)
+
+ def _actionTriggered(self, checked=False):
+ currentState = (self.plot.isDefaultPlotLines(),
+ self.plot.isDefaultPlotPoints())
+
+ # line only, line and symbol, symbol only
+ states = (True, False), (True, True), (False, True)
+ newState = states[(states.index(currentState) + 1) % 3]
+
+ self.plot.setDefaultPlotLines(newState[0])
+ self.plot.setDefaultPlotPoints(newState[1])
+
+
+class ColormapAction(PlotAction):
+ """QAction opening a ColormapDialog to update the colormap.
+
+ Both the active image colormap and the default colormap are updated.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+ def __init__(self, plot, parent=None):
+ self._dialog = None # To store an instance of ColormapDialog
+ super(ColormapAction, self).__init__(
+ plot, icon='colormap', text='Colormap',
+ tooltip="Change colormap",
+ triggered=self._actionTriggered,
+ checkable=False, parent=parent)
+
+ def _actionTriggered(self, checked=False):
+ """Create a cmap dialog and update active image and default cmap."""
+ # Create the dialog if not already existing
+ if self._dialog is None:
+ self._dialog = ColormapDialog()
+
+ image = self.plot.getActiveImage()
+ if not isinstance(image, items.ColormapMixIn):
+ # No active image or active image is RGBA,
+ # set dialog from default info
+ colormap = self.plot.getDefaultColormap()
+
+ self._dialog.setHistogram() # Reset histogram and range if any
+
+ else:
+ # Set dialog from active image
+ colormap = image.getColormap()
+
+ data = image.getData(copy=False)
+
+ goodData = data[numpy.isfinite(data)]
+ if goodData.size > 0:
+ dataMin = goodData.min()
+ dataMax = goodData.max()
+ else:
+ qt.QMessageBox.warning(
+ self, "No Data",
+ "Image data does not contain any real value")
+ dataMin, dataMax = 1., 10.
+
+ self._dialog.setHistogram() # Reset histogram if any
+ self._dialog.setDataRange(dataMin, dataMax)
+ # The histogram should be done in a worker thread
+ # hist, bin_edges = numpy.histogram(goodData, bins=256)
+ # self._dialog.setHistogram(hist, bin_edges)
+
+ self._dialog.setColormap(**colormap)
+
+ # Run the dialog listening to colormap change
+ self._dialog.sigColormapChanged.connect(self._colormapChanged)
+ result = self._dialog.exec_()
+ self._dialog.sigColormapChanged.disconnect(self._colormapChanged)
+
+ if not result: # Restore the previous colormap
+ self._colormapChanged(colormap)
+
+ def _colormapChanged(self, colormap):
+ # Update default colormap
+ self.plot.setDefaultColormap(colormap)
+
+ # Update active image colormap
+ activeImage = self.plot.getActiveImage()
+ if isinstance(activeImage, items.ColormapMixIn):
+ activeImage.setColormap(colormap)
+
+
+class KeepAspectRatioAction(PlotAction):
+ """QAction controlling aspect ratio on a :class:`.PlotWidget`.
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ # Uses two images for checked/unchecked states
+ self._states = {
+ False: (icons.getQIcon('shape-circle-solid'),
+ "Keep data aspect ratio"),
+ True: (icons.getQIcon('shape-ellipse-solid'),
+ "Do no keep data aspect ratio")
+ }
+
+ icon, tooltip = self._states[plot.isKeepDataAspectRatio()]
+ super(KeepAspectRatioAction, self).__init__(
+ plot,
+ icon=icon,
+ text='Toggle keep aspect ratio',
+ tooltip=tooltip,
+ triggered=self._actionTriggered,
+ checkable=False,
+ parent=parent)
+ plot.sigSetKeepDataAspectRatio.connect(
+ self._keepDataAspectRatioChanged)
+
+ def _keepDataAspectRatioChanged(self, aspectRatio):
+ """Handle Plot set keep aspect ratio signal"""
+ icon, tooltip = self._states[aspectRatio]
+ self.setIcon(icon)
+ self.setToolTip(tooltip)
+
+ def _actionTriggered(self, checked=False):
+ # This will trigger _keepDataAspectRatioChanged
+ self.plot.setKeepDataAspectRatio(not self.plot.isKeepDataAspectRatio())
+
+
+class YAxisInvertedAction(PlotAction):
+ """QAction controlling Y orientation on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ # Uses two images for checked/unchecked states
+ self._states = {
+ False: (icons.getQIcon('plot-ydown'),
+ "Orient Y axis downward"),
+ True: (icons.getQIcon('plot-yup'),
+ "Orient Y axis upward"),
+ }
+
+ icon, tooltip = self._states[plot.isYAxisInverted()]
+ super(YAxisInvertedAction, self).__init__(
+ plot,
+ icon=icon,
+ text='Invert Y Axis',
+ tooltip=tooltip,
+ triggered=self._actionTriggered,
+ checkable=False,
+ parent=parent)
+ plot.sigSetYAxisInverted.connect(self._yAxisInvertedChanged)
+
+ def _yAxisInvertedChanged(self, inverted):
+ """Handle Plot set y axis inverted signal"""
+ icon, tooltip = self._states[inverted]
+ self.setIcon(icon)
+ self.setToolTip(tooltip)
+
+ def _actionTriggered(self, checked=False):
+ # This will trigger _yAxisInvertedChanged
+ self.plot.setYAxisInverted(not self.plot.isYAxisInverted())
+
+
+class SaveAction(PlotAction):
+ """QAction for saving Plot content.
+
+ It opens a Save as... dialog.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate.
+ :param parent: See :class:`QAction`.
+ """
+ # TODO find a way to make the filter list selectable and extensible
+
+ SNAPSHOT_FILTER_SVG = 'Plot Snapshot as SVG (*.svg)'
+
+ SNAPSHOT_FILTERS = ('Plot Snapshot as PNG (*.png)',
+ 'Plot Snapshot as JPEG (*.jpg)',
+ SNAPSHOT_FILTER_SVG)
+
+ # Dict of curve filters with CSV-like format
+ # Using ordered dict to guarantee filters order
+ # Note: '%.18e' is numpy.savetxt default format
+ CURVE_FILTERS_TXT = OrderedDict((
+ ('Curve as Raw ASCII (*.txt)',
+ {'fmt': '%.18e', 'delimiter': ' ', 'header': False}),
+ ('Curve as ";"-separated CSV (*.csv)',
+ {'fmt': '%.18e', 'delimiter': ';', 'header': True}),
+ ('Curve as ","-separated CSV (*.csv)',
+ {'fmt': '%.18e', 'delimiter': ',', 'header': True}),
+ ('Curve as tab-separated CSV (*.csv)',
+ {'fmt': '%.18e', 'delimiter': '\t', 'header': True}),
+ ('Curve as OMNIC CSV (*.csv)',
+ {'fmt': '%.7E', 'delimiter': ',', 'header': False}),
+ ('Curve as SpecFile (*.dat)',
+ {'fmt': '%.7g', 'delimiter': '', 'header': False})
+ ))
+
+ CURVE_FILTER_NPY = 'Curve as NumPy binary file (*.npy)'
+
+ CURVE_FILTERS = list(CURVE_FILTERS_TXT.keys()) + [CURVE_FILTER_NPY]
+
+ ALL_CURVES_FILTERS = ("All curves as SpecFile (*.dat)", )
+
+ IMAGE_FILTER_EDF = 'Image data as EDF (*.edf)'
+ IMAGE_FILTER_TIFF = 'Image data as TIFF (*.tif)'
+ IMAGE_FILTER_NUMPY = 'Image data as NumPy binary file (*.npy)'
+ IMAGE_FILTER_ASCII = 'Image data as ASCII (*.dat)'
+ IMAGE_FILTER_CSV_COMMA = 'Image data as ,-separated CSV (*.csv)'
+ IMAGE_FILTER_CSV_SEMICOLON = 'Image data as ;-separated CSV (*.csv)'
+ IMAGE_FILTER_CSV_TAB = 'Image data as tab-separated CSV (*.csv)'
+ IMAGE_FILTER_RGB_PNG = 'Image as PNG (*.png)'
+ IMAGE_FILTER_RGB_TIFF = 'Image as TIFF (*.tif)'
+ IMAGE_FILTERS = (IMAGE_FILTER_EDF,
+ IMAGE_FILTER_TIFF,
+ IMAGE_FILTER_NUMPY,
+ IMAGE_FILTER_ASCII,
+ IMAGE_FILTER_CSV_COMMA,
+ IMAGE_FILTER_CSV_SEMICOLON,
+ IMAGE_FILTER_CSV_TAB,
+ IMAGE_FILTER_RGB_PNG,
+ IMAGE_FILTER_RGB_TIFF)
+
+ def __init__(self, plot, parent=None):
+ super(SaveAction, self).__init__(
+ plot, icon='document-save', text='Save as...',
+ tooltip='Save curve/image/plot snapshot dialog',
+ triggered=self._actionTriggered,
+ checkable=False, parent=parent)
+ self.setShortcut(qt.QKeySequence.Save)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+
+ def _errorMessage(self, informativeText=''):
+ """Display an error message."""
+ # TODO issue with QMessageBox size fixed and too small
+ msg = qt.QMessageBox(self.plot)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setInformativeText(informativeText + ' ' + str(sys.exc_info()[1]))
+ msg.setDetailedText(traceback.format_exc())
+ msg.exec_()
+
+ def _saveSnapshot(self, filename, nameFilter):
+ """Save a snapshot of the :class:`PlotWindow` widget.
+
+ :param str filename: The name of the file to write
+ :param str nameFilter: The selected name filter
+ :return: False if format is not supported or save failed,
+ True otherwise.
+ """
+ if nameFilter == self.SNAPSHOT_FILTER_SVG:
+ self.plot.saveGraph(filename, fileFormat='svg')
+
+ else:
+ if hasattr(qt.QPixmap, "grabWidget"):
+ # Qt 4
+ pixmap = qt.QPixmap.grabWidget(self.plot.getWidgetHandle())
+ else:
+ # Qt 5
+ pixmap = self.plot.getWidgetHandle().grab()
+ if not pixmap.save(filename):
+ self._errorMessage()
+ return False
+ return True
+
+ def _saveCurve(self, filename, nameFilter):
+ """Save a curve from the plot.
+
+ :param str filename: The name of the file to write
+ :param str nameFilter: The selected name filter
+ :return: False if format is not supported or save failed,
+ True otherwise.
+ """
+ if nameFilter not in self.CURVE_FILTERS:
+ return False
+
+ # Check if a curve is to be saved
+ curve = self.plot.getActiveCurve()
+ # before calling _saveCurve, if there is no selected curve, we
+ # make sure there is only one curve on the graph
+ if curve is None:
+ curves = self.plot.getAllCurves()
+ if not curves:
+ self._errorMessage("No curve to be saved")
+ return False
+ curve = curves[0]
+
+ if nameFilter in self.CURVE_FILTERS_TXT:
+ filter_ = self.CURVE_FILTERS_TXT[nameFilter]
+ fmt = filter_['fmt']
+ csvdelim = filter_['delimiter']
+ autoheader = filter_['header']
+ else:
+ # .npy
+ fmt, csvdelim, autoheader = ("", "", False)
+
+ # If curve has no associated label, get the default from the plot
+ xlabel = curve.getXLabel()
+ if xlabel is None:
+ xlabel = self.plot.getGraphXLabel()
+ ylabel = curve.getYLabel()
+ if ylabel is None:
+ ylabel = self.plot.getGraphYLabel()
+
+ try:
+ save1D(filename,
+ curve.getXData(copy=False),
+ curve.getYData(copy=False),
+ xlabel, [ylabel],
+ fmt=fmt, csvdelim=csvdelim,
+ autoheader=autoheader)
+ except IOError:
+ self._errorMessage('Save failed\n')
+ return False
+
+ return True
+
+ def _saveCurves(self, filename, nameFilter):
+ """Save all curves from the plot.
+
+ :param str filename: The name of the file to write
+ :param str nameFilter: The selected name filter
+ :return: False if format is not supported or save failed,
+ True otherwise.
+ """
+ if nameFilter not in self.ALL_CURVES_FILTERS:
+ return False
+
+ curves = self.plot.getAllCurves()
+ if not curves:
+ self._errorMessage("No curves to be saved")
+ return False
+
+ curve = curves[0]
+ scanno = 1
+ try:
+ specfile = savespec(filename,
+ curve.getXData(copy=False),
+ curve.getYData(copy=False),
+ curve.getXLabel(),
+ curve.getYLabel(),
+ fmt="%.7g", scan_number=1, mode="w",
+ write_file_header=True,
+ close_file=False)
+ except IOError:
+ self._errorMessage('Save failed\n')
+ return False
+
+ for curve in curves[1:]:
+ try:
+ scanno += 1
+ specfile = savespec(specfile,
+ curve.getXData(copy=False),
+ curve.getYData(copy=False),
+ curve.getXLabel(),
+ curve.getYLabel(),
+ fmt="%.7g", scan_number=scanno, mode="w",
+ write_file_header=False,
+ close_file=False)
+ except IOError:
+ self._errorMessage('Save failed\n')
+ return False
+ specfile.close()
+
+ return True
+
+ def _saveImage(self, filename, nameFilter):
+ """Save an image from the plot.
+
+ :param str filename: The name of the file to write
+ :param str nameFilter: The selected name filter
+ :return: False if format is not supported or save failed,
+ True otherwise.
+ """
+ if nameFilter not in self.IMAGE_FILTERS:
+ return False
+
+ image = self.plot.getActiveImage()
+ if image is None:
+ qt.QMessageBox.warning(
+ self.plot, "No Data", "No image to be saved")
+ return False
+
+ data = image.getData(copy=False)
+
+ # TODO Use silx.io for writing files
+ if nameFilter == self.IMAGE_FILTER_EDF:
+ edfFile = EdfFile(filename, access="w+")
+ edfFile.WriteImage({}, data, Append=0)
+ return True
+
+ elif nameFilter == self.IMAGE_FILTER_TIFF:
+ tiffFile = TiffIO(filename, mode='w')
+ tiffFile.writeImage(data, software='silx')
+ return True
+
+ elif nameFilter == self.IMAGE_FILTER_NUMPY:
+ try:
+ numpy.save(filename, data)
+ except IOError:
+ self._errorMessage('Save failed\n')
+ return False
+ return True
+
+ elif nameFilter in (self.IMAGE_FILTER_ASCII,
+ self.IMAGE_FILTER_CSV_COMMA,
+ self.IMAGE_FILTER_CSV_SEMICOLON,
+ self.IMAGE_FILTER_CSV_TAB):
+ csvdelim, filetype = {
+ self.IMAGE_FILTER_ASCII: (' ', 'txt'),
+ self.IMAGE_FILTER_CSV_COMMA: (',', 'csv'),
+ self.IMAGE_FILTER_CSV_SEMICOLON: (';', 'csv'),
+ self.IMAGE_FILTER_CSV_TAB: ('\t', 'csv'),
+ }[nameFilter]
+
+ height, width = data.shape
+ rows, cols = numpy.mgrid[0:height, 0:width]
+ try:
+ save1D(filename, rows.ravel(), (cols.ravel(), data.ravel()),
+ filetype=filetype,
+ xlabel='row',
+ ylabels=['column', 'value'],
+ csvdelim=csvdelim,
+ autoheader=True)
+
+ except IOError:
+ self._errorMessage('Save failed\n')
+ return False
+ return True
+
+ elif nameFilter in (self.IMAGE_FILTER_RGB_PNG,
+ self.IMAGE_FILTER_RGB_TIFF):
+ # Get displayed image
+ rgbaImage = image.getRbgaImageData(copy=False)
+ # Convert RGB QImage
+ qimage = convertArrayToQImage(rgbaImage[:, :, :3])
+
+ if nameFilter == self.IMAGE_FILTER_RGB_PNG:
+ fileFormat = 'PNG'
+ else:
+ fileFormat = 'TIFF'
+
+ if qimage.save(filename, fileFormat):
+ return True
+ else:
+ _logger.error('Failed to save image as %s', filename)
+ qt.QMessageBox.critical(
+ self.parent(),
+ 'Save image as',
+ 'Failed to save image')
+
+ return False
+
+ def _actionTriggered(self, checked=False):
+ """Handle save action."""
+ # Set-up filters
+ filters = []
+
+ # Add image filters if there is an active image
+ if self.plot.getActiveImage() is not None:
+ filters.extend(self.IMAGE_FILTERS)
+
+ # Add curve filters if there is a curve to save
+ if (self.plot.getActiveCurve() is not None or
+ len(self.plot.getAllCurves()) == 1):
+ filters.extend(self.CURVE_FILTERS)
+ if len(self.plot.getAllCurves()) > 1:
+ filters.extend(self.ALL_CURVES_FILTERS)
+
+ filters.extend(self.SNAPSHOT_FILTERS)
+
+ # Create and run File dialog
+ dialog = qt.QFileDialog(self.plot)
+ dialog.setWindowTitle("Output File Selection")
+ dialog.setModal(1)
+ dialog.setNameFilters(filters)
+
+ dialog.setFileMode(dialog.AnyFile)
+ dialog.setAcceptMode(dialog.AcceptSave)
+
+ if not dialog.exec_():
+ return False
+
+ nameFilter = dialog.selectedNameFilter()
+ filename = dialog.selectedFiles()[0]
+ dialog.close()
+
+ # Forces the filename extension to match the chosen filter
+ extension = nameFilter.split()[-1][2:-1]
+ if (len(filename) <= len(extension) or
+ filename[-len(extension):].lower() != extension.lower()):
+ filename += extension
+
+ # Handle save
+ if nameFilter in self.SNAPSHOT_FILTERS:
+ return self._saveSnapshot(filename, nameFilter)
+ elif nameFilter in self.CURVE_FILTERS:
+ return self._saveCurve(filename, nameFilter)
+ elif nameFilter in self.ALL_CURVES_FILTERS:
+ return self._saveCurves(filename, nameFilter)
+ elif nameFilter in self.IMAGE_FILTERS:
+ return self._saveImage(filename, nameFilter)
+ else:
+ _logger.warning('Unsupported file filter: %s', nameFilter)
+ return False
+
+
+def _plotAsPNG(plot):
+ """Save a :class:`Plot` as PNG and return the payload.
+
+ :param plot: The :class:`Plot` to save
+ """
+ pngFile = BytesIO()
+ plot.saveGraph(pngFile, fileFormat='png')
+ pngFile.flush()
+ pngFile.seek(0)
+ data = pngFile.read()
+ pngFile.close()
+ return data
+
+
+class PrintAction(PlotAction):
+ """QAction for printing the plot.
+
+ It opens a Print dialog.
+
+ Current implementation print a bitmap of the plot area and not vector
+ graphics, so printing quality is not great.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate.
+ :param parent: See :class:`QAction`.
+ """
+
+ # Share QPrinter instance to propose latest used as default
+ _printer = None
+
+ def __init__(self, plot, parent=None):
+ super(PrintAction, self).__init__(
+ plot, icon='document-print', text='Print...',
+ tooltip='Open print dialog',
+ triggered=self.printPlot,
+ checkable=False, parent=parent)
+ self.setShortcut(qt.QKeySequence.Print)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+
+ @property
+ def printer(self):
+ """The QPrinter instance used by the actions.
+
+ This is shared accross all instances of PrintAct
+ """
+ if self._printer is None:
+ PrintAction._printer = qt.QPrinter()
+ return self._printer
+
+ def printPlotAsWidget(self):
+ """Open the print dialog and print the plot.
+
+ Use :meth:`QWidget.render` to print the plot
+
+ :return: True if successful
+ """
+ dialog = qt.QPrintDialog(self.printer, self.plot)
+ dialog.setWindowTitle('Print Plot')
+ if not dialog.exec_():
+ return False
+
+ # Print a snapshot of the plot widget at the top of the page
+ widget = self.plot.centralWidget()
+
+ painter = qt.QPainter()
+ if not painter.begin(self.printer):
+ return False
+
+ pageRect = self.printer.pageRect()
+ xScale = pageRect.width() / widget.width()
+ yScale = pageRect.height() / widget.height()
+ scale = min(xScale, yScale)
+
+ painter.translate(pageRect.width() / 2., 0.)
+ painter.scale(scale, scale)
+ painter.translate(-widget.width() / 2., 0.)
+ widget.render(painter)
+ painter.end()
+
+ return True
+
+ def printPlot(self):
+ """Open the print dialog and print the plot.
+
+ Use :meth:`Plot.saveGraph` to print the plot.
+
+ :return: True if successful
+ """
+ # Init printer and start printer dialog
+ dialog = qt.QPrintDialog(self.printer, self.plot)
+ dialog.setWindowTitle('Print Plot')
+ if not dialog.exec_():
+ return False
+
+ # Save Plot as PNG and make a pixmap from it with default dpi
+ pngData = _plotAsPNG(self.plot)
+
+ pixmap = qt.QPixmap()
+ pixmap.loadFromData(pngData, 'png')
+
+ xScale = self.printer.pageRect().width() / pixmap.width()
+ yScale = self.printer.pageRect().height() / pixmap.height()
+ scale = min(xScale, yScale)
+
+ # Draw pixmap with painter
+ painter = qt.QPainter()
+ if not painter.begin(self.printer):
+ return False
+
+ painter.drawPixmap(0, 0,
+ pixmap.width() * scale,
+ pixmap.height() * scale,
+ pixmap)
+ painter.end()
+
+ return True
+
+
+class CopyAction(PlotAction):
+ """QAction to copy :class:`.PlotWidget` content to clipboard.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ super(CopyAction, self).__init__(
+ plot, icon='edit-copy', text='Copy plot',
+ tooltip='Copy a snapshot of the plot into the clipboard',
+ triggered=self.copyPlot,
+ checkable=False, parent=parent)
+ self.setShortcut(qt.QKeySequence.Copy)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+
+ def copyPlot(self):
+ """Copy plot content to the clipboard as a bitmap."""
+ # Save Plot as PNG and make a QImage from it with default dpi
+ pngData = _plotAsPNG(self.plot)
+ image = qt.QImage.fromData(pngData, 'png')
+ qt.QApplication.clipboard().setImage(image)
+
+
+class CrosshairAction(PlotAction):
+ """QAction toggling crosshair cursor on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param str color: Color to use to draw the crosshair
+ :param int linewidth: Width of the crosshair cursor
+ :param str linestyle: Style of line. See :meth:`.Plot.setGraphCursor`
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, color='black', linewidth=1, linestyle='-',
+ parent=None):
+ self.color = color
+ """Color used to draw the crosshair (str)."""
+
+ self.linewidth = linewidth
+ """Width of the crosshair cursor (int)."""
+
+ self.linestyle = linestyle
+ """Style of line of the cursor (str)."""
+
+ super(CrosshairAction, self).__init__(
+ plot, icon='crosshair', text='Crosshair Cursor',
+ tooltip='Enable crosshair cursor when checked',
+ triggered=self._actionTriggered,
+ checkable=True, parent=parent)
+ self.setChecked(plot.getGraphCursor() is not None)
+ plot.sigSetGraphCursor.connect(self.setChecked)
+
+ def _actionTriggered(self, checked=False):
+ self.plot.setGraphCursor(checked,
+ color=self.color,
+ linestyle=self.linestyle,
+ linewidth=self.linewidth)
+
+
+class PanWithArrowKeysAction(PlotAction):
+ """QAction toggling pan with arrow keys on a :class:`.PlotWidget`.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+
+ super(PanWithArrowKeysAction, self).__init__(
+ plot, icon='arrow-keys', text='Pan with arrow keys',
+ tooltip='Enable pan with arrow keys when checked',
+ triggered=self._actionTriggered,
+ checkable=True, parent=parent)
+ self.setChecked(plot.isPanWithArrowKeys())
+ plot.sigSetPanWithArrowKeys.connect(self.setChecked)
+
+ def _actionTriggered(self, checked=False):
+ self.plot.setPanWithArrowKeys(checked)
+
+
+def _warningMessage(informativeText='', detailedText='', parent=None):
+ """Display a popup warning message."""
+ msg = qt.QMessageBox(parent)
+ msg.setIcon(qt.QMessageBox.Warning)
+ msg.setInformativeText(informativeText)
+ msg.setDetailedText(detailedText)
+ msg.exec_()
+
+
+def _getOneCurve(plt, mode="unique"):
+ """Get a single curve from the plot.
+ By default, get the active curve if any, else if a single curve is plotted
+ get it, else return None and display a warning popup.
+
+ This behavior can be adjusted by modifying the *mode* parameter: always
+ return the active curve if any, but adjust the behavior in case no curve
+ is active.
+
+ :param plt: :class:`.PlotWidget` instance on which to operate
+ :param mode: Parameter defining the behavior when no curve is active.
+ Possible modes:
+ - "none": return None (enforce curve activation)
+ - "unique": return the unique curve or None if multiple curves
+ - "first": return first curve
+ - "last": return last curve (most recently added one)
+ :return: return value of plt.getActiveCurve(), or plt.getAllCurves()[0],
+ or plt.getAllCurves()[-1], or None
+ """
+ curve = plt.getActiveCurve()
+ if curve is not None:
+ return curve
+
+ if mode is None or mode.lower() == "none":
+ _warningMessage("You must activate a curve!",
+ parent=plt)
+ return None
+
+ curves = plt.getAllCurves()
+ if len(curves) == 0:
+ _warningMessage("No curve on this plot.",
+ parent=plt)
+ return None
+
+ if len(curves) == 1:
+ return curves[0]
+
+ if len(curves) > 1:
+ if mode == "unique":
+ _warningMessage("Multiple curves are plotted. " +
+ "Please activate the one you want to use.",
+ parent=plt)
+ return None
+ if mode.lower() == "first":
+ return curves[0]
+ if mode.lower() == "last":
+ return curves[-1]
+
+ raise ValueError("Illegal value for parameter 'mode'." +
+ " Allowed values: 'none', 'unique', 'first', 'last'.")
+
+
+class FitAction(PlotAction):
+ """QAction to open a :class:`FitWidget` and set its data to the
+ active curve if any, or to the first curve.
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+ def __init__(self, plot, parent=None):
+ super(FitAction, self).__init__(
+ plot, icon='math-fit', text='Fit curve',
+ tooltip='Open a fit dialog',
+ triggered=self._getFitWindow,
+ checkable=False, parent=parent)
+ self.fit_window = None
+
+ def _getFitWindow(self):
+ curve = _getOneCurve(self.plot)
+ if curve is None:
+ return
+ self.xlabel = self.plot.getGraphXLabel()
+ self.ylabel = self.plot.getGraphYLabel()
+ self.x = curve.getXData(copy=False)
+ self.y = curve.getYData(copy=False)
+ self.legend = curve.getLegend()
+ self.xmin, self.xmax = self.plot.getGraphXLimits()
+
+ # open a window with a FitWidget
+ if self.fit_window is None:
+ self.fit_window = qt.QMainWindow()
+ # import done here rather than at module level to avoid circular import
+ # FitWidget -> BackgroundWidget -> PlotWindow -> PlotActions -> FitWidget
+ from ..fit.FitWidget import FitWidget
+ self.fit_widget = FitWidget(parent=self.fit_window)
+ self.fit_window.setCentralWidget(
+ self.fit_widget)
+ self.fit_widget.guibuttons.DismissButton.clicked.connect(
+ self.fit_window.close)
+ self.fit_widget.sigFitWidgetSignal.connect(
+ self.handle_signal)
+ self.fit_window.show()
+ else:
+ if self.fit_window.isHidden():
+ self.fit_window.show()
+ self.fit_widget.show()
+ self.fit_window.raise_()
+
+ self.fit_widget.setData(self.x, self.y,
+ xmin=self.xmin, xmax=self.xmax)
+ self.fit_window.setWindowTitle(
+ "Fitting " + self.legend +
+ " on x range %f-%f" % (self.xmin, self.xmax))
+
+ def handle_signal(self, ddict):
+ x_fit = self.x[self.xmin <= self.x]
+ x_fit = x_fit[x_fit <= self.xmax]
+ fit_legend = "Fit <%s>" % self.legend
+ fit_curve = self.plot.getCurve(fit_legend)
+
+ if ddict["event"] == "FitFinished":
+ y_fit = self.fit_widget.fitmanager.gendata()
+ if fit_curve is None:
+ self.plot.addCurve(x_fit, y_fit,
+ fit_legend,
+ xlabel=self.xlabel, ylabel=self.ylabel,
+ resetzoom=False)
+ else:
+ fit_curve.setData(x_fit, y_fit)
+ fit_curve.setVisible(True)
+
+ if ddict["event"] in ["FitStarted", "FitFailed"]:
+ if fit_curve is not None:
+ fit_curve.setVisible(False)
+
+
+class PixelIntensitiesHistoAction(PlotAction):
+ """QAction to plot the pixels intensities diagram
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ PlotAction.__init__(self,
+ plot,
+ icon='pixel-intensities',
+ text='pixels intensity',
+ tooltip='Compute image intensity distribution',
+ triggered=self._triggered,
+ parent=parent,
+ checkable=True)
+ self._plotHistogram = None
+ self._connectedToActiveImage = False
+ self._histo = None
+
+ def _triggered(self, checked):
+ """Update the plot of the histogram visibility status
+
+ :param bool checked: status of the action button
+ """
+ if checked:
+ if not self._connectedToActiveImage:
+ self.plot.sigActiveImageChanged.connect(
+ self._activeImageChanged)
+ self._connectedToActiveImage = True
+ self.computeIntensityDistribution()
+
+ self.getHistogramPlotWidget().show()
+
+ else:
+ if self._connectedToActiveImage:
+ self.plot.sigActiveImageChanged.disconnect(
+ self._activeImageChanged)
+ self._connectedToActiveImage = False
+
+ self.getHistogramPlotWidget().hide()
+
+ def _activeImageChanged(self, previous, legend):
+ """Handle active image change: toggle enabled toolbar, update curve"""
+ if self.isChecked():
+ self.computeIntensityDistribution()
+
+ def computeIntensityDistribution(self):
+ """Get the active image and compute the image intensity distribution
+ """
+ activeImage = self.plot.getActiveImage()
+
+ if activeImage is not None:
+ image = activeImage.getData(copy=False)
+ if image.ndim == 3: # RGB(A) images
+ _logger.info('Converting current image from RGB(A) to grayscale\
+ in order to compute the intensity distribution')
+ image = (image[:, :, 0] * 0.299 +
+ image[:, :, 1] * 0.587 +
+ image[:, :, 2] * 0.114)
+
+ xmin = numpy.nanmin(image)
+ xmax = numpy.nanmax(image)
+ nbins = min(1024, int(numpy.sqrt(image.size)))
+ data_range = xmin, xmax
+
+ # bad hack: get 256 bins in the case we have a B&W
+ if numpy.issubdtype(image.dtype, numpy.integer):
+ if nbins > xmax - xmin:
+ nbins = xmax - xmin
+
+ nbins = max(2, nbins)
+
+ data = image.ravel().astype(numpy.float32)
+ histogram = Histogramnd(data, n_bins=nbins, histo_range=data_range)
+ assert len(histogram.edges) == 1
+ self._histo = histogram.histo
+ edges = histogram.edges[0]
+ plot = self.getHistogramPlotWidget()
+ plot.addHistogram(histogram=self._histo,
+ edges=edges,
+ legend='pixel intensity',
+ fill=True,
+ color='red')
+ plot.resetZoom()
+
+ def eventFilter(self, qobject, event):
+ """Observe when the close event is emitted then
+ simply uncheck the action button
+
+ :param qobject: the object observe
+ :param event: the event received by qobject
+ """
+ if event.type() == qt.QEvent.Close:
+ if self._plotHistogram is not None:
+ self._plotHistogram.hide()
+ self.setChecked(False)
+
+ return PlotAction.eventFilter(self, qobject, event)
+
+ def getHistogramPlotWidget(self):
+ """Create the plot histogram if needed, otherwise create it
+
+ :return: the PlotWidget showing the histogram of the pixel intensities
+ """
+ from silx.gui.plot.PlotWindow import Plot1D
+ if self._plotHistogram is None:
+ self._plotHistogram = Plot1D(parent=self.plot)
+ self._plotHistogram.setWindowFlags(qt.Qt.Window)
+ self._plotHistogram.setWindowTitle('Image Intensity Histogram')
+ self._plotHistogram.installEventFilter(self)
+ self._plotHistogram.setGraphXLabel("Value")
+ self._plotHistogram.setGraphYLabel("Count")
+
+ return self._plotHistogram
+
+ def getHistogram(self):
+ """Return the last computed histogram
+
+ :return: the histogram displayed in the HistogramPlotWiget
+ """
+ return self._histo
+
+
+class MedianFilterAction(PlotAction):
+ """QAction to plot the pixels intensities diagram
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+
+ def __init__(self, plot, parent=None):
+ PlotAction.__init__(self,
+ plot,
+ icon='median-filter',
+ text='median filter',
+ tooltip='Apply a median filter on the image',
+ triggered=self._triggered,
+ parent=parent)
+ self._originalImage = None
+ self._legend = None
+ self._filteredImage = None
+ self._popup = MedianFilterDialog(parent=None)
+ self._popup.sigFilterOptChanged.connect(self._updateFilter)
+ self.plot.sigActiveImageChanged.connect( self._updateActiveImage)
+ self._updateActiveImage()
+
+ def _triggered(self, checked):
+ """Update the plot of the histogram visibility status
+
+ :param bool checked: status of the action button
+ """
+ self._popup.show()
+
+ def _updateActiveImage(self):
+ """Set _activeImageLegend and _originalImage from the active image"""
+ self._activeImageLegend = self.plot.getActiveImage(just_legend=True)
+ if self._activeImageLegend is None:
+ self._originalImage = None
+ self._legend = None
+ else:
+ self._originalImage = self.plot.getImage(self._activeImageLegend).getData(copy=False)
+ self._legend = self.plot.getImage(self._activeImageLegend).getLegend()
+
+ def _updateFilter(self, kernelWidth, conditional=False):
+ if self._originalImage is None:
+ return
+
+ self.plot.sigActiveImageChanged.disconnect(self._updateActiveImage)
+ filteredImage = self._computeFilteredImage(kernelWidth, conditional)
+ self.plot.addImage(data=filteredImage,
+ legend=self._legend,
+ replace=True)
+ self.plot.sigActiveImageChanged.connect(self._updateActiveImage)
+
+ def _computeFilteredImage(self, kernelWidth, conditional):
+ raise NotImplemented('MedianFilterAction is a an abstract class')
+
+ def getFilteredImage(self):
+ """
+ :return: the image with the median filter apply on"""
+ return self._filteredImage
+
+
+class MedianFilter1DAction(MedianFilterAction):
+ """Define the MedianFilterAction for 1D
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+ def __init__(self, plot, parent=None):
+ MedianFilterAction.__init__(self,
+ plot,
+ parent=parent)
+
+ def _computeFilteredImage(self, kernelWidth, conditional):
+ assert(self.plot is not None)
+ return medfilt2d(self._originalImage,
+ (kernelWidth, 1),
+ conditional)
+
+
+class MedianFilter2DAction(MedianFilterAction):
+ """Define the MedianFilterAction for 2D
+
+ :param plot: :class:`.PlotWidget` instance on which to operate
+ :param parent: See :class:`QAction`
+ """
+ def __init__(self, plot, parent=None):
+ MedianFilterAction.__init__(self,
+ plot,
+ parent=parent)
+
+ def _computeFilteredImage(self, kernelWidth, conditional):
+ assert(self.plot is not None)
+ return medfilt2d(self._originalImage,
+ (kernelWidth, kernelWidth),
+ conditional)
diff --git a/silx/gui/plot/PlotEvents.py b/silx/gui/plot/PlotEvents.py
new file mode 100644
index 0000000..83f253c
--- /dev/null
+++ b/silx/gui/plot/PlotEvents.py
@@ -0,0 +1,166 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+# ###########################################################################*/
+"""Functions to prepare events to be sent to Plot callback."""
+
+__author__ = ["V.A. Sole", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/02/2016"
+
+
+import numpy as np
+
+
+def prepareDrawingSignal(event, type_, points, parameters=None):
+ """See Plot documentation for content of events"""
+ assert event in ('drawingProgress', 'drawingFinished')
+
+ if parameters is None:
+ parameters = {}
+
+ eventDict = {}
+ eventDict['event'] = event
+ eventDict['type'] = type_
+ points = np.array(points, dtype=np.float32)
+ points.shape = -1, 2
+ eventDict['points'] = points
+ eventDict['xdata'] = points[:, 0]
+ eventDict['ydata'] = points[:, 1]
+ if type_ in ('rectangle',):
+ eventDict['x'] = eventDict['xdata'].min()
+ eventDict['y'] = eventDict['ydata'].min()
+ eventDict['width'] = eventDict['xdata'].max() - eventDict['x']
+ eventDict['height'] = eventDict['ydata'].max() - eventDict['y']
+ eventDict['parameters'] = parameters.copy()
+ return eventDict
+
+
+def prepareMouseSignal(eventType, button, xData, yData, xPixel, yPixel):
+ """See Plot documentation for content of events"""
+ assert eventType in ('mouseMoved', 'mouseClicked', 'mouseDoubleClicked')
+ assert button in (None, 'left', 'middle', 'right')
+
+ return {'event': eventType,
+ 'x': xData,
+ 'y': yData,
+ 'xpixel': xPixel,
+ 'ypixel': yPixel,
+ 'button': button}
+
+
+def prepareHoverSignal(label, type_, posData, posPixel, draggable, selectable):
+ """See Plot documentation for content of events"""
+ return {'event': 'hover',
+ 'label': label,
+ 'type': type_,
+ 'x': posData[0],
+ 'y': posData[1],
+ 'xpixel': posPixel[0],
+ 'ypixel': posPixel[1],
+ 'draggable': draggable,
+ 'selectable': selectable}
+
+
+def prepareMarkerSignal(eventType, button, label, type_,
+ draggable, selectable,
+ posDataMarker,
+ posPixelCursor=None, posDataCursor=None):
+ """See Plot documentation for content of events"""
+ if eventType == 'markerClicked':
+ assert posPixelCursor is not None
+ assert posDataCursor is None
+
+ posDataCursor = list(posDataMarker)
+ if hasattr(posDataCursor[0], "__len__"):
+ posDataCursor[0] = posDataCursor[0][-1]
+ if hasattr(posDataCursor[1], "__len__"):
+ posDataCursor[1] = posDataCursor[1][-1]
+
+ elif eventType == 'markerMoving':
+ assert posPixelCursor is not None
+ assert posDataCursor is not None
+
+ elif eventType == 'markerMoved':
+ assert posPixelCursor is None
+ assert posDataCursor is None
+
+ posDataCursor = posDataMarker
+ else:
+ raise NotImplementedError("Unknown event type {0}".format(eventType))
+
+ eventDict = {'event': eventType,
+ 'button': button,
+ 'label': label,
+ 'type': type_,
+ 'x': posDataCursor[0],
+ 'y': posDataCursor[1],
+ 'xdata': posDataMarker[0],
+ 'ydata': posDataMarker[1],
+ 'draggable': draggable,
+ 'selectable': selectable}
+
+ if eventType in ('markerMoving', 'markerClicked'):
+ eventDict['xpixel'] = posPixelCursor[0]
+ eventDict['ypixel'] = posPixelCursor[1]
+
+ return eventDict
+
+
+def prepareImageSignal(button, label, type_, col, row,
+ x, y, xPixel, yPixel):
+ """See Plot documentation for content of events"""
+ return {'event': 'imageClicked',
+ 'button': button,
+ 'label': label,
+ 'type': type_,
+ 'col': col,
+ 'row': row,
+ 'x': x,
+ 'y': y,
+ 'xpixel': xPixel,
+ 'ypixel': yPixel}
+
+
+def prepareCurveSignal(button, label, type_, xData, yData,
+ x, y, xPixel, yPixel):
+ """See Plot documentation for content of events"""
+ return {'event': 'curveClicked',
+ 'button': button,
+ 'label': label,
+ 'type': type_,
+ 'xdata': xData,
+ 'ydata': yData,
+ 'x': x,
+ 'y': y,
+ 'xpixel': xPixel,
+ 'ypixel': yPixel}
+
+
+def prepareLimitsChangedSignal(sourceObj, xRange, yRange, y2Range):
+ """See Plot documentation for content of events"""
+ return {'event': 'limitsChanged',
+ 'source': id(sourceObj),
+ 'xdata': xRange,
+ 'ydata': yRange,
+ 'y2data': y2Range}
diff --git a/silx/gui/plot/PlotInteraction.py b/silx/gui/plot/PlotInteraction.py
new file mode 100644
index 0000000..fbc9c1f
--- /dev/null
+++ b/silx/gui/plot/PlotInteraction.py
@@ -0,0 +1,1493 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""Implementation of the interaction for the :class:`Plot`."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "24/01/2017"
+
+
+import math
+import numpy
+import time
+import weakref
+
+from . import Colors
+from . import items
+from .Interaction import (ClickOrDrag, LEFT_BTN, RIGHT_BTN,
+ State, StateMachine)
+from .PlotEvents import (prepareCurveSignal, prepareDrawingSignal,
+ prepareHoverSignal, prepareImageSignal,
+ prepareMarkerSignal, prepareMouseSignal)
+
+from .backends.BackendBase import (CURSOR_POINTING, CURSOR_SIZE_HOR,
+ CURSOR_SIZE_VER, CURSOR_SIZE_ALL)
+
+from ._utils import (FLOAT32_SAFE_MIN, FLOAT32_MINPOS, FLOAT32_SAFE_MAX,
+ applyZoomToPlot)
+
+
+# Base class ##################################################################
+
+class _PlotInteraction(object):
+ """Base class for interaction handler.
+
+ It provides a weakref to the plot and methods to set/reset overlay.
+ """
+ def __init__(self, plot):
+ """Init.
+
+ :param plot: The plot to apply modifications to.
+ """
+ self._needReplot = False
+ self._selectionAreas = set()
+ self._plot = weakref.ref(plot) # Avoid cyclic-ref
+
+ @property
+ def plot(self):
+ plot = self._plot()
+ assert plot is not None
+ return plot
+
+ def setSelectionArea(self, points, fill, color, name='', shape='polygon'):
+ """Set a polygon selection area overlaid on the plot.
+ Multiple simultaneous areas are supported through the name parameter.
+
+ :param points: The 2D coordinates of the points of the polygon
+ :type points: An iterable of (x, y) coordinates
+ :param str fill: The fill mode: 'hatch', 'solid' or 'none'
+ :param color: RGBA color to use or None to disable display
+ :type color: list or tuple of 4 float in the range [0, 1]
+ :param name: The key associated with this selection area
+ :param str shape: Shape of the area in 'polygon', 'polylines'
+ """
+ assert shape in ('polygon', 'polylines')
+
+ if color is None:
+ return
+
+ points = numpy.asarray(points)
+
+ # TODO Not very nice, but as is for now
+ legend = '__SELECTION_AREA__' + name
+
+ fill = fill != 'none' # TODO not very nice either
+
+ self.plot.addItem(points[:, 0], points[:, 1], legend=legend,
+ replace=False,
+ shape=shape, color=color, fill=fill,
+ overlay=True)
+ self._selectionAreas.add(legend)
+
+ def resetSelectionArea(self):
+ """Remove all selection areas set by setSelectionArea."""
+ for legend in self._selectionAreas:
+ self.plot.remove(legend, kind='item')
+ self._selectionAreas = set()
+
+
+# Zoom/Pan ####################################################################
+
+class _ZoomOnWheel(ClickOrDrag, _PlotInteraction):
+ """:class:`ClickOrDrag` state machine with zooming on mouse wheel.
+
+ Base class for :class:`Pan` and :class:`Zoom`
+ """
+ class ZoomIdle(ClickOrDrag.Idle):
+ def onWheel(self, x, y, angle):
+ scaleF = 1.1 if angle > 0 else 1. / 1.1
+ applyZoomToPlot(self.machine.plot, scaleF, (x, y))
+
+ def __init__(self, plot):
+ """Init.
+
+ :param plot: The plot to apply modifications to.
+ """
+ _PlotInteraction.__init__(self, plot)
+
+ states = {
+ 'idle': _ZoomOnWheel.ZoomIdle,
+ 'rightClick': ClickOrDrag.RightClick,
+ 'clickOrDrag': ClickOrDrag.ClickOrDrag,
+ 'drag': ClickOrDrag.Drag
+ }
+ StateMachine.__init__(self, states, 'idle')
+
+
+# Pan #########################################################################
+
+class Pan(_ZoomOnWheel):
+ """Pan plot content and zoom on wheel state machine."""
+
+ def _pixelToData(self, x, y):
+ xData, yData = self.plot.pixelToData(x, y)
+ _, y2Data = self.plot.pixelToData(x, y, axis='right')
+ return xData, yData, y2Data
+
+ def beginDrag(self, x, y):
+ self._previousDataPos = self._pixelToData(x, y)
+
+ def drag(self, x, y):
+ xData, yData, y2Data = self._pixelToData(x, y)
+ lastX, lastY, lastY2 = self._previousDataPos
+
+ xMin, xMax = self.plot.getGraphXLimits()
+ yMin, yMax = self.plot.getGraphYLimits(axis='left')
+ y2Min, y2Max = self.plot.getGraphYLimits(axis='right')
+
+ if self.plot.isXAxisLogarithmic():
+ try:
+ dx = math.log10(xData) - math.log10(lastX)
+ newXMin = pow(10., (math.log10(xMin) - dx))
+ newXMax = pow(10., (math.log10(xMax) - dx))
+ except (ValueError, OverflowError):
+ newXMin, newXMax = xMin, xMax
+
+ # Makes sure both values stays in positive float32 range
+ if newXMin < FLOAT32_MINPOS or newXMax > FLOAT32_SAFE_MAX:
+ newXMin, newXMax = xMin, xMax
+ else:
+ dx = xData - lastX
+ newXMin, newXMax = xMin - dx, xMax - dx
+
+ # Makes sure both values stays in float32 range
+ if newXMin < FLOAT32_SAFE_MIN or newXMax > FLOAT32_SAFE_MAX:
+ newXMin, newXMax = xMin, xMax
+
+ if self.plot.isYAxisLogarithmic():
+ try:
+ dy = math.log10(yData) - math.log10(lastY)
+ newYMin = pow(10., math.log10(yMin) - dy)
+ newYMax = pow(10., math.log10(yMax) - dy)
+
+ dy2 = math.log10(y2Data) - math.log10(lastY2)
+ newY2Min = pow(10., math.log10(y2Min) - dy2)
+ newY2Max = pow(10., math.log10(y2Max) - dy2)
+ except (ValueError, OverflowError):
+ newYMin, newYMax = yMin, yMax
+ newY2Min, newY2Max = y2Min, y2Max
+
+ # Makes sure y and y2 stays in positive float32 range
+ if (newYMin < FLOAT32_MINPOS or newYMax > FLOAT32_SAFE_MAX or
+ newY2Min < FLOAT32_MINPOS or newY2Max > FLOAT32_SAFE_MAX):
+ newYMin, newYMax = yMin, yMax
+ newY2Min, newY2Max = y2Min, y2Max
+ else:
+ dy = yData - lastY
+ dy2 = y2Data - lastY2
+ newYMin, newYMax = yMin - dy, yMax - dy
+ newY2Min, newY2Max = y2Min - dy2, y2Max - dy2
+
+ # Makes sure y and y2 stays in float32 range
+ if (newYMin < FLOAT32_SAFE_MIN or
+ newYMax > FLOAT32_SAFE_MAX or
+ newY2Min < FLOAT32_SAFE_MIN or
+ newY2Max > FLOAT32_SAFE_MAX):
+ newYMin, newYMax = yMin, yMax
+ newY2Min, newY2Max = y2Min, y2Max
+
+ self.plot.setLimits(newXMin, newXMax,
+ newYMin, newYMax,
+ newY2Min, newY2Max)
+
+ self._previousDataPos = self._pixelToData(x, y)
+
+ def endDrag(self, startPos, endPos):
+ del self._previousDataPos
+
+ def cancel(self):
+ pass
+
+
+# Zoom ########################################################################
+
+class Zoom(_ZoomOnWheel):
+ """Zoom-in/out state machine.
+
+ Zoom-in on selected area, zoom-out on right click,
+ and zoom on mouse wheel.
+ """
+ _DOUBLE_CLICK_TIMEOUT = 0.4
+
+ def __init__(self, plot, color):
+ self.color = color
+ self.zoomStack = []
+ self._lastClick = 0., None
+
+ super(Zoom, self).__init__(plot)
+
+ def _areaWithAspectRatio(self, x0, y0, x1, y1):
+ _plotLeft, _plotTop, plotW, plotH = self.plot.getPlotBoundsInPixels()
+
+ areaX0, areaY0, areaX1, areaY1 = x0, y0, x1, y1
+
+ if plotH != 0.:
+ plotRatio = plotW / float(plotH)
+ width, height = math.fabs(x1 - x0), math.fabs(y1 - y0)
+
+ if height != 0. and width != 0.:
+ if width / height > plotRatio:
+ areaHeight = width / plotRatio
+ areaX0, areaX1 = x0, x1
+ center = 0.5 * (y0 + y1)
+ areaY0 = center - numpy.sign(y1 - y0) * 0.5 * areaHeight
+ areaY1 = center + numpy.sign(y1 - y0) * 0.5 * areaHeight
+ else:
+ areaWidth = height * plotRatio
+ areaY0, areaY1 = y0, y1
+ center = 0.5 * (x0 + x1)
+ areaX0 = center - numpy.sign(x1 - x0) * 0.5 * areaWidth
+ areaX1 = center + numpy.sign(x1 - x0) * 0.5 * areaWidth
+
+ return areaX0, areaY0, areaX1, areaY1
+
+ def click(self, x, y, btn):
+ if btn == LEFT_BTN:
+ lastClickTime, lastClickPos = self._lastClick
+
+ # Signal mouse double clicked event first
+ if (time.time() - lastClickTime) <= self._DOUBLE_CLICK_TIMEOUT:
+ # Use position of first click
+ eventDict = prepareMouseSignal('mouseDoubleClicked', 'left',
+ *lastClickPos)
+ self.plot.notify(**eventDict)
+
+ self._lastClick = 0., None
+ else:
+ # Signal mouse clicked event
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+ eventDict = prepareMouseSignal('mouseClicked', 'left',
+ dataPos[0], dataPos[1],
+ x, y)
+ self.plot.notify(**eventDict)
+
+ self._lastClick = time.time(), (dataPos[0], dataPos[1], x, y)
+
+ # Zoom-in centered on mouse cursor
+ # xMin, xMax = self.plot.getGraphXLimits()
+ # yMin, yMax = self.plot.getGraphYLimits()
+ # y2Min, y2Max = self.plot.getGraphYLimits(axis="right")
+ # self.zoomStack.append((xMin, xMax, yMin, yMax, y2Min, y2Max))
+ # self._zoom(x, y, 2)
+ elif btn == RIGHT_BTN:
+ try:
+ xMin, xMax, yMin, yMax, y2Min, y2Max = self.zoomStack.pop()
+ except IndexError:
+ # Signal mouse clicked event
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+ eventDict = prepareMouseSignal('mouseClicked', 'right',
+ dataPos[0], dataPos[1],
+ x, y)
+ self.plot.notify(**eventDict)
+ else:
+ self.plot.setLimits(xMin, xMax, yMin, yMax, y2Min, y2Max)
+
+ def beginDrag(self, x, y):
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+ self.x0, self.y0 = x, y
+
+ def drag(self, x1, y1):
+ if self.color is None:
+ return # Do not draw zoom area
+
+ dataPos = self.plot.pixelToData(x1, y1)
+ assert dataPos is not None
+
+ if self.plot.isKeepDataAspectRatio():
+ area = self._areaWithAspectRatio(self.x0, self.y0, x1, y1)
+ areaX0, areaY0, areaX1, areaY1 = area
+ areaPoints = ((areaX0, areaY0),
+ (areaX1, areaY0),
+ (areaX1, areaY1),
+ (areaX0, areaY1))
+ areaPoints = numpy.array([self.plot.pixelToData(
+ x, y, check=False) for (x, y) in areaPoints])
+
+ if self.color != 'video inverted':
+ areaColor = list(self.color)
+ areaColor[3] *= 0.25
+ else:
+ areaColor = [1., 1., 1., 1.]
+
+ self.setSelectionArea(areaPoints,
+ fill='none',
+ color=areaColor,
+ name="zoomedArea")
+
+ corners = ((self.x0, self.y0),
+ (self.x0, y1),
+ (x1, y1),
+ (x1, self.y0))
+ corners = numpy.array([self.plot.pixelToData(x, y, check=False)
+ for (x, y) in corners])
+
+ self.setSelectionArea(corners, fill='none', color=self.color)
+
+ def endDrag(self, startPos, endPos):
+ x0, y0 = startPos
+ x1, y1 = endPos
+
+ if x0 != x1 or y0 != y1: # Avoid empty zoom area
+ # Store current zoom state in stack
+ xMin, xMax = self.plot.getGraphXLimits()
+ yMin, yMax = self.plot.getGraphYLimits()
+ y2Min, y2Max = self.plot.getGraphYLimits(axis="right")
+ self.zoomStack.append((xMin, xMax, yMin, yMax, y2Min, y2Max))
+
+ if self.plot.isKeepDataAspectRatio():
+ x0, y0, x1, y1 = self._areaWithAspectRatio(x0, y0, x1, y1)
+
+ # Convert to data space and set limits
+ x0, y0 = self.plot.pixelToData(x0, y0, check=False)
+
+ dataPos = self.plot.pixelToData(
+ startPos[0], startPos[1], axis="right", check=False)
+ y2_0 = dataPos[1]
+
+ x1, y1 = self.plot.pixelToData(x1, y1, check=False)
+
+ dataPos = self.plot.pixelToData(
+ endPos[0], endPos[1], axis="right", check=False)
+ y2_1 = dataPos[1]
+
+ xMin, xMax = min(x0, x1), max(x0, x1)
+ yMin, yMax = min(y0, y1), max(y0, y1)
+ y2Min, y2Max = min(y2_0, y2_1), max(y2_0, y2_1)
+
+ self.plot.setLimits(xMin, xMax, yMin, yMax, y2Min, y2Max)
+
+ self.resetSelectionArea()
+
+ def cancel(self):
+ if isinstance(self.state, self.states['drag']):
+ self.resetSelectionArea()
+
+
+# Select ######################################################################
+
+class Select(StateMachine, _PlotInteraction):
+ """Base class for drawing selection areas."""
+
+ def __init__(self, plot, parameters, states, state):
+ """Init a state machine.
+
+ :param plot: The plot to apply changes to.
+ :param dict parameters: A dict of parameters such as color.
+ :param dict states: The states of the state machine.
+ :param str state: The name of the initial state.
+ """
+ _PlotInteraction.__init__(self, plot)
+ self.parameters = parameters
+ StateMachine.__init__(self, states, state)
+
+ def onWheel(self, x, y, angle):
+ scaleF = 1.1 if angle > 0 else 1. / 1.1
+ applyZoomToPlot(self.plot, scaleF, (x, y))
+
+ @property
+ def color(self):
+ return self.parameters.get('color', None)
+
+
+class SelectPolygon(Select):
+ """Drawing selection polygon area state machine."""
+
+ DRAG_THRESHOLD_DIST = 4
+
+ class Idle(State):
+ def onPress(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.goto('select', x, y)
+ return True
+
+ class Select(State):
+ def enterState(self, x, y):
+ dataPos = self.machine.plot.pixelToData(x, y)
+ assert dataPos is not None
+ self._firstPos = dataPos
+ self.points = [dataPos, dataPos]
+
+ self.updateFirstPoint()
+
+ def updateFirstPoint(self):
+ """Update drawing first point, using self._firstPos"""
+ x, y = self.machine.plot.dataToPixel(*self._firstPos, check=False)
+
+ offset = self.machine.DRAG_THRESHOLD_DIST
+ points = [(x - offset, y - offset),
+ (x - offset, y + offset),
+ (x + offset, y + offset),
+ (x + offset, y - offset)]
+ points = [self.machine.plot.pixelToData(xpix, ypix, check=False)
+ for xpix, ypix in points]
+ self.machine.setSelectionArea(points, fill=None,
+ color=self.machine.color,
+ name='first_point')
+
+ def updateSelectionArea(self):
+ """Update drawing selection area using self.points"""
+ self.machine.setSelectionArea(self.points,
+ fill='hatch',
+ color=self.machine.color)
+ eventDict = prepareDrawingSignal('drawingProgress',
+ 'polygon',
+ self.points,
+ self.machine.parameters)
+ self.machine.plot.notify(**eventDict)
+
+ def onWheel(self, x, y, angle):
+ self.machine.onWheel(x, y, angle)
+ self.updateFirstPoint()
+
+ def onRelease(self, x, y, btn):
+ if btn == LEFT_BTN:
+ # checking if the position is close to the first point
+ # if yes : closing the "loop"
+ firstPos = self.machine.plot.dataToPixel(*self._firstPos,
+ check=False)
+ dx, dy = abs(firstPos[0] - x), abs(firstPos[1] - y)
+
+ # Only allow to close polygon after first point
+ if (len(self.points) > 2 and
+ dx < self.machine.DRAG_THRESHOLD_DIST and
+ dy < self.machine.DRAG_THRESHOLD_DIST):
+ self.machine.resetSelectionArea()
+
+ self.points[-1] = self.points[0]
+
+ eventDict = prepareDrawingSignal('drawingFinished',
+ 'polygon',
+ self.points,
+ self.machine.parameters)
+ self.machine.plot.notify(**eventDict)
+ self.goto('idle')
+ return False
+
+ # Update polygon last point not too close to previous one
+ dataPos = self.machine.plot.pixelToData(x, y)
+ assert dataPos is not None
+ self.updateSelectionArea()
+
+ # checking that the new points isnt the same (within range)
+ # of the previous one
+ # This has to be done because sometimes the mouse release event
+ # is caught right after entering the Select state (i.e : press
+ # in Idle state, but with a slightly different position that
+ # the mouse press. So we had the two first vertices that were
+ # almost identical.
+ previousPos = self.machine.plot.dataToPixel(*self.points[-2],
+ check=False)
+ dx, dy = abs(previousPos[0] - x), abs(previousPos[1] - y)
+ if(dx >= self.machine.DRAG_THRESHOLD_DIST or
+ dy >= self.machine.DRAG_THRESHOLD_DIST):
+ self.points.append(dataPos)
+ else:
+ self.points[-1] = dataPos
+
+ return True
+
+ elif btn == RIGHT_BTN:
+ self.machine.resetSelectionArea()
+
+ firstPos = self.machine.plot.dataToPixel(*self._firstPos,
+ check=False)
+ dx, dy = abs(firstPos[0] - x), abs(firstPos[1] - y)
+
+ if (dx < self.machine.DRAG_THRESHOLD_DIST and
+ dy < self.machine.DRAG_THRESHOLD_DIST):
+ self.points[-1] = self.points[0]
+ else:
+ dataPos = self.machine.plot.pixelToData(x, y)
+ assert dataPos is not None
+ self.points[-1] = dataPos
+ if self.points[-2] == self.points[-1]:
+ self.points.pop()
+ self.points.append(self.points[0])
+
+ eventDict = prepareDrawingSignal('drawingFinished',
+ 'polygon',
+ self.points,
+ self.machine.parameters)
+ self.machine.plot.notify(**eventDict)
+ self.goto('idle')
+ return False
+
+ return False
+
+ def onMove(self, x, y):
+ firstPos = self.machine.plot.dataToPixel(*self._firstPos,
+ check=False)
+ dx, dy = abs(firstPos[0] - x), abs(firstPos[1] - y)
+ if (dx < self.machine.DRAG_THRESHOLD_DIST and
+ dy < self.machine.DRAG_THRESHOLD_DIST):
+ x, y = firstPos # Snap to first point
+
+ dataPos = self.machine.plot.pixelToData(x, y)
+ assert dataPos is not None
+ self.points[-1] = dataPos
+ self.updateSelectionArea()
+
+ def __init__(self, plot, parameters):
+ states = {
+ 'idle': SelectPolygon.Idle,
+ 'select': SelectPolygon.Select
+ }
+ super(SelectPolygon, self).__init__(plot, parameters,
+ states, 'idle')
+
+ def cancel(self):
+ if isinstance(self.state, self.states['select']):
+ self.resetSelectionArea()
+
+
+class Select2Points(Select):
+ """Base class for drawing selection based on 2 input points."""
+ class Idle(State):
+ def onPress(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.goto('start', x, y)
+ return True
+
+ class Start(State):
+ def enterState(self, x, y):
+ self.machine.beginSelect(x, y)
+
+ def onMove(self, x, y):
+ self.goto('select', x, y)
+
+ def onRelease(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.goto('select', x, y)
+ return True
+
+ class Select(State):
+ def enterState(self, x, y):
+ self.onMove(x, y)
+
+ def onMove(self, x, y):
+ self.machine.select(x, y)
+
+ def onRelease(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.machine.endSelect(x, y)
+ self.goto('idle')
+
+ def __init__(self, plot, parameters):
+ states = {
+ 'idle': Select2Points.Idle,
+ 'start': Select2Points.Start,
+ 'select': Select2Points.Select
+ }
+ super(Select2Points, self).__init__(plot, parameters,
+ states, 'idle')
+
+ def beginSelect(self, x, y):
+ pass
+
+ def select(self, x, y):
+ pass
+
+ def endSelect(self, x, y):
+ pass
+
+ def cancelSelect(self):
+ pass
+
+ def cancel(self):
+ if isinstance(self.state, self.states['select']):
+ self.cancelSelect()
+
+
+class SelectRectangle(Select2Points):
+ """Drawing rectangle selection area state machine."""
+ def beginSelect(self, x, y):
+ self.startPt = self.plot.pixelToData(x, y)
+ assert self.startPt is not None
+
+ def select(self, x, y):
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+
+ self.setSelectionArea((self.startPt,
+ (self.startPt[0], dataPos[1]),
+ dataPos,
+ (dataPos[0], self.startPt[1])),
+ fill='hatch',
+ color=self.color)
+
+ eventDict = prepareDrawingSignal('drawingProgress',
+ 'rectangle',
+ (self.startPt, dataPos),
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ def endSelect(self, x, y):
+ self.resetSelectionArea()
+
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+
+ eventDict = prepareDrawingSignal('drawingFinished',
+ 'rectangle',
+ (self.startPt, dataPos),
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ def cancelSelect(self):
+ self.resetSelectionArea()
+
+
+class SelectLine(Select2Points):
+ """Drawing line selection area state machine."""
+ def beginSelect(self, x, y):
+ self.startPt = self.plot.pixelToData(x, y)
+ assert self.startPt is not None
+
+ def select(self, x, y):
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+
+ self.setSelectionArea((self.startPt, dataPos),
+ fill='hatch',
+ color=self.color)
+
+ eventDict = prepareDrawingSignal('drawingProgress',
+ 'line',
+ (self.startPt, dataPos),
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ def endSelect(self, x, y):
+ self.resetSelectionArea()
+
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+
+ eventDict = prepareDrawingSignal('drawingFinished',
+ 'line',
+ (self.startPt, dataPos),
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ def cancelSelect(self):
+ self.resetSelectionArea()
+
+
+class Select1Point(Select):
+ """Base class for drawing selection area based on one input point."""
+ class Idle(State):
+ def onPress(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.goto('select', x, y)
+ return True
+
+ class Select(State):
+ def enterState(self, x, y):
+ self.onMove(x, y)
+
+ def onMove(self, x, y):
+ self.machine.select(x, y)
+
+ def onRelease(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.machine.endSelect(x, y)
+ self.goto('idle')
+
+ def onWheel(self, x, y, angle):
+ self.machine.onWheel(x, y, angle) # Call select default wheel
+ self.machine.select(x, y)
+
+ def __init__(self, plot, parameters):
+ states = {
+ 'idle': Select1Point.Idle,
+ 'select': Select1Point.Select
+ }
+ super(Select1Point, self).__init__(plot, parameters, states, 'idle')
+
+ def select(self, x, y):
+ pass
+
+ def endSelect(self, x, y):
+ pass
+
+ def cancelSelect(self):
+ pass
+
+ def cancel(self):
+ if isinstance(self.state, self.states['select']):
+ self.cancelSelect()
+
+
+class SelectHLine(Select1Point):
+ """Drawing a horizontal line selection area state machine."""
+ def _hLine(self, y):
+ """Return points in data coords of the segment visible in the plot.
+
+ Supports non-orthogonal axes.
+ """
+ left, _top, width, _height = self.plot.getPlotBoundsInPixels()
+
+ dataPos1 = self.plot.pixelToData(left, y, check=False)
+ dataPos2 = self.plot.pixelToData(left + width, y, check=False)
+ return dataPos1, dataPos2
+
+ def select(self, x, y):
+ points = self._hLine(y)
+ self.setSelectionArea(points, fill='hatch', color=self.color)
+
+ eventDict = prepareDrawingSignal('drawingProgress',
+ 'hline',
+ points,
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ def endSelect(self, x, y):
+ self.resetSelectionArea()
+
+ eventDict = prepareDrawingSignal('drawingFinished',
+ 'hline',
+ self._hLine(y),
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ def cancelSelect(self):
+ self.resetSelectionArea()
+
+
+class SelectVLine(Select1Point):
+ """Drawing a vertical line selection area state machine."""
+ def _vLine(self, x):
+ """Return points in data coords of the segment visible in the plot.
+
+ Supports non-orthogonal axes.
+ """
+ _left, top, _width, height = self.plot.getPlotBoundsInPixels()
+
+ dataPos1 = self.plot.pixelToData(x, top, check=False)
+ dataPos2 = self.plot.pixelToData(x, top + height, check=False)
+ return dataPos1, dataPos2
+
+ def select(self, x, y):
+ points = self._vLine(x)
+ self.setSelectionArea(points, fill='hatch', color=self.color)
+
+ eventDict = prepareDrawingSignal('drawingProgress',
+ 'vline',
+ points,
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ def endSelect(self, x, y):
+ self.resetSelectionArea()
+
+ eventDict = prepareDrawingSignal('drawingFinished',
+ 'vline',
+ self._vLine(x),
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ def cancelSelect(self):
+ self.resetSelectionArea()
+
+
+class DrawFreeHand(Select):
+ """Interaction for drawing pencil. It display the preview of the pencil
+ before pressing the mouse.
+ """
+
+ class Idle(State):
+ def onPress(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self.goto('select', x, y)
+ return True
+
+ def onMove(self, x, y):
+ self.machine.updatePencilShape(x, y)
+
+ def onLeave(self):
+ self.machine.cancel()
+
+ class Select(State):
+ def enterState(self, x, y):
+ self.__isOut = False
+ self.machine.setFirstPoint(x, y)
+
+ def onMove(self, x, y):
+ self.machine.updatePencilShape(x, y)
+ self.machine.select(x, y)
+
+ def onRelease(self, x, y, btn):
+ if btn == LEFT_BTN:
+ if self.__isOut:
+ self.machine.resetSelectionArea()
+ self.machine.endSelect(x, y)
+ self.goto('idle')
+
+ def onEnter(self):
+ self.__isOut = False
+
+ def onLeave(self):
+ self.__isOut = True
+
+ def __init__(self, plot, parameters):
+ # Circle used for pencil preview
+ angle = numpy.arange(13.) * numpy.pi * 2.0 / 13.
+ size = parameters.get('width', 1.) * 0.5
+ self._circle = size * numpy.array((numpy.cos(angle),
+ numpy.sin(angle))).T
+
+ states = {
+ 'idle': DrawFreeHand.Idle,
+ 'select': DrawFreeHand.Select
+ }
+ super(DrawFreeHand, self).__init__(plot, parameters, states, 'idle')
+
+ @property
+ def width(self):
+ return self.parameters.get('width', None)
+
+ def setFirstPoint(self, x, y):
+ self._points = []
+ self.select(x, y)
+
+ def updatePencilShape(self, x, y):
+ center = self.plot.pixelToData(x, y, check=False)
+ assert center is not None
+
+ polygon = center + self._circle
+
+ self.setSelectionArea(polygon, fill='none', color=self.color)
+
+ def select(self, x, y):
+ pos = self.plot.pixelToData(x, y, check=False)
+ if len(self._points) > 0:
+ if self._points[-1] == pos:
+ # Skip same points
+ return
+ self._points.append(pos)
+ eventDict = prepareDrawingSignal('drawingProgress',
+ 'polylines',
+ self._points,
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ def endSelect(self, x, y):
+ pos = self.plot.pixelToData(x, y, check=False)
+ if len(self._points) > 0:
+ if self._points[-1] != pos:
+ # Append if different
+ self._points.append(pos)
+
+ eventDict = prepareDrawingSignal('drawingFinished',
+ 'polylines',
+ self._points,
+ self.parameters)
+ self.plot.notify(**eventDict)
+ self._points = None
+
+ def cancelSelect(self):
+ self.resetSelectionArea()
+
+ def cancel(self):
+ self.resetSelectionArea()
+
+
+class SelectFreeLine(ClickOrDrag, _PlotInteraction):
+ """Base class for drawing free lines with tools such as pencil."""
+
+ def __init__(self, plot, parameters):
+ """Init a state machine.
+
+ :param plot: The plot to apply changes to.
+ :param dict parameters: A dict of parameters such as color.
+ """
+ # self.DRAG_THRESHOLD_SQUARE_DIST = 1 # Disable first move threshold
+ self._points = []
+ ClickOrDrag.__init__(self)
+ _PlotInteraction.__init__(self, plot)
+ self.parameters = parameters
+
+ def onWheel(self, x, y, angle):
+ scaleF = 1.1 if angle > 0 else 1. / 1.1
+ applyZoomToPlot(self.plot, scaleF, (x, y))
+
+ @property
+ def color(self):
+ return self.parameters.get('color', None)
+
+ def click(self, x, y, btn):
+ if btn == LEFT_BTN:
+ self._processEvent(x, y, isLast=True)
+
+ def beginDrag(self, x, y):
+ self._processEvent(x, y, isLast=False)
+
+ def drag(self, x, y):
+ self._processEvent(x, y, isLast=False)
+
+ def endDrag(self, startPos, endPos):
+ x, y = endPos
+ self._processEvent(x, y, isLast=True)
+
+ def cancel(self):
+ self.resetSelectionArea()
+ self._points = []
+
+ def _processEvent(self, x, y, isLast):
+ dataPos = self.plot.pixelToData(x, y, check=False)
+ isNewPoint = not self._points or dataPos != self._points[-1]
+
+ if isNewPoint:
+ self._points.append(dataPos)
+
+ if isNewPoint or isLast:
+ eventDict = prepareDrawingSignal(
+ 'drawingFinished' if isLast else 'drawingProgress',
+ 'polylines',
+ self._points,
+ self.parameters)
+ self.plot.notify(**eventDict)
+
+ if not isLast:
+ self.setSelectionArea(self._points, fill='none', color=self.color,
+ shape='polylines')
+ else:
+ self.cancel()
+
+
+# ItemInteraction #############################################################
+
+class ItemsInteraction(ClickOrDrag, _PlotInteraction):
+ """Interaction with items (markers, curves and images).
+
+ This class provides selection and dragging of plot primitives
+ that support those interaction.
+ It is also meant to be combined with the zoom interaction.
+ """
+
+ class Idle(ClickOrDrag.Idle):
+ def __init__(self, *args, **kw):
+ super(ItemsInteraction.Idle, self).__init__(*args, **kw)
+ self._hoverMarker = None
+
+ def onWheel(self, x, y, angle):
+ scaleF = 1.1 if angle > 0 else 1. / 1.1
+ applyZoomToPlot(self.machine.plot, scaleF, (x, y))
+
+ def onMove(self, x, y):
+ marker = self.machine.plot._pickMarker(x, y)
+ if marker is not None:
+ dataPos = self.machine.plot.pixelToData(x, y)
+ assert dataPos is not None
+ eventDict = prepareHoverSignal(
+ marker.getLegend(), 'marker',
+ dataPos, (x, y),
+ marker.isDraggable(),
+ marker.isSelectable())
+ self.machine.plot.notify(**eventDict)
+
+ if marker != self._hoverMarker:
+ self._hoverMarker = marker
+
+ if marker is None:
+ self.machine.plot.setGraphCursorShape()
+
+ elif marker.isDraggable():
+ if isinstance(marker, items.YMarker):
+ self.machine.plot.setGraphCursorShape(CURSOR_SIZE_VER)
+ elif isinstance(marker, items.XMarker):
+ self.machine.plot.setGraphCursorShape(CURSOR_SIZE_HOR)
+ else:
+ self.machine.plot.setGraphCursorShape(CURSOR_SIZE_ALL)
+
+ elif marker.isSelectable():
+ self.machine.plot.setGraphCursorShape(CURSOR_POINTING)
+
+ return True
+
+ def __init__(self, plot):
+ _PlotInteraction.__init__(self, plot)
+
+ states = {
+ 'idle': ItemsInteraction.Idle,
+ 'rightClick': ClickOrDrag.RightClick,
+ 'clickOrDrag': ClickOrDrag.ClickOrDrag,
+ 'drag': ClickOrDrag.Drag
+ }
+ StateMachine.__init__(self, states, 'idle')
+
+ def click(self, x, y, btn):
+ """Handle mouse click
+
+ :param x: X position of the mouse in pixels
+ :param y: Y position of the mouse in pixels
+ :param btn: Pressed button id
+ :return: True if click is catched by an item, False otherwise
+ """
+ # Signal mouse clicked event
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+ eventDict = prepareMouseSignal('mouseClicked', btn,
+ dataPos[0], dataPos[1],
+ x, y)
+ self.plot.notify(**eventDict)
+
+ eventDict = self._handleClick(x, y, btn)
+ if eventDict is not None:
+ self.plot.notify(**eventDict)
+
+ def _handleClick(self, x, y, btn):
+ """Perform picking and prepare event if click is handled here
+
+ :param x: X position of the mouse in pixels
+ :param y: Y position of the mouse in pixels
+ :param btn: Pressed button id
+ :return: event description to send of None if not handling event.
+ :rtype: dict or None
+ """
+
+ if btn == LEFT_BTN:
+ marker = self.plot._pickMarker(
+ x, y, lambda m: m.isSelectable())
+ if marker is not None:
+ xData, yData = marker.getPosition()
+ if xData is None:
+ xData = [0, 1]
+ if yData is None:
+ yData = [0, 1]
+
+ eventDict = prepareMarkerSignal('markerClicked',
+ 'left',
+ marker.getLegend(),
+ 'marker',
+ marker.isDraggable(),
+ marker.isSelectable(),
+ (xData, yData),
+ (x, y), None)
+ return eventDict
+
+ else:
+ picked = self.plot._pickImageOrCurve(
+ x, y, lambda item: item.isSelectable())
+
+ if picked is None:
+ pass
+
+ elif picked[0] == 'curve':
+ curve = picked[1]
+
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+
+ eventDict = prepareCurveSignal('left',
+ curve.getLegend(),
+ 'curve',
+ picked[2], picked[3],
+ dataPos[0], dataPos[1],
+ x, y)
+ return eventDict
+
+ elif picked[0] == 'image':
+ image = picked[1]
+
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+
+ # Get corresponding coordinate in image
+ origin = image.getOrigin()
+ scale = image.getScale()
+ column = int((dataPos[0] - origin[0]) / float(scale[0]))
+ row = int((dataPos[1] - origin[1]) / float(scale[1]))
+
+ eventDict = prepareImageSignal('left',
+ image.getLegend(),
+ 'image',
+ column, row,
+ dataPos[0], dataPos[1],
+ x, y)
+ return eventDict
+
+ return None
+
+ def _signalMarkerMovingEvent(self, eventType, marker, x, y):
+ assert marker is not None
+
+ xData, yData = marker.getPosition()
+ if xData is None:
+ xData = [0, 1]
+ if yData is None:
+ yData = [0, 1]
+
+ posDataCursor = self.plot.pixelToData(x, y)
+ assert posDataCursor is not None
+
+ eventDict = prepareMarkerSignal(eventType,
+ 'left',
+ marker.getLegend(),
+ 'marker',
+ marker.isDraggable(),
+ marker.isSelectable(),
+ (xData, yData),
+ (x, y),
+ posDataCursor)
+ self.plot.notify(**eventDict)
+
+ def beginDrag(self, x, y):
+ """Handle begining of drag interaction
+
+ :param x: X position of the mouse in pixels
+ :param y: Y position of the mouse in pixels
+ :return: True if drag is catched by an item, False otherwise
+ """
+ self._lastPos = self.plot.pixelToData(x, y)
+ assert self._lastPos is not None
+
+ self.imageLegend = None
+ self.markerLegend = None
+ marker = self.plot._pickMarker(
+ x, y, lambda m: m.isDraggable())
+
+ if marker is not None:
+ self.markerLegend = marker.getLegend()
+ self._signalMarkerMovingEvent('markerMoving', marker, x, y)
+ else:
+ picked = self.plot._pickImageOrCurve(
+ x,
+ y,
+ lambda item:
+ hasattr(item, 'isDraggable') and item.isDraggable())
+ if picked is None:
+ self.imageLegend = None
+ self.plot.setGraphCursorShape()
+ return False
+ else:
+ assert picked[0] == 'image' # For now only drag images
+ self.imageLegend = picked[1].getLegend()
+ return True
+
+ def drag(self, x, y):
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+ xData, yData = dataPos
+
+ if self.markerLegend is not None:
+ marker = self.plot._getMarker(self.markerLegend)
+ if marker is not None:
+ marker.setPosition(xData, yData)
+
+ self._signalMarkerMovingEvent(
+ 'markerMoving', marker, x, y)
+
+ if self.imageLegend is not None:
+ image = self.plot.getImage(self.imageLegend)
+ origin = image.getOrigin()
+ xImage = origin[0] + xData - self._lastPos[0]
+ yImage = origin[1] + yData - self._lastPos[1]
+ image.setOrigin((xImage, yImage))
+
+ self._lastPos = xData, yData
+
+ def endDrag(self, startPos, endPos):
+ if self.markerLegend is not None:
+ marker = self.plot._getMarker(self.markerLegend)
+ posData = list(marker.getPosition())
+ if posData[0] is None:
+ posData[0] = [0, 1]
+ if posData[1] is None:
+ posData[1] = [0, 1]
+
+ eventDict = prepareMarkerSignal(
+ 'markerMoved',
+ 'left',
+ marker.getLegend(),
+ 'marker',
+ marker.isDraggable(),
+ marker.isSelectable(),
+ posData)
+ self.plot.notify(**eventDict)
+
+ self.plot.setGraphCursorShape()
+
+ del self.markerLegend
+ del self.imageLegend
+ del self._lastPos
+
+ def cancel(self):
+ self.plot.setGraphCursorShape()
+
+
+# FocusManager ################################################################
+
+class FocusManager(StateMachine):
+ """Manages focus across multiple event handlers
+
+ On press an event handler can acquire focus.
+ By default it looses focus when all buttons are released.
+ """
+ class Idle(State):
+ def onPress(self, x, y, btn):
+ for eventHandler in self.machine.eventHandlers:
+ requestFocus = eventHandler.handleEvent('press', x, y, btn)
+ if requestFocus:
+ self.goto('focus', eventHandler, btn)
+ break
+
+ def _processEvent(self, *args):
+ for eventHandler in self.machine.eventHandlers:
+ consumeEvent = eventHandler.handleEvent(*args)
+ if consumeEvent:
+ break
+
+ def onMove(self, x, y):
+ self._processEvent('move', x, y)
+
+ def onRelease(self, x, y, btn):
+ self._processEvent('release', x, y, btn)
+
+ def onWheel(self, x, y, angle):
+ self._processEvent('wheel', x, y, angle)
+
+ class Focus(State):
+ def enterState(self, eventHandler, btn):
+ self.eventHandler = eventHandler
+ self.focusBtns = {btn}
+
+ def onPress(self, x, y, btn):
+ self.focusBtns.add(btn)
+ self.eventHandler.handleEvent('press', x, y, btn)
+
+ def onMove(self, x, y):
+ self.eventHandler.handleEvent('move', x, y)
+
+ def onRelease(self, x, y, btn):
+ self.focusBtns.discard(btn)
+ requestFocus = self.eventHandler.handleEvent('release', x, y, btn)
+ if len(self.focusBtns) == 0 and not requestFocus:
+ self.goto('idle')
+
+ def onWheel(self, x, y, angleInDegrees):
+ self.eventHandler.handleEvent('wheel', x, y, angleInDegrees)
+
+ def __init__(self, eventHandlers=()):
+ self.eventHandlers = list(eventHandlers)
+
+ states = {
+ 'idle': FocusManager.Idle,
+ 'focus': FocusManager.Focus
+ }
+ super(FocusManager, self).__init__(states, 'idle')
+
+ def cancel(self):
+ for handler in self.eventHandlers:
+ handler.cancel()
+
+
+class ZoomAndSelect(ItemsInteraction):
+ """Combine Zoom and ItemInteraction state machine.
+
+ :param plot: The Plot to which this interaction is attached
+ :param color: The color to use for the zoom area bounding box
+ """
+
+ def __init__(self, plot, color):
+ super(ZoomAndSelect, self).__init__(plot)
+ self._zoom = Zoom(plot, color)
+ self._doZoom = False
+
+ @property
+ def color(self):
+ """Color of the zoom area"""
+ return self._zoom.color
+
+ def click(self, x, y, btn):
+ """Handle mouse click
+
+ :param x: X position of the mouse in pixels
+ :param y: Y position of the mouse in pixels
+ :param btn: Pressed button id
+ :return: True if click is catched by an item, False otherwise
+ """
+ eventDict = self._handleClick(x, y, btn)
+
+ if eventDict is not None:
+ # Signal mouse clicked event
+ dataPos = self.plot.pixelToData(x, y)
+ assert dataPos is not None
+ clickedEventDict = prepareMouseSignal('mouseClicked', btn,
+ dataPos[0], dataPos[1],
+ x, y)
+ self.plot.notify(**clickedEventDict)
+
+ self.plot.notify(**eventDict)
+
+ else:
+ self._zoom.click(x, y, btn)
+
+ def beginDrag(self, x, y):
+ """Handle start drag and switching between zoom and item drag.
+
+ :param x: X position in pixels
+ :param y: Y position in pixels
+ """
+ self._doZoom = not super(ZoomAndSelect, self).beginDrag(x, y)
+ if self._doZoom:
+ self._zoom.beginDrag(x, y)
+
+ def drag(self, x, y):
+ """Handle drag, eventually forwarding to zoom.
+
+ :param x: X position in pixels
+ :param y: Y position in pixels
+ """
+ if self._doZoom:
+ return self._zoom.drag(x, y)
+ else:
+ return super(ZoomAndSelect, self).drag(x, y)
+
+ def endDrag(self, startPos, endPos):
+ """Handle end of drag, eventually forwarding to zoom.
+
+ :param startPos: (x, y) position at the beginning of the drag
+ :param endPos: (x, y) position at the end of the drag
+ """
+ if self._doZoom:
+ return self._zoom.endDrag(startPos, endPos)
+ else:
+ return super(ZoomAndSelect, self).endDrag(startPos, endPos)
+
+
+# Interaction mode control ####################################################
+
+class PlotInteraction(object):
+ """Proxy to currently use state machine for interaction.
+
+ This allows to switch interactive mode.
+
+ :param plot: The :class:`Plot` to apply interaction to
+ """
+
+ _DRAW_MODES = {
+ 'polygon': SelectPolygon,
+ 'rectangle': SelectRectangle,
+ 'line': SelectLine,
+ 'vline': SelectVLine,
+ 'hline': SelectHLine,
+ 'polylines': SelectFreeLine,
+ 'pencil': DrawFreeHand,
+ }
+
+ def __init__(self, plot):
+ self._plot = weakref.ref(plot) # Avoid cyclic-ref
+
+ self.zoomOnWheel = True
+ """True to enable zoom on wheel, False otherwise."""
+
+ # Default event handler
+ self._eventHandler = ItemsInteraction(plot)
+
+ def getInteractiveMode(self):
+ """Returns the current interactive mode as a dict.
+
+ The returned dict contains at least the key 'mode'.
+ Mode can be: 'draw', 'pan', 'select', 'zoom'.
+ It can also contains extra keys (e.g., 'color') specific to a mode
+ as provided to :meth:`setInteractiveMode`.
+ """
+ if isinstance(self._eventHandler, ZoomAndSelect):
+ return {'mode': 'zoom', 'color': self._eventHandler.color}
+
+ elif isinstance(self._eventHandler, Select):
+ result = self._eventHandler.parameters.copy()
+ result['mode'] = 'draw'
+ return result
+
+ elif isinstance(self._eventHandler, Pan):
+ return {'mode': 'pan'}
+
+ else:
+ return {'mode': 'select'}
+
+ def setInteractiveMode(self, mode, color='black',
+ shape='polygon', label=None, width=None):
+ """Switch the interactive mode.
+
+ :param str mode: The name of the interactive mode.
+ In 'draw', 'pan', 'select', 'zoom'.
+ :param color: Only for 'draw' and 'zoom' modes.
+ Color to use for drawing selection area. Default black.
+ If None, selection area is not drawn.
+ :type color: Color description: The name as a str or
+ a tuple of 4 floats or None.
+ :param str shape: Only for 'draw' mode. The kind of shape to draw.
+ In 'polygon', 'rectangle', 'line', 'vline', 'hline',
+ 'polylines'.
+ Default is 'polygon'.
+ :param str label: Only for 'draw' mode.
+ :param float width: Width of the pencil. Only for draw pencil mode.
+ """
+ assert mode in ('draw', 'pan', 'select', 'zoom')
+
+ plot = self._plot()
+ assert plot is not None
+
+ if color not in (None, 'video inverted'):
+ color = Colors.rgba(color)
+
+ if mode == 'draw':
+ assert shape in self._DRAW_MODES
+ eventHandlerClass = self._DRAW_MODES[shape]
+ parameters = {
+ 'shape': shape,
+ 'label': label,
+ 'color': color,
+ 'width': width,
+ }
+
+ self._eventHandler.cancel()
+ self._eventHandler = eventHandlerClass(plot, parameters)
+
+ elif mode == 'pan':
+ # Ignores color, shape and label
+ self._eventHandler.cancel()
+ self._eventHandler = Pan(plot)
+
+ elif mode == 'zoom':
+ # Ignores shape and label
+ self._eventHandler.cancel()
+ self._eventHandler = ZoomAndSelect(plot, color)
+
+ else: # Default mode: interaction with plot objects
+ # Ignores color, shape and label
+ self._eventHandler.cancel()
+ self._eventHandler = ItemsInteraction(plot)
+
+ def handleEvent(self, event, *args, **kwargs):
+ """Forward event to current interactive mode state machine."""
+ if not self.zoomOnWheel and event == 'wheel':
+ return # Discard wheel events
+ self._eventHandler.handleEvent(event, *args, **kwargs)
diff --git a/silx/gui/plot/PlotToolButtons.py b/silx/gui/plot/PlotToolButtons.py
new file mode 100644
index 0000000..8042391
--- /dev/null
+++ b/silx/gui/plot/PlotToolButtons.py
@@ -0,0 +1,280 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a set of QToolButton to use with :class:`.PlotWidget`.
+
+The following QToolButton are available:
+
+- :class:`AspectToolButton`
+- :class:`YAxisOriginToolButton`
+- :class:`ProfileToolButton`
+
+"""
+
+__authors__ = ["V. Valls", "H. Payno"]
+__license__ = "MIT"
+__date__ = "26/01/2017"
+
+
+import logging
+from .. import icons
+from .. import qt
+
+
+_logger = logging.getLogger(__name__)
+
+
+class PlotToolButton(qt.QToolButton):
+ """A QToolButton connected to a :class:`.PlotWidget`.
+ """
+
+ def __init__(self, parent=None, plot=None):
+ super(PlotToolButton, self).__init__(parent)
+ self._plot = None
+ if plot is not None:
+ self.setPlot(plot)
+
+ def plot(self):
+ """
+ Returns the plot connected to the widget.
+ """
+ return self._plot
+
+ def setPlot(self, plot):
+ """
+ Set the plot connected to the widget
+
+ :param plot: :class:`.PlotWidget` instance on which to operate.
+ """
+ if self._plot is plot:
+ return
+ if self._plot is not None:
+ self._disconnectPlot(self._plot)
+ self._plot = plot
+ if self._plot is not None:
+ self._connectPlot(self._plot)
+
+ def _connectPlot(self, plot):
+ """
+ Called when the plot is connected to the widget
+
+ :param plot: :class:`.PlotWidget` instance
+ """
+ pass
+
+ def _disconnectPlot(self, plot):
+ """
+ Called when the plot is disconnected from the widget
+
+ :param plot: :class:`.PlotWidget` instance
+ """
+ pass
+
+
+class AspectToolButton(PlotToolButton):
+
+ STATE = None
+ """Lazy loaded states used to feed AspectToolButton"""
+
+ def __init__(self, parent=None, plot=None):
+ if self.STATE is None:
+ self.STATE = {}
+ # dont keep ratio
+ self.STATE[False, "icon"] = icons.getQIcon('shape-ellipse-solid')
+ self.STATE[False, "state"] = "Aspect ratio is not kept"
+ self.STATE[False, "action"] = "Do no keep data aspect ratio"
+ # keep ratio
+ self.STATE[True, "icon"] = icons.getQIcon('shape-circle-solid')
+ self.STATE[True, "state"] = "Aspect ratio is kept"
+ self.STATE[True, "action"] = "Keep data aspect ratio"
+
+ super(AspectToolButton, self).__init__(parent=parent, plot=plot)
+
+ keepAction = self._createAction(True)
+ keepAction.triggered.connect(self.keepDataAspectRatio)
+ keepAction.setIconVisibleInMenu(True)
+
+ dontKeepAction = self._createAction(False)
+ dontKeepAction.triggered.connect(self.dontKeepDataAspectRatio)
+ dontKeepAction.setIconVisibleInMenu(True)
+
+ menu = qt.QMenu(self)
+ menu.addAction(keepAction)
+ menu.addAction(dontKeepAction)
+ self.setMenu(menu)
+ self.setPopupMode(qt.QToolButton.InstantPopup)
+
+ def _createAction(self, keepAspectRatio):
+ icon = self.STATE[keepAspectRatio, "icon"]
+ text = self.STATE[keepAspectRatio, "action"]
+ return qt.QAction(icon, text, self)
+
+ def _connectPlot(self, plot):
+ plot.sigSetKeepDataAspectRatio.connect(self._keepDataAspectRatioChanged)
+ self._keepDataAspectRatioChanged(plot.isKeepDataAspectRatio())
+
+ def _disconnectPlot(self, plot):
+ plot.sigSetKeepDataAspectRatio.disconnect(self._keepDataAspectRatioChanged)
+
+ def keepDataAspectRatio(self):
+ """Configure the plot to keep the aspect ratio"""
+ plot = self.plot()
+ if plot is not None:
+ # This will trigger _keepDataAspectRatioChanged
+ plot.setKeepDataAspectRatio(True)
+
+ def dontKeepDataAspectRatio(self):
+ """Configure the plot to not keep the aspect ratio"""
+ plot = self.plot()
+ if plot is not None:
+ # This will trigger _keepDataAspectRatioChanged
+ plot.setKeepDataAspectRatio(False)
+
+ def _keepDataAspectRatioChanged(self, aspectRatio):
+ """Handle Plot set keep aspect ratio signal"""
+ icon, toolTip = self.STATE[aspectRatio, "icon"], self.STATE[aspectRatio, "state"]
+ self.setIcon(icon)
+ self.setToolTip(toolTip)
+
+
+class YAxisOriginToolButton(PlotToolButton):
+
+ STATE = None
+ """Lazy loaded states used to feed YAxisOriginToolButton"""
+
+ def __init__(self, parent=None, plot=None):
+ if self.STATE is None:
+ self.STATE = {}
+ # is down
+ self.STATE[False, "icon"] = icons.getQIcon('plot-ydown')
+ self.STATE[False, "state"] = "Y-axis is oriented downward"
+ self.STATE[False, "action"] = "Orient Y-axis downward"
+ # keep ration
+ self.STATE[True, "icon"] = icons.getQIcon('plot-yup')
+ self.STATE[True, "state"] = "Y-axis is oriented upward"
+ self.STATE[True, "action"] = "Orient Y-axis upward"
+
+ super(YAxisOriginToolButton, self).__init__(parent=parent, plot=plot)
+
+ upwardAction = self._createAction(True)
+ upwardAction.triggered.connect(self.setYAxisUpward)
+ upwardAction.setIconVisibleInMenu(True)
+
+ downwardAction = self._createAction(False)
+ downwardAction.triggered.connect(self.setYAxisDownward)
+ downwardAction.setIconVisibleInMenu(True)
+
+ menu = qt.QMenu(self)
+ menu.addAction(upwardAction)
+ menu.addAction(downwardAction)
+ self.setMenu(menu)
+ self.setPopupMode(qt.QToolButton.InstantPopup)
+
+ def _createAction(self, isUpward):
+ icon = self.STATE[isUpward, "icon"]
+ text = self.STATE[isUpward, "action"]
+ return qt.QAction(icon, text, self)
+
+ def _connectPlot(self, plot):
+ plot.sigSetYAxisInverted.connect(self._yAxisInvertedChanged)
+ self._yAxisInvertedChanged(plot.isYAxisInverted())
+
+ def _disconnectPlot(self, plot):
+ plot.sigSetYAxisInverted.disconnect(self._yAxisInvertedChanged)
+
+ def setYAxisUpward(self):
+ """Configure the plot to use y-axis upward"""
+ plot = self.plot()
+ if plot is not None:
+ # This will trigger _yAxisInvertedChanged
+ plot.setYAxisInverted(False)
+
+ def setYAxisDownward(self):
+ """Configure the plot to use y-axis downward"""
+ plot = self.plot()
+ if plot is not None:
+ # This will trigger _yAxisInvertedChanged
+ plot.setYAxisInverted(True)
+
+ def _yAxisInvertedChanged(self, inverted):
+ """Handle Plot set y axis inverted signal"""
+ isUpward = not inverted
+ icon, toolTip = self.STATE[isUpward, "icon"], self.STATE[isUpward, "state"]
+ self.setIcon(icon)
+ self.setToolTip(toolTip)
+
+
+class ProfileToolButton(PlotToolButton):
+ """Button used in Profile3DToolbar to switch between 2D profile
+ and 1D profile."""
+ STATE = None
+ """Lazy loaded states used to feed ProfileToolButton"""
+
+ sigDimensionChanged = qt.Signal(int)
+
+ def __init__(self, parent=None, plot=None):
+ if self.STATE is None:
+ self.STATE = {
+ (1, "icon"): icons.getQIcon('profile1D'),
+ (1, "state"): "1D profile is computed on visible image",
+ (1, "action"): "1D profile on visible image",
+ (2, "icon"): icons.getQIcon('profile2D'),
+ (2, "state"): "2D profile is computed, one 1D profile for each image in the stack",
+ (2, "action"): "2D profile on image stack"}
+ # Compute 1D profile
+ # Compute 2D profile
+
+ super(ProfileToolButton, self).__init__(parent=parent, plot=plot)
+
+ profile1DAction = self._createAction(1)
+ profile1DAction.triggered.connect(self.computeProfileIn1D)
+ profile1DAction.setIconVisibleInMenu(True)
+
+ profile2DAction = self._createAction(2)
+ profile2DAction.triggered.connect(self.computeProfileIn2D)
+ profile2DAction.setIconVisibleInMenu(True)
+
+ menu = qt.QMenu(self)
+ menu.addAction(profile1DAction)
+ menu.addAction(profile2DAction)
+ self.setMenu(menu)
+ self.setPopupMode(qt.QToolButton.InstantPopup)
+ menu.setTitle('Select profile dimension')
+
+ def _createAction(self, profileDimension):
+ icon = self.STATE[profileDimension, "icon"]
+ text = self.STATE[profileDimension, "action"]
+ return qt.QAction(icon, text, self)
+
+ def _profileDimensionChanged(self, profileDimension):
+ """Update icon in toolbar, emit number of dimensions for profile"""
+ self.setIcon(self.STATE[profileDimension, "icon"])
+ self.setToolTip(self.STATE[profileDimension, "state"])
+ self.sigDimensionChanged.emit(profileDimension)
+
+ def computeProfileIn1D(self):
+ self._profileDimensionChanged(1)
+
+ def computeProfileIn2D(self):
+ self._profileDimensionChanged(2)
diff --git a/silx/gui/plot/PlotTools.py b/silx/gui/plot/PlotTools.py
new file mode 100644
index 0000000..7158d0e
--- /dev/null
+++ b/silx/gui/plot/PlotTools.py
@@ -0,0 +1,313 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Set of widgets to associate with a :class:'PlotWidget'.
+"""
+
+from __future__ import division
+
+__authors__ = ["V.A. Sole", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/03/2017"
+
+
+import logging
+import numbers
+import traceback
+import weakref
+
+import numpy
+
+from .. import qt
+
+_logger = logging.getLogger(__name__)
+_logger.setLevel(logging.DEBUG)
+
+
+# PositionInfo ################################################################
+
+class PositionInfo(qt.QWidget):
+ """QWidget displaying coords converted from data coords of the mouse.
+
+ Provide this widget with a list of couple:
+
+ - A name to display before the data
+ - A function that takes (x, y) as arguments and returns something that
+ gets converted to a string.
+ If the result is a float it is converted with '%.7g' format.
+
+ To run the following sample code, a QApplication must be initialized.
+ First, create a PlotWindow and add a QToolBar where to place the
+ PositionInfo widget.
+
+ >>> from silx.gui.plot import PlotWindow
+ >>> from silx.gui import qt
+
+ >>> plot = PlotWindow() # Create a PlotWindow to add the widget to
+ >>> toolBar = qt.QToolBar() # Create a toolbar to place the widget in
+ >>> plot.addToolBar(qt.Qt.BottomToolBarArea, toolBar) # Add it to plot
+
+ Then, create the PositionInfo widget and add it to the toolbar.
+ The PositionInfo widget is created with a list of converters, here
+ to display polar coordinates of the mouse position.
+
+ >>> import numpy
+ >>> from silx.gui.plot.PlotTools import PositionInfo
+
+ >>> position = PositionInfo(plot=plot, converters=[
+ ... ('Radius', lambda x, y: numpy.sqrt(x*x + y*y)),
+ ... ('Angle', lambda x, y: numpy.degrees(numpy.arctan2(y, x)))])
+ >>> toolBar.addWidget(position) # Add the widget to the toolbar
+ <...>
+ >>> plot.show() # To display the PlotWindow with the position widget
+
+ :param plot: The PlotWidget this widget is displaying data coords from.
+ :param converters: List of name to display and conversion function from
+ (x, y) in data coords to displayed value.
+ If None, the default, it displays X and Y.
+ :type converters: Iterable of 2-tuple (str, function)
+ :param parent: Parent widget
+ """
+
+ def __init__(self, parent=None, plot=None, converters=None):
+ assert plot is not None
+ self._plotRef = weakref.ref(plot)
+
+ super(PositionInfo, self).__init__(parent)
+
+ if converters is None:
+ converters = (('X', lambda x, y: x), ('Y', lambda x, y: y))
+
+ self.autoSnapToActiveCurve = False
+ """Toggle snapping use position to active curve.
+
+ - True to snap used coordinates to the active curve if the active curve
+ is displayed with symbols and mouse is close enough.
+ If the mouse is not close to a point of the curve, values are
+ displayed in red.
+ - False (the default) to always use mouse coordinates.
+
+ """
+
+ self._fields = [] # To store (QLineEdit, name, function (x, y)->v)
+
+ # Create a new layout with new widgets
+ layout = qt.QHBoxLayout()
+ layout.setContentsMargins(0, 0, 0, 0)
+ # layout.setSpacing(0)
+
+ # Create all QLabel and store them with the corresponding converter
+ for name, func in converters:
+ layout.addWidget(qt.QLabel('<b>' + name + ':</b>'))
+
+ contentWidget = qt.QLabel()
+ contentWidget.setText('------')
+ contentWidget.setTextInteractionFlags(qt.Qt.TextSelectableByMouse)
+ contentWidget.setFixedWidth(
+ contentWidget.fontMetrics().width('##############'))
+ layout.addWidget(contentWidget)
+ self._fields.append((contentWidget, name, func))
+
+ layout.addStretch(1)
+ self.setLayout(layout)
+
+ # Connect to Plot events
+ plot.sigPlotSignal.connect(self._plotEvent)
+
+ @property
+ def plot(self):
+ """The :class:`.PlotWindow` this widget is attached to."""
+ return self._plotRef()
+
+ def getConverters(self):
+ """Return the list of converters as 2-tuple (name, function)."""
+ return [(name, func) for _label, name, func in self._fields]
+
+ def _plotEvent(self, event):
+ """Handle events from the Plot.
+
+ :param dict event: Plot event
+ """
+ if event['event'] == 'mouseMoved':
+ x, y = event['x'], event['y'] # Position in data
+ styleSheet = "color: rgb(0, 0, 0);" # Default style
+
+ if self.autoSnapToActiveCurve and self.plot.getGraphCursor():
+ # Check if near active curve with symbols.
+
+ styleSheet = "color: rgb(255, 0, 0);" # Style far from curve
+
+ activeCurve = self.plot.getActiveCurve()
+ if activeCurve:
+ xData = activeCurve.getXData(copy=False)
+ yData = activeCurve.getYData(copy=False)
+ if activeCurve.getSymbol(): # Only handled if symbols on curve
+ closestIndex = numpy.argmin(
+ pow(xData - x, 2) + pow(yData - y, 2))
+
+ xClosest = xData[closestIndex]
+ yClosest = yData[closestIndex]
+
+ closestInPixels = self.plot.dataToPixel(
+ xClosest, yClosest, axis=activeCurve.getYAxis())
+ if closestInPixels is not None:
+ xPixel, yPixel = event['xpixel'], event['ypixel']
+
+ if (abs(closestInPixels[0] - xPixel) < 5 and
+ abs(closestInPixels[1] - yPixel) < 5):
+ # Update label style sheet
+ styleSheet = "color: rgb(0, 0, 0);"
+
+ # if close enough, wrap to data point coords
+ x, y = xClosest, yClosest
+
+ for label, name, func in self._fields:
+ label.setStyleSheet(styleSheet)
+
+ try:
+ value = func(x, y)
+ except:
+ label.setText('Error')
+ _logger.error(
+ "Error while converting coordinates (%f, %f)"
+ "with converter '%s'" % (x, y, name))
+ _logger.error(traceback.format_exc())
+ else:
+ if isinstance(value, numbers.Real):
+ value = '%.7g' % value # Use this for floats and int
+ else:
+ value = str(value) # Fallback for other types
+ label.setText(value)
+
+
+# LimitsToolBar ##############################################################
+
+class LimitsToolBar(qt.QToolBar):
+ """QToolBar displaying and controlling the limits of a :class:`PlotWidget`.
+
+ To run the following sample code, a QApplication must be initialized.
+ First, create a PlotWindow:
+
+ >>> from silx.gui.plot import PlotWindow
+ >>> plot = PlotWindow() # Create a PlotWindow to add the toolbar to
+
+ Then, create the LimitsToolBar and add it to the PlotWindow.
+
+ >>> from silx.gui import qt
+ >>> from silx.gui.plot.PlotTools import LimitsToolBar
+
+ >>> toolbar = LimitsToolBar(plot=plot) # Create the toolbar
+ >>> plot.addToolBar(qt.Qt.BottomToolBarArea, toolbar) # Add it to the plot
+ >>> plot.show() # To display the PlotWindow with the limits toolbar
+
+ :param parent: See :class:`QToolBar`.
+ :param plot: :class:`PlotWidget` instance on which to operate.
+ :param str title: See :class:`QToolBar`.
+ """
+
+ class _FloatEdit(qt.QLineEdit):
+ """Field to edit a float value."""
+ def __init__(self, value=None, *args, **kwargs):
+ qt.QLineEdit.__init__(self, *args, **kwargs)
+ self.setValidator(qt.QDoubleValidator())
+ self.setFixedWidth(100)
+ self.setAlignment(qt.Qt.AlignLeft)
+ if value is not None:
+ self.setValue(value)
+
+ def value(self):
+ return float(self.text())
+
+ def setValue(self, value):
+ self.setText('%g' % value)
+
+ def __init__(self, parent=None, plot=None, title='Limits'):
+ super(LimitsToolBar, self).__init__(title, parent)
+ assert plot is not None
+ self._plot = plot
+ self._plot.sigPlotSignal.connect(self._plotWidgetSlot)
+
+ self._initWidgets()
+
+ @property
+ def plot(self):
+ """The :class:`PlotWidget` the toolbar is attached to."""
+ return self._plot
+
+ def _initWidgets(self):
+ """Create and init Toolbar widgets."""
+ xMin, xMax = self.plot.getGraphXLimits()
+ yMin, yMax = self.plot.getGraphYLimits()
+
+ self.addWidget(qt.QLabel('Limits: '))
+ self.addWidget(qt.QLabel(' X: '))
+ self._xMinFloatEdit = self._FloatEdit(xMin)
+ self._xMinFloatEdit.editingFinished[()].connect(
+ self._xFloatEditChanged)
+ self.addWidget(self._xMinFloatEdit)
+
+ self._xMaxFloatEdit = self._FloatEdit(xMax)
+ self._xMaxFloatEdit.editingFinished[()].connect(
+ self._xFloatEditChanged)
+ self.addWidget(self._xMaxFloatEdit)
+
+ self.addWidget(qt.QLabel(' Y: '))
+ self._yMinFloatEdit = self._FloatEdit(yMin)
+ self._yMinFloatEdit.editingFinished[()].connect(
+ self._yFloatEditChanged)
+ self.addWidget(self._yMinFloatEdit)
+
+ self._yMaxFloatEdit = self._FloatEdit(yMax)
+ self._yMaxFloatEdit.editingFinished[()].connect(
+ self._yFloatEditChanged)
+ self.addWidget(self._yMaxFloatEdit)
+
+ def _plotWidgetSlot(self, event):
+ """Listen to :class:`PlotWidget` events."""
+ if event['event'] not in ('limitsChanged',):
+ return
+
+ xMin, xMax = self.plot.getGraphXLimits()
+ yMin, yMax = self.plot.getGraphYLimits()
+
+ self._xMinFloatEdit.setValue(xMin)
+ self._xMaxFloatEdit.setValue(xMax)
+ self._yMinFloatEdit.setValue(yMin)
+ self._yMaxFloatEdit.setValue(yMax)
+
+ def _xFloatEditChanged(self):
+ """Handle X limits changed from the GUI."""
+ xMin, xMax = self._xMinFloatEdit.value(), self._xMaxFloatEdit.value()
+ if xMax < xMin:
+ xMin, xMax = xMax, xMin
+
+ self.plot.setGraphXLimits(xMin, xMax)
+
+ def _yFloatEditChanged(self):
+ """Handle Y limits changed from the GUI."""
+ yMin, yMax = self._yMinFloatEdit.value(), self._yMaxFloatEdit.value()
+ if yMax < yMin:
+ yMin, yMax = yMax, yMin
+
+ self.plot.setGraphYLimits(yMin, yMax)
diff --git a/silx/gui/plot/PlotWidget.py b/silx/gui/plot/PlotWidget.py
new file mode 100644
index 0000000..5666d56
--- /dev/null
+++ b/silx/gui/plot/PlotWidget.py
@@ -0,0 +1,267 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Qt widget providing Plot API for 1D and 2D data.
+
+This provides the plot API of :class:`silx.gui.plot.Plot.Plot` as a
+Qt widget.
+"""
+
+__authors__ = ["V.A. Sole", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "22/02/2016"
+
+
+import logging
+
+from . import Plot
+
+from .. import qt
+
+
+_logger = logging.getLogger(__name__)
+
+
+class PlotWidget(qt.QMainWindow, Plot.Plot):
+ """Qt Widget providing a 1D/2D plot.
+
+ This widget is a QMainWindow.
+ It provides Qt signals for the Plot and add supports for panning
+ with arrow keys.
+
+ :param parent: The parent of this widget or None.
+ :param backend: The backend to use for the plot (default: matplotlib).
+ See :class:`.Plot` for the list of supported backend.
+ :type backend: str or :class:`BackendBase.BackendBase`
+ """
+
+ sigPlotSignal = qt.Signal(object)
+ """Signal for all events of the plot.
+
+ The signal information is provided as a dict.
+ See :class:`.Plot` for documentation of the content of the dict.
+ """
+
+ sigSetYAxisInverted = qt.Signal(bool)
+ """Signal emitted when Y axis orientation has changed"""
+
+ sigSetXAxisLogarithmic = qt.Signal(bool)
+ """Signal emitted when X axis scale has changed"""
+
+ sigSetYAxisLogarithmic = qt.Signal(bool)
+ """Signal emitted when Y axis scale has changed"""
+
+ sigSetXAxisAutoScale = qt.Signal(bool)
+ """Signal emitted when X axis autoscale has changed"""
+
+ sigSetYAxisAutoScale = qt.Signal(bool)
+ """Signal emitted when Y axis autoscale has changed"""
+
+ sigSetKeepDataAspectRatio = qt.Signal(bool)
+ """Signal emitted when plot keep aspect ratio has changed"""
+
+ sigSetGraphGrid = qt.Signal(str)
+ """Signal emitted when plot grid has changed"""
+
+ sigSetGraphCursor = qt.Signal(bool)
+ """Signal emitted when plot crosshair cursor has changed"""
+
+ sigSetPanWithArrowKeys = qt.Signal(bool)
+ """Signal emitted when pan with arrow keys has changed"""
+
+ sigContentChanged = qt.Signal(str, str, str)
+ """Signal emitted when the content of the plot is changed.
+
+ It provides 3 informations:
+
+ - action: The change of the plot: 'add' or 'remove'
+ - kind: The kind of primitive changed:
+ 'curve', 'image', 'scatter', 'histogram', 'item' or 'marker'
+ - legend: The legend of the primitive changed.
+ """
+
+ sigActiveCurveChanged = qt.Signal(object, object)
+ """Signal emitted when the active curve has changed.
+
+ It provides 2 informations:
+
+ - previous: The legend of the previous active curve or None
+ - legend: The legend of the new active curve or None if no curve is active
+ """
+
+ sigActiveImageChanged = qt.Signal(object, object)
+ """Signal emitted when the active image has changed.
+
+ It provides 2 informations:
+
+ - previous: The legend of the previous active image or None
+ - legend: The legend of the new active image or None if no image is active
+ """
+
+ sigActiveScatterChanged = qt.Signal(object, object)
+ """Signal emitted when the active Scatter has changed.
+
+ It provides following information:
+
+ - previous: The legend of the previous active scatter or None
+ - legend: The legend of the new active image or None if no image is active
+ """
+
+ sigInteractiveModeChanged = qt.Signal(object)
+ """Signal emitted when the interactive mode has changed
+
+ It provides the source as passed to :meth:`setInteractiveMode`.
+ """
+
+ def __init__(self, parent=None, backend=None,
+ legends=False, callback=None, **kw):
+
+ if kw:
+ _logger.warning(
+ 'deprecated: __init__ extra arguments: %s', str(kw))
+ if legends:
+ _logger.warning('deprecated: __init__ legend argument')
+ if callback:
+ _logger.warning('deprecated: __init__ callback argument')
+
+ self._panWithArrowKeys = True
+
+ qt.QMainWindow.__init__(self, parent)
+ if parent is not None:
+ # behave as a widget
+ self.setWindowFlags(qt.Qt.Widget)
+ else:
+ self.setWindowTitle('PlotWidget')
+
+ Plot.Plot.__init__(self, parent, backend=backend)
+
+ widget = self.getWidgetHandle()
+ if widget is not None:
+ self.setCentralWidget(widget)
+ else:
+ _logger.warning("Plot backend does not support widget")
+
+ self.setFocusPolicy(qt.Qt.StrongFocus)
+ self.setFocus(qt.Qt.OtherFocusReason)
+
+ def notify(self, event, **kwargs):
+ """Override :meth:`Plot.notify` to send Qt signals."""
+ eventDict = kwargs.copy()
+ eventDict['event'] = event
+ self.sigPlotSignal.emit(eventDict)
+
+ if event == 'setYAxisInverted':
+ self.sigSetYAxisInverted.emit(kwargs['state'])
+ elif event == 'setXAxisLogarithmic':
+ self.sigSetXAxisLogarithmic.emit(kwargs['state'])
+ elif event == 'setYAxisLogarithmic':
+ self.sigSetYAxisLogarithmic.emit(kwargs['state'])
+ elif event == 'setXAxisAutoScale':
+ self.sigSetXAxisAutoScale.emit(kwargs['state'])
+ elif event == 'setYAxisAutoScale':
+ self.sigSetYAxisAutoScale.emit(kwargs['state'])
+ elif event == 'setKeepDataAspectRatio':
+ self.sigSetKeepDataAspectRatio.emit(kwargs['state'])
+ elif event == 'setGraphGrid':
+ self.sigSetGraphGrid.emit(kwargs['which'])
+ elif event == 'setGraphCursor':
+ self.sigSetGraphCursor.emit(kwargs['state'])
+ elif event == 'contentChanged':
+ self.sigContentChanged.emit(
+ kwargs['action'], kwargs['kind'], kwargs['legend'])
+ elif event == 'activeCurveChanged':
+ self.sigActiveCurveChanged.emit(
+ kwargs['previous'], kwargs['legend'])
+ elif event == 'activeImageChanged':
+ self.sigActiveImageChanged.emit(
+ kwargs['previous'], kwargs['legend'])
+ elif event == 'activeScatterChanged':
+ self.sigActiveScatterChanged.emit(
+ kwargs['previous'], kwargs['legend'])
+ elif event == 'interactiveModeChanged':
+ self.sigInteractiveModeChanged.emit(kwargs['source'])
+ Plot.Plot.notify(self, event, **kwargs)
+
+ # Panning with arrow keys
+
+ def isPanWithArrowKeys(self):
+ """Returns whether or not panning the graph with arrow keys is enable.
+
+ See :meth:`setPanWithArrowKeys`.
+ """
+ return self._panWithArrowKeys
+
+ def setPanWithArrowKeys(self, pan=False):
+ """Enable/Disable panning the graph with arrow keys.
+
+ This grabs the keyboard.
+
+ :param bool pan: True to enable panning, False to disable.
+ """
+ pan = bool(pan)
+ panHasChanged = self._panWithArrowKeys != pan
+
+ self._panWithArrowKeys = pan
+ if not self._panWithArrowKeys:
+ self.setFocusPolicy(qt.Qt.NoFocus)
+ else:
+ self.setFocusPolicy(qt.Qt.StrongFocus)
+ self.setFocus(qt.Qt.OtherFocusReason)
+
+ if panHasChanged:
+ self.sigSetPanWithArrowKeys.emit(pan)
+
+ # Dict to convert Qt arrow key code to direction str.
+ _ARROWS_TO_PAN_DIRECTION = {
+ qt.Qt.Key_Left: 'left',
+ qt.Qt.Key_Right: 'right',
+ qt.Qt.Key_Up: 'up',
+ qt.Qt.Key_Down: 'down'
+ }
+
+ def keyPressEvent(self, event):
+ """Key event handler handling panning on arrow keys.
+
+ Overrides base class implementation.
+ """
+ key = event.key()
+ if self._panWithArrowKeys and key in self._ARROWS_TO_PAN_DIRECTION:
+ self.pan(self._ARROWS_TO_PAN_DIRECTION[key], factor=0.1)
+
+ # Send a mouse move event to the plot widget to take into account
+ # that even if mouse didn't move on the screen, it moved relative
+ # to the plotted data.
+ qapp = qt.QApplication.instance()
+ event = qt.QMouseEvent(
+ qt.QEvent.MouseMove,
+ self.getWidgetHandle().mapFromGlobal(qt.QCursor.pos()),
+ qt.Qt.NoButton,
+ qapp.mouseButtons(),
+ qapp.keyboardModifiers())
+ qapp.sendEvent(self.getWidgetHandle(), event)
+
+ else:
+ # Only call base class implementation when key is not handled.
+ # See QWidget.keyPressEvent for details.
+ super(PlotWidget, self).keyPressEvent(event)
diff --git a/silx/gui/plot/PlotWindow.py b/silx/gui/plot/PlotWindow.py
new file mode 100644
index 0000000..ae25cfd
--- /dev/null
+++ b/silx/gui/plot/PlotWindow.py
@@ -0,0 +1,766 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""A :class:`.PlotWidget` with additional toolbars.
+
+The :class:`PlotWindow` is a subclass of :class:`.PlotWidget`.
+It provides the plot API fully defined in :class:`.Plot`.
+"""
+
+__authors__ = ["V.A. Sole", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "27/04/2017"
+
+import collections
+import logging
+
+from silx.utils.decorators import deprecated
+
+from . import PlotWidget
+from . import PlotActions
+from . import PlotToolButtons
+from .PlotTools import PositionInfo
+from .Profile import ProfileToolBar
+from .LegendSelector import LegendsDockWidget
+from .CurvesROIWidget import CurvesROIDockWidget
+from .MaskToolsWidget import MaskToolsDockWidget
+try:
+ from ..console import IPythonDockWidget
+except ImportError:
+ IPythonDockWidget = None
+
+from .. import qt
+
+
+_logger = logging.getLogger(__name__)
+
+
+class PlotWindow(PlotWidget):
+ """Qt Widget providing a 1D/2D plot area and additional tools.
+
+ This widgets inherits from :class:`.PlotWidget` and provides its plot API.
+
+ Initialiser parameters:
+
+ :param parent: The parent of this widget or None.
+ :param backend: The backend to use for the plot (default: matplotlib).
+ See :class:`.Plot` for the list of supported backend.
+ :type backend: str or :class:`BackendBase.BackendBase`
+ :param bool resetzoom: Toggle visibility of reset zoom action.
+ :param bool autoScale: Toggle visibility of axes autoscale actions.
+ :param bool logScale: Toggle visibility of axes log scale actions.
+ :param bool grid: Toggle visibility of grid mode action.
+ :param bool curveStyle: Toggle visibility of curve style action.
+ :param bool colormap: Toggle visibility of colormap action.
+ :param bool aspectRatio: Toggle visibility of aspect ratio button.
+ :param bool yInverted: Toggle visibility of Y axis direction button.
+ :param bool copy: Toggle visibility of copy action.
+ :param bool save: Toggle visibility of save action.
+ :param bool print_: Toggle visibility of print action.
+ :param bool control: True to display an Options button with a sub-menu
+ to show legends, toggle crosshair and pan with arrows.
+ (Default: False)
+ :param position: True to display widget with (x, y) mouse position
+ (Default: False).
+ It also supports a list of (name, funct(x, y)->value)
+ to customize the displayed values.
+ See :class:`silx.gui.plot.PlotTools.PositionInfo`.
+ :param bool roi: Toggle visibilty of ROI action.
+ :param bool mask: Toggle visibilty of mask action.
+ :param bool fit: Toggle visibilty of fit action.
+ """
+
+ def __init__(self, parent=None, backend=None,
+ resetzoom=True, autoScale=True, logScale=True, grid=True,
+ curveStyle=True, colormap=True,
+ aspectRatio=True, yInverted=True,
+ copy=True, save=True, print_=True,
+ control=False, position=False,
+ roi=True, mask=True, fit=False):
+ super(PlotWindow, self).__init__(parent=parent, backend=backend)
+ if parent is None:
+ self.setWindowTitle('PlotWindow')
+
+ self._dockWidgets = []
+
+ # lazy loaded dock widgets
+ self._legendsDockWidget = None
+ self._curvesROIDockWidget = None
+ self._maskToolsDockWidget = None
+
+ # Init actions
+ self.group = qt.QActionGroup(self)
+ self.group.setExclusive(False)
+
+ self.resetZoomAction = self.group.addAction(PlotActions.ResetZoomAction(self))
+ self.resetZoomAction.setVisible(resetzoom)
+ self.addAction(self.resetZoomAction)
+
+ self.zoomInAction = PlotActions.ZoomInAction(self)
+ self.addAction(self.zoomInAction)
+
+ self.zoomOutAction = PlotActions.ZoomOutAction(self)
+ self.addAction(self.zoomOutAction)
+
+ self.xAxisAutoScaleAction = self.group.addAction(
+ PlotActions.XAxisAutoScaleAction(self))
+ self.xAxisAutoScaleAction.setVisible(autoScale)
+ self.addAction(self.xAxisAutoScaleAction)
+
+ self.yAxisAutoScaleAction = self.group.addAction(
+ PlotActions.YAxisAutoScaleAction(self))
+ self.yAxisAutoScaleAction.setVisible(autoScale)
+ self.addAction(self.yAxisAutoScaleAction)
+
+ self.xAxisLogarithmicAction = self.group.addAction(
+ PlotActions.XAxisLogarithmicAction(self))
+ self.xAxisLogarithmicAction.setVisible(logScale)
+ self.addAction(self.xAxisLogarithmicAction)
+
+ self.yAxisLogarithmicAction = self.group.addAction(
+ PlotActions.YAxisLogarithmicAction(self))
+ self.yAxisLogarithmicAction.setVisible(logScale)
+ self.addAction(self.yAxisLogarithmicAction)
+
+ self.gridAction = self.group.addAction(
+ PlotActions.GridAction(self, gridMode='both'))
+ self.gridAction.setVisible(grid)
+ self.addAction(self.gridAction)
+
+ self.curveStyleAction = self.group.addAction(PlotActions.CurveStyleAction(self))
+ self.curveStyleAction.setVisible(curveStyle)
+ self.addAction(self.curveStyleAction)
+
+ self.colormapAction = self.group.addAction(PlotActions.ColormapAction(self))
+ self.colormapAction.setVisible(colormap)
+ self.addAction(self.colormapAction)
+
+ self.keepDataAspectRatioButton = PlotToolButtons.AspectToolButton(
+ parent=self, plot=self)
+ self.keepDataAspectRatioButton.setVisible(aspectRatio)
+
+ self.yAxisInvertedButton = PlotToolButtons.YAxisOriginToolButton(
+ parent=self, plot=self)
+ self.yAxisInvertedButton.setVisible(yInverted)
+
+ self.group.addAction(self.getRoiAction())
+ self.getRoiAction().setVisible(roi)
+
+ self.group.addAction(self.getMaskAction())
+ self.getMaskAction().setVisible(mask)
+
+ self._intensityHistoAction = self.group.addAction(
+ PlotActions.PixelIntensitiesHistoAction(self))
+ self._intensityHistoAction.setVisible(False)
+
+ self._medianFilter2DAction = self.group.addAction(
+ PlotActions.MedianFilter2DAction(self))
+ self._medianFilter2DAction.setVisible(False)
+
+ self._medianFilter1DAction = self.group.addAction(
+ PlotActions.MedianFilter1DAction(self))
+ self._medianFilter1DAction.setVisible(False)
+
+ self._separator = qt.QAction('separator', self)
+ self._separator.setSeparator(True)
+ self.group.addAction(self._separator)
+
+ self.copyAction = self.group.addAction(PlotActions.CopyAction(self))
+ self.copyAction.setVisible(copy)
+ self.addAction(self.copyAction)
+
+ self.saveAction = self.group.addAction(PlotActions.SaveAction(self))
+ self.saveAction.setVisible(save)
+ self.addAction(self.saveAction)
+
+ self.printAction = self.group.addAction(PlotActions.PrintAction(self))
+ self.printAction.setVisible(print_)
+ self.addAction(self.printAction)
+
+ self.fitAction = self.group.addAction(PlotActions.FitAction(self))
+ self.fitAction.setVisible(fit)
+ self.addAction(self.fitAction)
+
+ # lazy loaded actions needed by the controlButton menu
+ self._consoleAction = None
+ self._panWithArrowKeysAction = None
+ self._crosshairAction = None
+
+ if control or position:
+ hbox = qt.QHBoxLayout()
+ hbox.setContentsMargins(0, 0, 0, 0)
+
+ if control:
+ self.controlButton = qt.QToolButton()
+ self.controlButton.setText("Options")
+ self.controlButton.setToolButtonStyle(qt.Qt.ToolButtonTextBesideIcon)
+ self.controlButton.setAutoRaise(True)
+ self.controlButton.setPopupMode(qt.QToolButton.InstantPopup)
+ menu = qt.QMenu(self)
+ menu.aboutToShow.connect(self._customControlButtonMenu)
+ self.controlButton.setMenu(menu)
+
+ hbox.addWidget(self.controlButton)
+
+ if position: # Add PositionInfo widget to the bottom of the plot
+ if isinstance(position, collections.Iterable):
+ # Use position as a set of converters
+ converters = position
+ else:
+ converters = None
+ self.positionWidget = PositionInfo(
+ plot=self, converters=converters)
+ self.positionWidget.autoSnapToActiveCurve = True
+
+ hbox.addWidget(self.positionWidget)
+
+ hbox.addStretch(1)
+ bottomBar = qt.QWidget()
+ bottomBar.setLayout(hbox)
+
+ layout = qt.QVBoxLayout()
+ layout.setSpacing(0)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.addWidget(self.getWidgetHandle())
+ layout.addWidget(bottomBar)
+ layout.setStretch(0, 1)
+
+ centralWidget = qt.QWidget()
+ centralWidget.setLayout(layout)
+ self.setCentralWidget(centralWidget)
+
+ # Creating the toolbar also create actions for toolbuttons
+ self._toolbar = self._createToolBar(title='Plot', parent=None)
+ self.addToolBar(self._toolbar)
+
+ def getSelectionMask(self):
+ """Return the current mask handled by :attr:`maskToolsDockWidget`.
+
+ :return: The array of the mask with dimension of the 'active' image.
+ If there is no active image, an empty array is returned.
+ :rtype: 2D numpy.ndarray of uint8
+ """
+ return self.getMaskToolsDockWidget().getSelectionMask()
+
+ def setSelectionMask(self, mask):
+ """Set the mask handled by :attr:`maskToolsDockWidget`.
+
+ If the provided mask has not the same dimension as the 'active'
+ image, it will by cropped or padded.
+
+ :param mask: The array to use for the mask.
+ :type mask: numpy.ndarray of uint8 of dimension 2, C-contiguous.
+ Array of other types are converted.
+ :return: True if success, False if failed
+ """
+ return bool(self.getMaskToolsDockWidget().setSelectionMask(mask))
+
+ def _toggleConsoleVisibility(self, is_checked=False):
+ """Create IPythonDockWidget if needed,
+ show it or hide it."""
+ # create widget if needed (first call)
+ if not hasattr(self, '_consoleDockWidget'):
+ available_vars = {"plt": self}
+ banner = "The variable 'plt' is available. Use the 'whos' "
+ banner += "and 'help(plt)' commands for more information.\n\n"
+ self._consoleDockWidget = IPythonDockWidget(
+ available_vars=available_vars,
+ custom_banner=banner,
+ parent=self)
+ self.addTabbedDockWidget(self._consoleDockWidget)
+ self._consoleDockWidget.visibilityChanged.connect(
+ self.getConsoleAction().setChecked)
+
+ self._consoleDockWidget.setVisible(is_checked)
+
+ def _createToolBar(self, title, parent):
+ """Create a QToolBar from the QAction of the PlotWindow.
+
+ :param str title: The title of the QMenu
+ :param qt.QWidget parent: See :class:`QToolBar`
+ """
+ toolbar = qt.QToolBar(title, parent)
+
+ # Order widgets with actions
+ objects = self.group.actions()
+
+ # Add push buttons to list
+ index = objects.index(self.colormapAction)
+ objects.insert(index + 1, self.keepDataAspectRatioButton)
+ objects.insert(index + 2, self.yAxisInvertedButton)
+
+ for obj in objects:
+ if isinstance(obj, qt.QAction):
+ toolbar.addAction(obj)
+ else:
+ # Add action for toolbutton in order to allow changing
+ # visibility (see doc QToolBar.addWidget doc)
+ if obj is self.keepDataAspectRatioButton:
+ self.keepDataAspectRatioAction = toolbar.addWidget(obj)
+ elif obj is self.yAxisInvertedButton:
+ self.yAxisInvertedAction = toolbar.addWidget(obj)
+ else:
+ raise RuntimeError()
+ return toolbar
+
+ def toolBar(self):
+ """Return a QToolBar from the QAction of the PlotWindow.
+ """
+ return self._toolbar
+
+ def menu(self, title='Plot', parent=None):
+ """Return a QMenu from the QAction of the PlotWindow.
+
+ :param str title: The title of the QMenu
+ :param parent: See :class:`QMenu`
+ """
+ menu = qt.QMenu(title, parent)
+ for action in self.group.actions():
+ menu.addAction(action)
+ return menu
+
+ def _customControlButtonMenu(self):
+ """Display Options button sub-menu."""
+ controlMenu = self.controlButton.menu()
+ controlMenu.clear()
+ controlMenu.addAction(self.getLegendsDockWidget().toggleViewAction())
+ controlMenu.addAction(self.getRoiAction())
+ controlMenu.addAction(self.getMaskAction())
+ controlMenu.addAction(self.getConsoleAction())
+
+ controlMenu.addSeparator()
+ controlMenu.addAction(self.getCrosshairAction())
+ controlMenu.addAction(self.getPanWithArrowKeysAction())
+
+ def addTabbedDockWidget(self, dock_widget):
+ """Add a dock widget as a new tab if there are already dock widgets
+ in the plot. When the first tab is added, the area is chosen
+ depending on the plot geometry:
+ it the window is much wider than it is high, the right dock area
+ is used, else the bottom dock area is used.
+
+ :param dock_widget: Instance of :class:`QDockWidget` to be added.
+ """
+ if dock_widget not in self._dockWidgets:
+ self._dockWidgets.append(dock_widget)
+ if len(self._dockWidgets) == 1:
+ # The first created dock widget must be added to a Widget area
+ width = self.centralWidget().width()
+ height = self.centralWidget().height()
+ if width > (2.0 * height) and width > 1000:
+ area = qt.Qt.RightDockWidgetArea
+ else:
+ area = qt.Qt.BottomDockWidgetArea
+ self.addDockWidget(area, dock_widget)
+ else:
+ # Other dock widgets are added as tabs to the same widget area
+ self.tabifyDockWidget(self._dockWidgets[0],
+ dock_widget)
+
+ # getters for dock widgets
+ @property
+ @deprecated(replacement="getLegendsDockWidget()", since_version="0.4.0")
+ def legendsDockWidget(self):
+ return self.getLegendsDockWidget()
+
+ def getLegendsDockWidget(self):
+ """DockWidget with Legend panel"""
+ if self._legendsDockWidget is None:
+ self._legendsDockWidget = LegendsDockWidget(plot=self)
+ self._legendsDockWidget.hide()
+ self.addTabbedDockWidget(self._legendsDockWidget)
+ return self._legendsDockWidget
+
+ @property
+ @deprecated(replacement="getCurvesRoiDockWidget()", since_version="0.4.0")
+ def curvesROIDockWidget(self):
+ return self.getCurvesRoiDockWidget()
+
+ def getCurvesRoiDockWidget(self):
+ """DockWidget with curves' ROI panel (lazy-loaded).
+
+ The widget returned is a :class:`CurvesROIDockWidget`.
+ Its central widget is a :class:`CurvesROIWidget`
+ accessible as :attr:`CurvesROIDockWidget.roiWidget`.
+
+ :class:`silx.gui.plot.CurvesROIWidget.CurvesROIWidget` offers a getter
+ and a setter for the ROI data:
+
+ - :meth:`CurvesROIWidget.getRois`
+ - :meth:`CurvesROIWidget.setRois`
+ """
+ if self._curvesROIDockWidget is None:
+ self._curvesROIDockWidget = CurvesROIDockWidget(
+ plot=self, name='Regions Of Interest')
+ self._curvesROIDockWidget.hide()
+ self.addTabbedDockWidget(self._curvesROIDockWidget)
+ return self._curvesROIDockWidget
+
+ @property
+ @deprecated(replacement="getMaskToolsDockWidget()", since_version="0.4.0")
+ def maskToolsDockWidget(self):
+ return self.getMaskToolsDockWidget()
+
+ def getMaskToolsDockWidget(self):
+ """DockWidget with image mask panel (lazy-loaded)."""
+ if self._maskToolsDockWidget is None:
+ self._maskToolsDockWidget = MaskToolsDockWidget(
+ plot=self, name='Mask')
+ self._maskToolsDockWidget.hide()
+ self.addTabbedDockWidget(self._maskToolsDockWidget)
+ return self._maskToolsDockWidget
+
+ # getters for actions
+ @property
+ @deprecated(replacement="getConsoleAction()", since_version="0.4.0")
+ def consoleAction(self):
+ return self.getConsoleAction()
+
+ def getConsoleAction(self):
+ """QAction handling the IPython console activation.
+
+ By default, it is connected to a method that initializes the
+ console widget the first time the user clicks the "Console" menu
+ button. The following clicks, after initialization is done,
+ will toggle the visibility of the console widget.
+
+ :rtype: QAction
+ """
+ if self._consoleAction is None:
+ self._consoleAction = qt.QAction('Console', self)
+ self._consoleAction.setCheckable(True)
+ if IPythonDockWidget is not None:
+ self._consoleAction.toggled.connect(self._toggleConsoleVisibility)
+ else:
+ self._consoleAction.setEnabled(False)
+ return self._consoleAction
+
+ @property
+ @deprecated(replacement="getCrosshairAction()", since_version="0.4.0")
+ def crosshairAction(self):
+ return self.getCrosshairAction()
+
+ def getCrosshairAction(self):
+ """Action toggling crosshair cursor mode.
+
+ :rtype: PlotActions.PlotAction
+ """
+ if self._crosshairAction is None:
+ self._crosshairAction = PlotActions.CrosshairAction(self, color='red')
+ return self._crosshairAction
+
+ @property
+ @deprecated(replacement="getMaskAction()", since_version="0.4.0")
+ def maskAction(self):
+ return self.getMaskAction()
+
+ def getMaskAction(self):
+ """QAction toggling image mask dock widget
+
+ :rtype: QAction
+ """
+ return self.getMaskToolsDockWidget().toggleViewAction()
+
+ @property
+ @deprecated(replacement="getPanWithArrowKeysAction()",
+ since_version="0.4.0")
+ def panWithArrowKeysAction(self):
+ return self.getPanWithArrowKeysAction()
+
+ def getPanWithArrowKeysAction(self):
+ """Action toggling pan with arrow keys.
+
+ :rtype: PlotActions.PlotAction
+ """
+ if self._panWithArrowKeysAction is None:
+ self._panWithArrowKeysAction = PlotActions.PanWithArrowKeysAction(self)
+ return self._panWithArrowKeysAction
+
+ @property
+ @deprecated(replacement="getRoiAction()", since_version="0.4.0")
+ def roiAction(self):
+ return self.getRoiAction()
+
+ def getRoiAction(self):
+ """QAction toggling curve ROI dock widget
+
+ :rtype: QAction
+ """
+ return self.getCurvesRoiDockWidget().toggleViewAction()
+
+ def getResetZoomAction(self):
+ """Action resetting the zoom
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.resetZoomAction
+
+ def getZoomInAction(self):
+ """Action to zoom in
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.zoomInAction
+
+ def getZoomOutAction(self):
+ """Action to zoom out
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.zoomOutAction
+
+ def getXAxisAutoScaleAction(self):
+ """Action to toggle the X axis autoscale on zoom reset
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.xAxisAutoScaleAction
+
+ def getYAxisAutoScaleAction(self):
+ """Action to toggle the Y axis autoscale on zoom reset
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.yAxisAutoScaleAction
+
+ def getXAxisLogarithmicAction(self):
+ """Action to toggle logarithmic X axis
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.xAxisLogarithmicAction
+
+ def getYAxisLogarithmicAction(self):
+ """Action to toggle logarithmic Y axis
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.yAxisLogarithmicAction
+
+ def getGridAction(self):
+ """Action to toggle the grid visibility in the plot
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.gridAction
+
+ def getCurveStyleAction(self):
+ """Action to change curve line and markers styles
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.curveStyleAction
+
+ def getColormapAction(self):
+ """Action open a colormap dialog to change active image
+ and default colormap.
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.colormapAction
+
+ def getKeepDataAspectRatioButton(self):
+ """Button to toggle aspect ratio preservation
+
+ :rtype: PlotToolButtons.AspectToolButton
+ """
+ return self.keepDataAspectRatioButton
+
+ def getKeepDataAspectRatioAction(self):
+ """Action associated to keepDataAspectRatioButton.
+ Use this to change the visibility of keepDataAspectRatioButton in the
+ toolbar (See :meth:`QToolBar.addWidget` documentation).
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.keepDataAspectRatioButton
+
+ def getYAxisInvertedButton(self):
+ """Button to switch the Y axis orientation
+
+ :rtype: PlotToolButtons.YAxisOriginToolButton
+ """
+ return self.yAxisInvertedButton
+
+ def getYAxisInvertedAction(self):
+ """Action associated to yAxisInvertedButton.
+ Use this to change the visibility yAxisInvertedButton in the toolbar.
+ (See :meth:`QToolBar.addWidget` documentation).
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.yAxisInvertedAction
+
+ def getIntensityHistogramAction(self):
+ """Action toggling the histogram intensity Plot widget
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self._intensityHistoAction
+
+ def getCopyAction(self):
+ """Action to copy plot snapshot to clipboard
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.copyAction
+
+ def getSaveAction(self):
+ """Action to save plot
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.saveAction
+
+ def getPrintAction(self):
+ """Action to print plot
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.printAction
+
+ def getFitAction(self):
+ """Action to fit selected curve
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self.fitAction
+
+ def getMedianFilter1DAction(self):
+ """Action toggling the 1D median filter
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self._medianFilter1DAction
+
+ def getMedianFilter2DAction(self):
+ """Action toggling the 2D median filter
+
+ :rtype: PlotActions.PlotAction
+ """
+ return self._medianFilter2DAction
+
+
+class Plot1D(PlotWindow):
+ """PlotWindow with tools specific for curves.
+
+ This widgets provides the plot API of :class:`.PlotWidget`.
+
+ :param parent: The parent of this widget
+ :param backend: The backend to use for the plot (default: matplotlib).
+ See :class:`.Plot` for the list of supported backend.
+ :type backend: str or :class:`BackendBase.BackendBase`
+ """
+
+ def __init__(self, parent=None, backend=None):
+ super(Plot1D, self).__init__(parent=parent, backend=backend,
+ resetzoom=True, autoScale=True,
+ logScale=True, grid=True,
+ curveStyle=True, colormap=False,
+ aspectRatio=False, yInverted=False,
+ copy=True, save=True, print_=True,
+ control=True, position=True,
+ roi=True, mask=False, fit=True)
+ if parent is None:
+ self.setWindowTitle('Plot1D')
+ self.setGraphXLabel('X')
+ self.setGraphYLabel('Y')
+
+
+class Plot2D(PlotWindow):
+ """PlotWindow with a toolbar specific for images.
+
+ This widgets provides the plot API of :~:`.PlotWidget`.
+
+ :param parent: The parent of this widget
+ :param backend: The backend to use for the plot (default: matplotlib).
+ See :class:`.Plot` for the list of supported backend.
+ :type backend: str or :class:`BackendBase.BackendBase`
+ """
+
+ def __init__(self, parent=None, backend=None):
+ # List of information to display at the bottom of the plot
+ posInfo = [
+ ('X', lambda x, y: x),
+ ('Y', lambda x, y: y),
+ ('Data', self._getImageValue)]
+
+ super(Plot2D, self).__init__(parent=parent, backend=backend,
+ resetzoom=True, autoScale=False,
+ logScale=False, grid=False,
+ curveStyle=False, colormap=True,
+ aspectRatio=True, yInverted=True,
+ copy=True, save=True, print_=True,
+ control=False, position=posInfo,
+ roi=False, mask=True)
+ if parent is None:
+ self.setWindowTitle('Plot2D')
+ self.setGraphXLabel('Columns')
+ self.setGraphYLabel('Rows')
+
+ self.profile = ProfileToolBar(plot=self)
+
+ self.addToolBar(self.profile)
+
+ def _getImageValue(self, x, y):
+ """Get value of top most image at position (x, y)
+
+ :param float x: X position in plot coordinates
+ :param float y: Y position in plot coordinates
+ :return: The value at that point or '-'
+ """
+ value = '-'
+ valueZ = - float('inf')
+
+ for image in self.getAllImages():
+ data = image.getData(copy=False)
+ if image.getZValue() >= valueZ: # This image is over the previous one
+ ox, oy = image.getOrigin()
+ sx, sy = image.getScale()
+ row, col = (y - oy) / sy, (x - ox) / sx
+ if row >= 0 and col >= 0:
+ # Test positive before cast otherwise issue with int(-0.5) = 0
+ row, col = int(row), int(col)
+ if (row < data.shape[0] and col < data.shape[1]):
+ value = data[row, col]
+ valueZ = image.getZValue()
+ return value
+
+ def getProfileToolbar(self):
+ """Profile tools attached to this plot
+
+ See :class:`silx.gui.plot.Profile.ProfileToolBar`
+ """
+ return self.profile
+
+ @deprecated(replacement="getProfilePlot", since_version="0.5.0")
+ def getProfileWindow(self):
+ return self.getProfilePlot()
+
+ def getProfilePlot(self):
+ """Return plot window used to display profile curve.
+
+ :return: :class:`Plot1D`
+ """
+ return self.profile.getProfilePlot()
diff --git a/silx/gui/plot/Profile.py b/silx/gui/plot/Profile.py
new file mode 100644
index 0000000..a11b3f0
--- /dev/null
+++ b/silx/gui/plot/Profile.py
@@ -0,0 +1,741 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Utility functions, toolbars and actions to create profile on images
+and stacks of images"""
+
+
+__authors__ = ["V.A. Sole", "T. Vincent", "P. Knobel", "H. Payno"]
+__license__ = "MIT"
+__date__ = "24/04/2017"
+
+
+import numpy
+
+from silx.image.bilinear import BilinearImage
+
+from .. import icons
+from .. import qt
+from . import items
+from .Colors import cursorColorForColormap
+from .PlotActions import PlotAction
+from .PlotToolButtons import ProfileToolButton
+from .ProfileMainWindow import ProfileMainWindow
+
+from silx.utils.decorators import deprecated
+
+
+def _alignedFullProfile(data, origin, scale, position, roiWidth, axis):
+ """Get a profile along one axis on a stack of images
+
+ :param numpy.ndarray data: 3D volume (stack of 2D images)
+ The first dimension is the image index.
+ :param origin: Origin of image in plot (ox, oy)
+ :param scale: Scale of image in plot (sx, sy)
+ :param float position: Position of profile line in plot coords
+ on the axis orthogonal to the profile direction.
+ :param int roiWidth: Width of the profile in image pixels.
+ :param int axis: 0 for horizontal profile, 1 for vertical.
+ :return: profile image + effective ROI area corners in plot coords
+ """
+ assert axis in (0, 1)
+ assert len(data.shape) == 3
+
+ # Convert from plot to image coords
+ imgPos = int((position - origin[1 - axis]) / scale[1 - axis])
+
+ if axis == 1: # Vertical profile
+ # Transpose image to always do a horizontal profile
+ data = numpy.transpose(data, (0, 2, 1))
+
+ nimages, height, width = data.shape
+
+ roiWidth = min(height, roiWidth) # Clip roi width to image size
+
+ # Get [start, end[ coords of the roi in the data
+ start = int(int(imgPos) + 0.5 - roiWidth / 2.)
+ start = min(max(0, start), height - roiWidth)
+ end = start + roiWidth
+
+ if start < height and end > 0:
+ profile = data[:, max(0, start):min(end, height), :].mean(
+ axis=1, dtype=numpy.float32)
+ else:
+ profile = numpy.zeros((nimages, width), dtype=numpy.float32)
+
+ # Compute effective ROI in plot coords
+ profileBounds = numpy.array(
+ (0, width, width, 0),
+ dtype=numpy.float32) * scale[axis] + origin[axis]
+ roiBounds = numpy.array(
+ (start, start, end, end),
+ dtype=numpy.float32) * scale[1 - axis] + origin[1 - axis]
+
+ if axis == 0: # Horizontal profile
+ area = profileBounds, roiBounds
+ else: # vertical profile
+ area = roiBounds, profileBounds
+
+ return profile, area
+
+
+def _alignedPartialProfile(data, rowRange, colRange, axis):
+ """Mean of a rectangular region (ROI) of a stack of images
+ along a given axis.
+
+ Returned values and all parameters are in image coordinates.
+
+ :param numpy.ndarray data: 3D volume (stack of 2D images)
+ The first dimension is the image index.
+ :param rowRange: [min, max[ of ROI rows (upper bound excluded).
+ :type rowRange: 2-tuple of int (min, max) with min < max
+ :param colRange: [min, max[ of ROI columns (upper bound excluded).
+ :type colRange: 2-tuple of int (min, max) with min < max
+ :param int axis: The axis along which to take the profile of the ROI.
+ 0: Sum rows along columns.
+ 1: Sum columns along rows.
+ :return: Profile image along the ROI as the mean of the intersection
+ of the ROI and the image.
+ """
+ assert axis in (0, 1)
+ assert len(data.shape) == 3
+ assert rowRange[0] < rowRange[1]
+ assert colRange[0] < colRange[1]
+
+ nimages, height, width = data.shape
+
+ # Range aligned with the integration direction
+ profileRange = colRange if axis == 0 else rowRange
+
+ profileLength = abs(profileRange[1] - profileRange[0])
+
+ # Subset of the image to use as intersection of ROI and image
+ rowStart = min(max(0, rowRange[0]), height)
+ rowEnd = min(max(0, rowRange[1]), height)
+ colStart = min(max(0, colRange[0]), width)
+ colEnd = min(max(0, colRange[1]), width)
+
+ imgProfile = numpy.mean(data[:, rowStart:rowEnd, colStart:colEnd],
+ axis=axis + 1, dtype=numpy.float32)
+
+ # Profile including out of bound area
+ profile = numpy.zeros((nimages, profileLength), dtype=numpy.float32)
+
+ # Place imgProfile in full profile
+ offset = - min(0, profileRange[0])
+ profile[:, offset:offset + imgProfile.shape[1]] = imgProfile
+
+ return profile
+
+
+def createProfile(roiInfo, currentData, origin, scale, lineWidth):
+ """Create the profile line for the the given image.
+
+ :param roiInfo: information about the ROI: start point, end point and
+ type ("X", "Y", "D")
+ :param numpy.ndarray currentData: the 2D image or the 3D stack of images
+ on which we compute the profile.
+ :param origin: (ox, oy) the offset from origin
+ :type origin: 2-tuple of float
+ :param scale: (sx, sy) the scale to use
+ :type scale: 2-tuple of float
+ :param int lineWidth: width of the profile line
+ :return: `profile, area, profileName, xLabel`, where:
+ - profile is a 2D array of the profiles of the stack of images.
+ For a single image, the profile is a curve, so this parameter
+ has a shape *(1, len(curve))*
+ - area is a tuple of two 1D arrays with 4 values each. They represent
+ the effective ROI area corners in plot coords.
+ - profileName is a string describing the ROI, meant to be used as
+ title of the profile plot
+ - xLabel is a string describing the meaning of the X axis on the
+ profile plot ("rows", "columns", "distance")
+
+ :rtype: tuple(ndarray, (ndarray, ndarray), str, str)
+ """
+ if currentData is None or roiInfo is None or lineWidth is None:
+ raise ValueError("createProfile called with invalide arguments")
+
+ # force 3D data (stack of images)
+ if len(currentData.shape) == 2:
+ currentData3D = currentData.reshape((1,) + currentData.shape)
+ elif len(currentData.shape) == 3:
+ currentData3D = currentData
+
+ roiWidth = max(1, lineWidth)
+ roiStart, roiEnd, lineProjectionMode = roiInfo
+
+ if lineProjectionMode == 'X': # Horizontal profile on the whole image
+ profile, area = _alignedFullProfile(currentData3D,
+ origin, scale,
+ roiStart[1], roiWidth,
+ axis=0)
+
+ yMin, yMax = min(area[1]), max(area[1]) - 1
+ if roiWidth <= 1:
+ profileName = 'Y = %g' % yMin
+ else:
+ profileName = 'Y = [%g, %g]' % (yMin, yMax)
+ xLabel = 'Columns'
+
+ elif lineProjectionMode == 'Y': # Vertical profile on the whole image
+ profile, area = _alignedFullProfile(currentData3D,
+ origin, scale,
+ roiStart[0], roiWidth,
+ axis=1)
+
+ xMin, xMax = min(area[0]), max(area[0]) - 1
+ if roiWidth <= 1:
+ profileName = 'X = %g' % xMin
+ else:
+ profileName = 'X = [%g, %g]' % (xMin, xMax)
+ xLabel = 'Rows'
+
+ else: # Free line profile
+
+ # Convert start and end points in image coords as (row, col)
+ startPt = ((roiStart[1] - origin[1]) / scale[1],
+ (roiStart[0] - origin[0]) / scale[0])
+ endPt = ((roiEnd[1] - origin[1]) / scale[1],
+ (roiEnd[0] - origin[0]) / scale[0])
+
+ if (int(startPt[0]) == int(endPt[0]) or
+ int(startPt[1]) == int(endPt[1])):
+ # Profile is aligned with one of the axes
+
+ # Convert to int
+ startPt = int(startPt[0]), int(startPt[1])
+ endPt = int(endPt[0]), int(endPt[1])
+
+ # Ensure startPt <= endPt
+ if startPt[0] > endPt[0] or startPt[1] > endPt[1]:
+ startPt, endPt = endPt, startPt
+
+ if startPt[0] == endPt[0]: # Row aligned
+ rowRange = (int(startPt[0] + 0.5 - 0.5 * roiWidth),
+ int(startPt[0] + 0.5 + 0.5 * roiWidth))
+ colRange = startPt[1], endPt[1] + 1
+ profile = _alignedPartialProfile(currentData3D,
+ rowRange, colRange,
+ axis=0)
+
+ else: # Column aligned
+ rowRange = startPt[0], endPt[0] + 1
+ colRange = (int(startPt[1] + 0.5 - 0.5 * roiWidth),
+ int(startPt[1] + 0.5 + 0.5 * roiWidth))
+ profile = _alignedPartialProfile(currentData3D,
+ rowRange, colRange,
+ axis=1)
+
+ # Convert ranges to plot coords to draw ROI area
+ area = (
+ numpy.array(
+ (colRange[0], colRange[1], colRange[1], colRange[0]),
+ dtype=numpy.float32) * scale[0] + origin[0],
+ numpy.array(
+ (rowRange[0], rowRange[0], rowRange[1], rowRange[1]),
+ dtype=numpy.float32) * scale[1] + origin[1])
+
+ else: # General case: use bilinear interpolation
+
+ # Ensure startPt <= endPt
+ if (startPt[1] > endPt[1] or (
+ startPt[1] == endPt[1] and startPt[0] > endPt[0])):
+ startPt, endPt = endPt, startPt
+
+ profile = []
+ for slice_idx in range(currentData3D.shape[0]):
+ bilinear = BilinearImage(currentData3D[slice_idx, :, :])
+
+ profile.append(bilinear.profile_line(
+ (startPt[0] - 0.5, startPt[1] - 0.5),
+ (endPt[0] - 0.5, endPt[1] - 0.5),
+ roiWidth))
+ profile = numpy.array(profile)
+
+ # Extend ROI with half a pixel on each end, and
+ # Convert back to plot coords (x, y)
+ length = numpy.sqrt((endPt[0] - startPt[0]) ** 2 +
+ (endPt[1] - startPt[1]) ** 2)
+ dRow = (endPt[0] - startPt[0]) / length
+ dCol = (endPt[1] - startPt[1]) / length
+
+ # Extend ROI with half a pixel on each end
+ startPt = startPt[0] - 0.5 * dRow, startPt[1] - 0.5 * dCol
+ endPt = endPt[0] + 0.5 * dRow, endPt[1] + 0.5 * dCol
+
+ # Rotate deltas by 90 degrees to apply line width
+ dRow, dCol = dCol, -dRow
+
+ area = (
+ numpy.array((startPt[1] - 0.5 * roiWidth * dCol,
+ startPt[1] + 0.5 * roiWidth * dCol,
+ endPt[1] + 0.5 * roiWidth * dCol,
+ endPt[1] - 0.5 * roiWidth * dCol),
+ dtype=numpy.float32) * scale[0] + origin[0],
+ numpy.array((startPt[0] - 0.5 * roiWidth * dRow,
+ startPt[0] + 0.5 * roiWidth * dRow,
+ endPt[0] + 0.5 * roiWidth * dRow,
+ endPt[0] - 0.5 * roiWidth * dRow),
+ dtype=numpy.float32) * scale[1] + origin[1])
+
+ y0, x0 = startPt
+ y1, x1 = endPt
+ if x1 == x0 or y1 == y0:
+ profileName = 'From (%g, %g) to (%g, %g)' % (x0, y0, x1, y1)
+ else:
+ m = (y1 - y0) / (x1 - x0)
+ b = y0 - m * x0
+ profileName = 'y = %g * x %+g ; width=%d' % (m, b, roiWidth)
+ xLabel = 'Distance'
+
+ return profile, area, profileName, xLabel
+
+
+# ProfileToolBar ##############################################################
+
+class ProfileToolBar(qt.QToolBar):
+ """QToolBar providing profile tools operating on a :class:`PlotWindow`.
+
+ Attributes:
+
+ - plot: Associated :class:`PlotWindow` on which the profile line is drawn.
+ - actionGroup: :class:`QActionGroup` of available actions.
+
+ To run the following sample code, a QApplication must be initialized.
+ First, create a PlotWindow and add a :class:`ProfileToolBar`.
+
+ >>> from silx.gui.plot import PlotWindow
+ >>> from silx.gui.plot.Profile import ProfileToolBar
+
+ >>> plot = PlotWindow() # Create a PlotWindow
+ >>> toolBar = ProfileToolBar(plot=plot) # Create a profile toolbar
+ >>> plot.addToolBar(toolBar) # Add it to plot
+ >>> plot.show() # To display the PlotWindow with the profile toolbar
+
+ :param plot: :class:`PlotWindow` instance on which to operate.
+ :param profileWindow: Plot widget instance where to
+ display the profile curve or None to create one.
+ :param str title: See :class:`QToolBar`.
+ :param parent: See :class:`QToolBar`.
+ """
+ # TODO Make it a QActionGroup instead of a QToolBar
+
+ _POLYGON_LEGEND = '__ProfileToolBar_ROI_Polygon'
+
+ def __init__(self, parent=None, plot=None, profileWindow=None,
+ title='Profile Selection'):
+ super(ProfileToolBar, self).__init__(title, parent)
+ assert plot is not None
+ self.plot = plot
+
+ self._overlayColor = None
+ self._defaultOverlayColor = 'red' # update when active image change
+
+ self._roiInfo = None # Store start and end points and type of ROI
+
+ self._profileWindow = profileWindow
+ """User provided plot widget in which the profile curve is plotted.
+ None if no custom profile plot was provided."""
+
+ self._profileMainWindow = None
+ """Main window providing 2 profile plot widgets for 1D or 2D profiles.
+ The window provides two public methods
+ - :meth:`setProfileDimensions`
+ - :meth:`getPlot`: return handle on the actual plot widget
+ currently being used
+ None if the user specified a custom profile plot window.
+ """
+
+ if self._profileWindow is None:
+ self._profileMainWindow = ProfileMainWindow(self)
+
+ # Actions
+ self.browseAction = qt.QAction(
+ icons.getQIcon('normal'),
+ 'Browsing Mode', None)
+ self.browseAction.setToolTip(
+ 'Enables zooming interaction mode')
+ self.browseAction.setCheckable(True)
+ self.browseAction.triggered[bool].connect(self._browseActionTriggered)
+
+ self.hLineAction = qt.QAction(
+ icons.getQIcon('shape-horizontal'),
+ 'Horizontal Profile Mode', None)
+ self.hLineAction.setToolTip(
+ 'Enables horizontal profile selection mode')
+ self.hLineAction.setCheckable(True)
+ self.hLineAction.toggled[bool].connect(self._hLineActionToggled)
+
+ self.vLineAction = qt.QAction(
+ icons.getQIcon('shape-vertical'),
+ 'Vertical Profile Mode', None)
+ self.vLineAction.setToolTip(
+ 'Enables vertical profile selection mode')
+ self.vLineAction.setCheckable(True)
+ self.vLineAction.toggled[bool].connect(self._vLineActionToggled)
+
+ self.lineAction = qt.QAction(
+ icons.getQIcon('shape-diagonal'),
+ 'Free Line Profile Mode', None)
+ self.lineAction.setToolTip(
+ 'Enables line profile selection mode')
+ self.lineAction.setCheckable(True)
+ self.lineAction.toggled[bool].connect(self._lineActionToggled)
+
+ self.clearAction = qt.QAction(
+ icons.getQIcon('profile-clear'),
+ 'Clear Profile', None)
+ self.clearAction.setToolTip(
+ 'Clear the profile Region of interest')
+ self.clearAction.setCheckable(False)
+ self.clearAction.triggered.connect(self.clearProfile)
+
+ # ActionGroup
+ self.actionGroup = qt.QActionGroup(self)
+ self.actionGroup.addAction(self.browseAction)
+ self.actionGroup.addAction(self.hLineAction)
+ self.actionGroup.addAction(self.vLineAction)
+ self.actionGroup.addAction(self.lineAction)
+
+ self.browseAction.setChecked(True)
+
+ # Add actions to ToolBar
+ self.addAction(self.browseAction)
+ self.addAction(self.hLineAction)
+ self.addAction(self.vLineAction)
+ self.addAction(self.lineAction)
+ self.addAction(self.clearAction)
+
+ # Add width spin box to toolbar
+ self.addWidget(qt.QLabel('W:'))
+ self.lineWidthSpinBox = qt.QSpinBox(self)
+ self.lineWidthSpinBox.setRange(0, 1000)
+ self.lineWidthSpinBox.setValue(1)
+ self.lineWidthSpinBox.valueChanged[int].connect(
+ self._lineWidthSpinBoxValueChangedSlot)
+ self.addWidget(self.lineWidthSpinBox)
+
+ self.plot.sigInteractiveModeChanged.connect(
+ self._interactiveModeChanged)
+
+ # Enable toolbar only if there is an active image
+ self.setEnabled(self.plot.getActiveImage(just_legend=True) is not None)
+ self.plot.sigActiveImageChanged.connect(
+ self._activeImageChanged)
+
+ # listen to the profile window signals to clear profile polygon on close
+ if self.getProfileMainWindow() is not None:
+ self.getProfileMainWindow().sigClose.connect(self.clearProfile)
+
+ @property
+ @deprecated(replacement="getProfilePlot", since_version="0.5.0")
+ def profileWindow(self):
+ return self.getProfilePlot()
+
+ def getProfilePlot(self):
+ """Return plot widget in which the profile curve or the
+ profile image is plotted.
+ """
+ if self.getProfileMainWindow() is not None:
+ return self.getProfileMainWindow().getPlot()
+
+ # in case the user provided a custom plot for profiles
+ return self._profileWindow
+
+ def getProfileMainWindow(self):
+ """Return window containing the profile curve widget.
+ This can return *None* if a custom profile plot window was
+ specified in the constructor.
+ """
+ return self._profileMainWindow
+
+ def _activeImageChanged(self, previous, legend):
+ """Handle active image change: toggle enabled toolbar, update curve"""
+ self.setEnabled(legend is not None)
+ if legend is not None:
+ # Update default profile color
+ activeImage = self.plot.getActiveImage()
+ if isinstance(activeImage, items.ColormapMixIn):
+ self._defaultOverlayColor = cursorColorForColormap(
+ activeImage.getColormap()['name'])
+ else:
+ self._defaultOverlayColor = 'black'
+
+ self.updateProfile()
+
+ def _lineWidthSpinBoxValueChangedSlot(self, value):
+ """Listen to ROI width widget to refresh ROI and profile"""
+ self.updateProfile()
+
+ def _interactiveModeChanged(self, source):
+ """Handle plot interactive mode changed:
+
+ If changed from elsewhere, disable drawing tool
+ """
+ if source is not self:
+ self.browseAction.setChecked(True)
+
+ def _hLineActionToggled(self, checked):
+ """Handle horizontal line profile action toggle"""
+ if checked:
+ self.plot.setInteractiveMode('draw', shape='hline',
+ color=None, source=self)
+ self.plot.sigPlotSignal.connect(self._plotWindowSlot)
+ else:
+ self.plot.sigPlotSignal.disconnect(self._plotWindowSlot)
+
+ def _vLineActionToggled(self, checked):
+ """Handle vertical line profile action toggle"""
+ if checked:
+ self.plot.setInteractiveMode('draw', shape='vline',
+ color=None, source=self)
+ self.plot.sigPlotSignal.connect(self._plotWindowSlot)
+ else:
+ self.plot.sigPlotSignal.disconnect(self._plotWindowSlot)
+
+ def _lineActionToggled(self, checked):
+ """Handle line profile action toggle"""
+ if checked:
+ self.plot.setInteractiveMode('draw', shape='line',
+ color=None, source=self)
+ self.plot.sigPlotSignal.connect(self._plotWindowSlot)
+ else:
+ self.plot.sigPlotSignal.disconnect(self._plotWindowSlot)
+
+ def _browseActionTriggered(self, checked):
+ """Handle browse action mode triggered by user."""
+ if checked:
+ self.clearProfile()
+ self.plot.setInteractiveMode('zoom', source=self)
+ if self.getProfileMainWindow() is not None:
+ self.getProfileMainWindow().hide()
+
+ def _plotWindowSlot(self, event):
+ """Listen to Plot to handle drawing events to refresh ROI and profile.
+ """
+ if event['event'] not in ('drawingProgress', 'drawingFinished'):
+ return
+
+ checkedAction = self.actionGroup.checkedAction()
+ if checkedAction == self.hLineAction:
+ lineProjectionMode = 'X'
+ elif checkedAction == self.vLineAction:
+ lineProjectionMode = 'Y'
+ elif checkedAction == self.lineAction:
+ lineProjectionMode = 'D'
+ else:
+ return
+
+ roiStart, roiEnd = event['points'][0], event['points'][1]
+
+ self._roiInfo = roiStart, roiEnd, lineProjectionMode
+ self.updateProfile()
+
+ @property
+ def overlayColor(self):
+ """The color to use for the ROI.
+
+ If set to None (the default), the overlay color is adapted to the
+ active image colormap and changes if the active image colormap changes.
+ """
+ return self._overlayColor or self._defaultOverlayColor
+
+ @overlayColor.setter
+ def overlayColor(self, color):
+ self._overlayColor = color
+ self.updateProfile()
+
+ def clearProfile(self):
+ """Remove profile curve and profile area."""
+ self._roiInfo = None
+ self.updateProfile()
+
+ def updateProfile(self):
+ """Update the displayed profile and profile ROI.
+
+ This uses the current active image of the plot and the current ROI.
+ """
+ image = self.plot.getActiveImage()
+ if image is None:
+ return
+
+ # Clean previous profile area, and previous curve
+ self.plot.remove(self._POLYGON_LEGEND, kind='item')
+ self.getProfilePlot().clear()
+ self.getProfilePlot().setGraphTitle('')
+ self.getProfilePlot().setGraphXLabel('X')
+ self.getProfilePlot().setGraphYLabel('Y')
+
+ self._createProfile(currentData=image.getData(copy=False),
+ origin=image.getOrigin(),
+ scale=image.getScale(),
+ colormap=None, # Not used for 2D data
+ z=image.getZValue())
+
+ def _createProfile(self, currentData, origin, scale, colormap, z):
+ """Create the profile line for the the given image.
+
+ :param numpy.ndarray currentData: the image or the stack of images
+ on which we compute the profile
+ :param origin: (ox, oy) the offset from origin
+ :type origin: 2-tuple of float
+ :param scale: (sx, sy) the scale to use
+ :type scale: 2-tuple of float
+ :param dict colormap: The colormap to use
+ :param int z: The z layer of the image
+ """
+ if self._roiInfo is None:
+ return
+
+ profile, area, profileName, xLabel = createProfile(
+ roiInfo=self._roiInfo,
+ currentData=currentData,
+ origin=origin,
+ scale=scale,
+ lineWidth=self.lineWidthSpinBox.value())
+
+ self.getProfilePlot().setGraphTitle(profileName)
+
+ dataIs3D = len(currentData.shape) > 2
+ if dataIs3D:
+ self.getProfilePlot().addImage(profile,
+ legend=profileName,
+ xlabel=xLabel,
+ ylabel="Frame index (depth)",
+ colormap=colormap)
+ else:
+ coords = numpy.arange(len(profile[0]), dtype=numpy.float32)
+ self.getProfilePlot().addCurve(coords,
+ profile[0],
+ legend=profileName,
+ xlabel=xLabel,
+ color=self.overlayColor)
+
+ self.plot.addItem(area[0], area[1],
+ legend=self._POLYGON_LEGEND,
+ color=self.overlayColor,
+ shape='polygon', fill=True,
+ replace=False, z=z + 1)
+
+ self._showProfileMainWindow()
+
+ def _showProfileMainWindow(self):
+ """If profile window was created by this toolbar,
+ try to avoid overlapping with the toolbar's parent window.
+ """
+ profileMainWindow = self.getProfileMainWindow()
+ if profileMainWindow is not None:
+ winGeom = self.window().frameGeometry()
+ qapp = qt.QApplication.instance()
+ screenGeom = qapp.desktop().availableGeometry(self)
+
+ spaceOnLeftSide = winGeom.left()
+ spaceOnRightSide = screenGeom.width() - winGeom.right()
+
+ profileWindowWidth = profileMainWindow.frameGeometry().width()
+ if (profileWindowWidth < spaceOnRightSide or
+ spaceOnRightSide > spaceOnLeftSide):
+ # Place profile on the right
+ profileMainWindow.move(winGeom.right(), winGeom.top())
+ else:
+ # Not enough place on the right, place profile on the left
+ profileMainWindow.move(
+ max(0, winGeom.left() - profileWindowWidth), winGeom.top())
+
+ profileMainWindow.show()
+ else:
+ self.getProfilePlot().show()
+
+ def hideProfileWindow(self):
+ """Hide profile window.
+ """
+ # this method is currently only used by StackView when the perspective
+ # is changed
+ if self.getProfileMainWindow() is not None:
+ self.getProfileMainWindow().hide()
+
+
+class Profile3DToolBar(ProfileToolBar):
+ def __init__(self, parent=None, plot=None, title='Profile Selection'):
+ """QToolBar providing profile tools for an image or a stack of images.
+
+ :param parent: the parent QWidget
+ :param plot: :class:`PlotWindow` instance on which to operate.
+ :param str title: See :class:`QToolBar`.
+ :param parent: See :class:`QToolBar`.
+ """
+ # TODO: add param profileWindow (specify the plot used for profiles)
+ super(Profile3DToolBar, self).__init__(parent=parent, plot=plot,
+ title=title)
+
+ self.profile3dAction = ProfileToolButton(
+ parent=self, plot=self.plot)
+ self.profile3dAction.computeProfileIn2D()
+ self.profile3dAction.setVisible(True)
+ self.addWidget(self.profile3dAction)
+ self.profile3dAction.sigDimensionChanged.connect(self._setProfileType)
+
+ # create the 3D toolbar
+ self._profileType = None
+ self._setProfileType(2)
+
+ def _setProfileType(self, dimensions):
+ """Set the profile type: "1D" for a curve (profile on a single image)
+ or "2D" for an image (profile on a stack of images).
+
+ :param int dimensions: 1 for a "1D" profile or 2 for a "2D" profile
+ """
+ # fixme this assumes that we created _profileMainWindow
+ self._profileType = "1D" if dimensions == 1 else "2D"
+ self.getProfileMainWindow().setProfileType(self._profileType)
+ self.updateProfile()
+
+ def updateProfile(self):
+ """Method overloaded from :class:`ProfileToolBar`,
+ to pass the stack of images instead of just the active image.
+
+ In 1D profile mode, use the regular parent method.
+ """
+ if self._profileType == "1D":
+ super(Profile3DToolBar, self).updateProfile()
+ elif self._profileType == "2D":
+ stackData = self.plot.getCurrentView(copy=False,
+ returnNumpyArray=True)
+ if stackData is None:
+ return
+ self.plot.remove(self._POLYGON_LEGEND, kind='item')
+ self.getProfilePlot().clear()
+ self.getProfilePlot().setGraphTitle('')
+ self.getProfilePlot().setGraphXLabel('X')
+ self.getProfilePlot().setGraphYLabel('Y')
+
+ self._createProfile(currentData=stackData[0],
+ origin=stackData[1]['origin'],
+ scale=stackData[1]['scale'],
+ colormap=stackData[1]['colormap'],
+ z=stackData[1]['z'])
+ else:
+ raise ValueError(
+ "Profile type must be 1D or 2D, not %s" % self._profileType)
diff --git a/silx/gui/plot/ProfileMainWindow.py b/silx/gui/plot/ProfileMainWindow.py
new file mode 100644
index 0000000..835de2c
--- /dev/null
+++ b/silx/gui/plot/ProfileMainWindow.py
@@ -0,0 +1,99 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module contains a QMainWindow class used to display profile plots.
+"""
+from silx.gui import qt
+
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "21/02/2017"
+
+
+class ProfileMainWindow(qt.QMainWindow):
+ """QMainWindow providing 2 plot widgets specialized in
+ 1D and 2D plotting, with different toolbars.
+ Only one of the plots is visible at any given time.
+ """
+ sigProfileDimensionsChanged = qt.Signal(int)
+ """This signal is emitted when :meth:`setProfileDimensions` is called.
+ It carries the number of dimensions for the profile data (1 or 2).
+ It can be used to be notified that the profile plot widget has changed.
+ """
+
+ sigClose = qt.Signal()
+ """Emitted by :meth:`closeEvent` (e.g. when the window is closed
+ through the window manager's close icon)."""
+
+ def __init__(self, parent=None):
+ qt.QMainWindow.__init__(self, parent=parent)
+
+ self.setWindowTitle('Profile window')
+ # plots are created on demand, in self.setProfileDimensions()
+ self._plot1D = None
+ self._plot2D = None
+ # by default, profile is assumed to be a 1D curve
+ self._profileType = None
+ self.setProfileType("1D")
+
+ def setProfileType(self, profileType):
+ """Set which profile plot widget (1D or 2D) is to be used
+
+ :param str profileType: Type of profile data,
+ "1D" for a curve or "2D" for an image
+ """
+ # import here to avoid circular import
+ from .PlotWindow import Plot1D, Plot2D # noqa
+ self._profileType = profileType
+
+ if self._profileType == "1D":
+ if self._plot2D is not None:
+ self._plot2D.setParent(None) # necessary to avoid widget destruction
+ if self._plot1D is None:
+ self._plot1D = Plot1D()
+ self.setCentralWidget(self._plot1D)
+ elif self._profileType == "2D":
+ if self._plot1D is not None:
+ self._plot1D.setParent(None) # necessary to avoid widget destruction
+ if self._plot2D is None:
+ self._plot2D = Plot2D()
+ self.setCentralWidget(self._plot2D)
+ else:
+ raise ValueError("Profile type must be '1D' or '2D'")
+
+ self.sigProfileDimensionsChanged.emit(profileType)
+
+ def getPlot(self):
+ """Return the profile plot widget which is currently in use.
+ This can be the 2D profile plot or the 1D profile plot.
+ """
+ if self._profileType == "2D":
+ return self._plot2D
+ else:
+ return self._plot1D
+
+ def closeEvent(self, qCloseEvent):
+ self.sigClose.emit()
+ qCloseEvent.accept()
diff --git a/silx/gui/plot/ScatterMaskToolsWidget.py b/silx/gui/plot/ScatterMaskToolsWidget.py
new file mode 100644
index 0000000..793719d
--- /dev/null
+++ b/silx/gui/plot/ScatterMaskToolsWidget.py
@@ -0,0 +1,529 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""Widget providing a set of tools to draw masks on a PlotWidget.
+
+This widget is meant to work with a modified :class:`silx.gui.plot.PlotWidget`
+
+- :class:`ScatterMask`: Handle scatter mask update and history
+- :class:`ScatterMaskToolsWidget`: GUI for :class:`ScatterMask`
+- :class:`ScatterMaskToolsDockWidget`: DockWidget to integrate in :class:`PlotWindow`
+"""
+
+from __future__ import division
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "07/04/2017"
+
+
+import math
+import logging
+import os
+import numpy
+import sys
+
+from .. import qt
+from ...image import shapes
+
+from ._BaseMaskToolsWidget import BaseMask, BaseMaskToolsWidget, BaseMaskToolsDockWidget
+from .Colors import cursorColorForColormap, rgba
+
+
+_logger = logging.getLogger(__name__)
+
+
+class ScatterMask(BaseMask):
+ """A 1D mask for scatter data.
+ """
+ def __init__(self, scatter=None):
+ """
+
+ :param scatter: :class:`silx.gui.plot.items.Scatter` instance
+ """
+ BaseMask.__init__(self, scatter)
+
+ def _getXY(self):
+ x = self._dataItem.getXData(copy=False)
+ y = self._dataItem.getYData(copy=False)
+ return x, y
+
+ def getDataValues(self):
+ """Return scatter data values as a 1D array.
+
+ :rtype: 1D numpy.ndarray
+ """
+ return self._dataItem.getValueData(copy=False)
+
+ def save(self, filename, kind):
+ if kind == 'npy':
+ try:
+ numpy.save(filename, self.getMask(copy=False))
+ except IOError:
+ raise RuntimeError("Mask file can't be written")
+ elif kind in ["csv", "txt"]:
+ try:
+ numpy.savetxt(filename, self.getMask(copy=False))
+ except IOError:
+ raise RuntimeError("Mask file can't be written")
+
+ def updatePoints(self, level, indices, mask=True):
+ """Mask/Unmask points with given indices.
+
+ :param int level: Mask level to update.
+ :param indices: Sequence or 1D array of indices of points to be
+ updated
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ if mask:
+ self._mask[indices] = level
+ else:
+ # unmask only where mask level is the specified value
+ indices_stencil = numpy.zeros_like(self._mask, dtype=numpy.bool)
+ indices_stencil[indices] = True
+ self._mask[numpy.logical_and(self._mask == level, indices_stencil)] = 0
+ self._notify()
+
+ # update shapes
+ def updatePolygon(self, level, vertices, mask=True):
+ """Mask/Unmask a polygon of the given mask level.
+
+ :param int level: Mask level to update.
+ :param vertices: Nx2 array of polygon corners as (y, x) or (row, col)
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ polygon = shapes.Polygon(vertices)
+ x, y = self._getXY()
+
+ # TODO: this could be optimized if necessary
+ indices_in_polygon = [idx for idx in range(len(x)) if
+ polygon.is_inside(y[idx], x[idx])]
+
+ self.updatePoints(level, indices_in_polygon, mask)
+
+ def updateRectangle(self, level, y, x, height, width, mask=True):
+ """Mask/Unmask data inside a rectangle
+
+ :param int level: Mask level to update.
+ :param float y: Y coordinate of bottom left corner of the rectangle
+ :param float x: X coordinate of bottom left corner of the rectangle
+ :param float height:
+ :param float width:
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ vertices = [(y, x),
+ (y + height, x),
+ (y + height, x + width),
+ (y, x + width)]
+ self.updatePolygon(level, vertices, mask)
+
+ def updateDisk(self, level, cy, cx, radius, mask=True):
+ """Mask/Unmask a disk of the given mask level.
+
+ :param int level: Mask level to update.
+ :param float cy: Disk center (y).
+ :param float cx: Disk center (x).
+ :param float radius: Radius of the disk in mask array unit
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ x, y = self._getXY()
+ stencil = (y - cy)**2 + (x - cx)**2 < radius**2
+ self.updateStencil(level, stencil, mask)
+
+ def updateLine(self, level, y0, x0, y1, x1, width, mask=True):
+ """Mask/Unmask points inside a rectangle defined by a line (two
+ end points) and a width.
+
+ :param int level: Mask level to update.
+ :param float y0: Row of the starting point.
+ :param float x0: Column of the starting point.
+ :param float row1: Row of the end point.
+ :param float col1: Column of the end point.
+ :param float width: Width of the line.
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ # theta is the angle between the horizontal and the line
+ theta = math.atan((y1 - y0) / (x1 - x0)) if x1 - x0 else 0
+ w_over_2_sin_theta = width / 2. * math.sin(theta)
+ w_over_2_cos_theta = width / 2. * math.cos(theta)
+
+ vertices = [(y0 - w_over_2_cos_theta, x0 + w_over_2_sin_theta),
+ (y0 + w_over_2_cos_theta, x0 - w_over_2_sin_theta),
+ (y1 + w_over_2_cos_theta, x1 - w_over_2_sin_theta),
+ (y1 - w_over_2_cos_theta, x1 + w_over_2_sin_theta)]
+
+ self.updatePolygon(level, vertices, mask)
+
+
+class ScatterMaskToolsWidget(BaseMaskToolsWidget):
+ """Widget with tools for masking data points on a scatter in a
+ :class:`PlotWidget`."""
+
+ def __init__(self, parent=None, plot=None):
+ self._z = 2 # Mask layer in plot
+ self._data_scatter = None
+ """plot Scatter item for data"""
+ self._mask_scatter = None
+ """plot Scatter item for representing the mask"""
+
+ self._mask = ScatterMask()
+
+ super(ScatterMaskToolsWidget, self).__init__(parent, plot)
+
+ self._initWidgets()
+
+ def setSelectionMask(self, mask, copy=True):
+ """Set the mask to a new array.
+
+ :param numpy.ndarray mask: The array to use for the mask.
+ :type mask: numpy.ndarray of uint8, C-contiguous.
+ Array of other types are converted.
+ :param bool copy: True (the default) to copy the array,
+ False to use it as is if possible.
+ :return: None if failed, shape of mask as 1-tuple if successful.
+ The mask can be cropped or padded to fit active scatter,
+ the returned shape is that of the scatter data.
+ """
+ mask = numpy.array(mask, copy=False, dtype=numpy.uint8)
+
+ if self._data_scatter.getXData(copy=False).shape == (0,) \
+ or mask.shape == self._data_scatter.getXData(copy=False).shape:
+ self._mask.setMask(mask, copy=copy)
+ self._mask.commit()
+ return mask.shape
+ else:
+ raise ValueError("Mask does not have the same shape as the data")
+
+ # Handle mask refresh on the plot
+
+ def _updatePlotMask(self):
+ """Update mask image in plot"""
+ mask = self.getSelectionMask(copy=False)
+ if len(mask):
+ self.plot.addScatter(self._data_scatter.getXData(),
+ self._data_scatter.getYData(),
+ mask,
+ legend=self._maskName,
+ colormap=self._colormap,
+ z=self._z)
+ self._mask_scatter = self.plot._getItem(kind="scatter",
+ legend=self._maskName)
+ self._mask_scatter.setSymbolSize(
+ self._data_scatter.getSymbolSize() * 4.0
+ )
+ elif self.plot._getItem(kind="scatter",
+ legend=self._maskName) is not None:
+ self.plot.remove(self._maskName, kind='scatter')
+
+ # track widget visibility and plot active image changes
+
+ def showEvent(self, event):
+ try:
+ self.plot.sigActiveScatterChanged.disconnect(
+ self._activeScatterChangedAfterCare)
+ except (RuntimeError, TypeError):
+ pass
+ self._activeScatterChanged(None, None) # Init mask + enable/disable widget
+ self.plot.sigActiveScatterChanged.connect(self._activeScatterChanged)
+
+ def hideEvent(self, event):
+ self.plot.sigActiveScatterChanged.disconnect(self._activeScatterChanged)
+ if not self.browseAction.isChecked():
+ self.browseAction.trigger() # Disable drawing tool
+
+ if len(self.getSelectionMask(copy=False)):
+ self.plot.sigActiveScatterChanged.connect(
+ self._activeScatterChangedAfterCare)
+
+ def _activeScatterChangedAfterCare(self, previous, next):
+ """Check synchro of active scatter and mask when mask widget is hidden.
+
+ If active image has no more the same size as the mask, the mask is
+ removed, otherwise it is adjusted to z.
+ """
+ # check that content changed was the active scatter
+ activeScatter = self.plot._getActiveItem(kind="scatter")
+
+ if activeScatter is None or activeScatter.getLegend() == self._maskName:
+ # No active scatter or active scatter is the mask...
+ self.plot.sigActiveScatterChanged.disconnect(
+ self._activeScatterChangedAfterCare)
+ else:
+ colormap = activeScatter.getColormap()
+ self._defaultOverlayColor = rgba(cursorColorForColormap(colormap['name']))
+ self._setMaskColors(self.levelSpinBox.value(),
+ self.transparencySlider.value() /
+ self.transparencySlider.maximum())
+
+ self._z = activeScatter.getZValue() + 1
+ self._data_scatter = activeScatter
+ if self._data_scatter.getXData(copy=False).shape != self.getSelectionMask(copy=False).shape:
+ # scatter has not the same size, remove mask and stop listening
+ if self.plot._getItem(kind="scatter", legend=self._maskName):
+ self.plot.remove(self._maskName, kind='scatter')
+
+ self.plot.sigActiveScatterChanged.disconnect(
+ self._activeScatterChangedAfterCare)
+ else:
+ # Refresh in case z changed
+ self._mask.setDataItem(self._data_scatter)
+ self._updatePlotMask()
+
+ def _activeScatterChanged(self, previous, next):
+ """Update widget and mask according to active scatter changes"""
+ activeScatter = self.plot._getActiveItem(kind="scatter")
+
+ if activeScatter is None or activeScatter.getLegend() == self._maskName:
+ # No active scatter or active scatter is the mask...
+ self.setEnabled(False)
+
+ self._data_scatter = None
+ self._mask.reset()
+ self._mask.commit()
+
+ else: # There is an active scatter
+ self.setEnabled(True)
+
+ colormap = activeScatter.getColormap()
+ self._defaultOverlayColor = rgba(cursorColorForColormap(colormap['name']))
+ self._setMaskColors(self.levelSpinBox.value(),
+ self.transparencySlider.value() /
+ self.transparencySlider.maximum())
+
+ self._z = activeScatter.getZValue() + 1
+ self._data_scatter = activeScatter
+ self._mask.setDataItem(self._data_scatter)
+ if self._data_scatter.getXData(copy=False).shape != self.getSelectionMask(copy=False).shape:
+ self._mask.reset(self._data_scatter.getXData(copy=False).shape)
+ self._mask.commit()
+ else:
+ # Refresh in case z changed
+ self._updatePlotMask()
+
+ self._updateInteractiveMode()
+
+ # Handle whole mask operations
+
+ def load(self, filename):
+ """Load a mask from an image file.
+
+ :param str filename: File name from which to load the mask
+ :raise Exception: An exception in case of failure
+ :raise RuntimeWarning: In case the mask was applied but with some
+ import changes to notice
+ """
+ _, extension = os.path.splitext(filename)
+ extension = extension.lower()[1:]
+ if extension == "npy":
+ try:
+ mask = numpy.load(filename)
+ except IOError:
+ _logger.error("Can't load filename '%s'", filename)
+ _logger.debug("Backtrace", exc_info=True)
+ raise RuntimeError('File "%s" is not a numpy file.',
+ filename)
+ elif extension in ["txt", "csv"]:
+ try:
+ mask = numpy.loadtxt(filename)
+ except IOError:
+ _logger.error("Can't load filename '%s'", filename)
+ _logger.debug("Backtrace", exc_info=True)
+ raise RuntimeError('File "%s" is not a numpy txt file.',
+ filename)
+ else:
+ msg = "Extension '%s' is not supported."
+ raise RuntimeError(msg % extension)
+
+ self.setSelectionMask(mask, copy=False)
+
+ def _loadMask(self):
+ """Open load mask dialog"""
+ dialog = qt.QFileDialog(self)
+ dialog.setWindowTitle("Load Mask")
+ dialog.setModal(1)
+ filters = [
+ 'NumPy binary file (*.npy)',
+ 'CSV text file (*.csv)',
+ ]
+ dialog.setNameFilters(filters)
+ dialog.setFileMode(qt.QFileDialog.ExistingFile)
+ dialog.setDirectory(self.maskFileDir)
+ if not dialog.exec_():
+ dialog.close()
+ return
+
+ filename = dialog.selectedFiles()[0]
+ dialog.close()
+
+ self.maskFileDir = os.path.dirname(filename)
+ try:
+ self.load(filename)
+ # except RuntimeWarning as e:
+ # message = e.args[0]
+ # msg = qt.QMessageBox(self)
+ # msg.setIcon(qt.QMessageBox.Warning)
+ # msg.setText("Mask loaded but an operation was applied.\n" + message)
+ # msg.exec_()
+ except Exception as e:
+ message = e.args[0]
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setText("Cannot load mask from file. " + message)
+ msg.exec_()
+
+ def _saveMask(self):
+ """Open Save mask dialog"""
+ dialog = qt.QFileDialog(self)
+ dialog.setWindowTitle("Save Mask")
+ dialog.setModal(1)
+ filters = [
+ 'NumPy binary file (*.npy)',
+ 'CSV text file (*.csv)',
+ ]
+ dialog.setNameFilters(filters)
+ dialog.setFileMode(qt.QFileDialog.AnyFile)
+ dialog.setAcceptMode(qt.QFileDialog.AcceptSave)
+ dialog.setDirectory(self.maskFileDir)
+ if not dialog.exec_():
+ dialog.close()
+ return
+
+ # convert filter name to extension name with the .
+ extension = dialog.selectedNameFilter().split()[-1][2:-1]
+ filename = dialog.selectedFiles()[0]
+ dialog.close()
+
+ if not filename.lower().endswith(extension):
+ filename += extension
+
+ if os.path.exists(filename):
+ try:
+ os.remove(filename)
+ except IOError:
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setText("Cannot save.\n"
+ "Input Output Error: %s" % (sys.exc_info()[1]))
+ msg.exec_()
+ return
+
+ self.maskFileDir = os.path.dirname(filename)
+ try:
+ self.save(filename, extension[1:])
+ except Exception as e:
+ msg = qt.QMessageBox(self)
+ msg.setIcon(qt.QMessageBox.Critical)
+ msg.setText("Cannot save file %s\n%s" % (filename, e.args[0]))
+ msg.exec_()
+
+ def resetSelectionMask(self):
+ """Reset the mask"""
+ self._mask.reset(
+ shape=self._data_scatter.getXData(copy=False).shape)
+ self._mask.commit()
+
+ def _plotDrawEvent(self, event):
+ """Handle draw events from the plot"""
+ if (self._drawingMode is None or
+ event['event'] not in ('drawingProgress', 'drawingFinished')):
+ return
+
+ if not len(self._data_scatter.getXData(copy=False)):
+ return
+
+ level = self.levelSpinBox.value()
+
+ if (self._drawingMode == 'rectangle' and
+ event['event'] == 'drawingFinished'):
+ doMask = self._isMasking()
+
+ self._mask.updateRectangle(
+ level,
+ y=event['y'],
+ x=event['x'],
+ height=abs(event['height']),
+ width=abs(event['width']),
+ mask=doMask)
+ self._mask.commit()
+
+ elif (self._drawingMode == 'polygon' and
+ event['event'] == 'drawingFinished'):
+ doMask = self._isMasking()
+ vertices = event['points']
+ vertices = vertices.astype(numpy.int)[:, (1, 0)] # (y, x)
+ self._mask.updatePolygon(level, vertices, doMask)
+ self._mask.commit()
+
+ elif self._drawingMode == 'pencil':
+ doMask = self._isMasking()
+ # convert from plot to array coords
+ x, y = event['points'][-1]
+ brushSize = self.pencilSpinBox.value()
+
+ if self._lastPencilPos != (y, x):
+ if self._lastPencilPos is not None:
+ # Draw the line
+ self._mask.updateLine(
+ level,
+ self._lastPencilPos[0], self._lastPencilPos[1],
+ y, x,
+ brushSize,
+ doMask)
+
+ # Draw the very first, or last point
+ self._mask.updateDisk(level, y, x, brushSize / 2., doMask)
+
+ if event['event'] == 'drawingFinished':
+ self._mask.commit()
+ self._lastPencilPos = None
+ else:
+ self._lastPencilPos = y, x
+
+ def _loadRangeFromColormapTriggered(self):
+ """Set range from active scatter colormap range"""
+ if self._data_scatter is not None:
+ # Update thresholds according to colormap
+ colormap = self._data_scatter.getColormap()
+ if colormap['autoscale']:
+ min_ = numpy.nanmin(self._data_scatter.getValueData(copy=False))
+ max_ = numpy.nanmax(self._data_scatter.getValueData(copy=False))
+ else:
+ min_, max_ = colormap['vmin'], colormap['vmax']
+ self.minLineEdit.setText(str(min_))
+ self.maxLineEdit.setText(str(max_))
+
+
+class ScatterMaskToolsDockWidget(BaseMaskToolsDockWidget):
+ """:class:`ScatterMaskToolsWidget` embedded in a QDockWidget.
+
+ For integration in a :class:`PlotWindow`.
+
+ :param parent: See :class:`QDockWidget`
+ :param plot: The PlotWidget this widget is operating on
+ :paran str name: The title of this widget
+ """
+ def __init__(self, parent=None, plot=None, name='Mask'):
+ super(ScatterMaskToolsDockWidget, self).__init__(parent, name)
+ self.setWidget(ScatterMaskToolsWidget(plot=plot))
+ self.widget().sigMaskChanged.connect(self._emitSigMaskChanged)
diff --git a/silx/gui/plot/StackView.py b/silx/gui/plot/StackView.py
new file mode 100644
index 0000000..9bb0cf0
--- /dev/null
+++ b/silx/gui/plot/StackView.py
@@ -0,0 +1,1033 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""QWidget displaying a 3D volume as a stack of 2D images.
+
+The :class:`StackView` class implements this widget.
+
+Basic usage of :class:`StackView` is through the following methods:
+
+- :meth:`StackView.getColormap`, :meth:`StackView.setColormap` to update the
+ default colormap to use and update the currently displayed image.
+- :meth:`StackView.setStack` to update the displayed image.
+
+The :class:`StackView` uses :class:`PlotWindow` and also
+exposes a subset of the :class:`silx.gui.plot.Plot` API for further control
+(plot title, axes labels, ...).
+
+The :class:`StackViewMainWindow` class implements a widget that adds a status
+bar displaying the 3D index and the value under the mouse cursor.
+
+Example::
+
+ import numpy
+ import sys
+ from silx.gui import qt
+ from silx.gui.plot.StackView import StackViewMainWindow
+
+
+ app = qt.QApplication(sys.argv[1:])
+
+ # synthetic data, stack of 100 images of size 200x300
+ mystack = numpy.fromfunction(
+ lambda i, j, k: numpy.sin(i/15.) + numpy.cos(j/4.) + 2 * numpy.sin(k/6.),
+ (100, 200, 300)
+ )
+
+
+ sv = StackViewMainWindow()
+ sv.setColormap("jet", autoscale=True)
+ sv.setStack(mystack)
+ sv.setLabels(["1st dim (0-99)", "2nd dim (0-199)",
+ "3rd dim (0-299)"])
+ sv.show()
+
+ app.exec_()
+
+"""
+
+__authors__ = ["P. Knobel", "H. Payno"]
+__license__ = "MIT"
+__date__ = "20/01/2017"
+
+import numpy
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+from silx.gui import qt
+from .. import icons
+from . import items, PlotWindow, PlotActions
+from .Colors import cursorColorForColormap
+from .PlotTools import LimitsToolBar
+from .Profile import Profile3DToolBar
+from ..widgets.FrameBrowser import HorizontalSliderWithBrowser
+
+from silx.utils.array_like import DatasetView, ListOfImages
+from silx.math import calibration
+
+
+class StackView(qt.QMainWindow):
+ """Stack view widget, to display and browse through stack of
+ images.
+
+ The profile tool can be switched to "3D" mode, to compute the profile
+ on each image of the stack (not only the active image currently displayed)
+ and display the result as a slice.
+
+ :param QWidget parent: the Qt parent, or None
+ :param backend: The backend to use for the plot (default: matplotlib).
+ See :class:`.Plot` for the list of supported backend.
+ :type backend: str or :class:`BackendBase.BackendBase`
+ :param bool resetzoom: Toggle visibility of reset zoom action.
+ :param bool autoScale: Toggle visibility of axes autoscale actions.
+ :param bool logScale: Toggle visibility of axes log scale actions.
+ :param bool grid: Toggle visibility of grid mode action.
+ :param bool colormap: Toggle visibility of colormap action.
+ :param bool aspectRatio: Toggle visibility of aspect ratio button.
+ :param bool yInverted: Toggle visibility of Y axis direction button.
+ :param bool copy: Toggle visibility of copy action.
+ :param bool save: Toggle visibility of save action.
+ :param bool print_: Toggle visibility of print action.
+ :param bool control: True to display an Options button with a sub-menu
+ to show legends, toggle crosshair and pan with arrows.
+ (Default: False)
+ :param position: True to display widget with (x, y) mouse position
+ (Default: False).
+ It also supports a list of (name, funct(x, y)->value)
+ to customize the displayed values.
+ See :class:`silx.gui.plot.PlotTools.PositionInfo`.
+ :param bool mask: Toggle visibilty of mask action.
+ """
+ # Qt signals
+ valueChanged = qt.Signal(object, object, object)
+ """Signals that the data value under the cursor has changed.
+
+ It provides: row, column, data value.
+ """
+
+ sigPlaneSelectionChanged = qt.Signal(int)
+ """Signal emitted when there is a change is perspective/displayed axes.
+
+ It provides the perspective as an integer, with the following meaning:
+
+ - 0: axis Y is the 2nd dimension, axis X is the 3rd dimension
+ - 1: axis Y is the 1st dimension, axis X is the 3rd dimension
+ - 2: axis Y is the 1st dimension, axis X is the 2nd dimension
+ """
+
+ sigStackChanged = qt.Signal(int)
+ """Signal emitted when the stack is changed.
+ This happens when a new volume is loaded, or when the current volume
+ is transposed (change in perspective).
+
+ The signal provides the size (number of pixels) of the stack.
+ This will be 0 if the stack is cleared, else it will be a positive
+ integer.
+ """
+
+ def __init__(self, parent=None, resetzoom=True, backend=None,
+ autoScale=False, logScale=False, grid=False,
+ colormap=True, aspectRatio=True, yinverted=True,
+ copy=True, save=True, print_=True, control=False,
+ position=None, mask=True):
+ qt.QMainWindow.__init__(self, parent)
+ if parent is not None:
+ # behave as a widget
+ self.setWindowFlags(qt.Qt.Widget)
+ else:
+ self.setWindowTitle('StackView')
+
+ self._stack = None
+ """Loaded stack, as a 3D array, a 3D dataset or a list of 2D arrays."""
+ self.__transposed_view = None
+ """View on :attr:`_stack` with the axes sorted, to have
+ the orthogonal dimension first"""
+ self._perspective = 0
+ """Orthogonal dimension (depth) in :attr:`_stack`"""
+
+ self.__imageLegend = '__StackView__image' + str(id(self))
+ self.__autoscaleCmap = False
+ """Flag to disable/enable colormap auto-scaling
+ based on the min/max values of the entire 3D volume"""
+ self.__dimensionsLabels = ["Dimension 0", "Dimension 1",
+ "Dimension 2"]
+ """These labels are displayed on the X and Y axes.
+ :meth:`setLabels` updates this attribute."""
+
+ self._first_stack_dimension = 0
+ """Used for dimension labels and combobox"""
+
+ central_widget = qt.QWidget(self)
+
+ self._plot = PlotWindow(parent=central_widget, backend=backend,
+ resetzoom=resetzoom, autoScale=autoScale,
+ logScale=logScale, grid=grid,
+ curveStyle=False, colormap=colormap,
+ aspectRatio=aspectRatio, yInverted=yinverted,
+ copy=copy, save=save, print_=print_,
+ control=control, position=position,
+ roi=False, mask=mask)
+ self.sigInteractiveModeChanged = self._plot.sigInteractiveModeChanged
+ self.sigActiveImageChanged = self._plot.sigActiveImageChanged
+ self.sigPlotSignal = self._plot.sigPlotSignal
+
+ self._plot.profile = Profile3DToolBar(parent=self._plot,
+ plot=self)
+ self._plot.addToolBar(self._plot.profile)
+ self._plot.setGraphXLabel('Columns')
+ self._plot.setGraphYLabel('Rows')
+ self._plot.sigPlotSignal.connect(self._plotCallback)
+
+ self.__planeSelection = PlanesWidget(self._plot)
+ self.__planeSelection.sigPlaneSelectionChanged.connect(self.__setPerspective)
+
+ self._browser_label = qt.QLabel("Image index (Dim0):")
+
+ self._browser = HorizontalSliderWithBrowser(central_widget)
+ self._browser.valueChanged[int].connect(self.__updateFrameNumber)
+ self._browser.setEnabled(False)
+
+ layout = qt.QGridLayout()
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.addWidget(self._plot, 0, 0, 1, 3)
+ layout.addWidget(self.__planeSelection, 1, 0)
+ layout.addWidget(self._browser_label, 1, 1)
+ layout.addWidget(self._browser, 1, 2)
+
+ central_widget.setLayout(layout)
+ self.setCentralWidget(central_widget)
+
+ # clear profile lines when the perspective changes (plane browsed changed)
+ self.__planeSelection.sigPlaneSelectionChanged.connect(
+ self._plot.profile.getProfilePlot().clear)
+ self.__planeSelection.sigPlaneSelectionChanged.connect(
+ self._plot.profile.clearProfile)
+
+ def setOptionVisible(self, isVisible):
+ """
+ Set the visibility of the browsing options.
+
+ :param bool isVisible: True to have the options visible, else False
+ """
+ self._browser.setVisible(isVisible)
+ self.__planeSelection.setVisible(isVisible)
+
+ def _plotCallback(self, eventDict):
+ """Callback for plot events.
+
+ Emit :attr:`valueChanged` signal, with (x, y, value) tuple of the
+ cursor location in the plot."""
+ if eventDict['event'] == 'mouseMoved':
+ activeImage = self.getActiveImage()
+ if activeImage is not None:
+ data = activeImage.getData()
+ height, width = data.shape
+
+ # Get corresponding coordinate in image
+ origin = activeImage.getOrigin()
+ scale = activeImage.getScale()
+ x = int((eventDict['x'] - origin[0]) / scale[0])
+ y = int((eventDict['y'] - origin[1]) / scale[1])
+
+ if 0 <= x < width and 0 <= y < height:
+ self.valueChanged.emit(float(x), float(y),
+ data[y][x])
+ else:
+ self.valueChanged.emit(float(x), float(y),
+ None)
+
+ def __setPerspective(self, perspective):
+ """Function called when the browsed/orthogonal dimension changes.
+ Updates :attr:`_perspective`, transposes data, updates the plot,
+ emits :attr:`sigPlaneSelectionChanged` and :attr:`sigStackChanged`.
+
+ :param int perspective: the new browsed dimension
+ """
+ if perspective == self._perspective:
+ return
+ else:
+ if perspective > 2 or perspective < 0:
+ raise ValueError(
+ "Perspective must be 0, 1 or 2, not %s" % perspective)
+
+ self._perspective = perspective
+ self.__createTransposedView()
+ self.__updateFrameNumber(self._browser.value())
+ self._plot.resetZoom()
+ self.__updatePlotLabels()
+ self._browser_label.setText("Image index (Dim%d):" %
+ (self._first_stack_dimension + perspective))
+
+ self.sigPlaneSelectionChanged.emit(perspective)
+ self.sigStackChanged.emit(self._stack.size if
+ self._stack is not None else 0)
+
+ def __updatePlotLabels(self):
+ """Update plot axes labels depending on perspective"""
+ y, x = (1, 2) if self._perspective == 0 else \
+ (0, 2) if self._perspective == 1 else (0, 1)
+ self.setGraphXLabel(self.__dimensionsLabels[x])
+ self.setGraphYLabel(self.__dimensionsLabels[y])
+
+ def __createTransposedView(self):
+ """Create the new view on the stack depending on the perspective
+ (set orthogonal axis browsed on the viewer as first dimension)
+ """
+ assert self._stack is not None
+ assert 0 <= self._perspective < 3
+
+ # ensure we have the stack encapsulated in an array like object
+ # having a transpose() method
+ if isinstance(self._stack, numpy.ndarray):
+ self.__transposed_view = self._stack
+
+ elif h5py is not None and isinstance(self._stack, h5py.Dataset) or \
+ isinstance(self._stack, DatasetView):
+ self.__transposed_view = DatasetView(self._stack)
+
+ elif isinstance(self._stack, ListOfImages):
+ self.__transposed_view = ListOfImages(self._stack)
+
+ # transpose the array like object if necessary
+ if self._perspective == 1:
+ self.__transposed_view = self.__transposed_view.transpose((1, 0, 2))
+ elif self._perspective == 2:
+ self.__transposed_view = self.__transposed_view.transpose((2, 0, 1))
+
+ self._browser.setRange(0, self.__transposed_view.shape[0] - 1)
+ self._browser.setValue(0)
+
+ def setFrameNumber(self, number):
+ """Set the frame selection to a specific value\
+
+ :param int number: Number of the frame
+ """
+ self._browser.setValue(number)
+
+ def __updateFrameNumber(self, index):
+ """Update the current image.
+
+ :param index: index of the frame to be displayed
+ """
+ assert self.__transposed_view is not None
+ self._plot.addImage(self.__transposed_view[index, :, :],
+ origin=self._getImageOrigin(),
+ scale=self._getImageScale(),
+ legend=self.__imageLegend,
+ resetzoom=False, replace=False)
+ self._plot.setGraphTitle("Image z=%g" % self._getImageZ(index))
+
+ def _set3DScaleAndOrigin(self, calibrations):
+ """Set scale and origin for all 3 axes, to be used when plotting
+ an image.
+
+ See setStack for parameter documentation
+ """
+ if calibrations is None:
+ self.calibrations3D = (calibration.NoCalibration(),
+ calibration.NoCalibration(),
+ calibration.NoCalibration())
+ else:
+ self.calibrations3D = []
+ for calib in calibrations:
+ if hasattr(calib, "__len__") and len(calib) == 2:
+ calib = calibration.LinearCalibration(calib[0], calib[1])
+ elif calib is None:
+ calib = calibration.NoCalibration()
+ elif not isinstance(calib, calibration.AbstractCalibration):
+ raise TypeError("calibration must be a 2-tuple, None or" +
+ " an instance of an AbstractCalibration " +
+ "subclass")
+ self.calibrations3D.append(calib)
+
+ def _getXYZCalibs(self):
+ xy_dims = [0, 1, 2]
+ xy_dims.remove(self._perspective)
+
+ xcalib = self.calibrations3D[max(xy_dims)]
+ ycalib = self.calibrations3D[min(xy_dims)]
+ zcalib = self.calibrations3D[self._perspective]
+
+ return xcalib, ycalib, zcalib
+
+ def _getImageScale(self):
+ """
+ :return: 2-tuple (XScale, YScale) for current image view
+ """
+ xcalib, ycalib, _zcalib = self._getXYZCalibs()
+ return xcalib.get_slope(), ycalib.get_slope()
+
+ def _getImageOrigin(self):
+ """
+ :return: 2-tuple (XOrigin, YOrigin) for current image view
+ """
+ xcalib, ycalib, _zcalib = self._getXYZCalibs()
+ return xcalib(0), ycalib(0)
+
+ def _getImageZ(self, index):
+ """
+ :param idx: 0-based image index in the stack
+ :return: calibrated Z value corresponding to the image idx
+ """
+ _xcalib, _ycalib, zcalib = self._getXYZCalibs()
+ return zcalib(index)
+
+ # public API
+ def setStack(self, stack, perspective=0, reset=True, calibrations=None):
+ """Set the 3D stack.
+
+ The perspective parameter is used to define which dimension of the 3D
+ array is to be used as frame index. The lowest remaining dimension
+ number is the row index of the displayed image (Y axis), and the highest
+ remaining dimension is the column index (X axis).
+
+ :param stack: 3D stack, or `None` to clear plot.
+ :type stack: 3D numpy.ndarray, or 3D h5py.Dataset, or list/tuple of 2D
+ numpy arrays, or None.
+ :param int perspective: Dimension for the frame index: 0, 1 or 2.
+ By default, the dimension for the image index is the first
+ dimension of the 3D stack (``perspective=0``).
+ :param bool reset: Whether to reset zoom or not.
+ :param calibrations: Sequence of 3 calibration objects for each axis.
+ These objects can be a subclass of :class:`AbstractCalibration`,
+ or 2-tuples *(a, b)* where *a* is the y-intercept and *b* is the
+ slope of a linear calibration (:math:`x \mapsto a + b x`)
+ """
+ if stack is None:
+ self.clear()
+ self.sigStackChanged.emit(0)
+ return
+
+ self._set3DScaleAndOrigin(calibrations)
+
+ # stack as list of 2D arrays: must be converted into an array_like
+ if not isinstance(stack, numpy.ndarray):
+ if h5py is None or not isinstance(stack, h5py.Dataset):
+ try:
+ assert hasattr(stack, "__len__")
+ for img in stack:
+ assert hasattr(img, "shape")
+ assert len(img.shape) == 2
+ except AssertionError:
+ raise ValueError(
+ "Stack must be a 3D array/dataset or a list of " +
+ "2D arrays.")
+ stack = ListOfImages(stack)
+
+ assert len(stack.shape) == 3, "data must be 3D"
+
+ self._stack = stack
+ self.__createTransposedView()
+
+ if perspective != self._perspective:
+ self.__setPerspective(perspective)
+
+ # This call to setColormap redefines the meaning of autoscale
+ # for 3D volume: take global min/max rather than frame min/max
+ if self.__autoscaleCmap:
+ self.setColormap(autoscale=True)
+
+ # init plot
+ self._plot.addImage(self.__transposed_view[0, :, :],
+ legend=self.__imageLegend,
+ colormap=self.getColormap(),
+ origin=self._getImageOrigin(),
+ scale=self._getImageScale(),
+ resetzoom=False)
+ self._plot.setActiveImage(self.__imageLegend)
+ self._plot.setGraphTitle("Image z=%g" % self._getImageZ(0))
+ self.__updatePlotLabels()
+
+ if reset:
+ self._plot.resetZoom()
+
+ # enable and init browser
+ self._browser.setEnabled(True)
+
+ if perspective != self._perspective:
+ self.__planeSelection.setPerspective(perspective)
+ # this causes self.__setPerspective to be called, which emits
+ # sigStackChanged and sigPlaneSelectionChanged
+
+ else:
+ self.sigStackChanged.emit(stack.size)
+
+ def getStack(self, copy=True, returnNumpyArray=False):
+ """Get the original stack, as a 3D array or dataset.
+
+ The output has the form: [data, params]
+ where params is a dictionary containing display parameters.
+
+ :param bool copy: If True (default), then the object is copied
+ and returned as a numpy array.
+ Else, a reference to original data is returned, if possible.
+ If the original data is not a numpy array and parameter
+ returnNumpyArray is True, a copy will be made anyway.
+ :param bool returnNumpyArray: If True, the returned object is
+ guaranteed to be a numpy array.
+ :return: 3D stack and parameters.
+ :rtype: (numpy.ndarray, dict)
+ """
+ image = self.getActiveImage()
+ if image is None:
+ return None
+
+ if isinstance(image, items.ColormapMixIn):
+ colormap = image.getColormap()
+ else:
+ colormap = None
+
+ params = {
+ 'info': image.getInfo(),
+ 'origin': image.getOrigin(),
+ 'scale': image.getScale(),
+ 'z': image.getZValue(),
+ 'selectable': image.isSelectable(),
+ 'draggable': image.isDraggable(),
+ 'colormap': colormap,
+ 'xlabel': image.getXLabel(),
+ 'ylabel': image.getYLabel(),
+ }
+ if returnNumpyArray or copy:
+ return numpy.array(self._stack, copy=copy), params
+
+ # if a list of 2D arrays was cast into a ListOfImages,
+ # return the original list
+ if isinstance(self._stack, ListOfImages):
+ return self._stack.images, params
+
+ return self._stack, params
+
+ def getCurrentView(self, copy=True, returnNumpyArray=False):
+ """Get the stack, as it is currently displayed.
+
+ The first index of the returned stack is always the frame
+ index. If the perspective has been changed in the widget since the
+ data was first loaded, this will be reflected in the order of the
+ dimensions of the returned object.
+
+ The output has the form: [data, params]
+ where params is a dictionary containing display parameters.
+
+ :param bool copy: If True (default), then the object is copied
+ and returned as a numpy array.
+ Else, a reference to original data is returned, if possible.
+ If the original data is not a numpy array and parameter
+ `returnNumpyArray` is `True`, a copy will be made anyway.
+ :param bool returnNumpyArray: If `True`, the returned object is
+ guaranteed to be a numpy array.
+ :return: 3D stack and parameters.
+ :rtype: (numpy.ndarray, dict)
+ """
+ image = self.getActiveImage()
+ if image is None:
+ return None
+
+ if isinstance(image, items.ColormapMixIn):
+ colormap = image.getColormap()
+ else:
+ colormap = None
+
+ params = {
+ 'info': image.getInfo(),
+ 'origin': image.getOrigin(),
+ 'scale': image.getScale(),
+ 'z': image.getZValue(),
+ 'selectable': image.isSelectable(),
+ 'draggable': image.isDraggable(),
+ 'colormap': colormap,
+ 'xlabel': image.getXLabel(),
+ 'ylabel': image.getYLabel(),
+ }
+ if returnNumpyArray or copy:
+ return numpy.array(self.__transposed_view, copy=copy), params
+ return self.__transposed_view, params
+
+ def getActiveImage(self, just_legend=False):
+ """Returns the currently active image object.
+
+ It returns None in case of not having an active image.
+
+ :param bool just_legend: True to get the legend of the image,
+ False (the default) to get the image data and info.
+ Note: :class:`StackView` uses the same legend for all frames.
+ :return: legend or image object
+ :rtype: str or list or None
+ """
+ return self._plot.getActiveImage(just_legend=just_legend)
+
+ def clear(self):
+ """Clear the widget:
+
+ - clear the plot
+ - clear the loaded data volume
+ """
+ self._stack = None
+ self.__transposed_view = None
+ self._perspective = 0
+ self._browser.setEnabled(False)
+ self._plot.clear()
+
+ def resetZoom(self):
+ """Reset the plot limits to the bounds of the data and redraw the plot.
+ """
+ self._plot.resetZoom()
+
+ def getGraphTitle(self):
+ """Return the plot main title as a str."""
+ return self._plot.getGraphTitle()
+
+ def setGraphTitle(self, title=""):
+ """Set the plot main title.
+
+ :param str title: Main title of the plot (default: '')
+ """
+ return self._plot.setGraphTitle(title)
+
+ def setLabels(self, labels=None):
+ """Set the labels to be displayed on the plot axes.
+
+ You must provide a sequence of 3 strings, corresponding to the 3
+ dimensions of the original data volume.
+ The proper label will automatically be selected for each plot axis
+ when the volume is rotated (when different axes are selected as the
+ X and Y axes).
+
+ :param list(str) labels: 3 labels corresponding to the 3 dimensions
+ of the data volumes.
+ """
+
+ default_labels = ["Dimension %d" % self._first_stack_dimension,
+ "Dimension %d" % (self._first_stack_dimension + 1),
+ "Dimension %d" % (self._first_stack_dimension + 2)]
+ if labels is None:
+ new_labels = default_labels
+ else:
+ # filter-out None
+ new_labels = []
+ for i, label in enumerate(labels):
+ new_labels.append(label or default_labels[i])
+
+ self.__dimensionsLabels = new_labels
+ self.__updatePlotLabels()
+
+ def getGraphXLabel(self):
+ """Return the current horizontal axis label as a str."""
+ return self._plot.getGraphXLabel()
+
+ def setGraphXLabel(self, label=None):
+ """Set the plot horizontal axis label.
+
+ :param str label: The horizontal axis label
+ """
+ if label is None:
+ label = self.__dimensionsLabels[1 if self._perspective == 2 else 2]
+ self._plot.setGraphXLabel(label)
+
+ def getGraphYLabel(self, axis='left'):
+ """Return the current vertical axis label as a str.
+
+ :param str axis: The Y axis for which to get the label (left or right)
+ """
+ return self._plot.getGraphYLabel(axis)
+
+ def setGraphYLabel(self, label=None, axis='left'):
+ """Set the vertical axis label on the plot.
+
+ :param str label: The Y axis label
+ :param str axis: The Y axis for which to set the label (left or right)
+ """
+ if label is None:
+ label = self.__dimensionsLabels[1 if self._perspective == 0 else 0]
+ self._plot.setGraphYLabel(label, axis)
+
+ def setYAxisInverted(self, flag=True):
+ """Set the Y axis orientation.
+
+ :param bool flag: True for Y axis going from top to bottom,
+ False for Y axis going from bottom to top
+ """
+ self._plot.setYAxisInverted(flag)
+
+ def isYAxisInverted(self):
+ """Return True if Y axis goes from top to bottom, False otherwise."""
+ return self._backend.isYAxisInverted()
+
+ def getSupportedColormaps(self):
+ """Get the supported colormap names as a tuple of str.
+
+ The list should at least contain and start by:
+ ('gray', 'reversed gray', 'temperature', 'red', 'green', 'blue')
+ """
+ return self._plot.getSupportedColormaps()
+
+ def getColormap(self):
+ """Get the current colormap description.
+
+ :return: A description of the current colormap.
+ See :meth:`setColormap` for details.
+ :rtype: dict
+ """
+ # "default" colormap used by addImage when image is added without
+ # specifying a special colormap
+ return self._plot.getDefaultColormap()
+
+ def setColormap(self, colormap=None, normalization=None,
+ autoscale=None, vmin=None, vmax=None, colors=None):
+ """Set the colormap and update active image.
+
+ Parameters that are not provided are taken from the current colormap.
+
+ The colormap parameter can also be a dict with the following keys:
+
+ - *name*: string. The colormap to use:
+ 'gray', 'reversed gray', 'temperature', 'red', 'green', 'blue'.
+ - *normalization*: string. The mapping to use for the colormap:
+ either 'linear' or 'log'.
+ - *autoscale*: bool. Whether to use autoscale (True) or range
+ provided by keys
+ 'vmin' and 'vmax' (False).
+ - *vmin*: float. The minimum value of the range to use if 'autoscale'
+ is False.
+ - *vmax*: float. The maximum value of the range to use if 'autoscale'
+ is False.
+ - *colors*: optional. Nx3 or Nx4 array of float in [0, 1] or uint8.
+ List of RGB or RGBA colors to use (only if name is None)
+
+ :param colormap: Name of the colormap in
+ 'gray', 'reversed gray', 'temperature', 'red', 'green', 'blue'.
+ Or the description of the colormap as a dict.
+ :type colormap: dict or str.
+ :param str normalization: Colormap mapping: 'linear' or 'log'.
+ :param bool autoscale: Whether to use autoscale or [vmin, vmax] range.
+ Default value of autoscale is True if data is a numpy array,
+ False if data is a h5py dataset.
+ :param float vmin: The minimum value of the range to use if
+ 'autoscale' is False.
+ :param float vmax: The maximum value of the range to use if
+ 'autoscale' is False.
+ :param numpy.ndarray colors: Only used if name is None.
+ Custom colormap colors as Nx3 or Nx4 RGB or RGBA arrays
+ """
+ cmapDict = self.getColormap()
+
+ if isinstance(colormap, dict):
+ # Support colormap parameter as a dict
+ errmsg = "If colormap is provided as a dict, all other parameters"
+ errmsg += " must not be specified when calling setColormap"
+ assert normalization is None, errmsg
+ assert autoscale is None, errmsg
+ assert vmin is None, errmsg
+ assert vmax is None, errmsg
+ assert colors is None, errmsg
+ cmapDict.update(colormap)
+
+ else:
+ if colormap is not None:
+ cmapDict['name'] = colormap
+ if normalization is not None:
+ cmapDict['normalization'] = normalization
+ if colors is not None:
+ cmapDict['colors'] = colors
+
+ # Default meaning of autoscale is to reset min and max
+ # each time a new image is added to the plot.
+ # We want to use min and max of global volume,
+ # and not change them when browsing slides
+ cmapDict['autoscale'] = False
+
+ if autoscale is None:
+ # set default
+ autoscale = False
+ # TODO: assess cost of computing min/max for large 3D array
+ # if isinstance(self._stack, numpy.ndarray):
+ # autoscale = True
+ # else: # h5py.Dataset
+ # autoscale = False
+ elif autoscale and isinstance(self._stack, h5py.Dataset):
+ # h5py dataset has no min()/max() methods
+ raise RuntimeError(
+ "Cannot auto-scale colormap for a h5py dataset")
+ else:
+ autoscale = autoscale
+ self.__autoscaleCmap = autoscale
+ if autoscale and (self._stack is not None):
+ cmapDict['vmin'] = self._stack.min()
+ cmapDict['vmax'] = self._stack.max()
+ else:
+ if vmin is not None:
+ cmapDict['vmin'] = vmin
+ if vmax is not None:
+ cmapDict['vmax'] = vmax
+
+ cursorColor = cursorColorForColormap(cmapDict['name'])
+ self._plot.setInteractiveMode('zoom', color=cursorColor)
+
+ self._plot.setDefaultColormap(cmapDict)
+
+ # Update active image colormap
+ activeImage = self._plot.getActiveImage()
+ if isinstance(activeImage, items.ColormapMixIn):
+ activeImage.setColormap(self.getColormap())
+
+ def isKeepDataAspectRatio(self):
+ """Returns whether the plot is keeping data aspect ratio or not."""
+ return self._plot.isKeepDataAspectRatio()
+
+ def setKeepDataAspectRatio(self, flag=True):
+ """Set whether the plot keeps data aspect ratio or not.
+
+ :param bool flag: True to respect data aspect ratio
+ """
+ self._plot.setKeepDataAspectRatio(flag)
+
+ def getProfileToolbar(self):
+ """Profile tools attached to this plot
+
+ See :class:`silx.gui.plot.Profile.Profile3DToolBar`
+ """
+ return self._plot.profile
+
+ def getProfileWindow1D(self):
+ """Plot window used to display 1D profile curve.
+
+ :return: :class:`Plot1D`
+ """
+ return self._plot.profile.getProfileWindow1D()
+
+ def getProfileWindow2D(self):
+ """Plot window used to display 2D profile image.
+
+ :return: :class:`Plot2D`
+ """
+ return self._plot.profile.getProfileWindow2D()
+
+ # kind of private methods, but needed by Profile
+ def remove(self, legend=None,
+ kind=('curve', 'image', 'item', 'marker')):
+ """See :meth:`Plot.Plot.remove`"""
+ self._plot.remove(legend, kind)
+
+ def setInteractiveMode(self, *args, **kwargs):
+ """
+ See :meth:`Plot.Plot.setInteractiveMode`
+ """
+ self._plot.setInteractiveMode(*args, **kwargs)
+
+ def addItem(self, *args, **kwargs):
+ """
+ See :meth:`Plot.Plot.addItem`
+ """
+ self._plot.addItem(*args, **kwargs)
+
+ def setFirstStackDimension(self, first_stack_dimension):
+ """When viewing the last 3 dimensions of an n-D array (n>3), you can
+ use this method to change the text in the combobox.
+
+ For instance, for a 7-D array, first stack dim is 4, so the default
+ "Dim1-Dim2" text should be replaced with "Dim5-Dim6" (dimensions
+ numbers are 0-based).
+
+ :param int first_stack_dim: First stack dimension (n-3) when viewing the
+ last 3 dimensions of an n-D array.
+ """
+ old_state = self.__planeSelection.blockSignals(True)
+ self.__planeSelection.setFirstStackDimension(first_stack_dimension)
+ self.__planeSelection.blockSignals(old_state)
+ self._first_stack_dimension = first_stack_dimension
+ self._browser_label.setText("Image index (Dim%d):" % first_stack_dimension)
+
+
+class PlanesWidget(qt.QWidget):
+ """Widget for the plane/perspective selection
+
+ :param parent: the parent QWidget
+ """
+ sigPlaneSelectionChanged = qt.Signal(int)
+
+ def __init__(self, parent):
+ super(PlanesWidget, self).__init__(parent)
+
+ self.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum)
+ layout0 = qt.QHBoxLayout()
+ self.setLayout(layout0)
+ layout0.setContentsMargins(0, 0, 0, 0)
+
+ layout0.addWidget(qt.QLabel("Axes selection:"))
+
+ # By default, the first dimension (dim0) is the frame index/depth/z,
+ # the second dimension is the image row number/y axis
+ # and the third dimension is the image column index/x axis
+
+ # 1
+ # | 0
+ # |/__2
+ self.qcbAxisSelection = qt.QComboBox(self)
+ self._setCBChoices(first_stack_dimension=0)
+ self.qcbAxisSelection.currentIndexChanged[int].connect(
+ self.__planeSelectionChanged)
+
+ layout0.addWidget(self.qcbAxisSelection)
+
+ def __planeSelectionChanged(self, idx):
+ """Callback function when the combobox selection changes
+
+ idx is the dimension number orthogonal to the slice plane,
+ following the convention:
+
+ - slice plane Dim1-Dim2: perspective 0
+ - slice plane Dim0-Dim2: perspective 1
+ - slice plane Dim0-Dim1: perspective 2
+ """
+ self.sigPlaneSelectionChanged.emit(idx)
+
+ def _setCBChoices(self, first_stack_dimension):
+ self.qcbAxisSelection.clear()
+
+ dim1dim2 = 'Dim%d-Dim%d' % (first_stack_dimension + 1,
+ first_stack_dimension + 2)
+ dim0dim2 = 'Dim%d-Dim%d' % (first_stack_dimension,
+ first_stack_dimension + 2)
+ dim0dim1 = 'Dim%d-Dim%d' % (first_stack_dimension,
+ first_stack_dimension + 1)
+
+ self.qcbAxisSelection.addItem(icons.getQIcon("cube-front"), dim1dim2)
+ self.qcbAxisSelection.addItem(icons.getQIcon("cube-bottom"), dim0dim2)
+ self.qcbAxisSelection.addItem(icons.getQIcon("cube-left"), dim0dim1)
+
+ def setFirstStackDimension(self, first_stack_dim):
+ """When viewing the last 3 dimensions of an n-D array (n>3), you can
+ use this method to change the text in the combobox.
+
+ For instance, for a 7-D array, first stack dim is 4, so the default
+ "Dim1-Dim2" text should be replaced with "Dim5-Dim6" (dimensions
+ numbers are 0-based).
+
+ :param int first_stack_dim: First stack dimension (n-3) when viewing the
+ last 3 dimensions of an n-D array.
+ """
+ self._setCBChoices(first_stack_dim)
+
+ def setPerspective(self, perspective):
+ """Update the combobox selection.
+
+ - slice plane Dim1-Dim2: perspective 0
+ - slice plane Dim0-Dim2: perspective 1
+ - slice plane Dim0-Dim1: perspective 2
+
+ :param perspective: Orthogonal dimension number (0, 1, or 2)
+ """
+ self.qcbAxisSelection.setCurrentIndex(perspective)
+
+
+class StackViewMainWindow(StackView):
+ """This class is a :class:`StackView` with a menu, an additional toolbar
+ to set the plot limits, and a status bar to display the value and 3D
+ index of the data samples hovered by the mouse cursor.
+
+ :param QWidget parent: Parent widget, or None
+ """
+ def __init__(self, parent=None):
+ self._dataInfo = None
+ super(StackViewMainWindow, self).__init__(parent)
+ self.setWindowFlags(qt.Qt.Window)
+
+ # Add toolbars and status bar
+ self.addToolBar(qt.Qt.BottomToolBarArea,
+ LimitsToolBar(plot=self._plot))
+
+ self.statusBar()
+
+ menu = self.menuBar().addMenu('File')
+ menu.addAction(self._plot.saveAction)
+ menu.addAction(self._plot.printAction)
+ menu.addSeparator()
+ action = menu.addAction('Quit')
+ action.triggered[bool].connect(qt.QApplication.instance().quit)
+
+ menu = self.menuBar().addMenu('Edit')
+ menu.addAction(self._plot.copyAction)
+ menu.addSeparator()
+ menu.addAction(self._plot.resetZoomAction)
+ menu.addAction(self._plot.colormapAction)
+ menu.addAction(PlotActions.KeepAspectRatioAction(self._plot, self))
+ menu.addAction(PlotActions.YAxisInvertedAction(self._plot, self))
+
+ menu = self.menuBar().addMenu('Profile')
+ menu.addAction(self._plot.profile.browseAction)
+ menu.addAction(self._plot.profile.hLineAction)
+ menu.addAction(self._plot.profile.vLineAction)
+ menu.addAction(self._plot.profile.lineAction)
+ menu.addSeparator()
+ menu.addAction(self._plot.profile.clearAction)
+ self._plot.profile.profile3dAction.computeProfileIn2D()
+ menu.addMenu(self._plot.profile.profile3dAction.menu())
+
+ # Connect to StackView's signal
+ self.valueChanged.connect(self._statusBarSlot)
+
+ def _statusBarSlot(self, x, y, value):
+ """Update status bar with coordinates/value from plots."""
+ # todo (after implementing calibration):
+ # - use floats for (x, y, z)
+ # - display both indices (dim0, dim1, dim2) and (x, y, z)
+ msg = "Cursor out of range"
+ if x is not None and y is not None:
+ img_idx = self._browser.value()
+
+ if self._perspective == 0:
+ dim0, dim1, dim2 = img_idx, int(y), int(x)
+ elif self._perspective == 1:
+ dim0, dim1, dim2 = int(y), img_idx, int(x)
+ elif self._perspective == 2:
+ dim0, dim1, dim2 = int(y), int(x), img_idx
+
+ msg = 'Position: (%d, %d, %d)' % (dim0, dim1, dim2)
+ if value is not None:
+ msg += ', Value: %g' % value
+ if self._dataInfo is not None:
+ msg = self._dataInfo + ', ' + msg
+
+ self.statusBar().showMessage(msg)
+
+ def setStack(self, stack, *args, **kwargs):
+ """Set the displayed stack.
+
+ See :meth:`StackView.setStack` for details.
+ """
+ if hasattr(stack, 'dtype') and hasattr(stack, 'shape'):
+ assert len(stack.shape) == 3
+ nframes, height, width = stack.shape
+ self._dataInfo = 'Data: %dx%dx%d (%s)' % (nframes, height, width,
+ str(stack.dtype))
+ self.statusBar().showMessage(self._dataInfo)
+ else:
+ self._dataInfo = None
+
+ # Set the new stack in StackView widget
+ super(StackViewMainWindow, self).setStack(stack, *args, **kwargs)
+ self.setStatusBar(None)
diff --git a/silx/gui/plot/_BaseMaskToolsWidget.py b/silx/gui/plot/_BaseMaskToolsWidget.py
new file mode 100644
index 0000000..91bbe1c
--- /dev/null
+++ b/silx/gui/plot/_BaseMaskToolsWidget.py
@@ -0,0 +1,1138 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module is a collection of base classes used in modules
+:mod:`.MaskToolsWidget` (images) and :mod:`.ScatterMaskToolsWidget`
+"""
+from __future__ import division
+
+
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "20/04/2017"
+
+import os
+
+import numpy
+
+from silx.gui import qt, icons
+from silx.gui.plot.Colors import rgba
+
+
+class BaseMask(qt.QObject):
+ """Base class for :class:`ImageMask` and :class:`ScatterMask`
+
+ A mask field with update operations.
+
+ A mask is an array of the same shape as some underlying data. The mask
+ array stores integer values in the range 0-255, to allow for 254 levels
+ of mask (value 0 is reserved for unmasked data).
+
+ The mask is updated using spatial selection methods: data located inside
+ a selected area is masked with a specified mask level.
+
+ """
+
+ sigChanged = qt.Signal()
+ """Signal emitted when the mask has changed"""
+
+ sigUndoable = qt.Signal(bool)
+ """Signal emitted when undo becomes possible/impossible"""
+
+ sigRedoable = qt.Signal(bool)
+ """Signal emitted when redo becomes possible/impossible"""
+
+ def __init__(self, dataItem=None):
+ self.historyDepth = 10
+ """Maximum number of operation stored in history list for undo"""
+ # Init lists for undo/redo
+ self._history = []
+ self._redo = []
+
+ # Store the mask
+ self._mask = numpy.array((), dtype=numpy.uint8)
+
+ # Store the plot item to be masked
+ self._dataItem = None
+ if dataItem is not None:
+ self.setDataItem(dataItem)
+ self.reset(self.getDataValues().shape)
+
+ super(BaseMask, self).__init__()
+
+ def setDataItem(self, item):
+ """Set a data item
+
+ :param item: A plot item, subclass of :class:`silx.gui.plot.items.Item`
+ :return:
+ """
+ self._dataItem = item
+
+ def getDataValues(self):
+ """Return data values, as a numpy array with the same shape
+ as the mask.
+
+ This method must be implemented in a subclass, as the way of
+ accessing data depends on the data item passed to :meth:`setDataItem`
+
+ :return: Data values associated with the data item.
+ :rtype: numpy.ndarray
+ """
+ raise NotImplementedError("To be implemented in subclass")
+
+ def _notify(self):
+ """Notify of mask change."""
+ self.sigChanged.emit()
+
+ def getMask(self, copy=True):
+ """Get the current mask as a numpy array.
+
+ :param bool copy: True (default) to get a copy of the mask.
+ If False, the returned array MUST not be modified.
+ :return: The array of the mask with dimension of the data to be masked.
+ :rtype: numpy.ndarray of uint8
+ """
+ return numpy.array(self._mask, copy=copy)
+
+ def setMask(self, mask, copy=True):
+ """Set the mask to a new array.
+
+ :param numpy.ndarray mask: The array to use for the mask.
+ :type mask: numpy.ndarray of uint8, C-contiguous.
+ Array of other types are converted.
+ :param bool copy: True (the default) to copy the array,
+ False to use it as is if possible.
+ """
+ self._mask = numpy.array(mask, copy=copy, order='C', dtype=numpy.uint8)
+ self._notify()
+
+ # History control
+ def resetHistory(self):
+ """Reset history"""
+ self._history = [numpy.array(self._mask, copy=True)]
+ self._redo = []
+ self.sigUndoable.emit(False)
+ self.sigRedoable.emit(False)
+
+ def commit(self):
+ """Append the current mask to history if changed"""
+ if (not self._history or self._redo or
+ not numpy.all(numpy.equal(self._mask, self._history[-1]))):
+ if self._redo:
+ self._redo = [] # Reset redo as a new action as been performed
+ self.sigRedoable[bool].emit(False)
+
+ while len(self._history) >= self.historyDepth:
+ self._history.pop(0)
+ self._history.append(numpy.array(self._mask, copy=True))
+
+ if len(self._history) == 2:
+ self.sigUndoable.emit(True)
+
+ def undo(self):
+ """Restore previous mask if any"""
+ if len(self._history) > 1:
+ self._redo.append(self._history.pop())
+ self._mask = numpy.array(self._history[-1], copy=True)
+ self._notify() # Do not store this change in history
+
+ if len(self._redo) == 1: # First redo
+ self.sigRedoable.emit(True)
+ if len(self._history) == 1: # Last value in history
+ self.sigUndoable.emit(False)
+
+ def redo(self):
+ """Restore previously undone modification if any"""
+ if self._redo:
+ self._mask = self._redo.pop()
+ self._history.append(numpy.array(self._mask, copy=True))
+ self._notify()
+
+ if not self._redo: # No more redo
+ self.sigRedoable.emit(False)
+ if len(self._history) == 2: # Something to undo
+ self.sigUndoable.emit(True)
+
+ # Whole mask operations
+
+ def clear(self, level):
+ """Set all values of the given mask level to 0.
+
+ :param int level: Value of the mask to set to 0.
+ """
+ assert 0 < level < 256
+ self._mask[self._mask == level] = 0
+ self._notify()
+
+ def invert(self, level):
+ """Invert mask of the given mask level.
+
+ 0 values become level and level values become 0.
+
+ :param int level: The level to invert.
+ """
+ assert 0 < level < 256
+ masked = self._mask == level
+ self._mask[self._mask == 0] = level
+ self._mask[masked] = 0
+ self._notify()
+
+ def reset(self, shape=None):
+ """Reset the mask to zero and change its shape.
+
+ :param shape: Shape of the new mask with the correct dimensionality
+ with regards to the data dimensionality,
+ or None to have an empty mask
+ :type shape: tuple of int
+ """
+ if shape is None:
+ # assume dimensionality never changes
+ shape = (0, ) * len(self._mask.shape) # empty array
+ shapeChanged = (shape != self._mask.shape)
+ self._mask = numpy.zeros(shape, dtype=numpy.uint8)
+ if shapeChanged:
+ self.resetHistory()
+
+ self._notify()
+
+ # To be implemented
+ def save(self, filename, kind):
+ """Save current mask in a file
+
+ :param str filename: The file where to save to mask
+ :param str kind: The kind of file to save (e.g 'npy')
+ :raise Exception: Raised if the file writing fail
+ """
+ raise NotImplementedError("To be implemented in subclass")
+
+ # update thresholds
+ def updateStencil(self, level, stencil, mask=True):
+ """Mask/Unmask points from boolean mask: all elements that are True
+ in the boolean mask are set to ``level`` (if ``mask=True``) or 0
+ (if ``mask=False``)
+
+ :param int level: Mask level to update.
+ :param stencil: Boolean mask.
+ :type stencil: numpy.array of same dimension as the mask
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ if mask:
+ self._mask[stencil] = level
+ else:
+ self._mask[numpy.logical_and(self._mask == level, stencil)] = 0
+ self._notify()
+
+ def updateBelowThreshold(self, level, threshold, mask=True):
+ """Mask/unmask all points whose values are below a threshold.
+
+ :param int level:
+ :param float threshold: Threshold
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ self.updateStencil(level,
+ self.getDataValues() < threshold,
+ mask)
+
+ def updateBetweenThresholds(self, level, min_, max_, mask=True):
+ """Mask/unmask all points whose values are in a range.
+
+ :param int level:
+ :param float min_: Lower threshold
+ :param float max_: Upper threshold
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ stencil = numpy.logical_and(min_ <= self.getDataValues(),
+ self.getDataValues() <= max_)
+ self.updateStencil(level, stencil, mask)
+
+ def updateAboveThreshold(self, level, threshold, mask=True):
+ """Mask/unmask all points whose values are above a threshold.
+
+ :param int level: Mask level to update.
+ :param float threshold: Threshold.
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ self.updateStencil(level,
+ self.getDataValues() > threshold,
+ mask)
+
+ def updateNotFinite(self, level, mask=True):
+ """Mask/unmask all points whose values are not finite.
+
+ :param int level: Mask level to update.
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ self.updateStencil(level,
+ numpy.logical_not(numpy.isfinite(self.getDataValues())),
+ mask)
+
+ # Drawing operations:
+ def updateRectangle(self, level, row, col, height, width, mask=True):
+ """Mask/Unmask data inside a rectangle, with the given mask level.
+
+ :param int level: Mask level to update, in range 1-255.
+ :param row: Starting row/y of the rectangle
+ :param col: Starting column/x of the rectangle
+ :param height:
+ :param width:
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ raise NotImplementedError("To be implemented in subclass")
+
+ def updatePolygon(self, level, vertices, mask=True):
+ """Mask/Unmask data inside a polygon, with the given mask level.
+
+ :param int level: Mask level to update.
+ :param vertices: Nx2 array of polygon corners as (row, col) / (y, x)
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ raise NotImplementedError("To be implemented in subclass")
+
+ def updatePoints(self, level, rows, cols, mask=True):
+ """Mask/Unmask points with given coordinates.
+
+ :param int level: Mask level to update.
+ :param rows: Rows/ordinates (y) of selected points
+ :type rows: 1D numpy.ndarray
+ :param cols: Columns/abscissa (x) of selected points
+ :type cols: 1D numpy.ndarray
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ raise NotImplementedError("To be implemented in subclass")
+
+ def updateDisk(self, level, crow, ccol, radius, mask=True):
+ """Mask/Unmask data located inside a disk of the given mask level.
+
+ :param int level: Mask level to update.
+ :param crow: Disk center row/ordinate (y).
+ :param ccol: Disk center column/abscissa.
+ :param float radius: Radius of the disk in mask array unit
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ raise NotImplementedError("To be implemented in subclass")
+
+ def updateLine(self, level, row0, col0, row1, col1, width, mask=True):
+ """Mask/Unmask a line of the given mask level.
+
+ :param int level: Mask level to update.
+ :param row0: Row/y of the starting point.
+ :param col0: Column/x of the starting point.
+ :param row1: Row/y of the end point.
+ :param col1: Column/x of the end point.
+ :param width: Width of the line in mask array unit.
+ :param bool mask: True to mask (default), False to unmask.
+ """
+ raise NotImplementedError("To be implemented in subclass")
+
+
+class BaseMaskToolsWidget(qt.QWidget):
+ """Base class for :class:`MaskToolsWidget` (image mask) and
+ :class:`scatterMaskToolsWidget`"""
+
+ sigMaskChanged = qt.Signal()
+ _maxLevelNumber = 255
+
+ def __init__(self, parent=None, plot=None):
+ # register if the user as force a color for the corresponding mask level
+ self._defaultColors = numpy.ones((self._maxLevelNumber + 1), dtype=numpy.bool)
+ # overlays colors set by the user
+ self._overlayColors = numpy.zeros((self._maxLevelNumber + 1, 3), dtype=numpy.float32)
+
+ self._plot = plot
+ self._maskName = '__MASK_TOOLS_%d' % id(self) # Legend of the mask
+
+ self._colormap = {
+ 'name': None,
+ 'normalization': 'linear',
+ 'autoscale': False,
+ 'vmin': 0, 'vmax': self._maxLevelNumber,
+ 'colors': None}
+ self._defaultOverlayColor = rgba('gray') # Color of the mask
+ self._setMaskColors(1, 0.5)
+
+ self._mask.sigChanged.connect(self._updatePlotMask)
+ self._mask.sigChanged.connect(self._emitSigMaskChanged)
+
+ self._drawingMode = None # Store current drawing mode
+ self._lastPencilPos = None
+ self._multipleMasks = 'exclusive'
+
+ super(BaseMaskToolsWidget, self).__init__(parent)
+
+ self._maskFileDir = qt.QDir.home().absolutePath()
+ self.plot.sigInteractiveModeChanged.connect(
+ self._interactiveModeChanged)
+
+ def _emitSigMaskChanged(self):
+ """Notify mask changes"""
+ self.sigMaskChanged.emit()
+
+ def getSelectionMask(self, copy=True):
+ """Get the current mask as a numpy array.
+
+ :param bool copy: True (default) to get a copy of the mask.
+ If False, the returned array MUST not be modified.
+ :return: The array of the mask with dimension of the 'active' plot item.
+ If there is no active image or scatter, an empty array is
+ returned.
+ :rtype: numpy.ndarray of uint8
+ """
+ return self._mask.getMask(copy=copy)
+
+ def multipleMasks(self):
+ """Return the current mode of multiple masks support.
+
+ See :meth:`setMultipleMasks`
+ """
+ return self._multipleMasks
+
+ def setMultipleMasks(self, mode):
+ """Set the mode of multiple masks support.
+
+ Available modes:
+
+ - 'single': Edit a single level of mask
+ - 'exclusive': Supports to 256 levels of non overlapping masks
+
+ :param str mode: The mode to use
+ """
+ assert mode in ('exclusive', 'single')
+ if mode != self._multipleMasks:
+ self._multipleMasks = mode
+ self.levelWidget.setVisible(self._multipleMasks != 'single')
+ self.clearAllBtn.setVisible(self._multipleMasks != 'single')
+
+ @property
+ def maskFileDir(self):
+ """The directory from which to load/save mask from/to files."""
+ if not os.path.isdir(self._maskFileDir):
+ self._maskFileDir = qt.QDir.home().absolutePath()
+ return self._maskFileDir
+
+ @maskFileDir.setter
+ def maskFileDir(self, maskFileDir):
+ self._maskFileDir = str(maskFileDir)
+
+ @property
+ def plot(self):
+ """The :class:`.PlotWindow` this widget is attached to."""
+ return self._plot
+
+ def setDirection(self, direction=qt.QBoxLayout.LeftToRight):
+ """Set the direction of the layout of the widget
+
+ :param direction: QBoxLayout direction
+ """
+ self.layout().setDirection(direction)
+
+ def _initWidgets(self):
+ """Create widgets"""
+ layout = qt.QBoxLayout(qt.QBoxLayout.LeftToRight)
+ layout.addWidget(self._initMaskGroupBox())
+ layout.addWidget(self._initDrawGroupBox())
+ layout.addWidget(self._initThresholdGroupBox())
+ layout.addStretch(1)
+ self.setLayout(layout)
+
+ @staticmethod
+ def _hboxWidget(*widgets, **kwargs):
+ """Place widgets in widget with horizontal layout
+
+ :param widgets: Widgets to position horizontally
+ :param bool stretch: True for trailing stretch (default),
+ False for no trailing stretch
+ :return: A QWidget with a QHBoxLayout
+ """
+ stretch = kwargs.get('stretch', True)
+
+ layout = qt.QHBoxLayout()
+ layout.setContentsMargins(0, 0, 0, 0)
+ for widget in widgets:
+ layout.addWidget(widget)
+ if stretch:
+ layout.addStretch(1)
+ widget = qt.QWidget()
+ widget.setLayout(layout)
+ return widget
+
+ def _initTransparencyWidget(self):
+ """ Init the mask transparency widget """
+ transparencyWidget = qt.QWidget(self)
+ grid = qt.QGridLayout()
+ grid.setContentsMargins(0, 0, 0, 0)
+ self.transparencySlider = qt.QSlider(qt.Qt.Horizontal, parent=transparencyWidget)
+ self.transparencySlider.setRange(3, 10)
+ self.transparencySlider.setValue(8)
+ self.transparencySlider.setToolTip(
+ 'Set the transparency of the mask display')
+ self.transparencySlider.valueChanged.connect(self._updateColors)
+ grid.addWidget(qt.QLabel('Display:', parent=transparencyWidget), 0, 0)
+ grid.addWidget(self.transparencySlider, 0, 1, 1, 3)
+ grid.addWidget(qt.QLabel('<small><b>Transparent</b></small>', parent=transparencyWidget), 1, 1)
+ grid.addWidget(qt.QLabel('<small><b>Opaque</b></small>', parent=transparencyWidget), 1, 3)
+ transparencyWidget.setLayout(grid)
+ return transparencyWidget
+
+ def _initMaskGroupBox(self):
+ """Init general mask operation widgets"""
+
+ # Mask level
+ self.levelSpinBox = qt.QSpinBox()
+ self.levelSpinBox.setRange(1, self._maxLevelNumber)
+ self.levelSpinBox.setToolTip(
+ 'Choose which mask level is edited.\n'
+ 'A mask can have up to 255 non-overlapping levels.')
+ self.levelSpinBox.valueChanged[int].connect(self._updateColors)
+ self.levelWidget = self._hboxWidget(qt.QLabel('Mask level:'),
+ self.levelSpinBox)
+ # Transparency
+ self.transparencyWidget = self._initTransparencyWidget()
+
+ # Buttons group
+ invertBtn = qt.QPushButton('Invert')
+ invertBtn.setShortcut(qt.Qt.CTRL + qt.Qt.Key_I)
+ invertBtn.setToolTip('Invert current mask <b>%s</b>' %
+ invertBtn.shortcut().toString())
+ invertBtn.clicked.connect(self._handleInvertMask)
+
+ clearBtn = qt.QPushButton('Clear')
+ clearBtn.setShortcut(qt.QKeySequence.Delete)
+ clearBtn.setToolTip('Clear current mask level <b>%s</b>' %
+ clearBtn.shortcut().toString())
+ clearBtn.clicked.connect(self._handleClearMask)
+
+ invertClearWidget = self._hboxWidget(
+ invertBtn, clearBtn, stretch=False)
+
+ undoBtn = qt.QPushButton('Undo')
+ undoBtn.setShortcut(qt.QKeySequence.Undo)
+ undoBtn.setToolTip('Undo last mask change <b>%s</b>' %
+ undoBtn.shortcut().toString())
+ self._mask.sigUndoable.connect(undoBtn.setEnabled)
+ undoBtn.clicked.connect(self._mask.undo)
+
+ redoBtn = qt.QPushButton('Redo')
+ redoBtn.setShortcut(qt.QKeySequence.Redo)
+ redoBtn.setToolTip('Redo last undone mask change <b>%s</b>' %
+ redoBtn.shortcut().toString())
+ self._mask.sigRedoable.connect(redoBtn.setEnabled)
+ redoBtn.clicked.connect(self._mask.redo)
+
+ undoRedoWidget = self._hboxWidget(undoBtn, redoBtn, stretch=False)
+
+ self.clearAllBtn = qt.QPushButton('Clear all')
+ self.clearAllBtn.setToolTip('Clear all mask levels')
+ self.clearAllBtn.clicked.connect(self.resetSelectionMask)
+
+ loadBtn = qt.QPushButton('Load...')
+ loadBtn.clicked.connect(self._loadMask)
+
+ saveBtn = qt.QPushButton('Save...')
+ saveBtn.clicked.connect(self._saveMask)
+
+ self.loadSaveWidget = self._hboxWidget(loadBtn, saveBtn, stretch=False)
+
+ layout = qt.QVBoxLayout()
+ layout.addWidget(self.levelWidget)
+ layout.addWidget(self.transparencyWidget)
+ layout.addWidget(invertClearWidget)
+ layout.addWidget(undoRedoWidget)
+ layout.addWidget(self.clearAllBtn)
+ layout.addWidget(self.loadSaveWidget)
+ layout.addStretch(1)
+
+ maskGroup = qt.QGroupBox('Mask')
+ maskGroup.setLayout(layout)
+ return maskGroup
+
+ def _initDrawGroupBox(self):
+ """Init drawing tools widgets"""
+ layout = qt.QVBoxLayout()
+
+ # Draw tools
+ self.browseAction = qt.QAction(
+ icons.getQIcon('normal'), 'Browse', None)
+ self.browseAction.setShortcut(qt.QKeySequence(qt.Qt.Key_B))
+ self.browseAction.setToolTip(
+ 'Disables drawing tools, enables zooming interaction mode'
+ ' <b>B</b>')
+ self.browseAction.setCheckable(True)
+ self.browseAction.triggered.connect(self._activeBrowseMode)
+ self.addAction(self.browseAction)
+
+ self.rectAction = qt.QAction(
+ icons.getQIcon('shape-rectangle'), 'Rectangle selection', None)
+ self.rectAction.setToolTip(
+ 'Rectangle selection tool: (Un)Mask a rectangular region <b>R</b>')
+ self.rectAction.setShortcut(qt.QKeySequence(qt.Qt.Key_R))
+ self.rectAction.setCheckable(True)
+ self.rectAction.triggered.connect(self._activeRectMode)
+ self.addAction(self.rectAction)
+
+ self.polygonAction = qt.QAction(
+ icons.getQIcon('shape-polygon'), 'Polygon selection', None)
+ self.polygonAction.setShortcut(qt.QKeySequence(qt.Qt.Key_S))
+ self.polygonAction.setToolTip(
+ 'Polygon selection tool: (Un)Mask a polygonal region <b>S</b><br>'
+ 'Left-click to place polygon corners<br>'
+ 'Right-click to place the last corner')
+ self.polygonAction.setCheckable(True)
+ self.polygonAction.triggered.connect(self._activePolygonMode)
+ self.addAction(self.polygonAction)
+
+ self.pencilAction = qt.QAction(
+ icons.getQIcon('draw-pencil'), 'Pencil tool', None)
+ self.pencilAction.setShortcut(qt.QKeySequence(qt.Qt.Key_P))
+ self.pencilAction.setToolTip(
+ 'Pencil tool: (Un)Mask using a pencil <b>P</b>')
+ self.pencilAction.setCheckable(True)
+ self.pencilAction.triggered.connect(self._activePencilMode)
+ self.addAction(self.polygonAction)
+
+ self.drawActionGroup = qt.QActionGroup(self)
+ self.drawActionGroup.setExclusive(True)
+ self.drawActionGroup.addAction(self.browseAction)
+ self.drawActionGroup.addAction(self.rectAction)
+ self.drawActionGroup.addAction(self.polygonAction)
+ self.drawActionGroup.addAction(self.pencilAction)
+
+ self.browseAction.setChecked(True)
+
+ self.drawButtons = {}
+ for action in self.drawActionGroup.actions():
+ btn = qt.QToolButton()
+ btn.setDefaultAction(action)
+ self.drawButtons[action.text()] = btn
+ container = self._hboxWidget(*self.drawButtons.values())
+ layout.addWidget(container)
+
+ # Mask/Unmask radio buttons
+ maskRadioBtn = qt.QRadioButton('Mask')
+ maskRadioBtn.setToolTip(
+ 'Drawing masks with current level. Press <b>Ctrl</b> to unmask')
+ maskRadioBtn.setChecked(True)
+
+ unmaskRadioBtn = qt.QRadioButton('Unmask')
+ unmaskRadioBtn.setToolTip(
+ 'Drawing unmasks with current level. Press <b>Ctrl</b> to mask')
+
+ self.maskStateGroup = qt.QButtonGroup()
+ self.maskStateGroup.addButton(maskRadioBtn, 1)
+ self.maskStateGroup.addButton(unmaskRadioBtn, 0)
+
+ self.maskStateWidget = self._hboxWidget(maskRadioBtn, unmaskRadioBtn)
+ layout.addWidget(self.maskStateWidget)
+
+ # Connect mask state widget visibility with browse action
+ self.maskStateWidget.setHidden(self.browseAction.isChecked())
+ self.browseAction.toggled[bool].connect(
+ self.maskStateWidget.setHidden)
+
+ # Pencil settings
+ self.pencilSetting = self._createPencilSettings(None)
+ self.pencilSetting.setVisible(False)
+ layout.addWidget(self.pencilSetting)
+
+ layout.addStretch(1)
+
+ drawGroup = qt.QGroupBox('Draw tools')
+ drawGroup.setLayout(layout)
+ return drawGroup
+
+ def _createPencilSettings(self, parent=None):
+ pencilSetting = qt.QWidget(parent)
+
+ self.pencilSpinBox = qt.QSpinBox(parent=pencilSetting)
+ self.pencilSpinBox.setRange(1, 1024)
+ pencilToolTip = """Set pencil drawing tool size in pixels of the image
+ on which to make the mask."""
+ self.pencilSpinBox.setToolTip(pencilToolTip)
+
+ self.pencilSlider = qt.QSlider(qt.Qt.Horizontal, parent=pencilSetting)
+ self.pencilSlider.setRange(1, 50)
+ self.pencilSlider.setToolTip(pencilToolTip)
+
+ pencilLabel = qt.QLabel('Pencil size:', parent=pencilSetting)
+
+ layout = qt.QGridLayout()
+ layout.addWidget(pencilLabel, 0, 0)
+ layout.addWidget(self.pencilSpinBox, 0, 1)
+ layout.addWidget(self.pencilSlider, 1, 1)
+ pencilSetting.setLayout(layout)
+
+ self.pencilSpinBox.valueChanged.connect(self._pencilWidthChanged)
+ self.pencilSlider.valueChanged.connect(self._pencilWidthChanged)
+
+ return pencilSetting
+
+ def _initThresholdGroupBox(self):
+ """Init thresholding widgets"""
+ layout = qt.QVBoxLayout()
+
+ # Thresholing
+
+ self.belowThresholdAction = qt.QAction(
+ icons.getQIcon('plot-roi-below'), 'Mask below threshold', None)
+ self.belowThresholdAction.setToolTip(
+ 'Mask image where values are below given threshold')
+ self.belowThresholdAction.setCheckable(True)
+ self.belowThresholdAction.triggered[bool].connect(
+ self._belowThresholdActionTriggered)
+
+ self.betweenThresholdAction = qt.QAction(
+ icons.getQIcon('plot-roi-between'), 'Mask within range', None)
+ self.betweenThresholdAction.setToolTip(
+ 'Mask image where values are within given range')
+ self.betweenThresholdAction.setCheckable(True)
+ self.betweenThresholdAction.triggered[bool].connect(
+ self._betweenThresholdActionTriggered)
+
+ self.aboveThresholdAction = qt.QAction(
+ icons.getQIcon('plot-roi-above'), 'Mask above threshold', None)
+ self.aboveThresholdAction.setToolTip(
+ 'Mask image where values are above given threshold')
+ self.aboveThresholdAction.setCheckable(True)
+ self.aboveThresholdAction.triggered[bool].connect(
+ self._aboveThresholdActionTriggered)
+
+ self.thresholdActionGroup = qt.QActionGroup(self)
+ self.thresholdActionGroup.setExclusive(False)
+ self.thresholdActionGroup.addAction(self.belowThresholdAction)
+ self.thresholdActionGroup.addAction(self.betweenThresholdAction)
+ self.thresholdActionGroup.addAction(self.aboveThresholdAction)
+ self.thresholdActionGroup.triggered.connect(
+ self._thresholdActionGroupTriggered)
+
+ self.loadColormapRangeAction = qt.QAction(
+ icons.getQIcon('view-refresh'), 'Set min-max from colormap', None)
+ self.loadColormapRangeAction.setToolTip(
+ 'Set min and max values from current colormap range')
+ self.loadColormapRangeAction.setCheckable(False)
+ self.loadColormapRangeAction.triggered.connect(
+ self._loadRangeFromColormapTriggered)
+
+ widgets = []
+ for action in self.thresholdActionGroup.actions():
+ btn = qt.QToolButton()
+ btn.setDefaultAction(action)
+ widgets.append(btn)
+
+ spacer = qt.QWidget()
+ spacer.setSizePolicy(qt.QSizePolicy.Expanding,
+ qt.QSizePolicy.Preferred)
+ widgets.append(spacer)
+
+ loadColormapRangeBtn = qt.QToolButton()
+ loadColormapRangeBtn.setDefaultAction(self.loadColormapRangeAction)
+ widgets.append(loadColormapRangeBtn)
+
+ container = self._hboxWidget(*widgets, stretch=False)
+ layout.addWidget(container)
+
+ form = qt.QFormLayout()
+
+ self.minLineEdit = qt.QLineEdit()
+ self.minLineEdit.setText('0')
+ self.minLineEdit.setValidator(qt.QDoubleValidator())
+ self.minLineEdit.setEnabled(False)
+ form.addRow('Min:', self.minLineEdit)
+
+ self.maxLineEdit = qt.QLineEdit()
+ self.maxLineEdit.setText('0')
+ self.maxLineEdit.setValidator(qt.QDoubleValidator())
+ self.maxLineEdit.setEnabled(False)
+ form.addRow('Max:', self.maxLineEdit)
+
+ self.applyMaskBtn = qt.QPushButton('Apply mask')
+ self.applyMaskBtn.clicked.connect(self._maskBtnClicked)
+ self.applyMaskBtn.setEnabled(False)
+ form.addRow(self.applyMaskBtn)
+
+ self.maskNanBtn = qt.QPushButton('Mask not finite values')
+ self.maskNanBtn.setToolTip('Mask Not a Number and infinite values')
+ self.maskNanBtn.clicked.connect(self._maskNotFiniteBtnClicked)
+ form.addRow(self.maskNanBtn)
+
+ thresholdWidget = qt.QWidget()
+ thresholdWidget.setLayout(form)
+ layout.addWidget(thresholdWidget)
+
+ layout.addStretch(1)
+
+ self.thresholdGroup = qt.QGroupBox('Threshold')
+ self.thresholdGroup.setLayout(layout)
+ return self.thresholdGroup
+
+ # track widget visibility and plot active image changes
+
+ def changeEvent(self, event):
+ """Reset drawing action when disabling widget"""
+ if (event.type() == qt.QEvent.EnabledChange and
+ not self.isEnabled() and
+ not self.browseAction.isChecked()):
+ self.browseAction.trigger() # Disable drawing tool
+
+ def save(self, filename, kind):
+ """Save current mask in a file
+
+ :param str filename: The file where to save to mask
+ :param str kind: The kind of file to save in 'edf', 'tif', 'npy'
+ :raise Exception: Raised if the process fails
+ """
+ self._mask.save(filename, kind)
+
+ def getCurrentMaskColor(self):
+ """Returns the color of the current selected level.
+
+ :rtype: A tuple or a python array
+ """
+ currentLevel = self.levelSpinBox.value()
+ if self._defaultColors[currentLevel]:
+ return self._defaultOverlayColor
+ else:
+ return self._overlayColors[currentLevel].tolist()
+
+ def _setMaskColors(self, level, alpha):
+ """Set-up the mask colormap to highlight current mask level.
+
+ :param int level: The mask level to highlight
+ :param float alpha: Alpha level of mask in [0., 1.]
+ """
+ assert 0 < level <= self._maxLevelNumber
+
+ colors = numpy.empty((self._maxLevelNumber + 1, 4), dtype=numpy.float32)
+
+ # Set color
+ colors[:, :3] = self._defaultOverlayColor[:3]
+
+ # check if some colors has been directly set by the user
+ mask = numpy.equal(self._defaultColors, False)
+ colors[mask, :3] = self._overlayColors[mask, :3]
+
+ # Set alpha
+ colors[:, -1] = alpha / 2.
+
+ # Set highlighted level color
+ colors[level, 3] = alpha
+
+ # Set no mask level
+ colors[0] = (0., 0., 0., 0.)
+
+ self._colormap['colors'] = colors
+
+ def resetMaskColors(self, level=None):
+ """Reset the mask color at the given level to be defaultColors
+
+ :param level:
+ The index of the mask for which we want to reset the color.
+ If none we will reset color for all masks.
+ """
+ if level is None:
+ self._defaultColors[level] = True
+ else:
+ self._defaultColors[:] = True
+
+ self._updateColors()
+
+ def setMaskColors(self, rgb, level=None):
+ """Set the masks color
+
+ :param rgb: The rgb color
+ :param level:
+ The index of the mask for which we want to change the color.
+ If none set this color for all the masks
+ """
+ if level is None:
+ self._overlayColors[:] = rgb
+ self._defaultColors[:] = False
+ else:
+ self._overlayColors[level] = rgb
+ self._defaultColors[level] = False
+
+ self._updateColors()
+
+ def getMaskColors(self):
+ """masks colors getter"""
+ return self._overlayColors
+
+ def _updateColors(self, *args):
+ """Rebuild mask colormap when selected level or transparency change"""
+ self._setMaskColors(self.levelSpinBox.value(),
+ self.transparencySlider.value() /
+ self.transparencySlider.maximum())
+ self._updatePlotMask()
+ self._updateInteractiveMode()
+
+ def _pencilWidthChanged(self, width):
+
+ old = self.pencilSpinBox.blockSignals(True)
+ try:
+ self.pencilSpinBox.setValue(width)
+ finally:
+ self.pencilSpinBox.blockSignals(old)
+
+ old = self.pencilSlider.blockSignals(True)
+ try:
+ self.pencilSlider.setValue(width)
+ finally:
+ self.pencilSlider.blockSignals(old)
+ self._updateInteractiveMode()
+
+ def _updateInteractiveMode(self):
+ """Update the current mode to the same if some cached data have to be
+ updated. It is the case for the color for example.
+ """
+ if self._drawingMode == 'rectangle':
+ self._activeRectMode()
+ elif self._drawingMode == 'polygon':
+ self._activePolygonMode()
+ elif self._drawingMode == 'pencil':
+ self._activePencilMode()
+
+ def _handleClearMask(self):
+ """Handle clear button clicked: reset current level mask"""
+ self._mask.clear(self.levelSpinBox.value())
+ self._mask.commit()
+
+ def _handleInvertMask(self):
+ """Invert the current mask level selection."""
+ self._mask.invert(self.levelSpinBox.value())
+ self._mask.commit()
+
+ # Handle drawing tools UI events
+
+ def _interactiveModeChanged(self, source):
+ """Handle plot interactive mode changed:
+
+ If changed from elsewhere, disable drawing tool
+ """
+ if source is not self:
+ # Do not trigger browseAction to avoid to call
+ # self.plot.setInteractiveMode
+ self.browseAction.setChecked(True)
+ self._releaseDrawingMode()
+
+ def _releaseDrawingMode(self):
+ """Release the drawing mode if is was used"""
+ if self._drawingMode is None:
+ return
+ self.plot.sigPlotSignal.disconnect(self._plotDrawEvent)
+ self._drawingMode = None
+
+ def _activeBrowseMode(self):
+ """Handle browse action mode triggered by user.
+
+ Set plot interactive mode only when
+ the user is triggering the browse action.
+ """
+ self._releaseDrawingMode()
+ self.plot.setInteractiveMode('zoom', source=self)
+ self._updateDrawingModeWidgets()
+
+ def _activeRectMode(self):
+ """Handle rect action mode triggering"""
+ self._releaseDrawingMode()
+ self._drawingMode = 'rectangle'
+ self.plot.sigPlotSignal.connect(self._plotDrawEvent)
+ color = self.getCurrentMaskColor()
+ self.plot.setInteractiveMode(
+ 'draw', shape='rectangle', source=self, color=color)
+ self._updateDrawingModeWidgets()
+
+ def _activePolygonMode(self):
+ """Handle polygon action mode triggering"""
+ self._releaseDrawingMode()
+ self._drawingMode = 'polygon'
+ self.plot.sigPlotSignal.connect(self._plotDrawEvent)
+ color = self.getCurrentMaskColor()
+ self.plot.setInteractiveMode('draw', shape='polygon', source=self, color=color)
+ self._updateDrawingModeWidgets()
+
+ def _activePencilMode(self):
+ """Handle pencil action mode triggering"""
+ self._releaseDrawingMode()
+ self._drawingMode = 'pencil'
+ self.plot.sigPlotSignal.connect(self._plotDrawEvent)
+ color = self.getCurrentMaskColor()
+ width = self.pencilSpinBox.value()
+ self.plot.setInteractiveMode(
+ 'draw', shape='pencil', source=self, color=color, width=width)
+ self._updateDrawingModeWidgets()
+
+ def _updateDrawingModeWidgets(self):
+ self.pencilSetting.setVisible(self._drawingMode == 'pencil')
+
+ # Handle plot drawing events
+
+ def _isMasking(self):
+ """Returns true if the tool is used for masking, else it is used for
+ unmasking.
+
+ :rtype: bool"""
+ # First draw event, use current modifiers for all draw sequence
+ doMask = (self.maskStateGroup.checkedId() == 1)
+ if qt.QApplication.keyboardModifiers() & qt.Qt.ControlModifier:
+ doMask = not doMask
+ return doMask
+
+ # Handle threshold UI events
+ def _belowThresholdActionTriggered(self, triggered):
+ if triggered:
+ self.minLineEdit.setEnabled(True)
+ self.maxLineEdit.setEnabled(False)
+ self.applyMaskBtn.setEnabled(True)
+
+ def _betweenThresholdActionTriggered(self, triggered):
+ if triggered:
+ self.minLineEdit.setEnabled(True)
+ self.maxLineEdit.setEnabled(True)
+ self.applyMaskBtn.setEnabled(True)
+
+ def _aboveThresholdActionTriggered(self, triggered):
+ if triggered:
+ self.minLineEdit.setEnabled(False)
+ self.maxLineEdit.setEnabled(True)
+ self.applyMaskBtn.setEnabled(True)
+
+ def _thresholdActionGroupTriggered(self, triggeredAction):
+ """Threshold action group listener."""
+ if triggeredAction.isChecked():
+ # Uncheck other actions
+ for action in self.thresholdActionGroup.actions():
+ if action is not triggeredAction and action.isChecked():
+ action.setChecked(False)
+ else:
+ # Disable min/max edit
+ self.minLineEdit.setEnabled(False)
+ self.maxLineEdit.setEnabled(False)
+ self.applyMaskBtn.setEnabled(False)
+
+ def _maskBtnClicked(self):
+ if self.belowThresholdAction.isChecked():
+ if self.minLineEdit.text():
+ self._mask.updateBelowThreshold(self.levelSpinBox.value(),
+ float(self.minLineEdit.text()))
+ self._mask.commit()
+
+ elif self.betweenThresholdAction.isChecked():
+ if self.minLineEdit.text() and self.maxLineEdit.text():
+ min_ = float(self.minLineEdit.text())
+ max_ = float(self.maxLineEdit.text())
+ self._mask.updateBetweenThresholds(self.levelSpinBox.value(),
+ min_, max_)
+ self._mask.commit()
+
+ elif self.aboveThresholdAction.isChecked():
+ if self.maxLineEdit.text():
+ max_ = float(self.maxLineEdit.text())
+ self._mask.updateAboveThreshold(self.levelSpinBox.value(),
+ max_)
+ self._mask.commit()
+
+ def _maskNotFiniteBtnClicked(self):
+ """Handle not finite mask button clicked: mask NaNs and inf"""
+ self._mask.updateNotFinite(
+ self.levelSpinBox.value())
+ self._mask.commit()
+
+
+class BaseMaskToolsDockWidget(qt.QDockWidget):
+ """Base class for :class:`MaskToolsWidget` and
+ :class:`ScatterMaskToolsWidget`
+
+ For integration in a :class:`PlotWindow`.
+
+ :param parent: See :class:`QDockWidget`
+ :paran str name: The title of this widget
+ """
+
+ sigMaskChanged = qt.Signal()
+
+ def __init__(self, parent=None, name='Mask'):
+ super(BaseMaskToolsDockWidget, self).__init__(parent)
+ self.setWindowTitle(name)
+
+ self.layout().setContentsMargins(0, 0, 0, 0)
+ self.dockLocationChanged.connect(self._dockLocationChanged)
+ self.topLevelChanged.connect(self._topLevelChanged)
+
+ def _emitSigMaskChanged(self):
+ """Notify mask changes"""
+ # must be connected to self.widget().sigMaskChanged in child class
+ self.sigMaskChanged.emit()
+
+ def getSelectionMask(self, copy=True):
+ """Get the current mask as a 2D array.
+
+ :param bool copy: True (default) to get a copy of the mask.
+ If False, the returned array MUST not be modified.
+ :return: The array of the mask with dimension of the 'active' image.
+ If there is no active image, an empty array is returned.
+ :rtype: 2D numpy.ndarray of uint8
+ """
+ return self.widget().getSelectionMask(copy=copy)
+
+ def setSelectionMask(self, mask, copy=True):
+ """Set the mask to a new array.
+
+ :param numpy.ndarray mask: The array to use for the mask.
+ :type mask: numpy.ndarray of uint8 of dimension 2, C-contiguous.
+ Array of other types are converted.
+ :param bool copy: True (the default) to copy the array,
+ False to use it as is if possible.
+ :return: None if failed, shape of mask as 2-tuple if successful.
+ The mask can be cropped or padded to fit active image,
+ the returned shape is that of the active image.
+ """
+ return self.widget().setSelectionMask(mask, copy=copy)
+
+ def toggleViewAction(self):
+ """Returns a checkable action that shows or closes this widget.
+
+ See :class:`QMainWindow`.
+ """
+ action = super(BaseMaskToolsDockWidget, self).toggleViewAction()
+ action.setIcon(icons.getQIcon('image-mask'))
+ action.setToolTip("Display/hide mask tools")
+ return action
+
+ def _dockLocationChanged(self, area):
+ if area in (qt.Qt.LeftDockWidgetArea, qt.Qt.RightDockWidgetArea):
+ direction = qt.QBoxLayout.TopToBottom
+ else:
+ direction = qt.QBoxLayout.LeftToRight
+ self.widget().setDirection(direction)
+
+ def _topLevelChanged(self, topLevel):
+ if topLevel:
+ self.widget().setDirection(qt.QBoxLayout.LeftToRight)
+ self.resize(self.widget().minimumSize())
+ self.adjustSize()
+
+ def showEvent(self, event):
+ """Make sure this widget is raised when it is shown
+ (when it is first created as a tab in PlotWindow or when it is shown
+ again after hiding).
+ """
+ self.raise_()
diff --git a/silx/gui/plot/__init__.py b/silx/gui/plot/__init__.py
new file mode 100644
index 0000000..06a24a7
--- /dev/null
+++ b/silx/gui/plot/__init__.py
@@ -0,0 +1,71 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This package provides a set of Qt widgets for plotting curves and images.
+
+The plotting API is inherited from the `PyMca <http://pymca.sourceforge.net/>`_
+plot API and is mostly compatible with it.
+
+Those widgets supports interaction (e.g., zoom, pan, selections).
+
+List of Qt widgets:
+
+.. currentmodule:: silx.gui.plot
+
+- :mod:`.PlotWidget`: A widget displaying a single plot.
+- :mod:`.PlotWindow`: A :mod:`.PlotWidget` with a configurable set of tools.
+- :class:`.Plot1D`: A widget with tools for curves.
+- :class:`.Plot2D`: A widget with tools for images.
+- :class:`.ImageView`: A widget with tools for images and a side histogram.
+- :class:`.StackView`: A widget with tools for a stack of images.
+
+By default, those widget are using matplotlib_.
+They can optionally use a faster OpenGL-based rendering (beta feature),
+which is enabled by setting the ``backend`` argument to ``'gl'``
+when creating the widgets (See :class:`.Plot`).
+
+.. note::
+
+ This package depends on matplotlib_.
+ The OpenGL backend further depends on
+ `PyOpenGL <http://pyopengl.sourceforge.net/>`_ and OpenGL >= 2.1.
+
+.. _matplotlib: http://matplotlib.org/
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "22/02/2016"
+
+
+# First of all init matplotlib and set its backend
+from .backends import _matplotlib # noqa
+
+from .PlotWidget import PlotWidget # noqa
+from .PlotWindow import PlotWindow, Plot1D, Plot2D # noqa
+from .ImageView import ImageView # noqa
+from .StackView import StackView # noqa
+
+__all__ = ['ImageView', 'PlotWidget', 'PlotWindow', 'Plot1D', 'Plot2D',
+ 'StackView']
diff --git a/silx/gui/plot/_utils/__init__.py b/silx/gui/plot/_utils/__init__.py
new file mode 100644
index 0000000..355bc02
--- /dev/null
+++ b/silx/gui/plot/_utils/__init__.py
@@ -0,0 +1,104 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Miscellaneous utility functions for the Plot"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "21/03/2017"
+
+
+import numpy
+
+from .panzoom import FLOAT32_SAFE_MIN, FLOAT32_MINPOS, FLOAT32_SAFE_MAX
+from .panzoom import applyZoomToPlot, applyPan
+
+
+def clipColormapLogRange(colormap):
+ """Clip colormap vmin and vmax to 1, 10 if normalization is 'log' and vmin
+ or vmax <1
+
+ :param dict colormap: the colormap for which we want to clip vmin and vmax
+ """
+ if colormap['normalization'] is 'log':
+ if colormap['vmin'] < 1. or colormap['vmax'] < 1.:
+ colormap['vmin'], colormap['vmax'] = 1., 10.
+
+
+def addMarginsToLimits(margins, isXLog, isYLog,
+ xMin, xMax, yMin, yMax, y2Min=None, y2Max=None):
+ """Returns updated limits by extending them with margins.
+
+ :param margins: The ratio of the margins to add or None for no margins.
+ :type margins: A 4-tuple of floats as
+ (xMinMargin, xMaxMargin, yMinMargin, yMaxMargin)
+
+ :return: The updated limits
+ :rtype: tuple of 4 or 6 floats: Either (xMin, xMax, yMin, yMax) or
+ (xMin, xMax, yMin, yMax, y2Min, y2Max) if y2Min and y2Max
+ are provided.
+ """
+ if margins is not None:
+ xMinMargin, xMaxMargin, yMinMargin, yMaxMargin = margins
+
+ if not isXLog:
+ xRange = xMax - xMin
+ xMin -= xMinMargin * xRange
+ xMax += xMaxMargin * xRange
+
+ elif xMin > 0. and xMax > 0.: # Log scale
+ # Do not apply margins if limits < 0
+ xMinLog, xMaxLog = numpy.log10(xMin), numpy.log10(xMax)
+ xRangeLog = xMaxLog - xMinLog
+ xMin = pow(10., xMinLog - xMinMargin * xRangeLog)
+ xMax = pow(10., xMaxLog + xMaxMargin * xRangeLog)
+
+ if not isYLog:
+ yRange = yMax - yMin
+ yMin -= yMinMargin * yRange
+ yMax += yMaxMargin * yRange
+ elif yMin > 0. and yMax > 0.: # Log scale
+ # Do not apply margins if limits < 0
+ yMinLog, yMaxLog = numpy.log10(yMin), numpy.log10(yMax)
+ yRangeLog = yMaxLog - yMinLog
+ yMin = pow(10., yMinLog - yMinMargin * yRangeLog)
+ yMax = pow(10., yMaxLog + yMaxMargin * yRangeLog)
+
+ if y2Min is not None and y2Max is not None:
+ if not isYLog:
+ yRange = y2Max - y2Min
+ y2Min -= yMinMargin * yRange
+ y2Max += yMaxMargin * yRange
+ elif y2Min > 0. and y2Max > 0.: # Log scale
+ # Do not apply margins if limits < 0
+ yMinLog, yMaxLog = numpy.log10(y2Min), numpy.log10(y2Max)
+ yRangeLog = yMaxLog - yMinLog
+ y2Min = pow(10., yMinLog - yMinMargin * yRangeLog)
+ y2Max = pow(10., yMaxLog + yMaxMargin * yRangeLog)
+
+ if y2Min is None or y2Max is None:
+ return xMin, xMax, yMin, yMax
+ else:
+ return xMin, xMax, yMin, yMax, y2Min, y2Max
+
diff --git a/silx/gui/plot/_utils/panzoom.py b/silx/gui/plot/_utils/panzoom.py
new file mode 100644
index 0000000..bec31df
--- /dev/null
+++ b/silx/gui/plot/_utils/panzoom.py
@@ -0,0 +1,156 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Functions to apply pan and zoom on a Plot"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "21/03/2017"
+
+
+import math
+
+import numpy
+
+
+# Float 32 info ###############################################################
+# Using min/max value below limits of float32
+# so operation with such value (e.g., max - min) do not overflow
+
+FLOAT32_SAFE_MIN = -1e37
+FLOAT32_MINPOS = numpy.finfo(numpy.float32).tiny
+FLOAT32_SAFE_MAX = 1e37
+# TODO double support
+
+
+def scale1DRange(min_, max_, center, scale, isLog):
+ """Scale a 1D range given a scale factor and an center point.
+
+ Keeps the values in a smaller range than float32.
+
+ :param float min_: The current min value of the range.
+ :param float max_: The current max value of the range.
+ :param float center: The center of the zoom (i.e., invariant point).
+ :param float scale: The scale to use for zoom
+ :param bool isLog: Whether using log scale or not.
+ :return: The zoomed range.
+ :rtype: tuple of 2 floats: (min, max)
+ """
+ if isLog:
+ # Min and center can be < 0 when
+ # autoscale is off and switch to log scale
+ # max_ < 0 should not happen
+ min_ = numpy.log10(min_) if min_ > 0. else FLOAT32_MINPOS
+ center = numpy.log10(center) if center > 0. else FLOAT32_MINPOS
+ max_ = numpy.log10(max_) if max_ > 0. else FLOAT32_MINPOS
+
+ if min_ == max_:
+ return min_, max_
+
+ offset = (center - min_) / (max_ - min_)
+ range_ = (max_ - min_) / scale
+ newMin = center - offset * range_
+ newMax = center + (1. - offset) * range_
+
+ if isLog:
+ # No overflow as exponent is log10 of a float32
+ newMin = pow(10., newMin)
+ newMax = pow(10., newMax)
+ newMin = numpy.clip(newMin, FLOAT32_MINPOS, FLOAT32_SAFE_MAX)
+ newMax = numpy.clip(newMax, FLOAT32_MINPOS, FLOAT32_SAFE_MAX)
+ else:
+ newMin = numpy.clip(newMin, FLOAT32_SAFE_MIN, FLOAT32_SAFE_MAX)
+ newMax = numpy.clip(newMax, FLOAT32_SAFE_MIN, FLOAT32_SAFE_MAX)
+ return newMin, newMax
+
+
+def applyZoomToPlot(plot, scaleF, center=None):
+ """Zoom in/out plot given a scale and a center point.
+
+ :param plot: The plot on which to apply zoom.
+ :param float scaleF: Scale factor of zoom.
+ :param center: (x, y) coords in pixel coordinates of the zoom center.
+ :type center: 2-tuple of float
+ """
+ xMin, xMax = plot.getGraphXLimits()
+ yMin, yMax = plot.getGraphYLimits()
+
+ if center is None:
+ left, top, width, height = plot.getPlotBoundsInPixels()
+ cx, cy = left + width // 2, top + height // 2
+ else:
+ cx, cy = center
+
+ dataCenterPos = plot.pixelToData(cx, cy)
+ assert dataCenterPos is not None
+
+ xMin, xMax = scale1DRange(xMin, xMax, dataCenterPos[0], scaleF,
+ plot.isXAxisLogarithmic())
+
+ yMin, yMax = scale1DRange(yMin, yMax, dataCenterPos[1], scaleF,
+ plot.isYAxisLogarithmic())
+
+ dataPos = plot.pixelToData(cx, cy, axis="right")
+ assert dataPos is not None
+ y2Center = dataPos[1]
+ y2Min, y2Max = plot.getGraphYLimits(axis="right")
+ y2Min, y2Max = scale1DRange(y2Min, y2Max, y2Center, scaleF,
+ plot.isYAxisLogarithmic())
+
+ plot.setLimits(xMin, xMax, yMin, yMax, y2Min, y2Max)
+
+
+def applyPan(min_, max_, panFactor, isLog10):
+ """Returns a new range with applied panning.
+
+ Moves the range according to panFactor.
+ If isLog10 is True, converts to log10 before moving.
+
+ :param float min_: Min value of the data range to pan.
+ :param float max_: Max value of the data range to pan.
+ Must be >= min.
+ :param float panFactor: Signed proportion of the range to use for pan.
+ :param bool isLog10: True if log10 scale, False if linear scale.
+ :return: New min and max value with pan applied.
+ :rtype: 2-tuple of float.
+ """
+ if isLog10 and min_ > 0.:
+ # Negative range and log scale can happen with matplotlib
+ logMin, logMax = math.log10(min_), math.log10(max_)
+ logOffset = panFactor * (logMax - logMin)
+ newMin = pow(10., logMin + logOffset)
+ newMax = pow(10., logMax + logOffset)
+
+ # Takes care of out-of-range values
+ if newMin > 0. and newMax < float('inf'):
+ min_, max_ = newMin, newMax
+
+ else:
+ offset = panFactor * (max_ - min_)
+ newMin, newMax = min_ + offset, max_ + offset
+
+ # Takes care of out-of-range values
+ if newMin > - float('inf') and newMax < float('inf'):
+ min_, max_ = newMin, newMax
+ return min_, max_
diff --git a/silx/gui/plot/_utils/setup.py b/silx/gui/plot/_utils/setup.py
new file mode 100644
index 0000000..0271745
--- /dev/null
+++ b/silx/gui/plot/_utils/setup.py
@@ -0,0 +1,42 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "21/03/2017"
+
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('_utils', parent_package, top_path)
+ config.add_subpackage('test')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/gui/plot/_utils/test/__init__.py b/silx/gui/plot/_utils/test/__init__.py
new file mode 100644
index 0000000..4a443ac
--- /dev/null
+++ b/silx/gui/plot/_utils/test/__init__.py
@@ -0,0 +1,41 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/10/2016"
+
+
+import unittest
+
+from .test_ticklayout import suite as test_ticklayout_suite
+
+
+def suite():
+ testsuite = unittest.TestSuite()
+ testsuite.addTest(test_ticklayout_suite())
+ return testsuite
diff --git a/silx/gui/plot/_utils/test/test_ticklayout.py b/silx/gui/plot/_utils/test/test_ticklayout.py
new file mode 100644
index 0000000..8c67620
--- /dev/null
+++ b/silx/gui/plot/_utils/test/test_ticklayout.py
@@ -0,0 +1,78 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/10/2016"
+
+
+import unittest
+
+from silx.test.utils import ParametricTestCase
+
+from silx.gui.plot._utils import ticklayout
+
+
+class TestTickLayout(ParametricTestCase):
+ """Test ticks layout algorithms"""
+
+ def testNiceNumbers(self):
+ """Minimalistic tests of :func:`niceNumbers`"""
+ tests = { # (vmin, vmax): ref_ticks
+ (0.5, 10.5): (0.0, 12.0, 2.0, 0),
+ (10000., 10000.5): (10000.0, 10000.5, 0.1, 1),
+ (0.001, 0.005): (0.001, 0.005, 0.001, 3)
+ }
+
+ for (vmin, vmax), ref_ticks in tests.items():
+ with self.subTest(vmin=vmin, vmax=vmax):
+ ticks = ticklayout.niceNumbers(vmin, vmax)
+ self.assertEqual(ticks, ref_ticks)
+
+ def testNiceNumbersLog(self):
+ """Minimalistic tests of :func:`niceNumbersForLog10`"""
+ tests = { # (log10(min), log10(max): ref_ticks
+ (0., 3.): (0, 3, 1, 0),
+ (-3., 3): (-3, 3, 1, 0),
+ (-32., 0.): (-36, 0, 6, 0)
+ }
+
+ for (vmin, vmax), ref_ticks in tests.items():
+ with self.subTest(vmin=vmin, vmax=vmax):
+ ticks = ticklayout.niceNumbersForLog10(vmin, vmax)
+ self.assertEqual(ticks, ref_ticks)
+
+
+def suite():
+ testsuite = unittest.TestSuite()
+ testsuite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestTickLayout))
+ return testsuite
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/silx/gui/plot/_utils/ticklayout.py b/silx/gui/plot/_utils/ticklayout.py
new file mode 100644
index 0000000..5f4b636
--- /dev/null
+++ b/silx/gui/plot/_utils/ticklayout.py
@@ -0,0 +1,224 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ###########################################################################*/
+"""This module implements labels layout on graph axes."""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/10/2016"
+
+
+import math
+
+
+# utils #######################################################################
+
+def numberOfDigits(tickSpacing):
+ """Returns the number of digits to display for text label.
+
+ :param float tickSpacing: Step between ticks in data space.
+ :return: Number of digits to show for labels.
+ :rtype: int
+ """
+ nfrac = int(-math.floor(math.log10(tickSpacing)))
+ if nfrac < 0:
+ nfrac = 0
+ return nfrac
+
+
+# Nice Numbers ################################################################
+
+def _niceNum(value, isRound=False):
+ expvalue = math.floor(math.log10(value))
+ frac = value/pow(10., expvalue)
+ if isRound:
+ if frac < 1.5:
+ nicefrac = 1.
+ elif frac < 3.:
+ nicefrac = 2.
+ elif frac < 7.:
+ nicefrac = 5.
+ else:
+ nicefrac = 10.
+ else:
+ if frac <= 1.:
+ nicefrac = 1.
+ elif frac <= 2.:
+ nicefrac = 2.
+ elif frac <= 5.:
+ nicefrac = 5.
+ else:
+ nicefrac = 10.
+ return nicefrac * pow(10., expvalue)
+
+
+def niceNumbers(vMin, vMax, nTicks=5):
+ """Returns tick positions.
+
+ This function implements graph labels layout using nice numbers
+ by Paul Heckbert from "Graphics Gems", Academic Press, 1990.
+ See `C code <http://tog.acm.org/resources/GraphicsGems/gems/Label.c>`_.
+
+ :param float vMin: The min value on the axis
+ :param float vMax: The max value on the axis
+ :param int nTicks: The number of ticks to position
+ :returns: min, max, increment value of tick positions and
+ number of fractional digit to show
+ :rtype: tuple
+ """
+ vrange = _niceNum(vMax - vMin, False)
+ spacing = _niceNum(vrange / nTicks, True)
+ graphmin = math.floor(vMin / spacing) * spacing
+ graphmax = math.ceil(vMax / spacing) * spacing
+ nfrac = numberOfDigits(spacing)
+ return graphmin, graphmax, spacing, nfrac
+
+
+def _frange(start, stop, step):
+ """range for float (including stop)."""
+ assert step >= 0.
+ while start <= stop:
+ yield start
+ start += step
+
+
+def ticks(vMin, vMax, nbTicks=5):
+ """Returns tick positions and labels using nice numbers algorithm.
+
+ This enforces ticks to be within [vMin, vMax] range.
+ It returns at least 2 ticks.
+
+ :param float vMin: The min value on the axis
+ :param float vMax: The max value on the axis
+ :param int nbTicks: The number of ticks to position
+ :returns: tick positions and corresponding text labels
+ :rtype: 2-tuple: list of float, list of string
+ """
+ start, end, step, nfrac = niceNumbers(vMin, vMax, nbTicks)
+ positions = [t for t in _frange(start, end, step) if vMin <= t <= vMax]
+
+ # Makes sure there is at least 2 ticks
+ if len(positions) < 2:
+ positions = [vMin, vMax]
+ nfrac = numberOfDigits(vMax - vMin)
+
+ # Generate labels
+ format_ = '%g' if nfrac == 0 else '%.{}f'.format(nfrac)
+ labels = [format_ % tick for tick in positions]
+ return positions, labels
+
+
+def niceNumbersAdaptative(vMin, vMax, axisLength, tickDensity):
+ """Returns tick positions using :func:`niceNumbers` and a
+ density of ticks.
+
+ axisLength and tickDensity are based on the same unit (e.g., pixel).
+
+ :param float vMin: The min value on the axis
+ :param float vMax: The max value on the axis
+ :param float axisLength: The length of the axis.
+ :param float tickDensity: The density of ticks along the axis.
+ :returns: min, max, increment value of tick positions and
+ number of fractional digit to show
+ :rtype: tuple
+ """
+ # At least 2 ticks
+ nticks = max(2, int(round(tickDensity * axisLength)))
+ tickmin, tickmax, step, nfrac = niceNumbers(vMin, vMax, nticks)
+
+ return tickmin, tickmax, step, nfrac
+
+
+# Nice Numbers for log scale ##################################################
+
+def niceNumbersForLog10(minLog, maxLog, nTicks=5):
+ """Return tick positions for logarithmic scale
+
+ :param float minLog: log10 of the min value on the axis
+ :param float maxLog: log10 of the max value on the axis
+ :param int nTicks: The number of ticks to position
+ :returns: log10 of min, max, increment value of tick positions and
+ number of fractional digit to show
+ :rtype: tuple of int
+ """
+ graphminlog = math.floor(minLog)
+ graphmaxlog = math.ceil(maxLog)
+ rangelog = graphmaxlog - graphminlog
+
+ if rangelog <= nTicks:
+ spacing = 1.
+ else:
+ spacing = math.floor(rangelog / nTicks)
+
+ graphminlog = math.floor(graphminlog / spacing) * spacing
+ graphmaxlog = math.ceil(graphmaxlog / spacing) * spacing
+
+ nfrac = numberOfDigits(spacing)
+
+ return int(graphminlog), int(graphmaxlog), int(spacing), nfrac
+
+
+def niceNumbersAdaptativeForLog10(vMin, vMax, axisLength, tickDensity):
+ """Returns tick positions using :func:`niceNumbers` and a
+ density of ticks.
+
+ axisLength and tickDensity are based on the same unit (e.g., pixel).
+
+ :param float vMin: The min value on the axis
+ :param float vMax: The max value on the axis
+ :param float axisLength: The length of the axis.
+ :param float tickDensity: The density of ticks along the axis.
+ :returns: log10 of min, max, increment value of tick positions and
+ number of fractional digit to show
+ :rtype: tuple
+ """
+ # At least 2 ticks
+ nticks = max(2, int(round(tickDensity * axisLength)))
+ tickmin, tickmax, step, nfrac = niceNumbersForLog10(vMin, vMax, nticks)
+
+ return tickmin, tickmax, step, nfrac
+
+
+def computeLogSubTicks(ticks, lowBound, highBound):
+ """Return the sub ticks for the log scale for all given ticks if subtick
+ is in [lowBound, highBound]
+
+ :param ticks: log10 of the ticks
+ :param lowBound: the lower boundary of ticks
+ :param highBound: the higher boundary of ticks
+ :return: all the sub ticks contained in ticks (log10)
+ """
+ if len(ticks) < 1:
+ return []
+
+ res = []
+ for logPos in ticks:
+ dataOrigPos = logPos
+ for index in range(2, 10):
+ dataPos = dataOrigPos * index
+ if lowBound <= dataPos <= highBound:
+ res.append(dataPos)
+ return res
diff --git a/silx/gui/plot/backends/BackendBase.py b/silx/gui/plot/backends/BackendBase.py
new file mode 100644
index 0000000..74f96af
--- /dev/null
+++ b/silx/gui/plot/backends/BackendBase.py
@@ -0,0 +1,474 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ############################################################################*/
+"""Base class for Plot backends.
+
+It documents the Plot backend API.
+
+This API is a simplified version of PyMca PlotBackend API.
+"""
+
+__authors__ = ["V.A. Sole", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/02/2016"
+
+
+import weakref
+
+
+# Names for setCursor
+CURSOR_DEFAULT = 'default'
+CURSOR_POINTING = 'pointing'
+CURSOR_SIZE_HOR = 'size horizontal'
+CURSOR_SIZE_VER = 'size vertical'
+CURSOR_SIZE_ALL = 'size all'
+
+
+class BackendBase(object):
+ """Class defining the API a backend of the Plot should provide."""
+
+ def __init__(self, plot, parent=None):
+ """Init.
+
+ :param Plot plot: The Plot this backend is attached to
+ :param parent: The parent widget of the plot widget.
+ """
+ self.__xLimits = 1., 100.
+ self.__yLimits = {'left': (1., 100.), 'right': (1., 100.)}
+ self.__yAxisInverted = False
+ self.__keepDataAspectRatio = False
+ # Store a weakref to get access to the plot state.
+ self._setPlot(plot)
+
+ @property
+ def _plot(self):
+ """The plot this backend is attached to."""
+ if self._plotRef is None:
+ raise RuntimeError('This backend is not attached to a Plot')
+
+ plot = self._plotRef()
+ if plot is None:
+ raise RuntimeError('This backend is no more attached to a Plot')
+ return plot
+
+ def _setPlot(self, plot):
+ """Allow to set plot after init.
+
+ Use with caution, basically **immediately** after init.
+ """
+ self._plotRef = weakref.ref(plot)
+
+ # Add methods
+
+ def addCurve(self, x, y, legend,
+ color, symbol, linewidth, linestyle,
+ yaxis,
+ xerror, yerror, z, selectable,
+ fill, alpha, symbolsize):
+ """Add a 1D curve given by x an y to the graph.
+
+ :param numpy.ndarray x: The data corresponding to the x axis
+ :param numpy.ndarray y: The data corresponding to the y axis
+ :param str legend: The legend to be associated to the curve
+ :param color: color(s) to be used
+ :type color: string ("#RRGGBB") or (npoints, 4) unsigned byte array or
+ one of the predefined color names defined in Colors.py
+ :param str symbol: Symbol to be drawn at each (x, y) position::
+
+ - ' ' or '' no symbol
+ - 'o' circle
+ - '.' point
+ - ',' pixel
+ - '+' cross
+ - 'x' x-cross
+ - 'd' diamond
+ - 's' square
+
+ :param float linewidth: The width of the curve in pixels
+ :param str linestyle: Type of line::
+
+ - ' ' or '' no line
+ - '-' solid line
+ - '--' dashed line
+ - '-.' dash-dot line
+ - ':' dotted line
+
+ :param str yaxis: The Y axis this curve belongs to in: 'left', 'right'
+ :param xerror: Values with the uncertainties on the x values
+ :type xerror: numpy.ndarray or None
+ :param yerror: Values with the uncertainties on the y values
+ :type yerror: numpy.ndarray or None
+ :param int z: Layer on which to draw the cuve
+ :param bool selectable: indicate if the curve can be selected
+ :param bool fill: True to fill the curve, False otherwise
+ :param float alpha: Curve opacity, as a float in [0., 1.]
+ :param float symbolsize: Size of the symbol (if any) drawn
+ at each (x, y) position.
+ :returns: The handle used by the backend to univocally access the curve
+ """
+ return legend
+
+ def addImage(self, data, legend,
+ origin, scale, z,
+ selectable, draggable,
+ colormap, alpha):
+ """Add an image to the plot.
+
+ :param numpy.ndarray data: (nrows, ncolumns) data or
+ (nrows, ncolumns, RGBA) ubyte array
+ :param str legend: The legend to be associated to the image
+ :param origin: (origin X, origin Y) of the data.
+ Default: (0., 0.)
+ :type origin: 2-tuple of float
+ :param scale: (scale X, scale Y) of the data.
+ Default: (1., 1.)
+ :type scale: 2-tuple of float
+ :param int z: Layer on which to draw the image
+ :param bool selectable: indicate if the image can be selected
+ :param bool draggable: indicate if the image can be moved
+ :param colormap: Dictionary describing the colormap to use.
+ Ignored if data is RGB(A).
+ :type colormap: dict or None
+ :param float alpha: Opacity of the image, as a float in range [0, 1].
+ :returns: The handle used by the backend to univocally access the image
+ """
+ return legend
+
+ def addItem(self, x, y, legend, shape, color, fill, overlay, z):
+ """Add an item (i.e. a shape) to the plot.
+
+ :param numpy.ndarray x: The X coords of the points of the shape
+ :param numpy.ndarray y: The Y coords of the points of the shape
+ :param str legend: The legend to be associated to the item
+ :param str shape: Type of item to be drawn in
+ hline, polygon, rectangle, vline, polylines
+ :param str color: Color of the item
+ :param bool fill: True to fill the shape
+ :param bool overlay: True if item is an overlay, False otherwise
+ :param int z: Layer on which to draw the item
+ :returns: The handle used by the backend to univocally access the item
+ """
+ return legend
+
+ def addMarker(self, x, y, legend, text, color,
+ selectable, draggable,
+ symbol, constraint, overlay):
+ """Add a point, vertical line or horizontal line marker to the plot.
+
+ :param float x: Horizontal position of the marker in graph coordinates.
+ If None, the marker is a horizontal line.
+ :param float y: Vertical position of the marker in graph coordinates.
+ If None, the marker is a vertical line.
+ :param str legend: Legend associated to the marker
+ :param str text: Text associated to the marker (or None for no text)
+ :param str color: Color to be used for instance 'blue', 'b', '#FF0000'
+ :param bool selectable: indicate if the marker can be selected
+ :param bool draggable: indicate if the marker can be moved
+ :param str symbol: Symbol representing the marker.
+ Only relevant for point markers where X and Y are not None.
+ Value in:
+
+ - 'o' circle
+ - '.' point
+ - ',' pixel
+ - '+' cross
+ - 'x' x-cross
+ - 'd' diamond
+ - 's' square
+
+ :param constraint: A function filtering marker displacement by
+ dragging operations or None for no filter.
+ This function is called each time a marker is
+ moved.
+ This parameter is only used if draggable is True.
+ :type constraint: None or a callable that takes the coordinates of
+ the current cursor position in the plot as input
+ and that returns the filtered coordinates.
+ :param bool overlay: True if marker is an overlay (Default: False).
+ This allows for rendering optimization if this
+ marker is changed often.
+ :return: Handle used by the backend to univocally access the marker
+ """
+ return legend
+
+ # Remove methods
+
+ def remove(self, item):
+ """Remove an existing item from the plot.
+
+ :param item: A backend specific item handle returned by a add* method
+ """
+ pass
+
+ # Interaction methods
+
+ def setGraphCursorShape(self, cursor):
+ """Set the cursor shape.
+
+ To override in interactive backends.
+
+ :param str cursor: Name of the cursor shape or None
+ """
+ pass
+
+ def setGraphCursor(self, flag, color, linewidth, linestyle):
+ """Toggle the display of a crosshair cursor and set its attributes.
+
+ To override in interactive backends.
+
+ :param bool flag: Toggle the display of a crosshair cursor.
+ :param color: The color to use for the crosshair.
+ :type color: A string (either a predefined color name in Colors.py
+ or "#RRGGBB")) or a 4 columns unsigned byte array.
+ :param int linewidth: The width of the lines of the crosshair.
+ :param linestyle: Type of line::
+
+ - ' ' no line
+ - '-' solid line
+ - '--' dashed line
+ - '-.' dash-dot line
+ - ':' dotted line
+
+ :type linestyle: None or one of the predefined styles.
+ """
+ pass
+
+ def pickItems(self, x, y):
+ """Get a list of items at a pixel position.
+
+ :param float x: The x pixel coord where to pick.
+ :param float y: The y pixel coord where to pick.
+ :return: All picked items from back to front.
+ One dict per item,
+ with 'kind' key in 'curve', 'marker', 'image';
+ 'legend' key, the item legend.
+ and for curves, 'xdata' and 'ydata' keys storing picked
+ position on the curve.
+ :rtype: list of dict
+ """
+ return []
+
+ # Update curve
+
+ def setCurveColor(self, curve, color):
+ """Set the color of a curve.
+
+ :param curve: The curve handle
+ :param str color: The color to use.
+ """
+ pass
+
+ # Misc.
+
+ def getWidgetHandle(self):
+ """Return the widget this backend is drawing to."""
+ return None
+
+ def postRedisplay(self):
+ """Trigger a :meth:`Plot.replot`.
+
+ Default implementation triggers a synchronous replot if plot is dirty.
+ This method should be overridden by the embedding widget in order to
+ provide an asynchronous call to replot in order to optimize the number
+ replot operations.
+ """
+ # This method can be deferred and it might happen that plot has been
+ # destroyed in between, especially with unittests
+
+ plot = self._plotRef()
+ if plot is not None and plot._getDirtyPlot():
+ plot.replot()
+
+ def replot(self):
+ """Redraw the plot."""
+ pass
+
+ def saveGraph(self, fileName, fileFormat, dpi):
+ """Save the graph to a file (or a StringIO)
+
+ :param fileName: Destination
+ :type fileName: String or StringIO or BytesIO
+ :param str fileFormat: String specifying the format
+ :param int dpi: The resolution to use or None.
+ """
+ pass
+
+ # Graph labels
+
+ def setGraphTitle(self, title):
+ """Set the main title of the plot.
+
+ :param str title: Title associated to the plot
+ """
+ pass
+
+ def setGraphXLabel(self, label):
+ """Set the X axis label.
+
+ :param str label: label associated to the plot bottom X axis
+ """
+ pass
+
+ def setGraphYLabel(self, label, axis):
+ """Set the left Y axis label.
+
+ :param str label: label associated to the plot left Y axis
+ :param str axis: The axis for which to get the limits: left or right
+ """
+ pass
+
+ # Graph limits
+
+ def setLimits(self, xmin, xmax, ymin, ymax, y2min=None, y2max=None):
+ """Set the limits of the X and Y axes at once.
+
+ :param float xmin: minimum bottom axis value
+ :param float xmax: maximum bottom axis value
+ :param float ymin: minimum left axis value
+ :param float ymax: maximum left axis value
+ :param float y2min: minimum right axis value
+ :param float y2max: maximum right axis value
+ """
+ self.__xLimits = xmin, xmax
+ self.__yLimits['left'] = ymin, ymax
+ if y2min is not None and y2max is not None:
+ self.__yLimits['right'] = y2min, y2max
+
+ def getGraphXLimits(self):
+ """Get the graph X (bottom) limits.
+
+ :return: Minimum and maximum values of the X axis
+ """
+ return self.__xLimits
+
+ def setGraphXLimits(self, xmin, xmax):
+ """Set the limits of X axis.
+
+ :param float xmin: minimum bottom axis value
+ :param float xmax: maximum bottom axis value
+ """
+ self.__xLimits = xmin, xmax
+
+ def getGraphYLimits(self, axis):
+ """Get the graph Y (left) limits.
+
+ :param str axis: The axis for which to get the limits: left or right
+ :return: Minimum and maximum values of the Y axis
+ """
+ return self.__yLimits[axis]
+
+ def setGraphYLimits(self, ymin, ymax, axis):
+ """Set the limits of the Y axis.
+
+ :param float ymin: minimum left axis value
+ :param float ymax: maximum left axis value
+ :param str axis: The axis for which to get the limits: left or right
+ """
+ self.__yLimits[axis] = ymin, ymax
+
+ # Graph axes
+
+ def setXAxisLogarithmic(self, flag):
+ """Set the X axis scale between linear and log.
+
+ :param bool flag: If True, the bottom axis will use a log scale
+ """
+ pass
+
+ def setYAxisLogarithmic(self, flag):
+ """Set the Y axis scale between linear and log.
+
+ :param bool flag: If True, the left axis will use a log scale
+ """
+ pass
+
+ def setYAxisInverted(self, flag):
+ """Invert the Y axis.
+
+ :param bool flag: If True, put the vertical axis origin on the top
+ """
+ self.__yAxisInverted = bool(flag)
+
+ def isYAxisInverted(self):
+ """Return True if left Y axis is inverted, False otherwise."""
+ return self.__yAxisInverted
+
+ def isKeepDataAspectRatio(self):
+ """Returns whether the plot is keeping data aspect ratio or not."""
+ return self.__keepDataAspectRatio
+
+ def setKeepDataAspectRatio(self, flag):
+ """Set whether to keep data aspect ratio or not.
+
+ :param flag: True to respect data aspect ratio
+ :type flag: Boolean, default True
+ """
+ self.__keepDataAspectRatio = bool(flag)
+
+ def setGraphGrid(self, which):
+ """Set grid.
+
+ :param which: None to disable grid, 'major' for major grid,
+ 'both' for major and minor grid
+ """
+ pass
+
+ # Data <-> Pixel coordinates conversion
+
+ def dataToPixel(self, x, y, axis):
+ """Convert a position in data space to a position in pixels
+ in the widget.
+
+ :param float x: The X coordinate in data space.
+ :param float y: The Y coordinate in data space.
+ :param str axis: The Y axis to use for the conversion
+ ('left' or 'right').
+ :returns: The corresponding position in pixels or
+ None if the data position is not in the displayed area.
+ :rtype: A tuple of 2 floats: (xPixel, yPixel) or None.
+ """
+ raise NotImplementedError()
+
+ def pixelToData(self, x, y, axis, check):
+ """Convert a position in pixels in the widget to a position in
+ the data space.
+
+ :param float x: The X coordinate in pixels.
+ :param float y: The Y coordinate in pixels.
+ :param str axis: The Y axis to use for the conversion
+ ('left' or 'right').
+ :param bool check: True to check if the coordinates are in the
+ plot area.
+ :returns: The corresponding position in data space or
+ None if the pixel position is not in the plot area.
+ :rtype: A tuple of 2 floats: (xData, yData) or None.
+ """
+ raise NotImplementedError()
+
+ def getPlotBoundsInPixels(self):
+ """Plot area bounds in widget coordinates in pixels.
+
+ :return: bounds as a 4-tuple of int: (left, top, width, height)
+ """
+ raise NotImplementedError()
diff --git a/silx/gui/plot/backends/BackendMatplotlib.py b/silx/gui/plot/backends/BackendMatplotlib.py
new file mode 100644
index 0000000..f9e60d5
--- /dev/null
+++ b/silx/gui/plot/backends/BackendMatplotlib.py
@@ -0,0 +1,821 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Matplotlib Plot backend."""
+
+from __future__ import division
+
+__authors__ = ["V.A. Sole", "T. Vincent, H. Payno"]
+__license__ = "MIT"
+__date__ = "18/01/2017"
+
+
+import logging
+
+import numpy
+
+
+_logger = logging.getLogger(__name__)
+
+
+from ... import qt
+
+from ._matplotlib import FigureCanvasQTAgg
+import matplotlib
+from matplotlib.container import Container
+from matplotlib.figure import Figure
+from matplotlib.patches import Rectangle, Polygon
+from matplotlib.image import AxesImage
+from matplotlib.backend_bases import MouseEvent
+from matplotlib.lines import Line2D
+from matplotlib.collections import PathCollection, LineCollection
+
+from .ModestImage import ModestImage
+from . import BackendBase
+from .. import Colors
+from .._utils import FLOAT32_MINPOS
+
+
+class BackendMatplotlib(BackendBase.BackendBase):
+ """Base class for Matplotlib backend without a FigureCanvas.
+
+ For interactive on screen plot, see :class:`BackendMatplotlibQt`.
+
+ See :class:`BackendBase.BackendBase` for public API documentation.
+ """
+
+ def __init__(self, plot, parent=None):
+ super(BackendMatplotlib, self).__init__(plot, parent)
+
+ # matplotlib is handling keep aspect ratio at draw time
+ # When keep aspect ratio is on, and one changes the limits and
+ # ask them *before* next draw has been performed he will get the
+ # limits without applying keep aspect ratio.
+ # This attribute is used to ensure consistent values returned
+ # when getting the limits at the expense of a replot
+ self._dirtyLimits = True
+
+ self.fig = Figure()
+ self.fig.set_facecolor("w")
+
+ self.ax = self.fig.add_axes([.15, .15, .75, .75], label="left")
+ self.ax2 = self.ax.twinx()
+ self.ax2.set_label("right")
+
+ # critical for picking!!!!
+ self.ax2.set_zorder(0)
+ self.ax2.set_autoscaley_on(True)
+ self.ax.set_zorder(1)
+ # this works but the figure color is left
+ if matplotlib.__version__[0] < '2':
+ self.ax.set_axis_bgcolor('none')
+ else:
+ self.ax.set_facecolor('none')
+ self.fig.sca(self.ax)
+
+ self._overlays = set()
+ self._background = None
+
+ self._colormaps = {}
+
+ self._graphCursor = tuple()
+ self.matplotlibVersion = matplotlib.__version__
+
+ self.setGraphXLimits(0., 100.)
+ self.setGraphYLimits(0., 100., axis='right')
+ self.setGraphYLimits(0., 100., axis='left')
+
+ self._enableAxis('right', False)
+
+ # Add methods
+
+ def addCurve(self, x, y, legend,
+ color, symbol, linewidth, linestyle,
+ yaxis,
+ xerror, yerror, z, selectable,
+ fill, alpha, symbolsize):
+ for parameter in (x, y, legend, color, symbol, linewidth, linestyle,
+ yaxis, z, selectable, fill, alpha, symbolsize):
+ assert parameter is not None
+ assert yaxis in ('left', 'right')
+
+ if (len(color) == 4 and
+ type(color[3]) in [type(1), numpy.uint8, numpy.int8]):
+ color = numpy.array(color, dtype=numpy.float) / 255.
+
+ if yaxis == "right":
+ axes = self.ax2
+ self._enableAxis("right", True)
+ else:
+ axes = self.ax
+
+ picker = 3 if selectable else None
+
+ artists = [] # All the artists composing the curve
+
+ # First add errorbars if any so they are behind the curve
+ if xerror is not None or yerror is not None:
+ if hasattr(color, 'dtype') and len(color) == len(x):
+ errorbarColor = 'k'
+ else:
+ errorbarColor = color
+
+ # On Debian 7 at least, Nx1 array yerr does not seems supported
+ if (yerror is not None and yerror.ndim == 2 and
+ yerror.shape[1] == 1 and len(x) != 1):
+ yerror = numpy.ravel(yerror)
+
+ errorbars = axes.errorbar(x, y, label=legend,
+ xerr=xerror, yerr=yerror,
+ linestyle=' ', color=errorbarColor)
+ artists += list(errorbars.get_children())
+
+ if hasattr(color, 'dtype') and len(color) == len(x):
+ # scatter plot
+ if color.dtype not in [numpy.float32, numpy.float]:
+ actualColor = color / 255.
+ else:
+ actualColor = color
+
+ if linestyle not in ["", " ", None]:
+ # scatter plot with an actual line ...
+ # we need to assign a color ...
+ curveList = axes.plot(x, y, label=legend,
+ linestyle=linestyle,
+ color=actualColor[0],
+ linewidth=linewidth,
+ picker=picker,
+ marker=None)
+ artists += list(curveList)
+
+ scatter = axes.scatter(x, y,
+ label=legend,
+ color=actualColor,
+ marker=symbol,
+ picker=picker,
+ s=symbolsize)
+ artists.append(scatter)
+
+ if fill:
+ artists.append(axes.fill_between(
+ x, FLOAT32_MINPOS, y, facecolor=actualColor[0], linestyle=''))
+
+ else: # Curve
+ curveList = axes.plot(x, y,
+ label=legend,
+ linestyle=linestyle,
+ color=color,
+ linewidth=linewidth,
+ marker=symbol,
+ picker=picker,
+ markersize=symbolsize)
+ artists += list(curveList)
+
+ if fill:
+ artists.append(
+ axes.fill_between(x, FLOAT32_MINPOS, y, facecolor=color))
+
+ for artist in artists:
+ artist.set_zorder(z)
+ if alpha < 1:
+ artist.set_alpha(alpha)
+
+ return Container(artists)
+
+ def addImage(self, data, legend,
+ origin, scale, z,
+ selectable, draggable,
+ colormap, alpha):
+ # Non-uniform image
+ # http://wiki.scipy.org/Cookbook/Histograms
+ # Non-linear axes
+ # http://stackoverflow.com/questions/11488800/non-linear-axes-for-imshow-in-matplotlib
+ for parameter in (data, legend, origin, scale, z,
+ selectable, draggable):
+ assert parameter is not None
+
+ origin = float(origin[0]), float(origin[1])
+ scale = float(scale[0]), float(scale[1])
+ height, width = data.shape[0:2]
+
+ picker = (selectable or draggable)
+
+ # Debian 7 specific support
+ # No transparent colormap with matplotlib < 1.2.0
+ # Add support for transparent colormap for uint8 data with
+ # colormap with 256 colors, linear norm, [0, 255] range
+ if matplotlib.__version__ < '1.2.0':
+ if (len(data.shape) == 2 and colormap['name'] is None and
+ 'colors' in colormap):
+ colors = numpy.array(colormap['colors'], copy=False)
+ if (colors.shape[-1] == 4 and
+ not numpy.all(numpy.equal(colors[3], 255))):
+ # This is a transparent colormap
+ if (colors.shape == (256, 4) and
+ colormap['normalization'] == 'linear' and
+ not colormap['autoscale'] and
+ colormap['vmin'] == 0 and
+ colormap['vmax'] == 255 and
+ data.dtype == numpy.uint8):
+ # Supported case, convert data to RGBA
+ data = colors[data.reshape(-1)].reshape(
+ data.shape + (4,))
+ else:
+ _logger.warning(
+ 'matplotlib %s does not support transparent '
+ 'colormap.', matplotlib.__version__)
+
+ if ((height * width) > 5.0e5 and
+ origin == (0., 0.) and scale == (1., 1.)):
+ imageClass = ModestImage
+ else:
+ imageClass = AxesImage
+
+ # the normalization can be a source of time waste
+ # Two possibilities, we receive data or a ready to show image
+ if len(data.shape) == 3: # RGBA image
+ image = imageClass(self.ax,
+ label="__IMAGE__" + legend,
+ interpolation='nearest',
+ picker=picker,
+ zorder=z,
+ origin='lower')
+
+ else:
+ # Convert colormap argument to matplotlib colormap
+ scalarMappable = Colors.getMPLScalarMappable(colormap, data)
+
+ # try as data
+ image = imageClass(self.ax,
+ label="__IMAGE__" + legend,
+ interpolation='nearest',
+ cmap=scalarMappable.cmap,
+ picker=picker,
+ zorder=z,
+ norm=scalarMappable.norm,
+ origin='lower')
+ if alpha < 1:
+ image.set_alpha(alpha)
+
+ # Set image extent
+ xmin = origin[0]
+ xmax = xmin + scale[0] * width
+ if scale[0] < 0.:
+ xmin, xmax = xmax, xmin
+
+ ymin = origin[1]
+ ymax = ymin + scale[1] * height
+ if scale[1] < 0.:
+ ymin, ymax = ymax, ymin
+
+ image.set_extent((xmin, xmax, ymin, ymax))
+
+ # Set image data
+ if scale[0] < 0. or scale[1] < 0.:
+ # For negative scale, step by -1
+ xstep = 1 if scale[0] >= 0. else -1
+ ystep = 1 if scale[1] >= 0. else -1
+ data = data[::ystep, ::xstep]
+
+ image.set_data(data)
+
+ self.ax.add_artist(image)
+
+ return image
+
+ def addItem(self, x, y, legend, shape, color, fill, overlay, z):
+ xView = numpy.array(x, copy=False)
+ yView = numpy.array(y, copy=False)
+
+ if shape == "line":
+ item = self.ax.plot(x, y, label=legend, color=color,
+ linestyle='-', marker=None)[0]
+
+ elif shape == "hline":
+ if hasattr(y, "__len__"):
+ y = y[-1]
+ item = self.ax.axhline(y, label=legend, color=color)
+
+ elif shape == "vline":
+ if hasattr(x, "__len__"):
+ x = x[-1]
+ item = self.ax.axvline(x, label=legend, color=color)
+
+ elif shape == 'rectangle':
+ xMin = numpy.nanmin(xView)
+ xMax = numpy.nanmax(xView)
+ yMin = numpy.nanmin(yView)
+ yMax = numpy.nanmax(yView)
+ w = xMax - xMin
+ h = yMax - yMin
+ item = Rectangle(xy=(xMin, yMin),
+ width=w,
+ height=h,
+ fill=False,
+ color=color)
+ if fill:
+ item.set_hatch('.')
+
+ self.ax.add_patch(item)
+
+ elif shape in ('polygon', 'polylines'):
+ xView = xView.reshape(1, -1)
+ yView = yView.reshape(1, -1)
+ item = Polygon(numpy.vstack((xView, yView)).T,
+ closed=(shape == 'polygon'),
+ fill=False,
+ label=legend,
+ color=color)
+ if fill and shape == 'polygon':
+ item.set_hatch('/')
+
+ self.ax.add_patch(item)
+
+ else:
+ raise NotImplementedError("Unsupported item shape %s" % shape)
+
+ item.set_zorder(z)
+
+ if overlay:
+ item.set_animated(True)
+ self._overlays.add(item)
+
+ return item
+
+ def addMarker(self, x, y, legend, text, color,
+ selectable, draggable,
+ symbol, constraint, overlay):
+ legend = "__MARKER__" + legend
+
+ if x is not None and y is not None:
+ line = self.ax.plot(x, y, label=legend,
+ linestyle=" ",
+ color=color,
+ marker=symbol,
+ markersize=10.)[-1]
+
+ if text is not None:
+ xtmp, ytmp = self.ax.transData.transform_point((x, y))
+ inv = self.ax.transData.inverted()
+ xtmp, ytmp = inv.transform_point((xtmp, ytmp))
+
+ if symbol is None:
+ valign = 'baseline'
+ else:
+ valign = 'top'
+ text = " " + text
+
+ line._infoText = self.ax.text(x, ytmp, text,
+ color=color,
+ horizontalalignment='left',
+ verticalalignment=valign)
+
+ elif x is not None:
+ line = self.ax.axvline(x, label=legend, color=color)
+ if text is not None:
+ text = " " + text
+ ymin, ymax = self.getGraphYLimits(axis='left')
+ delta = abs(ymax - ymin)
+ if ymin > ymax:
+ ymax = ymin
+ ymax -= 0.005 * delta
+ line._infoText = self.ax.text(x, ymax, text,
+ color=color,
+ horizontalalignment='left',
+ verticalalignment='top')
+
+ elif y is not None:
+ line = self.ax.axhline(y, label=legend, color=color)
+
+ if text is not None:
+ text = " " + text
+ xmin, xmax = self.getGraphXLimits()
+ delta = abs(xmax - xmin)
+ if xmin > xmax:
+ xmax = xmin
+ xmax -= 0.005 * delta
+ line._infoText = self.ax.text(xmax, y, text,
+ color=color,
+ horizontalalignment='right',
+ verticalalignment='top')
+
+ else:
+ raise RuntimeError('A marker must at least have one coordinate')
+
+ if selectable or draggable:
+ line.set_picker(5)
+
+ if overlay:
+ line.set_animated(True)
+ self._overlays.add(line)
+
+ return line
+
+ # Remove methods
+
+ def remove(self, item):
+ # Warning: It also needs to remove extra stuff if added as for markers
+ if hasattr(item, "_infoText"): # For markers text
+ item._infoText.remove()
+ item._infoText = None
+ self._overlays.discard(item)
+ item.remove()
+
+ # Interaction methods
+
+ def setGraphCursor(self, flag, color, linewidth, linestyle):
+ if flag:
+ lineh = self.ax.axhline(
+ self.ax.get_ybound()[0], visible=False, color=color,
+ linewidth=linewidth, linestyle=linestyle)
+ lineh.set_animated(True)
+
+ linev = self.ax.axvline(
+ self.ax.get_xbound()[0], visible=False, color=color,
+ linewidth=linewidth, linestyle=linestyle)
+ linev.set_animated(True)
+
+ self._graphCursor = lineh, linev
+ else:
+ if self._graphCursor is not None:
+ lineh, linev = self._graphCursor
+ lineh.remove()
+ linev.remove()
+ self._graphCursor = tuple()
+
+ # Active curve
+
+ def setCurveColor(self, curve, color):
+ # Store Line2D and PathCollection
+ for artist in curve.get_children():
+ if isinstance(artist, (Line2D, LineCollection)):
+ artist.set_color(color)
+ elif isinstance(artist, PathCollection):
+ artist.set_facecolors(color)
+ artist.set_edgecolors(color)
+ else:
+ _logger.warning(
+ 'setActiveCurve ignoring artist %s', str(artist))
+
+ # Misc.
+
+ def getWidgetHandle(self):
+ return self.fig.canvas
+
+ def _enableAxis(self, axis, flag=True):
+ """Show/hide Y axis
+
+ :param str axis: Axis name: 'left' or 'right'
+ :param bool flag: Default, True
+ """
+ assert axis in ('right', 'left')
+ axes = self.ax2 if axis == 'right' else self.ax
+ axes.get_yaxis().set_visible(flag)
+
+ def replot(self):
+ """Do not perform rendering.
+
+ Override in subclass to actually draw something.
+ """
+ # TODO images, markers? scatter plot? move in remove?
+ # Right Y axis only support curve for now
+ # Hide right Y axis if no line is present
+ self._dirtyLimits = False
+ if not self.ax2.lines:
+ self._enableAxis('right', False)
+
+ def saveGraph(self, fileName, fileFormat, dpi):
+ # fileName can be also a StringIO or file instance
+ if dpi is not None:
+ self.fig.savefig(fileName, format=fileFormat, dpi=dpi)
+ else:
+ self.fig.savefig(fileName, format=fileFormat)
+ self._plot._setDirtyPlot()
+
+ # Graph labels
+
+ def setGraphTitle(self, title):
+ self.ax.set_title(title)
+
+ def setGraphXLabel(self, label):
+ self.ax.set_xlabel(label)
+
+ def setGraphYLabel(self, label, axis):
+ axes = self.ax if axis == 'left' else self.ax2
+ axes.set_ylabel(label)
+
+ # Graph limits
+
+ def setLimits(self, xmin, xmax, ymin, ymax, y2min=None, y2max=None):
+ # Let matplotlib taking care of keep aspect ratio if any
+ self._dirtyLimits = True
+ self.ax.set_xlim(min(xmin, xmax), max(xmin, xmax))
+
+ if y2min is not None and y2max is not None:
+ if not self.isYAxisInverted():
+ self.ax2.set_ylim(min(y2min, y2max), max(y2min, y2max))
+ else:
+ self.ax2.set_ylim(max(y2min, y2max), min(y2min, y2max))
+
+ if not self.isYAxisInverted():
+ self.ax.set_ylim(min(ymin, ymax), max(ymin, ymax))
+ else:
+ self.ax.set_ylim(max(ymin, ymax), min(ymin, ymax))
+
+ def getGraphXLimits(self):
+ if self._dirtyLimits and self.isKeepDataAspectRatio():
+ self.replot() # makes sure we get the right limits
+ return self.ax.get_xbound()
+
+ def setGraphXLimits(self, xmin, xmax):
+ self._dirtyLimits = True
+ self.ax.set_xlim(min(xmin, xmax), max(xmin, xmax))
+
+ def getGraphYLimits(self, axis):
+ assert axis in ('left', 'right')
+ ax = self.ax2 if axis == 'right' else self.ax
+
+ if not ax.get_visible():
+ return None
+
+ if self._dirtyLimits and self.isKeepDataAspectRatio():
+ self.replot() # makes sure we get the right limits
+
+ return ax.get_ybound()
+
+ def setGraphYLimits(self, ymin, ymax, axis):
+ ax = self.ax2 if axis == 'right' else self.ax
+ if ymax < ymin:
+ ymin, ymax = ymax, ymin
+ self._dirtyLimits = True
+
+ if self.isKeepDataAspectRatio():
+ # matplotlib keeps limits of shared axis when keeping aspect ratio
+ # So x limits are kept when changing y limits....
+ # Change x limits first by taking into account aspect ratio
+ # and then change y limits.. so matplotlib does not need
+ # to make change (to y) to keep aspect ratio
+ xmin, xmax = ax.get_xbound()
+ curYMin, curYMax = ax.get_ybound()
+
+ newXRange = (xmax - xmin) * (ymax - ymin) / (curYMax - curYMin)
+ xcenter = 0.5 * (xmin + xmax)
+ ax.set_xlim(xcenter - 0.5 * newXRange, xcenter + 0.5 * newXRange)
+
+ if not self.isYAxisInverted():
+ ax.set_ylim(ymin, ymax)
+ else:
+ ax.set_ylim(ymax, ymin)
+
+ # Graph axes
+
+ def setXAxisLogarithmic(self, flag):
+ self.ax2.set_xscale('log' if flag else 'linear')
+ self.ax.set_xscale('log' if flag else 'linear')
+
+ def setYAxisLogarithmic(self, flag):
+ self.ax2.set_yscale('log' if flag else 'linear')
+ self.ax.set_yscale('log' if flag else 'linear')
+
+ def setYAxisInverted(self, flag):
+ if self.ax.yaxis_inverted() != bool(flag):
+ self.ax.invert_yaxis()
+
+ def isYAxisInverted(self):
+ return self.ax.yaxis_inverted()
+
+ def isKeepDataAspectRatio(self):
+ return self.ax.get_aspect() in (1.0, 'equal')
+
+ def setKeepDataAspectRatio(self, flag):
+ self.ax.set_aspect(1.0 if flag else 'auto')
+ self.ax2.set_aspect(1.0 if flag else 'auto')
+
+ def setGraphGrid(self, which):
+ self.ax.grid(False, which='both') # Disable all grid first
+ if which is not None:
+ self.ax.grid(True, which=which)
+
+ # Data <-> Pixel coordinates conversion
+
+ def dataToPixel(self, x, y, axis):
+ ax = self.ax2 if axis == "right" else self.ax
+
+ pixels = ax.transData.transform_point((x, y))
+ xPixel, yPixel = pixels.T
+ return xPixel, yPixel
+
+ def pixelToData(self, x, y, axis, check):
+ ax = self.ax2 if axis == "right" else self.ax
+
+ inv = ax.transData.inverted()
+ x, y = inv.transform_point((x, y))
+
+ if check:
+ xmin, xmax = self.getGraphXLimits()
+ ymin, ymax = self.getGraphYLimits(axis=axis)
+
+ if x > xmax or x < xmin or y > ymax or y < ymin:
+ return None # (x, y) is out of plot area
+
+ return x, y
+
+ def getPlotBoundsInPixels(self):
+ bbox = self.ax.get_window_extent().transformed(
+ self.fig.dpi_scale_trans.inverted())
+ dpi = self.fig.dpi
+ # Warning this is not returning int...
+ return (bbox.bounds[0] * dpi, bbox.bounds[1] * dpi,
+ bbox.bounds[2] * dpi, bbox.bounds[3] * dpi)
+
+
+class BackendMatplotlibQt(FigureCanvasQTAgg, BackendMatplotlib):
+ """QWidget matplotlib backend using a QtAgg canvas.
+
+ It adds fast overlay drawing and mouse event management.
+ """
+
+ _sigPostRedisplay = qt.Signal()
+ """Signal handling automatic asynchronous replot"""
+
+ def __init__(self, plot, parent=None):
+ self._insideResizeEventMethod = False
+
+ BackendMatplotlib.__init__(self, plot, parent)
+ FigureCanvasQTAgg.__init__(self, self.fig)
+ self.setParent(parent)
+
+ FigureCanvasQTAgg.setSizePolicy(
+ self, qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding)
+ FigureCanvasQTAgg.updateGeometry(self)
+
+ # Make postRedisplay asynchronous using Qt signal
+ self._sigPostRedisplay.connect(
+ super(BackendMatplotlibQt, self).postRedisplay,
+ qt.Qt.QueuedConnection)
+
+ self._picked = None
+
+ self.mpl_connect('button_press_event', self._onMousePress)
+ self.mpl_connect('button_release_event', self._onMouseRelease)
+ self.mpl_connect('motion_notify_event', self._onMouseMove)
+ self.mpl_connect('scroll_event', self._onMouseWheel)
+
+ def postRedisplay(self):
+ self._sigPostRedisplay.emit()
+
+ # Mouse event forwarding
+
+ _MPL_TO_PLOT_BUTTONS = {1: 'left', 2: 'middle', 3: 'right'}
+
+ def _onMousePress(self, event):
+ self._plot.onMousePress(
+ event.x, event.y, self._MPL_TO_PLOT_BUTTONS[event.button])
+
+ def _onMouseMove(self, event):
+ if self._graphCursor:
+ lineh, linev = self._graphCursor
+ if event.inaxes != self.ax and lineh.get_visible():
+ lineh.set_visible(False)
+ linev.set_visible(False)
+ self._plot._setDirtyPlot(overlayOnly=True)
+ else:
+ linev.set_visible(True)
+ linev.set_xdata((event.xdata, event.xdata))
+ lineh.set_visible(True)
+ lineh.set_ydata((event.ydata, event.ydata))
+ self._plot._setDirtyPlot(overlayOnly=True)
+ # onMouseMove must trigger replot if dirty flag is raised
+
+ self._plot.onMouseMove(event.x, event.y)
+
+ def _onMouseRelease(self, event):
+ self._plot.onMouseRelease(
+ event.x, event.y, self._MPL_TO_PLOT_BUTTONS[event.button])
+
+ def _onMouseWheel(self, event):
+ self._plot.onMouseWheel(event.x, event.y, event.step)
+
+ def leaveEvent(self, event):
+ """QWidget event handler"""
+ self._plot.onMouseLeaveWidget()
+
+ # picking
+
+ def _onPick(self, event):
+ # TODO not very nice and fragile, find a better way?
+ # Make a selection according to kind
+ if self._picked is None:
+ _logger.error('Internal picking error')
+ return
+
+ label = event.artist.get_label()
+ if label.startswith('__MARKER__'):
+ self._picked.append({'kind': 'marker', 'legend': label[10:]})
+
+ elif label.startswith('__IMAGE__'):
+ self._picked.append({'kind': 'image', 'legend': label[9:]})
+
+ else: # it's a curve, item have no picker for now
+ if isinstance(event.artist, PathCollection):
+ data = event.artist.get_offsets()[event.ind, :]
+ xdata, ydata = data[:, 0], data[:, 1]
+ elif isinstance(event.artist, Line2D):
+ xdata = event.artist.get_xdata()[event.ind]
+ ydata = event.artist.get_ydata()[event.ind]
+ else:
+ _logger.info('Unsupported artist, ignored')
+ return
+
+ self._picked.append({'kind': 'curve', 'legend': label,
+ 'xdata': xdata, 'ydata': ydata})
+
+ def pickItems(self, x, y):
+ self._picked = []
+
+ # Weird way to do an explicit picking: Simulate a button press event
+ mouseEvent = MouseEvent('button_press_event', self, x, y)
+ cid = self.mpl_connect('pick_event', self._onPick)
+ self.fig.pick(mouseEvent)
+ self.mpl_disconnect(cid)
+ picked = self._picked
+ self._picked = None
+
+ return picked
+
+ # replot control
+
+ def resizeEvent(self, event):
+ self._insideResizeEventMethod = True
+ # Need to dirty the whole plot on resize.
+ self._plot._setDirtyPlot()
+ FigureCanvasQTAgg.resizeEvent(self, event)
+ self._insideResizeEventMethod = False
+
+ def draw(self):
+ """Override canvas draw method to support faster draw of overlays."""
+ if self._plot._getDirtyPlot(): # Need a full redraw
+ FigureCanvasQTAgg.draw(self)
+ self._background = None # Any saved background is dirty
+
+ if (self._overlays or self._graphCursor or
+ self._plot._getDirtyPlot() == 'overlay'):
+ # There are overlays or crosshair, or they is just no more overlays
+
+ # Specific case: called from resizeEvent:
+ # avoid store/restore background, just draw the overlay
+ if not self._insideResizeEventMethod:
+ if self._background is None: # First store the background
+ self._background = self.copy_from_bbox(self.fig.bbox)
+
+ self.restore_region(self._background)
+
+ # This assume that items are only on left/bottom Axes
+ for item in self._overlays:
+ self.ax.draw_artist(item)
+
+ for item in self._graphCursor:
+ self.ax.draw_artist(item)
+
+ self.blit(self.fig.bbox)
+
+ def replot(self):
+ BackendMatplotlib.replot(self)
+ self.draw()
+
+ # cursor
+
+ _QT_CURSORS = {
+ None: qt.Qt.ArrowCursor,
+ BackendBase.CURSOR_DEFAULT: qt.Qt.ArrowCursor,
+ BackendBase.CURSOR_POINTING: qt.Qt.PointingHandCursor,
+ BackendBase.CURSOR_SIZE_HOR: qt.Qt.SizeHorCursor,
+ BackendBase.CURSOR_SIZE_VER: qt.Qt.SizeVerCursor,
+ BackendBase.CURSOR_SIZE_ALL: qt.Qt.SizeAllCursor,
+ }
+
+ def setGraphCursorShape(self, cursor):
+ cursor = self._QT_CURSORS[cursor]
+
+ FigureCanvasQTAgg.setCursor(self, qt.QCursor(cursor))
diff --git a/silx/gui/plot/backends/BackendOpenGL.py b/silx/gui/plot/backends/BackendOpenGL.py
new file mode 100644
index 0000000..bc10eca
--- /dev/null
+++ b/silx/gui/plot/backends/BackendOpenGL.py
@@ -0,0 +1,1631 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ############################################################################*/
+"""OpenGL Plot backend."""
+
+from __future__ import division
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "21/03/2017"
+
+from collections import OrderedDict, namedtuple
+from ctypes import c_void_p
+import logging
+
+import numpy
+
+from .._utils import FLOAT32_MINPOS
+from . import BackendBase
+from .. import Colors
+from ... import qt
+
+from ..._glutils import gl
+from ... import _glutils as glu
+from .glutils import (
+ GLPlotCurve2D, GLPlotColormap, GLPlotRGBAImage, GLPlotFrame2D,
+ mat4Ortho, mat4Identity,
+ LEFT, RIGHT, BOTTOM, TOP,
+ Text2D, Shape2D)
+from .glutils.PlotImageFile import saveImageToFile
+
+_logger = logging.getLogger(__name__)
+
+
+# TODO idea: BackendQtMixIn class to share code between mpl and gl
+# TODO check if OpenGL is available
+# TODO make an off-screen mesa backend
+
+# Bounds ######################################################################
+
+class Range(namedtuple('Range', ('min_', 'max_'))):
+ """Describes a 1D range"""
+
+ @property
+ def range_(self):
+ return self.max_ - self.min_
+
+ @property
+ def center(self):
+ return 0.5 * (self.min_ + self.max_)
+
+
+class Bounds(object):
+ """Describes plot bounds with 2 y axis"""
+
+ def __init__(self, xMin, xMax, yMin, yMax, y2Min, y2Max):
+ self._xAxis = Range(xMin, xMax)
+ self._yAxis = Range(yMin, yMax)
+ self._y2Axis = Range(y2Min, y2Max)
+
+ def __repr__(self):
+ return "x: %s, y: %s, y2: %s" % (repr(self._xAxis),
+ repr(self._yAxis),
+ repr(self._y2Axis))
+
+ @property
+ def xAxis(self):
+ return self._xAxis
+
+ @property
+ def yAxis(self):
+ return self._yAxis
+
+ @property
+ def y2Axis(self):
+ return self._y2Axis
+
+
+# Content #####################################################################
+
+class PlotDataContent(object):
+ """Manage plot data content: images and curves.
+
+ This class is only meant to work with _OpenGLPlotCanvas.
+ """
+
+ _PRIMITIVE_TYPES = 'curve', 'image'
+
+ def __init__(self):
+ self._primitives = OrderedDict() # For images and curves
+
+ def add(self, primitive):
+ """Add a curve or image to the content dictionary.
+
+ This function generates the key in the dict from the primitive.
+
+ :param primitive: The primitive to add.
+ :type primitive: Instance of GLPlotCurve2D, GLPlotColormap,
+ GLPlotRGBAImage.
+ """
+ if isinstance(primitive, GLPlotCurve2D):
+ primitiveType = 'curve'
+ elif isinstance(primitive, (GLPlotColormap, GLPlotRGBAImage)):
+ primitiveType = 'image'
+ else:
+ raise RuntimeError('Unsupported object type: %s', primitive)
+
+ key = primitiveType, primitive.info['legend']
+ self._primitives[key] = primitive
+
+ def get(self, primitiveType, legend):
+ """Get the corresponding primitive of given type with given legend.
+
+ :param str primitiveType: Type of primitive ('curve' or 'image').
+ :param str legend: The legend of the primitive to retrieve.
+ :return: The corresponding curve or None if no such curve.
+ """
+ assert primitiveType in self._PRIMITIVE_TYPES
+ return self._primitives.get((primitiveType, legend))
+
+ def pop(self, primitiveType, key):
+ """Pop the corresponding curve or return None if no such curve.
+
+ :param str primitiveType:
+ :param str key:
+ :return:
+ """
+ assert primitiveType in self._PRIMITIVE_TYPES
+ return self._primitives.pop((primitiveType, key), None)
+
+ def zOrderedPrimitives(self, reverse=False):
+ """List of primitives sorted according to their z order.
+
+ It is a stable sort (as sorted):
+ Original order is preserved when key is the same.
+
+ :param bool reverse: Ascending (True, default) or descending (False).
+ """
+ return sorted(self._primitives.values(),
+ key=lambda primitive: primitive.info['zOrder'],
+ reverse=reverse)
+
+ def primitives(self):
+ """Iterator over all primitives."""
+ return self._primitives.values()
+
+ def primitiveKeys(self, primitiveType):
+ """Iterator over primitives of a specific type."""
+ assert primitiveType in self._PRIMITIVE_TYPES
+ for type_, key in self._primitives.keys():
+ if type_ == primitiveType:
+ yield key
+
+ def getBounds(self, xPositive=False, yPositive=False):
+ """Bounds of the data.
+
+ Can return strictly positive bounds (for log scale).
+ In this case, curves are clipped to their smaller positive value
+ and images with negative min are ignored.
+
+ :param bool xPositive: True to get strictly positive range.
+ :param bool yPositive: True to get strictly positive range.
+ :return: The range of data for x, y and y2, or default (1., 100.)
+ if no range found for one dimension.
+ :rtype: Bounds
+ """
+ xMin, yMin, y2Min = float('inf'), float('inf'), float('inf')
+ xMax = 0. if xPositive else -float('inf')
+ if yPositive:
+ yMax, y2Max = 0., 0.
+ else:
+ yMax, y2Max = -float('inf'), -float('inf')
+
+ for item in self._primitives.values():
+ # To support curve <= 0. and log and bypass images:
+ # If positive only, uses x|yMinPos if available
+ # and bypass other data with negative min bounds
+ if xPositive:
+ itemXMin = getattr(item, 'xMinPos', item.xMin)
+ if itemXMin is None or itemXMin < FLOAT32_MINPOS:
+ continue
+ else:
+ itemXMin = item.xMin
+
+ if yPositive:
+ itemYMin = getattr(item, 'yMinPos', item.yMin)
+ if itemYMin is None or itemYMin < FLOAT32_MINPOS:
+ continue
+ else:
+ itemYMin = item.yMin
+
+ if itemXMin < xMin:
+ xMin = itemXMin
+ if item.xMax > xMax:
+ xMax = item.xMax
+
+ if item.info.get('yAxis') == 'right':
+ if itemYMin < y2Min:
+ y2Min = itemYMin
+ if item.yMax > y2Max:
+ y2Max = item.yMax
+ else:
+ if itemYMin < yMin:
+ yMin = itemYMin
+ if item.yMax > yMax:
+ yMax = item.yMax
+
+ # One of the limit has not been updated, return default range
+ if xMin >= xMax:
+ xMin, xMax = 1., 100.
+ if yMin >= yMax:
+ yMin, yMax = 1., 100.
+ if y2Min >= y2Max:
+ y2Min, y2Max = 1., 100.
+
+ return Bounds(xMin, xMax, yMin, yMax, y2Min, y2Max)
+
+
+# shaders #####################################################################
+
+_baseVertShd = """
+ attribute vec2 position;
+ uniform mat4 matrix;
+ uniform bvec2 isLog;
+
+ const float oneOverLog10 = 0.43429448190325176;
+
+ void main(void) {
+ vec2 posTransformed = position;
+ if (isLog.x) {
+ posTransformed.x = oneOverLog10 * log(position.x);
+ }
+ if (isLog.y) {
+ posTransformed.y = oneOverLog10 * log(position.y);
+ }
+ gl_Position = matrix * vec4(posTransformed, 0.0, 1.0);
+ }
+ """
+
+_baseFragShd = """
+ uniform vec4 color;
+ uniform int hatchStep;
+ uniform float tickLen;
+
+ void main(void) {
+ if (tickLen != 0.) {
+ if (mod((gl_FragCoord.x + gl_FragCoord.y) / tickLen, 2.) < 1.) {
+ gl_FragColor = color;
+ } else {
+ discard;
+ }
+ } else if (hatchStep == 0 ||
+ mod(gl_FragCoord.x - gl_FragCoord.y, float(hatchStep)) == 0.) {
+ gl_FragColor = color;
+ } else {
+ discard;
+ }
+ }
+ """
+
+_texVertShd = """
+ attribute vec2 position;
+ attribute vec2 texCoords;
+ uniform mat4 matrix;
+
+ varying vec2 coords;
+
+ void main(void) {
+ gl_Position = matrix * vec4(position, 0.0, 1.0);
+ coords = texCoords;
+ }
+ """
+
+_texFragShd = """
+ uniform sampler2D tex;
+
+ varying vec2 coords;
+
+ void main(void) {
+ gl_FragColor = texture2D(tex, coords);
+ }
+ """
+
+
+# BackendOpenGL ###############################################################
+
+_current_context = None
+
+
+def _getContext():
+ assert _current_context is not None
+ return _current_context
+
+
+class BackendOpenGL(BackendBase.BackendBase, qt.QGLWidget):
+ """OpenGL-based Plot backend.
+
+ WARNINGS:
+ Unless stated otherwise, this API is NOT thread-safe and MUST be
+ called from the main thread.
+ When numpy arrays are passed as arguments to the API (through
+ :func:`addCurve` and :func:`addImage`), they are copied only if
+ required.
+ So, the caller should not modify these arrays afterwards.
+ """
+
+ _sigPostRedisplay = qt.Signal()
+ """Signal handling automatic asynchronous replot"""
+
+ def __init__(self, plot, parent=None):
+ qt.QGLWidget.__init__(self, parent)
+ BackendBase.BackendBase.__init__(self, plot, parent)
+
+ self.matScreenProj = mat4Identity()
+
+ self._progBase = glu.Program(
+ _baseVertShd, _baseFragShd, attrib0='position')
+ self._progTex = glu.Program(
+ _texVertShd, _texFragShd, attrib0='position')
+ self._plotFBOs = {}
+
+ self._keepDataAspectRatio = False
+
+ self._devicePixelRatio = 1.0
+
+ self._crosshairCursor = None
+ self._mousePosInPixels = None
+
+ self._markers = OrderedDict()
+ self._items = OrderedDict()
+ self._plotContent = PlotDataContent() # For images and curves
+ self._selectionAreas = OrderedDict()
+ self._glGarbageCollector = []
+
+ self._plotFrame = GLPlotFrame2D(
+ margins={'left': 100, 'right': 50, 'top': 50, 'bottom': 50})
+
+ # Make postRedisplay asynchronous using Qt signal
+ self._sigPostRedisplay.connect(
+ super(BackendOpenGL, self).postRedisplay,
+ qt.Qt.QueuedConnection)
+
+ # TODO is this needed? move it Plot?
+ self.setGraphXLimits(0., 100.)
+ self.setGraphYLimits(0., 100., axis='right')
+ self.setGraphYLimits(0., 100., axis='left')
+
+ self.setAutoFillBackground(False)
+ self.setMouseTracking(True)
+
+ # QWidget
+
+ _MOUSE_BTNS = {1: 'left', 2: 'right', 4: 'middle'}
+
+ def sizeHint(self):
+ return qt.QSize(8 * 80, 6 * 80) # Mimic MatplotlibBackend
+
+ def mousePressEvent(self, event):
+ xPixel = event.x() * self._devicePixelRatio
+ yPixel = event.y() * self._devicePixelRatio
+ btn = self._MOUSE_BTNS[event.button()]
+ self._plot.onMousePress(xPixel, yPixel, btn)
+ event.accept()
+
+ def mouseMoveEvent(self, event):
+ xPixel = event.x() * self._devicePixelRatio
+ yPixel = event.y() * self._devicePixelRatio
+
+ # Handle crosshair
+ inXPixel, inYPixel = self._mouseInPlotArea(xPixel, yPixel)
+ isCursorInPlot = inXPixel == xPixel and inYPixel == yPixel
+
+ previousMousePosInPixels = self._mousePosInPixels
+ self._mousePosInPixels = (xPixel, yPixel) if isCursorInPlot else None
+ if (self._crosshairCursor is not None and
+ previousMousePosInPixels != self._crosshairCursor):
+ # Avoid replot when cursor remains outside plot area
+ self._plot._setDirtyPlot(overlayOnly=True)
+
+ self._plot.onMouseMove(xPixel, yPixel)
+ event.accept()
+
+ def mouseReleaseEvent(self, event):
+ xPixel = event.x() * self._devicePixelRatio
+ yPixel = event.y() * self._devicePixelRatio
+
+ btn = self._MOUSE_BTNS[event.button()]
+ self._plot.onMouseRelease(xPixel, yPixel, btn)
+ event.accept()
+
+ def wheelEvent(self, event):
+ xPixel = event.x() * self._devicePixelRatio
+ yPixel = event.y() * self._devicePixelRatio
+
+ if hasattr(event, 'angleDelta'): # Qt 5
+ delta = event.angleDelta().y()
+ else: # Qt 4 support
+ delta = event.delta()
+ angleInDegrees = delta / 8.
+ self._plot.onMouseWheel(xPixel, yPixel, angleInDegrees)
+ event.accept()
+
+ def leaveEvent(self, _):
+ self._plot.onMouseLeaveWidget()
+
+ # QGLWidget API
+
+ @staticmethod
+ def _setBlendFuncGL():
+ # glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
+ gl.glBlendFuncSeparate(gl.GL_SRC_ALPHA,
+ gl.GL_ONE_MINUS_SRC_ALPHA,
+ gl.GL_ONE,
+ gl.GL_ONE)
+
+ def initializeGL(self):
+ gl.testGL()
+
+ gl.glClearColor(1., 1., 1., 1.)
+ gl.glClearStencil(0)
+
+ gl.glEnable(gl.GL_BLEND)
+ self._setBlendFuncGL()
+
+ # For lines
+ gl.glHint(gl.GL_LINE_SMOOTH_HINT, gl.GL_NICEST)
+
+ # For points
+ gl.glEnable(gl.GL_VERTEX_PROGRAM_POINT_SIZE) # OpenGL 2
+ gl.glEnable(gl.GL_POINT_SPRITE) # OpenGL 2
+ # gl.glEnable(gl.GL_PROGRAM_POINT_SIZE)
+
+ def _paintDirectGL(self):
+ self._renderPlotAreaGL()
+ self._plotFrame.render()
+ self._renderMarkersGL()
+ self._renderOverlayGL()
+
+ def _paintFBOGL(self):
+ context = glu.getGLContext()
+ plotFBOTex = self._plotFBOs.get(context)
+ if (self._plot._getDirtyPlot() or self._plotFrame.isDirty or
+ plotFBOTex is None):
+ self._plotVertices = numpy.array(((-1., -1., 0., 0.),
+ (1., -1., 1., 0.),
+ (-1., 1., 0., 1.),
+ (1., 1., 1., 1.)),
+ dtype=numpy.float32)
+ if plotFBOTex is None or \
+ plotFBOTex.shape[1] != self._plotFrame.size[0] or \
+ plotFBOTex.shape[0] != self._plotFrame.size[1]:
+ if plotFBOTex is not None:
+ plotFBOTex.discard()
+ plotFBOTex = glu.FramebufferTexture(
+ gl.GL_RGBA,
+ shape=(self._plotFrame.size[1],
+ self._plotFrame.size[0]),
+ minFilter=gl.GL_NEAREST,
+ magFilter=gl.GL_NEAREST,
+ wrap=(gl.GL_CLAMP_TO_EDGE,
+ gl.GL_CLAMP_TO_EDGE))
+ self._plotFBOs[context] = plotFBOTex
+
+ with plotFBOTex:
+ gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_STENCIL_BUFFER_BIT)
+ self._renderPlotAreaGL()
+ self._plotFrame.render()
+
+ # Render plot in screen coords
+ gl.glViewport(0, 0, self._plotFrame.size[0], self._plotFrame.size[1])
+
+ self._progTex.use()
+ texUnit = 0
+
+ gl.glUniform1i(self._progTex.uniforms['tex'], texUnit)
+ gl.glUniformMatrix4fv(self._progTex.uniforms['matrix'], 1, gl.GL_TRUE,
+ mat4Identity())
+
+ stride = self._plotVertices.shape[-1] * self._plotVertices.itemsize
+ gl.glEnableVertexAttribArray(self._progTex.attributes['position'])
+ gl.glVertexAttribPointer(self._progTex.attributes['position'],
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ stride, self._plotVertices)
+
+ texCoordsPtr = c_void_p(self._plotVertices.ctypes.data +
+ 2 * self._plotVertices.itemsize) # Better way?
+ gl.glEnableVertexAttribArray(self._progTex.attributes['texCoords'])
+ gl.glVertexAttribPointer(self._progTex.attributes['texCoords'],
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ stride, texCoordsPtr)
+
+ with plotFBOTex.texture:
+ gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, len(self._plotVertices))
+
+ self._renderMarkersGL()
+ self._renderOverlayGL()
+
+ def paintGL(self):
+ global _current_context
+ _current_context = self.context()
+
+ glu.setGLContextGetter(_getContext)
+
+ if hasattr(self, 'windowHandle'): # Qt 5
+ devicePixelRatio = self.windowHandle().devicePixelRatio()
+ if devicePixelRatio != self._devicePixelRatio:
+ self._devicePixelRatio = devicePixelRatio
+ self.resizeGL(int(self.width() * devicePixelRatio),
+ int(self.height() * devicePixelRatio))
+
+ # Release OpenGL resources
+ for item in self._glGarbageCollector:
+ item.discard()
+ self._glGarbageCollector = []
+
+ gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_STENCIL_BUFFER_BIT)
+
+ # Check if window is large enough
+ plotWidth, plotHeight = self.getPlotBoundsInPixels()[2:]
+ if plotWidth <= 2 or plotHeight <= 2:
+ return
+
+ # self._paintDirectGL()
+ self._paintFBOGL()
+
+ glu.setGLContextGetter()
+ _current_context = None
+
+ def _nonOrthoAxesLineMarkerPrimitives(self, marker, pixelOffset):
+ """Generates the vertices and label for a line marker.
+
+ :param dict marker: Description of a line marker
+ :param int pixelOffset: Offset of text from borders in pixels
+ :return: Line vertices and Text label or None
+ :rtype: 2-tuple (2x2 numpy.array of float, Text2D)
+ """
+ label, vertices = None, None
+
+ xCoord, yCoord = marker['x'], marker['y']
+ assert xCoord is None or yCoord is None # Specific to line markers
+
+ # Get plot corners in data coords
+ plotLeft, plotTop, plotWidth, plotHeight = self.getPlotBoundsInPixels()
+
+ corners = [(plotLeft, plotTop),
+ (plotLeft, plotTop + plotHeight),
+ (plotLeft + plotWidth, plotTop + plotHeight),
+ (plotLeft + plotWidth, plotTop)]
+ corners = numpy.array([self.pixelToData(x, y, axis='left', check=False)
+ for (x, y) in corners])
+
+ borders = {
+ 'right': (corners[3], corners[2]),
+ 'top': (corners[0], corners[3]),
+ 'bottom': (corners[2], corners[1]),
+ 'left': (corners[1], corners[0])
+ }
+
+ textLayouts = { # align, valign, offsets
+ 'right': (RIGHT, BOTTOM, (-1., -1.)),
+ 'top': (LEFT, TOP, (1., 1.)),
+ 'bottom': (LEFT, BOTTOM, (1., -1.)),
+ 'left': (LEFT, BOTTOM, (1., -1.))
+ }
+
+ if xCoord is None: # Horizontal line in data space
+ if marker['text'] is not None:
+ # Find intersection of hline with borders in data
+ # Order is important as it stops at first intersection
+ for border_name in ('right', 'top', 'bottom', 'left'):
+ (x0, y0), (x1, y1) = borders[border_name]
+
+ if min(y0, y1) <= yCoord < max(y0, y1):
+ xIntersect = (yCoord - y0) * (x1 - x0) / (y1 - y0) + x0
+
+ # Add text label
+ pixelPos = self.dataToPixel(
+ xIntersect, yCoord, axis='left', check=False)
+
+ align, valign, offsets = textLayouts[border_name]
+
+ x = pixelPos[0] + offsets[0] * pixelOffset
+ y = pixelPos[1] + offsets[1] * pixelOffset
+ label = Text2D(marker['text'], x, y,
+ color=marker['color'],
+ bgColor=(1., 1., 1., 0.5),
+ align=align, valign=valign)
+ break # Stop at first intersection
+
+ xMin, xMax = corners[:, 0].min(), corners[:, 0].max()
+ vertices = numpy.array(
+ ((xMin, yCoord), (xMax, yCoord)), dtype=numpy.float32)
+
+ else: # yCoord is None: vertical line in data space
+ if marker['text'] is not None:
+ # Find intersection of hline with borders in data
+ # Order is important as it stops at first intersection
+ for border_name in ('top', 'bottom', 'right', 'left'):
+ (x0, y0), (x1, y1) = borders[border_name]
+ if min(x0, x1) <= xCoord < max(x0, x1):
+ yIntersect = (xCoord - x0) * (y1 - y0) / (x1 - x0) + y0
+
+ # Add text label
+ pixelPos = self.dataToPixel(
+ xCoord, yIntersect, axis='left', check=False)
+
+ align, valign, offsets = textLayouts[border_name]
+
+ x = pixelPos[0] + offsets[0] * pixelOffset
+ y = pixelPos[1] + offsets[1] * pixelOffset
+ label = Text2D(marker['text'], x, y,
+ color=marker['color'],
+ bgColor=(1., 1., 1., 0.5),
+ align=align, valign=valign)
+ break # Stop at first intersection
+
+ yMin, yMax = corners[:, 1].min(), corners[:, 1].max()
+ vertices = numpy.array(
+ ((xCoord, yMin), (xCoord, yMax)), dtype=numpy.float32)
+
+ return vertices, label
+
+ def _renderMarkersGL(self):
+ if len(self._markers) == 0:
+ return
+
+ plotWidth, plotHeight = self.getPlotBoundsInPixels()[2:]
+
+ isXLog = self._plotFrame.xAxis.isLog
+ isYLog = self._plotFrame.yAxis.isLog
+
+ # Render in plot area
+ gl.glScissor(self._plotFrame.margins.left,
+ self._plotFrame.margins.bottom,
+ plotWidth, plotHeight)
+ gl.glEnable(gl.GL_SCISSOR_TEST)
+
+ gl.glViewport(self._plotFrame.margins.left,
+ self._plotFrame.margins.bottom,
+ plotWidth, plotHeight)
+
+ # Prepare vertical and horizontal markers rendering
+ self._progBase.use()
+ gl.glUniformMatrix4fv(self._progBase.uniforms['matrix'], 1, gl.GL_TRUE,
+ self._plotFrame.transformedDataProjMat)
+ gl.glUniform2i(self._progBase.uniforms['isLog'], isXLog, isYLog)
+ gl.glUniform1i(self._progBase.uniforms['hatchStep'], 0)
+ gl.glUniform1f(self._progBase.uniforms['tickLen'], 0.)
+ posAttrib = self._progBase.attributes['position']
+
+ labels = []
+ pixelOffset = 3
+
+ for marker in self._markers.values():
+ xCoord, yCoord = marker['x'], marker['y']
+
+ if ((isXLog and xCoord is not None and
+ xCoord < FLOAT32_MINPOS) or
+ (isYLog and yCoord is not None and
+ yCoord < FLOAT32_MINPOS)):
+ # Do not render markers with negative coords on log axis
+ continue
+
+ if xCoord is None or yCoord is None:
+ if not self.isDefaultBaseVectors(): # Non-orthogonal axes
+ vertices, label = self._nonOrthoAxesLineMarkerPrimitives(
+ marker, pixelOffset)
+ if label is not None:
+ labels.append(label)
+
+ else: # Orthogonal axes
+ pixelPos = self.dataToPixel(
+ xCoord, yCoord, axis='left', check=False)
+
+ if xCoord is None: # Horizontal line in data space
+ if marker['text'] is not None:
+ x = self._plotFrame.size[0] - \
+ self._plotFrame.margins.right - pixelOffset
+ y = pixelPos[1] - pixelOffset
+ label = Text2D(marker['text'], x, y,
+ color=marker['color'],
+ bgColor=(1., 1., 1., 0.5),
+ align=RIGHT, valign=BOTTOM)
+ labels.append(label)
+
+ xMin, xMax = self._plotFrame.dataRanges.x
+ vertices = numpy.array(((xMin, yCoord),
+ (xMax, yCoord)),
+ dtype=numpy.float32)
+
+ else: # yCoord is None: vertical line in data space
+ if marker['text'] is not None:
+ x = pixelPos[0] + pixelOffset
+ y = self._plotFrame.margins.top + pixelOffset
+ label = Text2D(marker['text'], x, y,
+ color=marker['color'],
+ bgColor=(1., 1., 1., 0.5),
+ align=LEFT, valign=TOP)
+ labels.append(label)
+
+ yMin, yMax = self._plotFrame.dataRanges.y
+ vertices = numpy.array(((xCoord, yMin),
+ (xCoord, yMax)),
+ dtype=numpy.float32)
+
+ self._progBase.use()
+
+ gl.glUniform4f(self._progBase.uniforms['color'],
+ *marker['color'])
+
+ gl.glEnableVertexAttribArray(posAttrib)
+ gl.glVertexAttribPointer(posAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0, vertices)
+ gl.glLineWidth(1)
+ gl.glDrawArrays(gl.GL_LINES, 0, len(vertices))
+
+ else:
+ pixelPos = self.dataToPixel(
+ xCoord, yCoord, axis='left', check=True)
+ if pixelPos is None:
+ # Do not render markers outside visible plot area
+ continue
+
+ if marker['text'] is not None:
+ x = pixelPos[0] + pixelOffset
+ y = pixelPos[1] + pixelOffset
+ label = Text2D(marker['text'], x, y,
+ color=marker['color'],
+ bgColor=(1., 1., 1., 0.5),
+ align=LEFT, valign=TOP)
+ labels.append(label)
+
+ # For now simple implementation: using a curve for each marker
+ # Should pack all markers to a single set of points
+ markerCurve = GLPlotCurve2D(
+ numpy.array((xCoord,), dtype=numpy.float32),
+ numpy.array((yCoord,), dtype=numpy.float32),
+ marker=marker['symbol'],
+ markerColor=marker['color'],
+ markerSize=11)
+ markerCurve.render(self._plotFrame.transformedDataProjMat,
+ isXLog, isYLog)
+ markerCurve.discard()
+
+ gl.glViewport(0, 0, self._plotFrame.size[0], self._plotFrame.size[1])
+
+ # Render marker labels
+ for label in labels:
+ label.render(self.matScreenProj)
+
+ gl.glDisable(gl.GL_SCISSOR_TEST)
+
+ def _renderOverlayGL(self):
+ # Render selection area and crosshair cursor
+ if self._selectionAreas or self._crosshairCursor is not None:
+ plotWidth, plotHeight = self.getPlotBoundsInPixels()[2:]
+
+ # Scissor to plot area
+ gl.glScissor(self._plotFrame.margins.left,
+ self._plotFrame.margins.bottom,
+ plotWidth, plotHeight)
+ gl.glEnable(gl.GL_SCISSOR_TEST)
+
+ self._progBase.use()
+ gl.glUniform2i(self._progBase.uniforms['isLog'],
+ self._plotFrame.xAxis.isLog,
+ self._plotFrame.yAxis.isLog)
+ gl.glUniform1f(self._progBase.uniforms['tickLen'], 0.)
+ posAttrib = self._progBase.attributes['position']
+ matrixUnif = self._progBase.uniforms['matrix']
+ colorUnif = self._progBase.uniforms['color']
+ hatchStepUnif = self._progBase.uniforms['hatchStep']
+
+ # Render selection area in plot area
+ if self._selectionAreas:
+ gl.glViewport(self._plotFrame.margins.left,
+ self._plotFrame.margins.bottom,
+ plotWidth, plotHeight)
+
+ gl.glUniformMatrix4fv(matrixUnif, 1, gl.GL_TRUE,
+ self._plotFrame.transformedDataProjMat)
+
+ for shape in self._selectionAreas.values():
+ if shape.isVideoInverted:
+ gl.glBlendFunc(gl.GL_ONE_MINUS_DST_COLOR, gl.GL_ZERO)
+
+ shape.render(posAttrib, colorUnif, hatchStepUnif)
+
+ if shape.isVideoInverted:
+ self._setBlendFuncGL()
+
+ # Render crosshair cursor is screen frame but with scissor
+ if (self._crosshairCursor is not None and
+ self._mousePosInPixels is not None):
+ gl.glViewport(
+ 0, 0, self._plotFrame.size[0], self._plotFrame.size[1])
+
+ gl.glUniformMatrix4fv(matrixUnif, 1, gl.GL_TRUE,
+ self.matScreenProj)
+
+ color, lineWidth = self._crosshairCursor
+ gl.glUniform4f(colorUnif, *color)
+ gl.glUniform1i(hatchStepUnif, 0)
+
+ xPixel, yPixel = self._mousePosInPixels
+ xPixel, yPixel = xPixel + 0.5, yPixel + 0.5
+ vertices = numpy.array(((0., yPixel),
+ (self._plotFrame.size[0], yPixel),
+ (xPixel, 0.),
+ (xPixel, self._plotFrame.size[1])),
+ dtype=numpy.float32)
+
+ gl.glEnableVertexAttribArray(posAttrib)
+ gl.glVertexAttribPointer(posAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0, vertices)
+ gl.glLineWidth(lineWidth)
+ gl.glDrawArrays(gl.GL_LINES, 0, len(vertices))
+
+ gl.glDisable(gl.GL_SCISSOR_TEST)
+
+ def _renderPlotAreaGL(self):
+ plotWidth, plotHeight = self.getPlotBoundsInPixels()[2:]
+
+ self._plotFrame.renderGrid()
+
+ gl.glScissor(self._plotFrame.margins.left,
+ self._plotFrame.margins.bottom,
+ plotWidth, plotHeight)
+ gl.glEnable(gl.GL_SCISSOR_TEST)
+
+ # Matrix
+ trBounds = self._plotFrame.transformedDataRanges
+ if trBounds.x[0] == trBounds.x[1] or \
+ trBounds.y[0] == trBounds.y[1]:
+ return
+
+ isXLog = self._plotFrame.xAxis.isLog
+ isYLog = self._plotFrame.yAxis.isLog
+
+ gl.glViewport(self._plotFrame.margins.left,
+ self._plotFrame.margins.bottom,
+ plotWidth, plotHeight)
+
+ # Render images and curves
+ # sorted is stable: original order is preserved when key is the same
+ for item in self._plotContent.zOrderedPrimitives():
+ if item.info.get('yAxis') == 'right':
+ item.render(self._plotFrame.transformedDataY2ProjMat,
+ isXLog, isYLog)
+ else:
+ item.render(self._plotFrame.transformedDataProjMat,
+ isXLog, isYLog)
+
+ # Render Items
+ self._progBase.use()
+ gl.glUniformMatrix4fv(self._progBase.uniforms['matrix'], 1, gl.GL_TRUE,
+ self._plotFrame.transformedDataProjMat)
+ gl.glUniform2i(self._progBase.uniforms['isLog'],
+ self._plotFrame.xAxis.isLog,
+ self._plotFrame.yAxis.isLog)
+ gl.glUniform1f(self._progBase.uniforms['tickLen'], 0.)
+
+ for item in self._items.values():
+ shape2D = item.get('_shape2D')
+ if shape2D is None:
+ shape2D = Shape2D(tuple(zip(item['x'], item['y'])),
+ fill=item['fill'],
+ fillColor=item['color'],
+ stroke=True,
+ strokeColor=item['color'])
+ item['_shape2D'] = shape2D
+
+ if ((isXLog and shape2D.xMin < FLOAT32_MINPOS) or
+ (isYLog and shape2D.yMin < FLOAT32_MINPOS)):
+ # Ignore items <= 0. on log axes
+ continue
+
+ posAttrib = self._progBase.attributes['position']
+ colorUnif = self._progBase.uniforms['color']
+ hatchStepUnif = self._progBase.uniforms['hatchStep']
+ shape2D.render(posAttrib, colorUnif, hatchStepUnif)
+
+ gl.glDisable(gl.GL_SCISSOR_TEST)
+
+ def resizeGL(self, width, height):
+ if width == 0 or height == 0: # Do not resize
+ return
+ self._plotFrame.size = width, height
+
+ self.matScreenProj = mat4Ortho(0, self._plotFrame.size[0],
+ self._plotFrame.size[1], 0,
+ 1, -1)
+
+ (xMin, xMax), (yMin, yMax), (y2Min, y2Max) = \
+ self._plotFrame.dataRanges
+ self.setLimits(xMin, xMax, yMin, yMax, y2Min, y2Max)
+
+ # Add methods
+
+ def addCurve(self, x, y, legend,
+ color, symbol, linewidth, linestyle,
+ yaxis,
+ xerror, yerror, z, selectable,
+ fill, alpha, symbolsize):
+ for parameter in (x, y, legend, color, symbol, linewidth, linestyle,
+ yaxis, z, selectable, fill, symbolsize):
+ assert parameter is not None
+ assert yaxis in ('left', 'right')
+
+ x = numpy.array(x, dtype=numpy.float32, copy=False, order='C')
+ y = numpy.array(y, dtype=numpy.float32, copy=False, order='C')
+ if xerror is not None:
+ xerror = numpy.array(
+ xerror, dtype=numpy.float32, copy=False, order='C')
+ if yerror is not None:
+ yerror = numpy.array(
+ yerror, dtype=numpy.float32, copy=False, order='C')
+
+ # TODO check and improve this
+ if (len(color) == 4 and
+ type(color[3]) in [type(1), numpy.uint8, numpy.int8]):
+ color = numpy.array(color, dtype=numpy.float32) / 255.
+
+ if isinstance(color, numpy.ndarray) and color.ndim == 2:
+ colorArray = color
+ color = None
+ else:
+ colorArray = None
+ color = Colors.rgba(color)
+
+ if alpha < 1.: # Apply image transparency
+ if colorArray is not None and colorArray.shape[1] == 4:
+ # multiply alpha channel
+ colorArray[:, 3] = colorArray[:, 3] * alpha
+ if color is not None:
+ color = color[0], color[1], color[2], color[3] * alpha
+
+ behaviors = set()
+ if selectable:
+ behaviors.add('selectable')
+
+ curve = GLPlotCurve2D(x, y, colorArray,
+ xError=xerror,
+ yError=yerror,
+ lineStyle=linestyle,
+ lineColor=color,
+ lineWidth=linewidth,
+ marker=symbol,
+ markerColor=color,
+ markerSize=symbolsize,
+ fillColor=color if fill else None)
+ curve.info = {
+ 'legend': legend,
+ 'zOrder': z,
+ 'behaviors': behaviors,
+ 'yAxis': 'left' if yaxis is None else yaxis,
+ }
+
+ if yaxis == "right":
+ self._plotFrame.isY2Axis = True
+
+ self._plotContent.add(curve)
+
+ return legend, 'curve'
+
+ def addImage(self, data, legend,
+ origin, scale, z,
+ selectable, draggable,
+ colormap, alpha):
+ for parameter in (data, legend, origin, scale, z,
+ selectable, draggable):
+ assert parameter is not None
+
+ behaviors = set()
+ if selectable:
+ behaviors.add('selectable')
+ if draggable:
+ behaviors.add('draggable')
+
+ if data.ndim == 2:
+ # Ensure array is contiguous and eventually convert its type
+ if data.dtype in (numpy.float32, numpy.uint8, numpy.uint16):
+ data = numpy.array(data, copy=False, order='C')
+ else:
+ _logger.info(
+ 'addImage: Convert %s data to float32', str(data.dtype))
+ data = numpy.array(data, dtype=numpy.float32, order='C')
+
+ colormapIsLog = colormap['normalization'].startswith('log')
+
+ if colormap['autoscale']:
+ cmapRange = None
+ else:
+ cmapRange = colormap['vmin'], colormap['vmax']
+ assert cmapRange[0] <= cmapRange[1]
+
+ # Retrieve colormap LUT from name and color array
+ colormapLut = Colors.applyColormapToData(
+ numpy.arange(256, dtype=numpy.uint8),
+ name=colormap['name'],
+ normalization='linear',
+ autoscale=False,
+ vmin=0,
+ vmax=255,
+ colors=colormap.get('colors'))
+
+ image = GLPlotColormap(data,
+ origin,
+ scale,
+ colormapLut,
+ colormapIsLog,
+ cmapRange,
+ alpha)
+ image.info = {
+ 'legend': legend,
+ 'zOrder': z,
+ 'behaviors': behaviors
+ }
+ self._plotContent.add(image)
+
+ elif len(data.shape) == 3:
+ # For RGB, RGBA data
+ assert data.shape[2] in (3, 4)
+ assert data.dtype in (numpy.float32, numpy.uint8)
+
+ image = GLPlotRGBAImage(data, origin, scale, alpha)
+
+ image.info = {
+ 'legend': legend,
+ 'zOrder': z,
+ 'behaviors': behaviors
+ }
+
+ if self._plotFrame.xAxis.isLog and image.xMin <= 0.:
+ raise RuntimeError(
+ 'Cannot add image with X <= 0 with X axis log scale')
+ if self._plotFrame.yAxis.isLog and image.yMin <= 0.:
+ raise RuntimeError(
+ 'Cannot add image with Y <= 0 with Y axis log scale')
+
+ self._plotContent.add(image)
+
+ else:
+ raise RuntimeError("Unsupported data shape {0}".format(data.shape))
+
+ return legend, 'image'
+
+ def addItem(self, x, y, legend, shape, color, fill, overlay, z):
+ # TODO handle overlay
+ if shape not in ('polygon', 'rectangle', 'line', 'vline', 'hline'):
+ raise NotImplementedError("Unsupported shape {0}".format(shape))
+
+ x = numpy.array(x, copy=False)
+ y = numpy.array(y, copy=False)
+
+ if shape == 'rectangle':
+ xMin, xMax = x
+ x = numpy.array((xMin, xMin, xMax, xMax))
+ yMin, yMax = y
+ y = numpy.array((yMin, yMax, yMax, yMin))
+
+ # TODO is this needed?
+ if self._plotFrame.xAxis.isLog and x.min() <= 0.:
+ raise RuntimeError(
+ 'Cannot add item with X <= 0 with X axis log scale')
+ if self._plotFrame.yAxis.isLog and y.min() <= 0.:
+ raise RuntimeError(
+ 'Cannot add item with Y <= 0 with Y axis log scale')
+
+ self._items[legend] = {
+ 'shape': shape,
+ 'color': Colors.rgba(color),
+ 'fill': 'hatch' if fill else None,
+ 'x': x,
+ 'y': y
+ }
+
+ return legend, 'item'
+
+ def addMarker(self, x, y, legend, text, color,
+ selectable, draggable,
+ symbol, constraint, overlay):
+ # TODO handle overlay
+
+ if symbol is None:
+ symbol = '+'
+
+ behaviors = set()
+ if selectable:
+ behaviors.add('selectable')
+ if draggable:
+ behaviors.add('draggable')
+
+ # Apply constraint to provided position
+ isConstraint = (draggable and constraint is not None and
+ x is not None and y is not None)
+ if isConstraint:
+ x, y = constraint(x, y)
+
+ if x is not None and self._plotFrame.xAxis.isLog and x <= 0.:
+ raise RuntimeError(
+ 'Cannot add marker with X <= 0 with X axis log scale')
+ if y is not None and self._plotFrame.yAxis.isLog and y <= 0.:
+ raise RuntimeError(
+ 'Cannot add marker with Y <= 0 with Y axis log scale')
+
+ self._markers[legend] = {
+ 'x': x,
+ 'y': y,
+ 'legend': legend,
+ 'text': text,
+ 'color': Colors.rgba(color),
+ 'behaviors': behaviors,
+ 'constraint': constraint if isConstraint else None,
+ 'symbol': symbol,
+ }
+
+ return legend, 'marker'
+
+ # Remove methods
+
+ def remove(self, item):
+ legend, kind = item
+
+ if kind == 'curve':
+ curve = self._plotContent.pop('curve', legend)
+ if curve is not None:
+ # Check if some curves remains on the right Y axis
+ y2AxisItems = (item for item in self._plotContent.primitives()
+ if item.info.get('yAxis', 'left') == 'right')
+ self._plotFrame.isY2Axis = next(y2AxisItems, None) is not None
+
+ self._glGarbageCollector.append(curve)
+
+ elif kind == 'image':
+ image = self._plotContent.pop('image', legend)
+ if image is not None:
+ self._glGarbageCollector.append(image)
+
+ elif kind == 'marker':
+ self._markers.pop(legend, False)
+
+ elif kind == 'item':
+ self._items.pop(legend, False)
+
+ else:
+ _logger.error('Unsupported kind: %s', str(kind))
+
+ # Interaction methods
+
+ _QT_CURSORS = {
+ None: qt.Qt.ArrowCursor,
+ BackendBase.CURSOR_DEFAULT: qt.Qt.ArrowCursor,
+ BackendBase.CURSOR_POINTING: qt.Qt.PointingHandCursor,
+ BackendBase.CURSOR_SIZE_HOR: qt.Qt.SizeHorCursor,
+ BackendBase.CURSOR_SIZE_VER: qt.Qt.SizeVerCursor,
+ BackendBase.CURSOR_SIZE_ALL: qt.Qt.SizeAllCursor,
+ }
+
+ def setGraphCursorShape(self, cursor):
+ cursor = self._QT_CURSORS[cursor]
+
+ super(BackendOpenGL, self).setCursor(qt.QCursor(cursor))
+
+ def setGraphCursor(self, flag, color, linewidth, linestyle):
+ if linestyle is not '-':
+ _logger.warning(
+ "BackendOpenGL.setGraphCursor linestyle parameter ignored")
+
+ if flag:
+ color = Colors.rgba(color)
+ crosshairCursor = color, linewidth
+ else:
+ crosshairCursor = None
+
+ if crosshairCursor != self._crosshairCursor:
+ self._crosshairCursor = crosshairCursor
+
+ _PICK_OFFSET = 3 # Offset in pixel used for picking
+
+ def _mouseInPlotArea(self, x, y):
+ xPlot = numpy.clip(
+ x, self._plotFrame.margins.left,
+ self._plotFrame.size[0] - self._plotFrame.margins.right - 1)
+ yPlot = numpy.clip(
+ y, self._plotFrame.margins.top,
+ self._plotFrame.size[1] - self._plotFrame.margins.bottom - 1)
+ return xPlot, yPlot
+
+ def pickItems(self, x, y):
+ picked = []
+
+ dataPos = self.pixelToData(x, y, axis='left', check=True)
+ if dataPos is not None:
+ # Pick markers
+ for marker in reversed(list(self._markers.values())):
+ pixelPos = self.dataToPixel(
+ marker['x'], marker['y'], axis='left', check=False)
+ if pixelPos is None: # negative coord on a log axis
+ continue
+
+ if marker['x'] is None: # Horizontal line
+ pt1 = self.pixelToData(
+ x, y - self._PICK_OFFSET, axis='left', check=False)
+ pt2 = self.pixelToData(
+ x, y + self._PICK_OFFSET, axis='left', check=False)
+ isPicked = (min(pt1[1], pt2[1]) <= marker['y'] <=
+ max(pt1[1], pt2[1]))
+
+ elif marker['y'] is None: # Vertical line
+ pt1 = self.pixelToData(
+ x - self._PICK_OFFSET, y, axis='left', check=False)
+ pt2 = self.pixelToData(
+ x + self._PICK_OFFSET, y, axis='left', check=False)
+ isPicked = (min(pt1[0], pt2[0]) <= marker['x'] <=
+ max(pt1[0], pt2[0]))
+
+ else:
+ isPicked = (
+ numpy.fabs(x - pixelPos[0]) <= self._PICK_OFFSET and
+ numpy.fabs(y - pixelPos[1]) <= self._PICK_OFFSET)
+
+ if isPicked:
+ picked.append(dict(kind='marker',
+ legend=marker['legend']))
+
+ # Pick image and curves
+ for item in self._plotContent.zOrderedPrimitives(reverse=True):
+ if isinstance(item, (GLPlotColormap, GLPlotRGBAImage)):
+ pickedPos = item.pick(*dataPos)
+ if pickedPos is not None:
+ picked.append(dict(kind='image',
+ legend=item.info['legend']))
+
+ elif isinstance(item, GLPlotCurve2D):
+ offset = self._PICK_OFFSET
+ if item.marker is not None:
+ offset = max(item.markerSize / 2., offset)
+ if item.lineStyle is not None:
+ offset = max(item.lineWidth / 2., offset)
+
+ yAxis = item.info['yAxis']
+
+ inAreaPos = self._mouseInPlotArea(x - offset, y - offset)
+ dataPos = self.pixelToData(inAreaPos[0], inAreaPos[1],
+ axis=yAxis, check=True)
+ if dataPos is None:
+ continue
+ xPick0, yPick0 = dataPos
+
+ inAreaPos = self._mouseInPlotArea(x + offset, y + offset)
+ dataPos = self.pixelToData(inAreaPos[0], inAreaPos[1],
+ axis=yAxis, check=True)
+ if dataPos is None:
+ continue
+ xPick1, yPick1 = dataPos
+
+ if xPick0 < xPick1:
+ xPickMin, xPickMax = xPick0, xPick1
+ else:
+ xPickMin, xPickMax = xPick1, xPick0
+
+ if yPick0 < yPick1:
+ yPickMin, yPickMax = yPick0, yPick1
+ else:
+ yPickMin, yPickMax = yPick1, yPick0
+
+ pickedIndices = item.pick(xPickMin, yPickMin,
+ xPickMax, yPickMax)
+ if pickedIndices:
+ picked.append(dict(kind='curve',
+ legend=item.info['legend'],
+ xdata=item.xData[pickedIndices],
+ ydata=item.yData[pickedIndices]))
+
+ return picked
+
+ # Update curve
+
+ def setCurveColor(self, curve, color):
+ pass # TODO
+
+ # Misc.
+
+ def getWidgetHandle(self):
+ return self
+
+ def postRedisplay(self):
+ self._sigPostRedisplay.emit()
+
+ def replot(self):
+ self.update() # async redraw
+ # self.repaint() # immediate redraw
+
+ def saveGraph(self, fileName, fileFormat, dpi):
+ if dpi is not None:
+ _logger.warning("saveGraph ignores dpi parameter")
+
+ if fileFormat not in ['png', 'ppm', 'svg', 'tiff']:
+ raise NotImplementedError('Unsupported format: %s' % fileFormat)
+
+ self.makeCurrent()
+
+ data = numpy.empty(
+ (self._plotFrame.size[1], self._plotFrame.size[0], 3),
+ dtype=numpy.uint8, order='C')
+
+ gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
+ gl.glPixelStorei(gl.GL_PACK_ALIGNMENT, 1)
+ gl.glReadPixels(0, 0, self._plotFrame.size[0], self._plotFrame.size[1],
+ gl.GL_RGB, gl.GL_UNSIGNED_BYTE, data)
+
+ # glReadPixels gives bottom to top,
+ # while images are stored as top to bottom
+ data = numpy.flipud(data)
+
+ # fileName is either a file-like object or a str
+ saveImageToFile(data, fileName, fileFormat)
+
+ # Graph labels
+
+ def setGraphTitle(self, title):
+ self._plotFrame.title = title
+
+ def setGraphXLabel(self, label):
+ self._plotFrame.xAxis.title = label
+
+ def setGraphYLabel(self, label, axis):
+ if axis == 'left':
+ self._plotFrame.yAxis.title = label
+ else: # right axis
+ if label:
+ _logger.warning('Right axis label not implemented')
+
+ # Non orthogonal axes
+
+ def setBaseVectors(self, x=(1., 0.), y=(0., 1.)):
+ """Set base vectors.
+
+ Useful for non-orthogonal axes.
+ If an axis is in log scale, skew is applied to log transformed values.
+
+ Base vector does not work well with log axes, to investi
+ """
+ if x != (1., 0.) and y != (0., 1.):
+ if self._plotFrame.xAxis.isLog:
+ _logger.warning("setBaseVectors disables X axis logarithmic.")
+ self.setXAxisLogarithmic(False)
+ if self._plotFrame.yAxis.isLog:
+ _logger.warning("setBaseVectors disables Y axis logarithmic.")
+ self.setYAxisLogarithmic(False)
+
+ if self.isKeepDataAspectRatio():
+ _logger.warning("setBaseVectors disables keepDataAspectRatio.")
+ self.keepDataAspectRatio(False)
+
+ self._plotFrame.baseVectors = x, y
+
+ def getBaseVectors(self):
+ return self._plotFrame.baseVectors
+
+ def isDefaultBaseVectors(self):
+ return self._plotFrame.baseVectors == \
+ self._plotFrame.DEFAULT_BASE_VECTORS
+
+ # Graph limits
+
+ def _setDataRanges(self, xlim=None, ylim=None, y2lim=None):
+ """Set the visible range of data in the plot frame.
+
+ This clips the ranges to possible values (takes care of float32
+ range + positive range for log).
+ This also takes care of non-orthogonal axes.
+
+ This should be moved to PlotFrame.
+ """
+ # Update axes range with a clipped range if too wide
+ self._plotFrame.setDataRanges(xlim, ylim, y2lim)
+
+ if not self.isDefaultBaseVectors():
+ # Update axes range with axes bounds in data coords
+ plotLeft, plotTop, plotWidth, plotHeight = \
+ self.getPlotBoundsInPixels()
+
+ self._plotFrame.xAxis.dataRange = sorted([
+ self.pixelToData(x, y, axis='left', check=False)[0]
+ for (x, y) in ((plotLeft, plotTop + plotHeight),
+ (plotLeft + plotWidth, plotTop + plotHeight))])
+
+ self._plotFrame.yAxis.dataRange = sorted([
+ self.pixelToData(x, y, axis='left', check=False)[1]
+ for (x, y) in ((plotLeft, plotTop + plotHeight),
+ (plotLeft, plotTop))])
+
+ self._plotFrame.y2Axis.dataRange = sorted([
+ self.pixelToData(x, y, axis='right', check=False)[1]
+ for (x, y) in ((plotLeft + plotWidth, plotTop + plotHeight),
+ (plotLeft + plotWidth, plotTop))])
+
+ def _ensureAspectRatio(self, keepDim=None):
+ """Update plot bounds in order to keep aspect ratio.
+
+ Warning: keepDim on right Y axis is not implemented !
+
+ :param str keepDim: The dimension to maintain: 'x', 'y' or None.
+ If None (the default), the dimension with the largest range.
+ """
+ plotWidth, plotHeight = self.getPlotBoundsInPixels()[2:]
+ if plotWidth <= 2 or plotHeight <= 2:
+ return
+
+ if keepDim is None:
+ dataBounds = self._plotContent.getBounds(
+ self._plotFrame.xAxis.isLog, self._plotFrame.yAxis.isLog)
+ if dataBounds.yAxis.range_ != 0.:
+ dataRatio = dataBounds.xAxis.range_
+ dataRatio /= float(dataBounds.yAxis.range_)
+
+ plotRatio = plotWidth / float(plotHeight) # Test != 0 before
+
+ keepDim = 'x' if dataRatio > plotRatio else 'y'
+ else: # Limit case
+ keepDim = 'x'
+
+ (xMin, xMax), (yMin, yMax), (y2Min, y2Max) = \
+ self._plotFrame.dataRanges
+ if keepDim == 'y':
+ dataW = (yMax - yMin) * plotWidth / float(plotHeight)
+ xCenter = 0.5 * (xMin + xMax)
+ xMin = xCenter - 0.5 * dataW
+ xMax = xCenter + 0.5 * dataW
+ elif keepDim == 'x':
+ dataH = (xMax - xMin) * plotHeight / float(plotWidth)
+ yCenter = 0.5 * (yMin + yMax)
+ yMin = yCenter - 0.5 * dataH
+ yMax = yCenter + 0.5 * dataH
+ y2Center = 0.5 * (y2Min + y2Max)
+ y2Min = y2Center - 0.5 * dataH
+ y2Max = y2Center + 0.5 * dataH
+ else:
+ raise RuntimeError('Unsupported dimension to keep: %s' % keepDim)
+
+ # Update plot frame bounds
+ self._setDataRanges(xlim=(xMin, xMax),
+ ylim=(yMin, yMax),
+ y2lim=(y2Min, y2Max))
+
+ def _setPlotBounds(self, xRange=None, yRange=None, y2Range=None,
+ keepDim=None):
+ # Update axes range with a clipped range if too wide
+ self._setDataRanges(xlim=xRange,
+ ylim=yRange,
+ y2lim=y2Range)
+
+ # Keep data aspect ratio
+ if self.isKeepDataAspectRatio():
+ self._ensureAspectRatio(keepDim)
+
+ def setLimits(self, xmin, xmax, ymin, ymax, y2min=None, y2max=None):
+ assert xmin < xmax
+ assert ymin < ymax
+
+ if y2min is None or y2max is None:
+ y2Range = None
+ else:
+ assert y2min < y2max
+ y2Range = y2min, y2max
+ self._setPlotBounds((xmin, xmax), (ymin, ymax), y2Range)
+
+ def getGraphXLimits(self):
+ return self._plotFrame.dataRanges.x
+
+ def setGraphXLimits(self, xmin, xmax):
+ assert xmin < xmax
+ self._setPlotBounds(xRange=(xmin, xmax), keepDim='x')
+
+ def getGraphYLimits(self, axis):
+ assert axis in ("left", "right")
+ if axis == "left":
+ return self._plotFrame.dataRanges.y
+ else:
+ return self._plotFrame.dataRanges.y2
+
+ def setGraphYLimits(self, ymin, ymax, axis):
+ assert ymin < ymax
+ assert axis in ("left", "right")
+
+ if axis == "left":
+ self._setPlotBounds(yRange=(ymin, ymax), keepDim='y')
+ else:
+ self._setPlotBounds(y2Range=(ymin, ymax), keepDim='y')
+
+ # Graph axes
+
+ def setXAxisLogarithmic(self, flag):
+ if flag != self._plotFrame.xAxis.isLog:
+ if flag and self._keepDataAspectRatio:
+ _logger.warning(
+ "KeepDataAspectRatio is ignored with log axes")
+
+ if flag and not self.isDefaultBaseVectors():
+ _logger.warning(
+ "setXAxisLogarithmic ignored because baseVectors are set")
+ return
+
+ self._plotFrame.xAxis.isLog = flag
+
+ def setYAxisLogarithmic(self, flag):
+ if (flag != self._plotFrame.yAxis.isLog or
+ flag != self._plotFrame.y2Axis.isLog):
+ if flag and self._keepDataAspectRatio:
+ _logger.warning(
+ "KeepDataAspectRatio is ignored with log axes")
+
+ if flag and not self.isDefaultBaseVectors():
+ _logger.warning(
+ "setYAxisLogarithmic ignored because baseVectors are set")
+ return
+
+ self._plotFrame.yAxis.isLog = flag
+ self._plotFrame.y2Axis.isLog = flag
+
+ def setYAxisInverted(self, flag):
+ if flag != self._plotFrame.isYAxisInverted:
+ self._plotFrame.isYAxisInverted = flag
+
+ def isYAxisInverted(self):
+ return self._plotFrame.isYAxisInverted
+
+ def isKeepDataAspectRatio(self):
+ if self._plotFrame.xAxis.isLog or self._plotFrame.yAxis.isLog:
+ return False
+ else:
+ return self._keepDataAspectRatio
+
+ def setKeepDataAspectRatio(self, flag):
+ if flag and (self._plotFrame.xAxis.isLog or
+ self._plotFrame.yAxis.isLog):
+ _logger.warning("KeepDataAspectRatio is ignored with log axes")
+ if flag and not self.isDefaultBaseVectors():
+ _logger.warning(
+ "keepDataAspectRatio ignored because baseVectors are set")
+
+ self._keepDataAspectRatio = flag
+
+ def setGraphGrid(self, which):
+ assert which in (None, 'major', 'both')
+ self._plotFrame.grid = which is not None # TODO True grid support
+
+ # Data <-> Pixel coordinates conversion
+
+ def dataToPixel(self, x, y, axis, check=False):
+ assert axis in ('left', 'right')
+
+ if x is None or y is None:
+ dataBounds = self._plotContent.getBounds(
+ self._plotFrame.xAxis.isLog, self._plotFrame.yAxis.isLog)
+
+ if x is None:
+ x = dataBounds.xAxis.center
+
+ if y is None:
+ if axis == 'left':
+ y = dataBounds.yAxis.center
+ else:
+ y = dataBounds.y2Axis.center
+
+ result = self._plotFrame.dataToPixel(x, y, axis)
+
+ if check and result is not None:
+ xPixel, yPixel = result
+ width, height = self._plotFrame.size
+ if (xPixel < self._plotFrame.margins.left or
+ xPixel > (width - self._plotFrame.margins.right) or
+ yPixel < self._plotFrame.margins.top or
+ yPixel > height - self._plotFrame.margins.bottom):
+ return None # (x, y) is out of plot area
+
+ return result
+
+ def pixelToData(self, x, y, axis, check):
+ assert axis in ("left", "right")
+
+ if x is None:
+ x = self._plotFrame.size[0] / 2.
+ if y is None:
+ y = self._plotFrame.size[1] / 2.
+
+ if check and (x < self._plotFrame.margins.left or
+ x > (self._plotFrame.size[0] -
+ self._plotFrame.margins.right) or
+ y < self._plotFrame.margins.top or
+ y > (self._plotFrame.size[1] -
+ self._plotFrame.margins.bottom)):
+ return None # (x, y) is out of plot area
+
+ return self._plotFrame.pixelToData(x, y, axis)
+
+ def getPlotBoundsInPixels(self):
+ return self._plotFrame.plotOrigin + self._plotFrame.plotSize
diff --git a/silx/gui/plot/backends/ModestImage.py b/silx/gui/plot/backends/ModestImage.py
new file mode 100644
index 0000000..93fba5a
--- /dev/null
+++ b/silx/gui/plot/backends/ModestImage.py
@@ -0,0 +1,174 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ############################################################################*/
+"""Matplotlib computationally modest image class."""
+
+__authors__ = ["V.A. Sole", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "16/02/2016"
+
+
+import numpy
+
+from matplotlib import cbook
+from matplotlib.image import AxesImage
+
+
+class ModestImage(AxesImage):
+ """Computationally modest image class.
+
+Customization of https://github.com/ChrisBeaumont/ModestImage to allow
+extent support.
+
+ModestImage is an extension of the Matplotlib AxesImage class
+better suited for the interactive display of larger images. Before
+drawing, ModestImage resamples the data array based on the screen
+resolution and view window. This has very little affect on the
+appearance of the image, but can substantially cut down on
+computation since calculations of unresolved or clipped pixels
+are skipped.
+
+The interface of ModestImage is the same as AxesImage. However, it
+does not currently support setting the 'extent' property. There
+may also be weird coordinate warping operations for images that
+I'm not aware of. Don't expect those to work either.
+"""
+ def __init__(self, *args, **kwargs):
+ self._full_res = None
+ self._sx, self._sy = None, None
+ self._bounds = (None, None, None, None)
+ self._origExtent = None
+ super(ModestImage, self).__init__(*args, **kwargs)
+ if 'extent' in kwargs and kwargs['extent'] is not None:
+ self.set_extent(kwargs['extent'])
+
+ def set_extent(self, extent):
+ super(ModestImage, self).set_extent(extent)
+ if self._origExtent is None:
+ self._origExtent = self.get_extent()
+
+ def get_image_extent(self):
+ """Returns the extent of the whole image.
+
+ get_extent returns the extent of the drawn area and not of the full
+ image.
+
+ :return: Bounds of the image (x0, x1, y0, y1).
+ :rtype: Tuple of 4 floats.
+ """
+ if self._origExtent is not None:
+ return self._origExtent
+ else:
+ return self.get_extent()
+
+ def set_data(self, A):
+ """
+ Set the image array
+
+ ACCEPTS: numpy/PIL Image A
+ """
+
+ self._full_res = A
+ self._A = A
+
+ if (self._A.dtype != numpy.uint8 and
+ not numpy.can_cast(self._A.dtype, numpy.float)):
+ raise TypeError("Image data can not convert to float")
+
+ if (self._A.ndim not in (2, 3) or
+ (self._A.ndim == 3 and self._A.shape[-1] not in (3, 4))):
+ raise TypeError("Invalid dimensions for image data")
+
+ self._imcache = None
+ self._rgbacache = None
+ self._oldxslice = None
+ self._oldyslice = None
+ self._sx, self._sy = None, None
+
+ def get_array(self):
+ """Override to return the full-resolution array"""
+ return self._full_res
+
+ def _scale_to_res(self):
+ """ Change self._A and _extent to render an image whose
+resolution is matched to the eventual rendering."""
+ # extent has to be set BEFORE set_data
+ if self._origExtent is None:
+ if self.origin == "upper":
+ self._origExtent = (0, self._full_res.shape[1],
+ self._full_res.shape[0], 0)
+ else:
+ self._origExtent = (0, self._full_res.shape[1],
+ 0, self._full_res.shape[0])
+
+ if self.origin == "upper":
+ origXMin, origXMax, origYMax, origYMin = self._origExtent[0:4]
+ else:
+ origXMin, origXMax, origYMin, origYMax = self._origExtent[0:4]
+ ax = self.axes
+ ext = ax.transAxes.transform([1, 1]) - ax.transAxes.transform([0, 0])
+ xlim, ylim = ax.get_xlim(), ax.get_ylim()
+ xlim = max(xlim[0], origXMin), min(xlim[1], origXMax)
+ if ylim[0] > ylim[1]:
+ ylim = max(ylim[1], origYMin), min(ylim[0], origYMax)
+ else:
+ ylim = max(ylim[0], origYMin), min(ylim[1], origYMax)
+ # print("THOSE LIMITS ARE TO BE COMPARED WITH THE EXTENT")
+ # print("IN ORDER TO KNOW WHAT IT IS LIMITING THE DISPLAY")
+ # print("IF THE AXES OR THE EXTENT")
+ dx, dy = xlim[1] - xlim[0], ylim[1] - ylim[0]
+
+ y0 = max(0, ylim[0] - 5)
+ y1 = min(self._full_res.shape[0], ylim[1] + 5)
+ x0 = max(0, xlim[0] - 5)
+ x1 = min(self._full_res.shape[1], xlim[1] + 5)
+ y0, y1, x0, x1 = [int(a) for a in [y0, y1, x0, x1]]
+
+ sy = int(max(1, min((y1 - y0) / 5., numpy.ceil(dy / ext[1]))))
+ sx = int(max(1, min((x1 - x0) / 5., numpy.ceil(dx / ext[0]))))
+
+ # have we already calculated what we need?
+ if (self._sx is not None) and (self._sy is not None):
+ if (sx >= self._sx and sy >= self._sy and
+ x0 >= self._bounds[0] and x1 <= self._bounds[1] and
+ y0 >= self._bounds[2] and y1 <= self._bounds[3]):
+ return
+
+ self._A = self._full_res[y0:y1:sy, x0:x1:sx]
+ self._A = cbook.safe_masked_invalid(self._A)
+ x1 = x0 + self._A.shape[1] * sx
+ y1 = y0 + self._A.shape[0] * sy
+
+ if self.origin == "upper":
+ self.set_extent([x0, x1, y1, y0])
+ else:
+ self.set_extent([x0, x1, y0, y1])
+ self._sx = sx
+ self._sy = sy
+ self._bounds = (x0, x1, y0, y1)
+ self.changed()
+
+ def draw(self, renderer, *args, **kwargs):
+ self._scale_to_res()
+ super(ModestImage, self).draw(renderer, *args, **kwargs)
diff --git a/silx/gui/plot/backends/__init__.py b/silx/gui/plot/backends/__init__.py
new file mode 100644
index 0000000..966d9df
--- /dev/null
+++ b/silx/gui/plot/backends/__init__.py
@@ -0,0 +1,29 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This package implements the backend of the Plot."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "21/03/2017"
diff --git a/silx/gui/plot/backends/_matplotlib.py b/silx/gui/plot/backends/_matplotlib.py
new file mode 100644
index 0000000..26732a0
--- /dev/null
+++ b/silx/gui/plot/backends/_matplotlib.py
@@ -0,0 +1,64 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module inits matplotlib and setups the backend to use.
+
+It MUST be imported prior to any other import of matplotlib.
+
+It provides the matplotlib :class:`FigureCanvasQTAgg` class corresponding
+to the used backend.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "26/10/2016"
+
+
+import sys
+import logging
+
+
+_logger = logging.getLogger(__name__)
+
+if 'matplotlib' in sys.modules:
+ _logger.warning(
+ 'matplotlib already loaded, setting its backend may not work')
+
+
+from ... import qt
+
+import matplotlib
+
+if qt.BINDING == 'PySide':
+ matplotlib.rcParams['backend'] = 'Qt4Agg'
+ matplotlib.rcParams['backend.qt4'] = 'PySide'
+ from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg # noqa
+
+elif qt.BINDING == 'PyQt4':
+ matplotlib.rcParams['backend'] = 'Qt4Agg'
+ from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg # noqa
+
+elif qt.BINDING == 'PyQt5':
+ matplotlib.rcParams['backend'] = 'Qt5Agg'
+ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg # noqa
diff --git a/silx/gui/plot/backends/glutils/GLPlotCurve.py b/silx/gui/plot/backends/glutils/GLPlotCurve.py
new file mode 100644
index 0000000..4f08054
--- /dev/null
+++ b/silx/gui/plot/backends/glutils/GLPlotCurve.py
@@ -0,0 +1,1317 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ############################################################################*/
+"""
+This module provides classes to render 2D lines and scatter plots
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import math
+import logging
+
+import numpy
+
+from silx.math.combo import min_max
+
+from ...._glutils import gl
+from ...._glutils import numpyToGLType, Program, vertexBuffer
+from ..._utils import FLOAT32_MINPOS
+from .GLSupport import buildFillMaskIndices
+
+
+_logger = logging.getLogger(__name__)
+
+
+_MPL_NONES = None, 'None', '', ' '
+
+
+# fill ########################################################################
+
+class _Fill2D(object):
+ _LINEAR, _LOG10_X, _LOG10_Y, _LOG10_X_Y = 0, 1, 2, 3
+
+ _SHADERS = {
+ 'vertexTransforms': {
+ _LINEAR: """
+ vec4 transformXY(float x, float y) {
+ return vec4(x, y, 0.0, 1.0);
+ }
+ """,
+ _LOG10_X: """
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 transformXY(float x, float y) {
+ return vec4(oneOverLog10 * log(x), y, 0.0, 1.0);
+ }
+ """,
+ _LOG10_Y: """
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 transformXY(float x, float y) {
+ return vec4(x, oneOverLog10 * log(y), 0.0, 1.0);
+ }
+ """,
+ _LOG10_X_Y: """
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 transformXY(float x, float y) {
+ return vec4(oneOverLog10 * log(x),
+ oneOverLog10 * log(y),
+ 0.0, 1.0);
+ }
+ """
+ },
+ 'vertex': """
+ #version 120
+
+ uniform mat4 matrix;
+ attribute float xPos;
+ attribute float yPos;
+
+ %s
+
+ void main(void) {
+ gl_Position = matrix * transformXY(xPos, yPos);
+ }
+ """,
+ 'fragment': """
+ #version 120
+
+ uniform vec4 color;
+
+ void main(void) {
+ gl_FragColor = color;
+ }
+ """
+ }
+
+ _programs = {
+ _LINEAR: Program(
+ _SHADERS['vertex'] % _SHADERS['vertexTransforms'][_LINEAR],
+ _SHADERS['fragment'], attrib0='xPos'),
+ _LOG10_X: Program(
+ _SHADERS['vertex'] % _SHADERS['vertexTransforms'][_LOG10_X],
+ _SHADERS['fragment'], attrib0='xPos'),
+ _LOG10_Y: Program(
+ _SHADERS['vertex'] % _SHADERS['vertexTransforms'][_LOG10_Y],
+ _SHADERS['fragment'], attrib0='xPos'),
+ _LOG10_X_Y: Program(
+ _SHADERS['vertex'] % _SHADERS['vertexTransforms'][_LOG10_X_Y],
+ _SHADERS['fragment'], attrib0='xPos'),
+ }
+
+ def __init__(self, xFillVboData=None, yFillVboData=None,
+ xMin=None, yMin=None, xMax=None, yMax=None,
+ color=(0., 0., 0., 1.)):
+ self.xFillVboData = xFillVboData
+ self.yFillVboData = yFillVboData
+ self.xMin, self.yMin = xMin, yMin
+ self.xMax, self.yMax = xMax, yMax
+ self.color = color
+
+ self._bboxVertices = None
+ self._indices = None
+ self._indicesType = None
+
+ def prepare(self):
+ if self._indices is None:
+ self._indices = buildFillMaskIndices(self.xFillVboData.size)
+ self._indicesType = numpyToGLType(self._indices.dtype)
+
+ if self._bboxVertices is None:
+ yMin, yMax = min(self.yMin, 1e-32), max(self.yMax, 1e-32)
+ self._bboxVertices = numpy.array(((self.xMin, self.xMin,
+ self.xMax, self.xMax),
+ (yMin, yMax, yMin, yMax)),
+ dtype=numpy.float32)
+
+ def render(self, matrix, isXLog, isYLog):
+ self.prepare()
+
+ if isXLog:
+ transform = self._LOG10_X_Y if isYLog else self._LOG10_X
+ else:
+ transform = self._LOG10_Y if isYLog else self._LINEAR
+
+ prog = self._programs[transform]
+ prog.use()
+
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, matrix)
+
+ gl.glUniform4f(prog.uniforms['color'], *self.color)
+
+ xPosAttrib = prog.attributes['xPos']
+ yPosAttrib = prog.attributes['yPos']
+
+ gl.glEnableVertexAttribArray(xPosAttrib)
+ self.xFillVboData.setVertexAttrib(xPosAttrib)
+
+ gl.glEnableVertexAttribArray(yPosAttrib)
+ self.yFillVboData.setVertexAttrib(yPosAttrib)
+
+ # Prepare fill mask
+ gl.glEnable(gl.GL_STENCIL_TEST)
+ gl.glStencilMask(1)
+ gl.glStencilFunc(gl.GL_ALWAYS, 1, 1)
+ gl.glStencilOp(gl.GL_INVERT, gl.GL_INVERT, gl.GL_INVERT)
+ gl.glColorMask(gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE)
+ gl.glDepthMask(gl.GL_FALSE)
+
+ gl.glDrawElements(gl.GL_TRIANGLE_STRIP, self._indices.size,
+ self._indicesType, self._indices)
+
+ gl.glStencilFunc(gl.GL_EQUAL, 1, 1)
+ # Reset stencil while drawing
+ gl.glStencilOp(gl.GL_ZERO, gl.GL_ZERO, gl.GL_ZERO)
+ gl.glColorMask(gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE)
+ gl.glDepthMask(gl.GL_TRUE)
+
+ gl.glVertexAttribPointer(xPosAttrib, 1, gl.GL_FLOAT, gl.GL_FALSE, 0,
+ self._bboxVertices[0])
+ gl.glVertexAttribPointer(yPosAttrib, 1, gl.GL_FLOAT, gl.GL_FALSE, 0,
+ self._bboxVertices[1])
+ gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, self._bboxVertices[0].size)
+
+ gl.glDisable(gl.GL_STENCIL_TEST)
+
+
+# line ########################################################################
+
+SOLID, DASHED, DASHDOT, DOTTED = '-', '--', '-.', ':'
+
+
+class _Lines2D(object):
+ STYLES = SOLID, DASHED, DASHDOT, DOTTED
+ """Supported line styles"""
+
+ _LINEAR, _LOG10_X, _LOG10_Y, _LOG10_X_Y = 0, 1, 2, 3
+
+ _SHADERS = {
+ 'vertexTransforms': {
+ _LINEAR: """
+ vec4 transformXY(float x, float y) {
+ return vec4(x, y, 0.0, 1.0);
+ }
+ """,
+ _LOG10_X: """
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 transformXY(float x, float y) {
+ return vec4(oneOverLog10 * log(x), y, 0.0, 1.0);
+ }
+ """,
+ _LOG10_Y: """
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 transformXY(float x, float y) {
+ return vec4(x, oneOverLog10 * log(y), 0.0, 1.0);
+ }
+ """,
+ _LOG10_X_Y: """
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 transformXY(float x, float y) {
+ return vec4(oneOverLog10 * log(x),
+ oneOverLog10 * log(y),
+ 0.0, 1.0);
+ }
+ """
+ },
+ 'solid': {
+ 'vertex': """
+ #version 120
+
+ uniform mat4 matrix;
+ attribute float xPos;
+ attribute float yPos;
+ attribute vec4 color;
+
+ varying vec4 vColor;
+
+ %s
+
+ void main(void) {
+ gl_Position = matrix * transformXY(xPos, yPos);
+ vColor = color;
+ }
+ """,
+ 'fragment': """
+ #version 120
+
+ varying vec4 vColor;
+
+ void main(void) {
+ gl_FragColor = vColor;
+ }
+ """
+ },
+
+
+ # Limitation: Dash using an estimate of distance in screen coord
+ # to avoid computing distance when viewport is resized
+ # results in inequal dashes when viewport aspect ratio is far from 1
+ 'dashed': {
+ 'vertex': """
+ #version 120
+
+ uniform mat4 matrix;
+ uniform vec2 halfViewportSize;
+ attribute float xPos;
+ attribute float yPos;
+ attribute vec4 color;
+ attribute float distance;
+
+ varying float vDist;
+ varying vec4 vColor;
+
+ %s
+
+ void main(void) {
+ gl_Position = matrix * transformXY(xPos, yPos);
+ //Estimate distance in pixels
+ vec2 probe = vec2(matrix * vec4(1., 1., 0., 0.)) *
+ halfViewportSize;
+ float pixelPerDataEstimate = length(probe)/sqrt(2.);
+ vDist = distance * pixelPerDataEstimate;
+ vColor = color;
+ }
+ """,
+ 'fragment': """
+ #version 120
+
+ /* Dashes: [0, x], [y, z]
+ Dash period: w */
+ uniform vec4 dash;
+
+ varying float vDist;
+ varying vec4 vColor;
+
+ void main(void) {
+ float dist = mod(vDist, dash.w);
+ if ((dist > dash.x && dist < dash.y) || dist > dash.z) {
+ discard;
+ }
+ gl_FragColor = vColor;
+ }
+ """
+ }
+ }
+
+ _programs = {}
+
+ def __init__(self, xVboData=None, yVboData=None,
+ colorVboData=None, distVboData=None,
+ style=SOLID, color=(0., 0., 0., 1.),
+ width=1, dashPeriod=20, drawMode=None):
+ self.xVboData = xVboData
+ self.yVboData = yVboData
+ self.distVboData = distVboData
+ self.colorVboData = colorVboData
+ self.useColorVboData = colorVboData is not None
+
+ self.color = color
+ self._width = 1
+ self.width = width
+ self._style = None
+ self.style = style
+ self.dashPeriod = dashPeriod
+
+ self._drawMode = drawMode if drawMode is not None else gl.GL_LINE_STRIP
+
+ @property
+ def style(self):
+ return self._style
+
+ @style.setter
+ def style(self, style):
+ if style in _MPL_NONES:
+ self._style = None
+ self.render = self._renderNone
+ else:
+ assert style in self.STYLES
+ self._style = style
+ if style == SOLID:
+ self.render = self._renderSolid
+ else: # DASHED, DASHDOT, DOTTED
+ self.render = self._renderDash
+
+ @property
+ def width(self):
+ return self._width
+
+ @width.setter
+ def width(self, width):
+ # try:
+ # widthRange = self._widthRange
+ # except AttributeError:
+ # widthRange = gl.glGetFloatv(gl.GL_ALIASED_LINE_WIDTH_RANGE)
+ # # Shared among contexts, this should be enough..
+ # _Lines2D._widthRange = widthRange
+ # assert width >= widthRange[0] and width <= widthRange[1]
+ self._width = width
+
+ @classmethod
+ def _getProgram(cls, transform, style):
+ try:
+ prgm = cls._programs[(transform, style)]
+ except KeyError:
+ sources = cls._SHADERS[style]
+ vertexShdr = sources['vertex'] % \
+ cls._SHADERS['vertexTransforms'][transform]
+ prgm = Program(vertexShdr, sources['fragment'], attrib0='xPos')
+ cls._programs[(transform, style)] = prgm
+ return prgm
+
+ @classmethod
+ def init(cls):
+ gl.glHint(gl.GL_LINE_SMOOTH_HINT, gl.GL_NICEST)
+
+ def _renderNone(self, matrix, isXLog, isYLog):
+ pass
+
+ render = _renderNone # Overridden in style setter
+
+ def _renderSolid(self, matrix, isXLog, isYLog):
+ if isXLog:
+ transform = self._LOG10_X_Y if isYLog else self._LOG10_X
+ else:
+ transform = self._LOG10_Y if isYLog else self._LINEAR
+
+ prog = self._getProgram(transform, 'solid')
+ prog.use()
+
+ gl.glEnable(gl.GL_LINE_SMOOTH)
+
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, matrix)
+
+ colorAttrib = prog.attributes['color']
+ if self.useColorVboData and self.colorVboData is not None:
+ gl.glEnableVertexAttribArray(colorAttrib)
+ self.colorVboData.setVertexAttrib(colorAttrib)
+ else:
+ gl.glDisableVertexAttribArray(colorAttrib)
+ gl.glVertexAttrib4f(colorAttrib, *self.color)
+
+ xPosAttrib = prog.attributes['xPos']
+ gl.glEnableVertexAttribArray(xPosAttrib)
+ self.xVboData.setVertexAttrib(xPosAttrib)
+
+ yPosAttrib = prog.attributes['yPos']
+ gl.glEnableVertexAttribArray(yPosAttrib)
+ self.yVboData.setVertexAttrib(yPosAttrib)
+
+ gl.glLineWidth(self.width)
+ gl.glDrawArrays(self._drawMode, 0, self.xVboData.size)
+
+ gl.glDisable(gl.GL_LINE_SMOOTH)
+
+ def _renderDash(self, matrix, isXLog, isYLog):
+ if isXLog:
+ transform = self._LOG10_X_Y if isYLog else self._LOG10_X
+ else:
+ transform = self._LOG10_Y if isYLog else self._LINEAR
+
+ prog = self._getProgram(transform, 'dashed')
+ prog.use()
+
+ gl.glEnable(gl.GL_LINE_SMOOTH)
+
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, matrix)
+ x, y, viewWidth, viewHeight = gl.glGetFloatv(gl.GL_VIEWPORT)
+ gl.glUniform2f(prog.uniforms['halfViewportSize'],
+ 0.5 * viewWidth, 0.5 * viewHeight)
+
+ if self.style == DOTTED:
+ dash = (0.1 * self.dashPeriod,
+ 0.6 * self.dashPeriod,
+ 0.7 * self.dashPeriod,
+ self.dashPeriod)
+ elif self.style == DASHDOT:
+ dash = (0.3 * self.dashPeriod,
+ 0.5 * self.dashPeriod,
+ 0.6 * self.dashPeriod,
+ self.dashPeriod)
+ else:
+ dash = (0.5 * self.dashPeriod,
+ self.dashPeriod,
+ self.dashPeriod,
+ self.dashPeriod)
+
+ gl.glUniform4f(prog.uniforms['dash'], *dash)
+
+ colorAttrib = prog.attributes['color']
+ if self.useColorVboData and self.colorVboData is not None:
+ gl.glEnableVertexAttribArray(colorAttrib)
+ self.colorVboData.setVertexAttrib(colorAttrib)
+ else:
+ gl.glDisableVertexAttribArray(colorAttrib)
+ gl.glVertexAttrib4f(colorAttrib, *self.color)
+
+ distAttrib = prog.attributes['distance']
+ gl.glEnableVertexAttribArray(distAttrib)
+ self.distVboData.setVertexAttrib(distAttrib)
+
+ xPosAttrib = prog.attributes['xPos']
+ gl.glEnableVertexAttribArray(xPosAttrib)
+ self.xVboData.setVertexAttrib(xPosAttrib)
+
+ yPosAttrib = prog.attributes['yPos']
+ gl.glEnableVertexAttribArray(yPosAttrib)
+ self.yVboData.setVertexAttrib(yPosAttrib)
+
+ gl.glLineWidth(self.width)
+ gl.glDrawArrays(self._drawMode, 0, self.xVboData.size)
+
+ gl.glDisable(gl.GL_LINE_SMOOTH)
+
+
+def _distancesFromArrays(xData, yData):
+ deltas = numpy.dstack((
+ numpy.ediff1d(xData, to_begin=numpy.float32(0.)),
+ numpy.ediff1d(yData, to_begin=numpy.float32(0.))))[0]
+ return numpy.cumsum(numpy.sqrt(numpy.sum(deltas ** 2, axis=1)))
+
+
+# points ######################################################################
+
+DIAMOND, CIRCLE, SQUARE, PLUS, X_MARKER, POINT, PIXEL, ASTERISK = \
+ 'd', 'o', 's', '+', 'x', '.', ',', '*'
+
+H_LINE, V_LINE = '_', '|'
+
+
+class _Points2D(object):
+ MARKERS = (DIAMOND, CIRCLE, SQUARE, PLUS, X_MARKER, POINT, PIXEL, ASTERISK,
+ H_LINE, V_LINE)
+
+ _LINEAR, _LOG10_X, _LOG10_Y, _LOG10_X_Y = 0, 1, 2, 3
+
+ _SHADERS = {
+ 'vertexTransforms': {
+ _LINEAR: """
+ vec4 transformXY(float x, float y) {
+ return vec4(x, y, 0.0, 1.0);
+ }
+ """,
+ _LOG10_X: """
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 transformXY(float x, float y) {
+ return vec4(oneOverLog10 * log(x), y, 0.0, 1.0);
+ }
+ """,
+ _LOG10_Y: """
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 transformXY(float x, float y) {
+ return vec4(x, oneOverLog10 * log(y), 0.0, 1.0);
+ }
+ """,
+ _LOG10_X_Y: """
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 transformXY(float x, float y) {
+ return vec4(oneOverLog10 * log(x),
+ oneOverLog10 * log(y),
+ 0.0, 1.0);
+ }
+ """
+ },
+ 'vertex': """
+ #version 120
+
+ uniform mat4 matrix;
+ uniform int transform;
+ uniform float size;
+ attribute float xPos;
+ attribute float yPos;
+ attribute vec4 color;
+
+ varying vec4 vColor;
+
+ %s
+
+ void main(void) {
+ gl_Position = matrix * transformXY(xPos, yPos);
+ vColor = color;
+ gl_PointSize = size;
+ }
+ """,
+
+ 'fragmentSymbols': {
+ DIAMOND: """
+ float alphaSymbol(vec2 coord, float size) {
+ vec2 centerCoord = abs(coord - vec2(0.5, 0.5));
+ float f = centerCoord.x + centerCoord.y;
+ return clamp(size * (0.5 - f), 0.0, 1.0);
+ }
+ """,
+ CIRCLE: """
+ float alphaSymbol(vec2 coord, float size) {
+ float radius = 0.5;
+ float r = distance(coord, vec2(0.5, 0.5));
+ return clamp(size * (radius - r), 0.0, 1.0);
+ }
+ """,
+ SQUARE: """
+ float alphaSymbol(vec2 coord, float size) {
+ return 1.0;
+ }
+ """,
+ PLUS: """
+ float alphaSymbol(vec2 coord, float size) {
+ vec2 d = abs(size * (coord - vec2(0.5, 0.5)));
+ if (min(d.x, d.y) < 0.5) {
+ return 1.0;
+ } else {
+ return 0.0;
+ }
+ }
+ """,
+ X_MARKER: """
+ float alphaSymbol(vec2 coord, float size) {
+ vec2 pos = floor(size * coord) + 0.5;
+ vec2 d_x = abs(pos.x + vec2(- pos.y, pos.y - size));
+ if (min(d_x.x, d_x.y) <= 0.5) {
+ return 1.0;
+ } else {
+ return 0.0;
+ }
+ }
+ """,
+ ASTERISK: """
+ float alphaSymbol(vec2 coord, float size) {
+ /* Combining +, x and cirle */
+ vec2 d_plus = abs(size * (coord - vec2(0.5, 0.5)));
+ vec2 pos = floor(size * coord) + 0.5;
+ vec2 d_x = abs(pos.x + vec2(- pos.y, pos.y - size));
+ if (min(d_plus.x, d_plus.y) < 0.5) {
+ return 1.0;
+ } else if (min(d_x.x, d_x.y) <= 0.5) {
+ float r = distance(coord, vec2(0.5, 0.5));
+ return clamp(size * (0.5 - r), 0.0, 1.0);
+ } else {
+ return 0.0;
+ }
+ }
+ """,
+ H_LINE: """
+ float alphaSymbol(vec2 coord, float size) {
+ float dy = abs(size * (coord.y - 0.5));
+ if (dy < 0.5) {
+ return 1.0;
+ } else {
+ return 0.0;
+ }
+ }
+ """,
+ V_LINE: """
+ float alphaSymbol(vec2 coord, float size) {
+ float dx = abs(size * (coord.x - 0.5));
+ if (dx < 0.5) {
+ return 1.0;
+ } else {
+ return 0.0;
+ }
+ }
+ """
+ },
+
+ 'fragment': """
+ #version 120
+
+ uniform float size;
+
+ varying vec4 vColor;
+
+ %s
+
+ void main(void) {
+ float alpha = alphaSymbol(gl_PointCoord, size);
+ if (alpha <= 0.0) {
+ discard;
+ } else {
+ gl_FragColor = vec4(vColor.rgb, alpha * clamp(vColor.a, 0.0, 1.0));
+ }
+ }
+ """
+ }
+
+ _programs = {}
+
+ def __init__(self, xVboData=None, yVboData=None, colorVboData=None,
+ marker=SQUARE, color=(0., 0., 0., 1.), size=7):
+ self.color = color
+ self._marker = None
+ self.marker = marker
+ self._size = 1
+ self.size = size
+
+ self.xVboData = xVboData
+ self.yVboData = yVboData
+ self.colorVboData = colorVboData
+ self.useColorVboData = colorVboData is not None
+
+ @property
+ def marker(self):
+ return self._marker
+
+ @marker.setter
+ def marker(self, marker):
+ if marker in _MPL_NONES:
+ self._marker = None
+ self.render = self._renderNone
+ else:
+ assert marker in self.MARKERS
+ self._marker = marker
+ self.render = self._renderMarkers
+
+ @property
+ def size(self):
+ return self._size
+
+ @size.setter
+ def size(self, size):
+ # try:
+ # sizeRange = self._sizeRange
+ # except AttributeError:
+ # sizeRange = gl.glGetFloatv(gl.GL_POINT_SIZE_RANGE)
+ # # Shared among contexts, this should be enough..
+ # _Points2D._sizeRange = sizeRange
+ # assert size >= sizeRange[0] and size <= sizeRange[1]
+ self._size = size
+
+ @classmethod
+ def _getProgram(cls, transform, marker):
+ """On-demand shader program creation."""
+ if marker == PIXEL:
+ marker = SQUARE
+ elif marker == POINT:
+ marker = CIRCLE
+ try:
+ prgm = cls._programs[(transform, marker)]
+ except KeyError:
+ vertShdr = cls._SHADERS['vertex'] % \
+ cls._SHADERS['vertexTransforms'][transform]
+ fragShdr = cls._SHADERS['fragment'] % \
+ cls._SHADERS['fragmentSymbols'][marker]
+ prgm = Program(vertShdr, fragShdr, attrib0='xPos')
+
+ cls._programs[(transform, marker)] = prgm
+ return prgm
+
+ @classmethod
+ def init(cls):
+ version = gl.glGetString(gl.GL_VERSION)
+ majorVersion = int(version[0])
+ assert majorVersion >= 2
+ gl.glEnable(gl.GL_VERTEX_PROGRAM_POINT_SIZE) # OpenGL 2
+ gl.glEnable(gl.GL_POINT_SPRITE) # OpenGL 2
+ if majorVersion >= 3: # OpenGL 3
+ gl.glEnable(gl.GL_PROGRAM_POINT_SIZE)
+
+ def _renderNone(self, matrix, isXLog, isYLog):
+ pass
+
+ render = _renderNone
+
+ def _renderMarkers(self, matrix, isXLog, isYLog):
+ if isXLog:
+ transform = self._LOG10_X_Y if isYLog else self._LOG10_X
+ else:
+ transform = self._LOG10_Y if isYLog else self._LINEAR
+
+ prog = self._getProgram(transform, self.marker)
+ prog.use()
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, matrix)
+ if self.marker == PIXEL:
+ size = 1
+ elif self.marker == POINT:
+ size = math.ceil(0.5 * self.size) + 1 # Mimic Matplotlib point
+ else:
+ size = self.size
+ gl.glUniform1f(prog.uniforms['size'], size)
+ # gl.glPointSize(self.size)
+
+ cAttrib = prog.attributes['color']
+ if self.useColorVboData and self.colorVboData is not None:
+ gl.glEnableVertexAttribArray(cAttrib)
+ self.colorVboData.setVertexAttrib(cAttrib)
+ else:
+ gl.glDisableVertexAttribArray(cAttrib)
+ gl.glVertexAttrib4f(cAttrib, *self.color)
+
+ xAttrib = prog.attributes['xPos']
+ gl.glEnableVertexAttribArray(xAttrib)
+ self.xVboData.setVertexAttrib(xAttrib)
+
+ yAttrib = prog.attributes['yPos']
+ gl.glEnableVertexAttribArray(yAttrib)
+ self.yVboData.setVertexAttrib(yAttrib)
+
+ gl.glDrawArrays(gl.GL_POINTS, 0, self.xVboData.size)
+
+ gl.glUseProgram(0)
+
+
+# error bars ##################################################################
+
+class _ErrorBars(object):
+ """Display errors bars.
+
+ This is using its own VBO as opposed to fill/points/lines.
+ There is no picking on error bars.
+ As is, there is no way to update data and errors, but it handles
+ log scales by removing data <= 0 and clipping error bars to positive
+ range.
+
+ It uses 2 vertices per error bars and uses :class:`_Lines2D` to
+ render error bars and :class:`_Points2D` to render the ends.
+ """
+
+ def __init__(self, xData, yData, xError, yError,
+ xMin, yMin,
+ color=(0., 0., 0., 1.)):
+ """Initialization.
+
+ :param numpy.ndarray xData: X coordinates of the data.
+ :param numpy.ndarray yData: Y coordinates of the data.
+ :param xError: The absolute error on the X axis.
+ :type xError: A float, or a numpy.ndarray of float32.
+ If it is an array, it can either be a 1D array of
+ same length as the data or a 2D array with 2 rows
+ of same length as the data: row 0 for negative errors,
+ row 1 for positive errors.
+ :param yError: The absolute error on the Y axis.
+ :type yError: A float, or a numpy.ndarray of float32. See xError.
+ :param float xMin: The min X value already computed by GLPlotCurve2D.
+ :param float yMin: The min Y value already computed by GLPlotCurve2D.
+ :param color: The color to use for both lines and ending points.
+ :type color: tuple of 4 floats
+ """
+ self._attribs = None
+ self._isXLog, self._isYLog = False, False
+ self._xMin, self._yMin = xMin, yMin
+
+ if xError is not None or yError is not None:
+ assert len(xData) == len(yData)
+ self._xData = numpy.array(
+ xData, order='C', dtype=numpy.float32, copy=False)
+ self._yData = numpy.array(
+ yData, order='C', dtype=numpy.float32, copy=False)
+
+ # This also works if xError, yError is a float/int
+ self._xError = numpy.array(
+ xError, order='C', dtype=numpy.float32, copy=False)
+ self._yError = numpy.array(
+ yError, order='C', dtype=numpy.float32, copy=False)
+ else:
+ self._xData, self._yData = None, None
+ self._xError, self._yError = None, None
+
+ self._lines = _Lines2D(None, None, color=color, drawMode=gl.GL_LINES)
+ self._xErrPoints = _Points2D(None, None, color=color, marker=V_LINE)
+ self._yErrPoints = _Points2D(None, None, color=color, marker=H_LINE)
+
+ def _positiveValueFilter(self, onlyXPos, onlyYPos):
+ """Filter data (x, y) and errors (xError, yError) to remove
+ negative and null data values on required axis (onlyXPos, onlyYPos).
+
+ Returned arrays might be NOT contiguous.
+
+ :return: Filtered xData, yData, xError and yError arrays.
+ """
+ if ((not onlyXPos or self._xMin > 0.) and
+ (not onlyYPos or self._yMin > 0.)):
+ # No need to filter, all values are > 0 on log axes
+ return self._xData, self._yData, self._xError, self._yError
+
+ _logger.warning(
+ 'Removing values <= 0 of curve with error bars on a log axis.')
+
+ x, y = self._xData, self._yData
+ xError, yError = self._xError, self._yError
+
+ # First remove negative data
+ if onlyXPos and onlyYPos:
+ mask = (x > 0.) & (y > 0.)
+ elif onlyXPos:
+ mask = x > 0.
+ else: # onlyYPos
+ mask = y > 0.
+ x, y = x[mask], y[mask]
+
+ # Remove corresponding values from error arrays
+ if xError is not None and xError.size != 1:
+ if len(xError.shape) == 1:
+ xError = xError[mask]
+ else: # 2 rows
+ xError = xError[:, mask]
+ if yError is not None and yError.size != 1:
+ if len(yError.shape) == 1:
+ yError = yError[mask]
+ else: # 2 rows
+ yError = yError[:, mask]
+
+ return x, y, xError, yError
+
+ def _buildVertices(self, isXLog, isYLog):
+ """Generates error bars vertices according to log scales."""
+ xData, yData, xError, yError = self._positiveValueFilter(
+ isXLog, isYLog)
+
+ nbLinesPerDataPts = 1 if xError is not None else 0
+ nbLinesPerDataPts += 1 if yError is not None else 0
+
+ nbDataPts = len(xData)
+
+ # interleave coord+error, coord-error.
+ # xError vertices first if any, then yError vertices if any.
+ xCoords = numpy.empty(nbDataPts * nbLinesPerDataPts * 2,
+ dtype=numpy.float32)
+ yCoords = numpy.empty(nbDataPts * nbLinesPerDataPts * 2,
+ dtype=numpy.float32)
+
+ if xError is not None: # errors on the X axis
+ if len(xError.shape) == 2:
+ xErrorMinus, xErrorPlus = xError[0], xError[1]
+ else:
+ # numpy arrays of len 1 or len(xData)
+ xErrorMinus, xErrorPlus = xError, xError
+
+ # Interleave vertices for xError
+ endXError = 2 * nbDataPts
+ xCoords[0:endXError-1:2] = xData + xErrorPlus
+
+ minValues = xData - xErrorMinus
+ if isXLog:
+ # Clip min bounds to positive value
+ minValues[minValues <= 0] = FLOAT32_MINPOS
+ xCoords[1:endXError:2] = minValues
+
+ yCoords[0:endXError-1:2] = yData
+ yCoords[1:endXError:2] = yData
+ else:
+ endXError = 0
+
+ if yError is not None: # errors on the Y axis
+ if len(yError.shape) == 2:
+ yErrorMinus, yErrorPlus = yError[0], yError[1]
+ else:
+ # numpy arrays of len 1 or len(yData)
+ yErrorMinus, yErrorPlus = yError, yError
+
+ # Interleave vertices for yError
+ xCoords[endXError::2] = xData
+ xCoords[endXError+1::2] = xData
+ yCoords[endXError::2] = yData + yErrorPlus
+ minValues = yData - yErrorMinus
+ if isYLog:
+ # Clip min bounds to positive value
+ minValues[minValues <= 0] = FLOAT32_MINPOS
+ yCoords[endXError+1::2] = minValues
+
+ return xCoords, yCoords
+
+ def prepare(self, isXLog, isYLog):
+ if self._xData is None:
+ return
+
+ if self._isXLog != isXLog or self._isYLog != isYLog:
+ # Log state has changed
+ self._isXLog, self._isYLog = isXLog, isYLog
+
+ self.discard() # discard existing VBOs
+
+ if self._attribs is None:
+ xCoords, yCoords = self._buildVertices(isXLog, isYLog)
+
+ xAttrib, yAttrib = vertexBuffer((xCoords, yCoords))
+ self._attribs = xAttrib, yAttrib
+
+ self._lines.xVboData, self._lines.yVboData = xAttrib, yAttrib
+
+ # Set xError points using the same VBO as lines
+ self._xErrPoints.xVboData = xAttrib.copy()
+ self._xErrPoints.xVboData.size //= 2
+ self._xErrPoints.yVboData = yAttrib.copy()
+ self._xErrPoints.yVboData.size //= 2
+
+ # Set yError points using the same VBO as lines
+ self._yErrPoints.xVboData = xAttrib.copy()
+ self._yErrPoints.xVboData.size //= 2
+ self._yErrPoints.xVboData.offset += (xAttrib.itemsize *
+ xAttrib.size // 2)
+ self._yErrPoints.yVboData = yAttrib.copy()
+ self._yErrPoints.yVboData.size //= 2
+ self._yErrPoints.yVboData.offset += (yAttrib.itemsize *
+ yAttrib.size // 2)
+
+ def render(self, matrix, isXLog, isYLog):
+ if self._attribs is not None:
+ self._lines.render(matrix, isXLog, isYLog)
+ self._xErrPoints.render(matrix, isXLog, isYLog)
+ self._yErrPoints.render(matrix, isXLog, isYLog)
+
+ def discard(self):
+ if self._attribs is not None:
+ self._lines.xVboData, self._lines.yVboData = None, None
+ self._xErrPoints.xVboData, self._xErrPoints.yVboData = None, None
+ self._yErrPoints.xVboData, self._yErrPoints.yVboData = None, None
+ self._attribs[0].vbo.discard()
+ self._attribs = None
+
+
+# curves ######################################################################
+
+def _proxyProperty(*componentsAttributes):
+ """Create a property to access an attribute of attribute(s).
+ Useful for composition.
+ Supports multiple components this way:
+ getter returns the first found, setter sets all
+ """
+ def getter(self):
+ for compName, attrName in componentsAttributes:
+ try:
+ component = getattr(self, compName)
+ except AttributeError:
+ pass
+ else:
+ return getattr(component, attrName)
+
+ def setter(self, value):
+ for compName, attrName in componentsAttributes:
+ component = getattr(self, compName)
+ setattr(component, attrName, value)
+ return property(getter, setter)
+
+
+class GLPlotCurve2D(object):
+ def __init__(self, xData, yData, colorData=None,
+ xError=None, yError=None,
+ lineStyle=None, lineColor=None,
+ lineWidth=None, lineDashPeriod=None,
+ marker=None, markerColor=None, markerSize=None,
+ fillColor=None):
+ self._isXLog = False
+ self._isYLog = False
+ self.xData, self.yData, self.colorData = xData, yData, colorData
+
+ if fillColor is not None:
+ self.fill = _Fill2D(color=fillColor)
+ else:
+ self.fill = None
+
+ # Compute x bounds
+ if xError is None:
+ result = min_max(xData, min_positive=True)
+ self.xMin = result.minimum
+ self.xMinPos = result.min_positive
+ self.xMax = result.maximum
+ else:
+ # Takes the error into account
+ if hasattr(xError, 'shape') and len(xError.shape) == 2:
+ xErrorPlus, xErrorMinus = xError[0], xError[1]
+ else:
+ xErrorPlus, xErrorMinus = xError, xError
+ result = min_max(xData - xErrorMinus, min_positive=True)
+ self.xMin = result.minimum
+ self.xMinPos = result.min_positive
+ self.xMax = (xData + xErrorPlus).max()
+
+ # Compute y bounds
+ if yError is None:
+ result = min_max(yData, min_positive=True)
+ self.yMin = result.minimum
+ self.yMinPos = result.min_positive
+ self.yMax = result.maximum
+ else:
+ # Takes the error into account
+ if hasattr(yError, 'shape') and len(yError.shape) == 2:
+ yErrorPlus, yErrorMinus = yError[0], yError[1]
+ else:
+ yErrorPlus, yErrorMinus = yError, yError
+ result = min_max(yData - yErrorMinus, min_positive=True)
+ self.yMin = result.minimum
+ self.yMinPos = result.min_positive
+ self.yMax = (yData + yErrorPlus).max()
+
+ self._errorBars = _ErrorBars(xData, yData, xError, yError,
+ self.xMin, self.yMin)
+
+ kwargs = {'style': lineStyle}
+ if lineColor is not None:
+ kwargs['color'] = lineColor
+ if lineWidth is not None:
+ kwargs['width'] = lineWidth
+ if lineDashPeriod is not None:
+ kwargs['dashPeriod'] = lineDashPeriod
+ self.lines = _Lines2D(**kwargs)
+
+ kwargs = {'marker': marker}
+ if markerColor is not None:
+ kwargs['color'] = markerColor
+ if markerSize is not None:
+ kwargs['size'] = markerSize
+ self.points = _Points2D(**kwargs)
+
+ xVboData = _proxyProperty(('lines', 'xVboData'), ('points', 'xVboData'))
+
+ yVboData = _proxyProperty(('lines', 'yVboData'), ('points', 'yVboData'))
+
+ colorVboData = _proxyProperty(('lines', 'colorVboData'),
+ ('points', 'colorVboData'))
+
+ useColorVboData = _proxyProperty(('lines', 'useColorVboData'),
+ ('points', 'useColorVboData'))
+
+ distVboData = _proxyProperty(('lines', 'distVboData'))
+
+ lineStyle = _proxyProperty(('lines', 'style'))
+
+ lineColor = _proxyProperty(('lines', 'color'))
+
+ lineWidth = _proxyProperty(('lines', 'width'))
+
+ lineDashPeriod = _proxyProperty(('lines', 'dashPeriod'))
+
+ marker = _proxyProperty(('points', 'marker'))
+
+ markerColor = _proxyProperty(('points', 'color'))
+
+ markerSize = _proxyProperty(('points', 'size'))
+
+ @classmethod
+ def init(cls):
+ _Lines2D.init()
+ _Points2D.init()
+
+ @staticmethod
+ def _logFilterData(x, y, color=None, xLog=False, yLog=False):
+ # Copied from Plot.py
+ if xLog and yLog:
+ idx = numpy.nonzero((x > 0) & (y > 0))[0]
+ x = numpy.take(x, idx)
+ y = numpy.take(y, idx)
+ elif yLog:
+ idx = numpy.nonzero(y > 0)[0]
+ x = numpy.take(x, idx)
+ y = numpy.take(y, idx)
+ elif xLog:
+ idx = numpy.nonzero(x > 0)[0]
+ x = numpy.take(x, idx)
+ y = numpy.take(y, idx)
+ else:
+ idx = None
+
+ if idx is not None and isinstance(color, numpy.ndarray):
+ colors = numpy.zeros((x.size, 4), color.dtype)
+ colors[:, 0] = color[idx, 0]
+ colors[:, 1] = color[idx, 1]
+ colors[:, 2] = color[idx, 2]
+ colors[:, 3] = color[idx, 3]
+ else:
+ colors = color
+ return x, y, colors
+
+ def prepare(self, isXLog, isYLog):
+ # init only supports updating isXLog, isYLog
+ xData, yData, colorData = self.xData, self.yData, self.colorData
+
+ if self._isXLog != isXLog or self._isYLog != isYLog:
+ # Log state has changed
+ self._isXLog, self._isYLog = isXLog, isYLog
+
+ # Check if data <= 0. with log scale
+ if (isXLog and self.xMin <= 0.) or (isYLog and self.yMin <= 0.):
+ # Filtering data is needed
+ xData, yData, colorData = self._logFilterData(
+ self.xData, self.yData, self.colorData,
+ self._isXLog, self._isYLog)
+
+ self.discard() # discard existing VBOs
+
+ if self.xVboData is None:
+ xAttrib, yAttrib, cAttrib, dAttrib = None, None, None, None
+ if self.lineStyle in (DASHED, DASHDOT, DOTTED):
+ dists = _distancesFromArrays(xData, yData)
+ if self.colorData is None:
+ xAttrib, yAttrib, dAttrib = vertexBuffer(
+ (xData, yData, dists),
+ prefix=(1, 1, 0), suffix=(1, 1, 0))
+ else:
+ xAttrib, yAttrib, cAttrib, dAttrib = vertexBuffer(
+ (xData, yData, colorData, dists),
+ prefix=(1, 1, 0, 0), suffix=(1, 1, 0, 0))
+ elif self.colorData is None:
+ xAttrib, yAttrib = vertexBuffer(
+ (xData, yData), prefix=(1, 1), suffix=(1, 1))
+ else:
+ xAttrib, yAttrib, cAttrib = vertexBuffer(
+ (xData, yData, colorData), prefix=(1, 1, 0))
+
+ # Shrink VBO
+ self.xVboData = xAttrib.copy()
+ self.xVboData.size -= 2
+ self.xVboData.offset += xAttrib.itemsize
+
+ self.yVboData = yAttrib.copy()
+ self.yVboData.size -= 2
+ self.yVboData.offset += yAttrib.itemsize
+
+ if cAttrib is not None and colorData.dtype.kind == 'u':
+ cAttrib.normalisation = True # Normalise uint to [0, 1]
+ self.colorVboData = cAttrib
+ self.useColorVboData = cAttrib is not None
+ self.distVboData = dAttrib
+
+ if self.fill is not None:
+ xData = xData.reshape(xData.size, 1)
+ zero = numpy.array((1e-32,), dtype=self.yData.dtype)
+
+ # Add one point before data: (x0, 0.)
+ xAttrib.vbo.update(xData[0], xAttrib.offset,
+ xData[0].itemsize)
+ yAttrib.vbo.update(zero, yAttrib.offset, zero.itemsize)
+
+ # Add one point after data: (xN, 0.)
+ xAttrib.vbo.update(xData[-1],
+ xAttrib.offset +
+ (xAttrib.size - 1) * xAttrib.itemsize,
+ xData[-1].itemsize)
+ yAttrib.vbo.update(zero,
+ yAttrib.offset +
+ (yAttrib.size - 1) * yAttrib.itemsize,
+ zero.itemsize)
+
+ self.fill.xFillVboData = xAttrib
+ self.fill.yFillVboData = yAttrib
+ self.fill.xMin, self.fill.yMin = self.xMin, self.yMin
+ self.fill.xMax, self.fill.yMax = self.xMax, self.yMax
+
+ self._errorBars.prepare(isXLog, isYLog)
+
+ def render(self, matrix, isXLog, isYLog):
+ self.prepare(isXLog, isYLog)
+ if self.fill is not None:
+ self.fill.render(matrix, isXLog, isYLog)
+ self._errorBars.render(matrix, isXLog, isYLog)
+ self.lines.render(matrix, isXLog, isYLog)
+ self.points.render(matrix, isXLog, isYLog)
+
+ def discard(self):
+ if self.xVboData is not None:
+ self.xVboData.vbo.discard()
+
+ self.xVboData = None
+ self.yVboData = None
+ self.colorVboData = None
+ self.distVboData = None
+
+ self._errorBars.discard()
+
+ def pick(self, xPickMin, yPickMin, xPickMax, yPickMax):
+ """Perform picking on the curve according to its rendering.
+
+ The picking area is [xPickMin, xPickMax], [yPickMin, yPickMax].
+
+ In case a segment between 2 points with indices i, i+1 is picked,
+ only its lower index end point (i.e., i) is added to the result.
+ In case an end point with index i is picked it is added to the result,
+ and the segment [i-1, i] is not tested for picking.
+
+ :return: The indices of the picked data
+ :rtype: list of int
+ """
+ if (self.marker is None and self.lineStyle is None) or \
+ self.xMin > xPickMax or xPickMin > self.xMax or \
+ self.yMin > yPickMax or yPickMin > self.yMax:
+ # Note: With log scale the bounding box is too large if
+ # some data <= 0.
+ return None
+
+ elif self.lineStyle is not None:
+ # Using Cohen-Sutherland algorithm for line clipping
+ codes = ((self.yData > yPickMax) << 3) | \
+ ((self.yData < yPickMin) << 2) | \
+ ((self.xData > xPickMax) << 1) | \
+ (self.xData < xPickMin)
+
+ # Add all points that are inside the picking area
+ indices = numpy.nonzero(codes == 0)[0].tolist()
+
+ # Segment that might cross the area with no end point inside it
+ segToTestIdx = numpy.nonzero((codes[:-1] != 0) &
+ (codes[1:] != 0) &
+ ((codes[:-1] & codes[1:]) == 0))[0]
+
+ TOP, BOTTOM, RIGHT, LEFT = (1 << 3), (1 << 2), (1 << 1), (1 << 0)
+
+ for index in segToTestIdx:
+ if index not in indices:
+ x0, y0 = self.xData[index], self.yData[index]
+ x1, y1 = self.xData[index + 1], self.yData[index + 1]
+ code1 = codes[index + 1]
+
+ # check for crossing with horizontal bounds
+ # y0 == y1 is a never event:
+ # => pt0 and pt1 in same vertical area are not in segToTest
+ if code1 & TOP:
+ x = x0 + (x1 - x0) * (yPickMax - y0) / (y1 - y0)
+ elif code1 & BOTTOM:
+ x = x0 + (x1 - x0) * (yPickMin - y0) / (y1 - y0)
+ else:
+ x = None # No horizontal bounds intersection test
+
+ if x is not None and xPickMin <= x <= xPickMax:
+ # Intersection
+ indices.append(index)
+
+ else:
+ # check for crossing with vertical bounds
+ # x0 == x1 is a never event (see remark for y)
+ if code1 & RIGHT:
+ y = y0 + (y1 - y0) * (xPickMax - x0) / (x1 - x0)
+ elif code1 & LEFT:
+ y = y0 + (y1 - y0) * (xPickMin - x0) / (x1 - x0)
+ else:
+ y = None # No vertical bounds intersection test
+
+ if y is not None and yPickMin <= y <= yPickMax:
+ # Intersection
+ indices.append(index)
+
+ indices.sort()
+
+ else:
+ indices = numpy.nonzero((self.xData >= xPickMin) &
+ (self.xData <= xPickMax) &
+ (self.yData >= yPickMin) &
+ (self.yData <= yPickMax))[0].tolist()
+
+ return indices
diff --git a/silx/gui/plot/backends/glutils/GLPlotFrame.py b/silx/gui/plot/backends/glutils/GLPlotFrame.py
new file mode 100644
index 0000000..367419c
--- /dev/null
+++ b/silx/gui/plot/backends/glutils/GLPlotFrame.py
@@ -0,0 +1,1039 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ############################################################################*/
+"""
+This modules provides the rendering of plot titles, axes and grid.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+# TODO
+# keep aspect ratio managed here?
+# smarter dirty flag handling?
+
+import math
+import weakref
+import logging
+from collections import namedtuple
+
+import numpy
+
+from ...._glutils import gl, Program
+from ..._utils import FLOAT32_SAFE_MIN, FLOAT32_MINPOS, FLOAT32_SAFE_MAX
+from .GLSupport import mat4Ortho
+from .GLText import Text2D, CENTER, BOTTOM, TOP, LEFT, RIGHT, ROTATE_270
+from ..._utils.ticklayout import niceNumbersAdaptative, niceNumbersForLog10
+
+
+_logger = logging.getLogger(__name__)
+
+
+# PlotAxis ####################################################################
+
+class PlotAxis(object):
+ """Represents a 1D axis of the plot.
+ This class is intended to be used with :class:`GLPlotFrame`.
+ """
+
+ def __init__(self, plot,
+ tickLength=(0., 0.),
+ labelAlign=CENTER, labelVAlign=CENTER,
+ titleAlign=CENTER, titleVAlign=CENTER,
+ titleRotate=0, titleOffset=(0., 0.)):
+ self._ticks = None
+
+ self._plot = weakref.ref(plot)
+
+ self._isLog = False
+ self._dataRange = 1., 100.
+ self._displayCoords = (0., 0.), (1., 0.)
+ self._title = ''
+
+ self._tickLength = tickLength
+ self._labelAlign = labelAlign
+ self._labelVAlign = labelVAlign
+ self._titleAlign = titleAlign
+ self._titleVAlign = titleVAlign
+ self._titleRotate = titleRotate
+ self._titleOffset = titleOffset
+
+ @property
+ def dataRange(self):
+ """The range of the data represented on the axis as a tuple
+ of 2 floats: (min, max)."""
+ return self._dataRange
+
+ @dataRange.setter
+ def dataRange(self, dataRange):
+ assert len(dataRange) == 2
+ assert dataRange[0] <= dataRange[1]
+ dataRange = float(dataRange[0]), float(dataRange[1])
+
+ if dataRange != self._dataRange:
+ self._dataRange = dataRange
+ self._dirtyTicks()
+
+ @property
+ def isLog(self):
+ """Whether the axis is using a log10 scale or not as a bool."""
+ return self._isLog
+
+ @isLog.setter
+ def isLog(self, isLog):
+ isLog = bool(isLog)
+ if isLog != self._isLog:
+ self._isLog = isLog
+ self._dirtyTicks()
+
+ @property
+ def displayCoords(self):
+ """The coordinates of the start and end points of the axis
+ in display space (i.e., in pixels) as a tuple of 2 tuples of
+ 2 floats: ((x0, y0), (x1, y1)).
+ """
+ return self._displayCoords
+
+ @displayCoords.setter
+ def displayCoords(self, displayCoords):
+ assert len(displayCoords) == 2
+ assert len(displayCoords[0]) == 2
+ assert len(displayCoords[1]) == 2
+ displayCoords = tuple(displayCoords[0]), tuple(displayCoords[1])
+ if displayCoords != self._displayCoords:
+ self._displayCoords = displayCoords
+ self._dirtyTicks()
+
+ @property
+ def title(self):
+ """The text label associated with this axis as a str in latin-1."""
+ return self._title
+
+ @title.setter
+ def title(self, title):
+ if title != self._title:
+ self._title = title
+
+ plot = self._plot()
+ if plot is not None:
+ plot._dirty()
+
+ @property
+ def ticks(self):
+ """Ticks as tuples: ((x, y) in display, dataPos, textLabel)."""
+ if self._ticks is None:
+ self._ticks = tuple(self._ticksGenerator())
+ return self._ticks
+
+ def getVerticesAndLabels(self):
+ """Create the list of vertices for axis and associated text labels.
+
+ :returns: A tuple: List of 2D line vertices, List of Text2D labels.
+ """
+ vertices = list(self.displayCoords) # Add start and end points
+ labels = []
+ tickLabelsSize = [0., 0.]
+
+ xTickLength, yTickLength = self._tickLength
+ for (xPixel, yPixel), dataPos, text in self.ticks:
+ if text is None:
+ tickScale = 0.5
+ else:
+ tickScale = 1.
+
+ label = Text2D(text=text,
+ x=xPixel - xTickLength,
+ y=yPixel - yTickLength,
+ align=self._labelAlign,
+ valign=self._labelVAlign)
+
+ width, height = label.size
+ if width > tickLabelsSize[0]:
+ tickLabelsSize[0] = width
+ if height > tickLabelsSize[1]:
+ tickLabelsSize[1] = height
+
+ labels.append(label)
+
+ vertices.append((xPixel, yPixel))
+ vertices.append((xPixel + tickScale * xTickLength,
+ yPixel + tickScale * yTickLength))
+
+ (x0, y0), (x1, y1) = self.displayCoords
+ xAxisCenter = 0.5 * (x0 + x1)
+ yAxisCenter = 0.5 * (y0 + y1)
+
+ xOffset, yOffset = self._titleOffset
+
+ # Adaptative title positioning:
+ # tickNorm = math.sqrt(xTickLength ** 2 + yTickLength ** 2)
+ # xOffset = -tickLabelsSize[0] * xTickLength / tickNorm
+ # xOffset -= 3 * xTickLength
+ # yOffset = -tickLabelsSize[1] * yTickLength / tickNorm
+ # yOffset -= 3 * yTickLength
+
+ axisTitle = Text2D(text=self.title,
+ x=xAxisCenter + xOffset,
+ y=yAxisCenter + yOffset,
+ align=self._titleAlign,
+ valign=self._titleVAlign,
+ rotate=self._titleRotate)
+ labels.append(axisTitle)
+
+ return vertices, labels
+
+ def _dirtyTicks(self):
+ """Mark ticks as dirty and notify listener (i.e., background)."""
+ self._ticks = None
+ plot = self._plot()
+ if plot is not None:
+ plot._dirty()
+
+ @staticmethod
+ def _frange(start, stop, step):
+ """range for float (including stop)."""
+ while start <= stop:
+ yield start
+ start += step
+
+ def _ticksGenerator(self):
+ """Generator of ticks as tuples:
+ ((x, y) in display, dataPos, textLabel).
+ """
+ dataMin, dataMax = self.dataRange
+ if self.isLog and dataMin <= 0.:
+ _logger.warning(
+ 'Getting ticks while isLog=True and dataRange[0]<=0.')
+ dataMin = 1.
+ if dataMax < dataMin:
+ dataMax = 1.
+
+ if dataMin != dataMax: # data range is not null
+ (x0, y0), (x1, y1) = self.displayCoords
+
+ if self.isLog:
+ logMin, logMax = math.log10(dataMin), math.log10(dataMax)
+ tickMin, tickMax, step, _ = niceNumbersForLog10(logMin, logMax)
+
+ xScale = (x1 - x0) / (logMax - logMin)
+ yScale = (y1 - y0) / (logMax - logMin)
+
+ for logPos in self._frange(tickMin, tickMax, step):
+ if logMin <= logPos <= logMax:
+ dataPos = 10 ** logPos
+ xPixel = x0 + (logPos - logMin) * xScale
+ yPixel = y0 + (logPos - logMin) * yScale
+ text = '1e%+03d' % logPos
+ yield ((xPixel, yPixel), dataPos, text)
+
+ if step == 1:
+ ticks = list(self._frange(tickMin, tickMax, step))[:-1]
+ for logPos in ticks:
+ dataOrigPos = 10 ** logPos
+ for index in range(2, 10):
+ dataPos = dataOrigPos * index
+ if dataMin <= dataPos <= dataMax:
+ logSubPos = math.log10(dataPos)
+ xPixel = x0 + (logSubPos - logMin) * xScale
+ yPixel = y0 + (logSubPos - logMin) * yScale
+ yield ((xPixel, yPixel), dataPos, None)
+
+ else:
+ xScale = (x1 - x0) / (dataMax - dataMin)
+ yScale = (y1 - y0) / (dataMax - dataMin)
+
+ nbPixels = math.sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2))
+
+ # Density of 1.3 label per 92 pixels
+ # i.e., 1.3 label per inch on a 92 dpi screen
+ tickMin, tickMax, step, nbFrac = niceNumbersAdaptative(
+ dataMin, dataMax, nbPixels, 1.3 / 92)
+
+ for dataPos in self._frange(tickMin, tickMax, step):
+ if dataMin <= dataPos <= dataMax:
+ xPixel = x0 + (dataPos - dataMin) * xScale
+ yPixel = y0 + (dataPos - dataMin) * yScale
+
+ if nbFrac == 0:
+ text = '%g' % dataPos
+ else:
+ text = ('%.' + str(nbFrac) + 'f') % dataPos
+ yield ((xPixel, yPixel), dataPos, text)
+
+
+# GLPlotFrame #################################################################
+
+class GLPlotFrame(object):
+ """Base class for rendering a 2D frame surrounded by axes."""
+
+ _TICK_LENGTH_IN_PIXELS = 5
+ _LINE_WIDTH = 1
+
+ _SHADERS = {
+ 'vertex': """
+ attribute vec2 position;
+ uniform mat4 matrix;
+
+ void main(void) {
+ gl_Position = matrix * vec4(position, 0.0, 1.0);
+ }
+ """,
+ 'fragment': """
+ uniform vec4 color;
+ uniform float tickFactor; /* = 1./tickLength or 0. for solid line */
+
+ void main(void) {
+ if (mod(tickFactor * (gl_FragCoord.x + gl_FragCoord.y), 2.) < 1.) {
+ gl_FragColor = color;
+ } else {
+ discard;
+ }
+ }
+ """
+ }
+
+ _Margins = namedtuple('Margins', ('left', 'right', 'top', 'bottom'))
+
+ def __init__(self, margins):
+ """
+ :param margins: The margins around plot area for axis and labels.
+ :type margins: dict with 'left', 'right', 'top', 'bottom' keys and
+ values as ints.
+ """
+ self._renderResources = None
+
+ self._margins = self._Margins(**margins)
+
+ self.axes = [] # List of PlotAxis to be updated by subclasses
+
+ self._grid = False
+ self._size = 0., 0.
+ self._title = ''
+
+ @property
+ def isDirty(self):
+ """True if it need to refresh graphic rendering, False otherwise."""
+ return self._renderResources is None
+
+ GRID_NONE = 0
+ GRID_MAIN_TICKS = 1
+ GRID_SUB_TICKS = 2
+ GRID_ALL_TICKS = (GRID_MAIN_TICKS + GRID_SUB_TICKS)
+
+ @property
+ def margins(self):
+ """Margins in pixels around the plot."""
+ return self._margins
+
+ @property
+ def grid(self):
+ """Grid display mode:
+ - 0: No grid.
+ - 1: Grid on main ticks.
+ - 2: Grid on sub-ticks for log scale axes.
+ - 3: Grid on main and sub ticks."""
+ return self._grid
+
+ @grid.setter
+ def grid(self, grid):
+ assert grid in (self.GRID_NONE, self.GRID_MAIN_TICKS,
+ self.GRID_SUB_TICKS, self.GRID_ALL_TICKS)
+ if grid != self._grid:
+ self._grid = grid
+ self._dirty()
+
+ @property
+ def size(self):
+ """Size in pixels of the plot area including margins."""
+ return self._size
+
+ @size.setter
+ def size(self, size):
+ assert len(size) == 2
+ size = tuple(size)
+ if size != self._size:
+ self._size = size
+ self._dirty()
+
+ @property
+ def plotOrigin(self):
+ """Plot area origin (left, top) in widget coordinates in pixels."""
+ return self.margins.left, self.margins.top
+
+ @property
+ def plotSize(self):
+ """Plot area size (width, height) in pixels."""
+ w, h = self.size
+ w -= self.margins.left + self.margins.right
+ h -= self.margins.top + self.margins.bottom
+ return w, h
+
+ @property
+ def title(self):
+ """Main title as a str in latin-1."""
+ return self._title
+
+ @title.setter
+ def title(self, title):
+ if title != self._title:
+ self._title = title
+ self._dirty()
+
+ # In-place update
+ # if self._renderResources is not None:
+ # self._renderResources[-1][-1].text = title
+
+ def _dirty(self):
+ # When Text2D require discard we need to handle it
+ self._renderResources = None
+
+ def _buildGridVertices(self):
+ if self._grid == self.GRID_NONE:
+ return []
+
+ elif self._grid == self.GRID_MAIN_TICKS:
+ def test(text):
+ return text is not None
+ elif self._grid == self.GRID_SUB_TICKS:
+ def test(text):
+ return text is None
+ elif self._grid == self.GRID_ALL_TICKS:
+ def test(_):
+ return True
+ else:
+ logging.warning('Wrong grid mode: %d' % self._grid)
+ return []
+
+ return self._buildGridVerticesWithTest(test)
+
+ def _buildGridVerticesWithTest(self, test):
+ """Override in subclass to generate grid vertices"""
+ return []
+
+ def _buildVerticesAndLabels(self):
+ # To fill with copy of axes lists
+ vertices = []
+ labels = []
+
+ for axis in self.axes:
+ axisVertices, axisLabels = axis.getVerticesAndLabels()
+ vertices += axisVertices
+ labels += axisLabels
+
+ vertices = numpy.array(vertices, dtype=numpy.float32)
+
+ # Add main title
+ xTitle = (self.size[0] + self.margins.left -
+ self.margins.right) // 2
+ yTitle = self.margins.top - self._TICK_LENGTH_IN_PIXELS
+ labels.append(Text2D(text=self.title,
+ x=xTitle,
+ y=yTitle,
+ align=CENTER,
+ valign=BOTTOM))
+
+ # grid
+ gridVertices = numpy.array(self._buildGridVertices(),
+ dtype=numpy.float32)
+
+ self._renderResources = (vertices, gridVertices, labels)
+
+ _program = Program(
+ _SHADERS['vertex'], _SHADERS['fragment'], attrib0='position')
+
+ def render(self):
+ if self._renderResources is None:
+ self._buildVerticesAndLabels()
+ vertices, gridVertices, labels = self._renderResources
+
+ width, height = self.size
+ matProj = mat4Ortho(0, width, height, 0, 1, -1)
+
+ gl.glViewport(0, 0, width, height)
+
+ prog = self._program
+ prog.use()
+
+ gl.glLineWidth(self._LINE_WIDTH)
+
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, matProj)
+ gl.glUniform4f(prog.uniforms['color'], 0., 0., 0., 1.)
+ gl.glUniform1f(prog.uniforms['tickFactor'], 0.)
+
+ gl.glEnableVertexAttribArray(prog.attributes['position'])
+ gl.glVertexAttribPointer(prog.attributes['position'],
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0, vertices)
+
+ gl.glDrawArrays(gl.GL_LINES, 0, len(vertices))
+
+ for label in labels:
+ label.render(matProj)
+
+ def renderGrid(self):
+ if self._grid == self.GRID_NONE:
+ return
+
+ if self._renderResources is None:
+ self._buildVerticesAndLabels()
+ vertices, gridVertices, labels = self._renderResources
+
+ width, height = self.size
+ matProj = mat4Ortho(0, width, height, 0, 1, -1)
+
+ gl.glViewport(0, 0, width, height)
+
+ prog = self._program
+ prog.use()
+
+ gl.glLineWidth(self._LINE_WIDTH)
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, matProj)
+ gl.glUniform4f(prog.uniforms['color'], 0.7, 0.7, 0.7, 1.)
+ gl.glUniform1f(prog.uniforms['tickFactor'], 0.) # 1/2.) # 1/tickLen
+
+ gl.glEnableVertexAttribArray(prog.attributes['position'])
+ gl.glVertexAttribPointer(prog.attributes['position'],
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0, gridVertices)
+
+ gl.glDrawArrays(gl.GL_LINES, 0, len(gridVertices))
+
+
+# GLPlotFrame2D ###############################################################
+
+class GLPlotFrame2D(GLPlotFrame):
+ def __init__(self, margins):
+ """
+ :param margins: The margins around plot area for axis and labels.
+ :type margins: dict with 'left', 'right', 'top', 'bottom' keys and
+ values as ints.
+ """
+ super(GLPlotFrame2D, self).__init__(margins)
+ self.axes.append(PlotAxis(self,
+ tickLength=(0., -5.),
+ labelAlign=CENTER, labelVAlign=TOP,
+ titleAlign=CENTER, titleVAlign=TOP,
+ titleRotate=0,
+ titleOffset=(0, self.margins.bottom // 2)))
+
+ self._x2AxisCoords = ()
+
+ self.axes.append(PlotAxis(self,
+ tickLength=(5., 0.),
+ labelAlign=RIGHT, labelVAlign=CENTER,
+ titleAlign=CENTER, titleVAlign=BOTTOM,
+ titleRotate=ROTATE_270,
+ titleOffset=(-3 * self.margins.left // 4,
+ 0)))
+
+ self._y2Axis = PlotAxis(self,
+ tickLength=(-5., 0.),
+ labelAlign=LEFT, labelVAlign=CENTER,
+ titleAlign=CENTER, titleVAlign=TOP,
+ titleRotate=ROTATE_270,
+ titleOffset=(3 * self.margins.right // 4,
+ 0))
+
+ self._isYAxisInverted = False
+
+ self._dataRanges = {
+ 'x': (1., 100.), 'y': (1., 100.), 'y2': (1., 100.)}
+
+ self._baseVectors = (1., 0.), (0., 1.)
+
+ self._transformedDataRanges = None
+ self._transformedDataProjMat = None
+ self._transformedDataY2ProjMat = None
+
+ def _dirty(self):
+ super(GLPlotFrame2D, self)._dirty()
+ self._transformedDataRanges = None
+ self._transformedDataProjMat = None
+ self._transformedDataY2ProjMat = None
+
+ @property
+ def isDirty(self):
+ """True if it need to refresh graphic rendering, False otherwise."""
+ return (super(GLPlotFrame2D, self).isDirty or
+ self._transformedDataRanges is None or
+ self._transformedDataProjMat is None or
+ self._transformedDataY2ProjMat is None)
+
+ @property
+ def xAxis(self):
+ return self.axes[0]
+
+ @property
+ def yAxis(self):
+ return self.axes[1]
+
+ @property
+ def y2Axis(self):
+ return self._y2Axis
+
+ @property
+ def isY2Axis(self):
+ """Whether to display the left Y axis or not."""
+ return len(self.axes) == 3
+
+ @isY2Axis.setter
+ def isY2Axis(self, isY2Axis):
+ if isY2Axis != self.isY2Axis:
+ if isY2Axis:
+ self.axes.append(self._y2Axis)
+ else:
+ self.axes = self.axes[:2]
+
+ self._dirty()
+
+ @property
+ def isYAxisInverted(self):
+ """Whether Y axes are inverted or not as a bool."""
+ return self._isYAxisInverted
+
+ @isYAxisInverted.setter
+ def isYAxisInverted(self, value):
+ value = bool(value)
+ if value != self._isYAxisInverted:
+ self._isYAxisInverted = value
+ self._dirty()
+
+ DEFAULT_BASE_VECTORS = (1., 0.), (0., 1.)
+ """Values of baseVectors for orthogonal axes."""
+
+ @property
+ def baseVectors(self):
+ """Coordinates of the X and Y axes in the orthogonal plot coords.
+
+ Raises ValueError if corresponding matrix is singular.
+
+ 2 tuples of 2 floats: (xx, xy), (yx, yy)
+ """
+ return self._baseVectors
+
+ @baseVectors.setter
+ def baseVectors(self, baseVectors):
+ self._dirty()
+
+ (xx, xy), (yx, yy) = baseVectors
+ vectors = (float(xx), float(xy)), (float(yx), float(yy))
+
+ det = (vectors[0][0] * vectors[1][1] - vectors[1][0] * vectors[0][1])
+ if det == 0.:
+ raise ValueError("Singular matrix for base vectors: " +
+ str(vectors))
+
+ if vectors != self._baseVectors:
+ self._baseVectors = vectors
+ self._dirty()
+
+ @property
+ def dataRanges(self):
+ """Ranges of data visible in the plot on x, y and y2 axes.
+
+ This is different to the axes range when axes are not orthogonal.
+
+ Type: ((xMin, xMax), (yMin, yMax), (y2Min, y2Max))
+ """
+ return self._DataRanges(self._dataRanges['x'],
+ self._dataRanges['y'],
+ self._dataRanges['y2'])
+
+ @staticmethod
+ def _clipToSafeRange(min_, max_, isLog):
+ # Clip range if needed
+ minLimit = FLOAT32_MINPOS if isLog else FLOAT32_SAFE_MIN
+ min_ = numpy.clip(min_, minLimit, FLOAT32_SAFE_MAX)
+ max_ = numpy.clip(max_, minLimit, FLOAT32_SAFE_MAX)
+ assert min_ < max_
+ return min_, max_
+
+ def setDataRanges(self, x=None, y=None, y2=None):
+ """Set data range over each axes.
+
+ The provided ranges are clipped to possible values
+ (i.e., 32 float range + positive range for log scale).
+
+ :param x: (min, max) data range over X axis
+ :param y: (min, max) data range over Y axis
+ :param y2: (min, max) data range over Y2 axis
+ """
+ if x is not None:
+ self._dataRanges['x'] = \
+ self._clipToSafeRange(x[0], x[1], self.xAxis.isLog)
+
+ if y is not None:
+ self._dataRanges['y'] = \
+ self._clipToSafeRange(y[0], y[1], self.yAxis.isLog)
+
+ if y2 is not None:
+ self._dataRanges['y2'] = \
+ self._clipToSafeRange(y2[0], y2[1], self.y2Axis.isLog)
+
+ self.xAxis.dataRange = self._dataRanges['x']
+ self.yAxis.dataRange = self._dataRanges['y']
+ self.y2Axis.dataRange = self._dataRanges['y2']
+
+ _DataRanges = namedtuple('dataRanges', ('x', 'y', 'y2'))
+
+ @property
+ def transformedDataRanges(self):
+ """Bounds of the displayed area in transformed data coordinates
+ (i.e., log scale applied if any as well as skew)
+
+ 3-tuple of 2-tuple (min, max) for each axis: x, y, y2.
+ """
+ if self._transformedDataRanges is None:
+ (xMin, xMax), (yMin, yMax), (y2Min, y2Max) = self.dataRanges
+
+ if self.xAxis.isLog:
+ try:
+ xMin = math.log10(xMin)
+ except ValueError:
+ _logger.info('xMin: warning log10(%f)', xMin)
+ xMin = 0.
+ try:
+ xMax = math.log10(xMax)
+ except ValueError:
+ _logger.info('xMax: warning log10(%f)', xMax)
+ xMax = 0.
+
+ if self.yAxis.isLog:
+ try:
+ yMin = math.log10(yMin)
+ except ValueError:
+ _logger.info('yMin: warning log10(%f)', yMin)
+ yMin = 0.
+ try:
+ yMax = math.log10(yMax)
+ except ValueError:
+ _logger.info('yMax: warning log10(%f)', yMax)
+ yMax = 0.
+
+ try:
+ y2Min = math.log10(y2Min)
+ except ValueError:
+ _logger.info('yMin: warning log10(%f)', y2Min)
+ y2Min = 0.
+ try:
+ y2Max = math.log10(y2Max)
+ except ValueError:
+ _logger.info('yMax: warning log10(%f)', y2Max)
+ y2Max = 0.
+
+ # Non-orthogonal axes
+ if self.baseVectors != self.DEFAULT_BASE_VECTORS:
+ (xx, xy), (yx, yy) = self.baseVectors
+ skew_mat = numpy.array(((xx, yx), (xy, yy)))
+
+ corners = [(xMin, yMin), (xMin, yMax),
+ (xMax, yMin), (xMax, yMax),
+ (xMin, y2Min), (xMin, y2Max),
+ (xMax, y2Min), (xMax, y2Max)]
+
+ corners = numpy.array(
+ [numpy.dot(skew_mat, corner) for corner in corners],
+ dtype=numpy.float32)
+ xMin, xMax = corners[:, 0].min(), corners[:, 0].max()
+ yMin, yMax = corners[0:4, 1].min(), corners[0:4, 1].max()
+ y2Min, y2Max = corners[4:, 1].min(), corners[4:, 1].max()
+
+ self._transformedDataRanges = self._DataRanges(
+ (xMin, xMax), (yMin, yMax), (y2Min, y2Max))
+
+ return self._transformedDataRanges
+
+ @property
+ def transformedDataProjMat(self):
+ """Orthographic projection matrix for rendering transformed data
+
+ :type: numpy.matrix
+ """
+ if self._transformedDataProjMat is None:
+ xMin, xMax = self.transformedDataRanges.x
+ yMin, yMax = self.transformedDataRanges.y
+
+ if self.isYAxisInverted:
+ mat = mat4Ortho(xMin, xMax, yMax, yMin, 1, -1)
+ else:
+ mat = mat4Ortho(xMin, xMax, yMin, yMax, 1, -1)
+
+ # Non-orthogonal axes
+ if self.baseVectors != self.DEFAULT_BASE_VECTORS:
+ (xx, xy), (yx, yy) = self.baseVectors
+ mat = mat * numpy.matrix((
+ (xx, yx, 0., 0.),
+ (xy, yy, 0., 0.),
+ (0., 0., 1., 0.),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+ self._transformedDataProjMat = mat
+
+ return self._transformedDataProjMat
+
+ @property
+ def transformedDataY2ProjMat(self):
+ """Orthographic projection matrix for rendering transformed data
+ for the 2nd Y axis
+
+ :type: numpy.matrix
+ """
+ if self._transformedDataY2ProjMat is None:
+ xMin, xMax = self.transformedDataRanges.x
+ y2Min, y2Max = self.transformedDataRanges.y2
+
+ if self.isYAxisInverted:
+ mat = mat4Ortho(xMin, xMax, y2Max, y2Min, 1, -1)
+ else:
+ mat = mat4Ortho(xMin, xMax, y2Min, y2Max, 1, -1)
+
+ # Non-orthogonal axes
+ if self.baseVectors != self.DEFAULT_BASE_VECTORS:
+ (xx, xy), (yx, yy) = self.baseVectors
+ mat = mat * numpy.matrix((
+ (xx, yx, 0., 0.),
+ (xy, yy, 0., 0.),
+ (0., 0., 1., 0.),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+ self._transformedDataY2ProjMat = mat
+
+ return self._transformedDataY2ProjMat
+
+ def dataToPixel(self, x, y, axis='left'):
+ """Convert data coordinate to widget pixel coordinate.
+ """
+ assert axis in ('left', 'right')
+
+ trBounds = self.transformedDataRanges
+
+ if self.xAxis.isLog:
+ if x < FLOAT32_MINPOS:
+ return None
+ xDataTr = math.log10(x)
+ else:
+ xDataTr = x
+
+ if self.yAxis.isLog:
+ if y < FLOAT32_MINPOS:
+ return None
+ yDataTr = math.log10(y)
+ else:
+ yDataTr = y
+
+ # Non-orthogonal axes
+ if self.baseVectors != self.DEFAULT_BASE_VECTORS:
+ (xx, xy), (yx, yy) = self.baseVectors
+ skew_mat = numpy.array(((xx, yx), (xy, yy)))
+
+ coords = numpy.dot(skew_mat, numpy.array((xDataTr, yDataTr)))
+ xDataTr, yDataTr = coords
+
+ plotWidth, plotHeight = self.plotSize
+
+ xPixel = int(self.margins.left +
+ plotWidth * (xDataTr - trBounds.x[0]) /
+ (trBounds.x[1] - trBounds.x[0]))
+
+ usedAxis = trBounds.y if axis == "left" else trBounds.y2
+ yOffset = (plotHeight * (yDataTr - usedAxis[0]) /
+ (usedAxis[1] - usedAxis[0]))
+
+ if self.isYAxisInverted:
+ yPixel = int(self.margins.top + yOffset)
+ else:
+ yPixel = int(self.size[1] - self.margins.bottom - yOffset)
+
+ return xPixel, yPixel
+
+ def pixelToData(self, x, y, axis="left"):
+ """Convert pixel position to data coordinates.
+
+ :param float x: X coord
+ :param float y: Y coord
+ :param str axis: Y axis to use in ('left', 'right')
+ :return: (x, y) position in data coords
+ """
+ assert axis in ("left", "right")
+
+ plotWidth, plotHeight = self.plotSize
+
+ trBounds = self.transformedDataRanges
+
+ xData = (x - self.margins.left + 0.5) / float(plotWidth)
+ xData = trBounds.x[0] + xData * (trBounds.x[1] - trBounds.x[0])
+
+ usedAxis = trBounds.y if axis == "left" else trBounds.y2
+ if self.isYAxisInverted:
+ yData = (y - self.margins.top + 0.5) / float(plotHeight)
+ yData = usedAxis[0] + yData * (usedAxis[1] - usedAxis[0])
+ else:
+ yData = self.size[1] - self.margins.bottom - y - 0.5
+ yData /= float(plotHeight)
+ yData = usedAxis[0] + yData * (usedAxis[1] - usedAxis[0])
+
+ # non-orthogonal axis
+ if self.baseVectors != self.DEFAULT_BASE_VECTORS:
+ (xx, xy), (yx, yy) = self.baseVectors
+ skew_mat = numpy.array(((xx, yx), (xy, yy)))
+ skew_mat = numpy.linalg.inv(skew_mat)
+
+ coords = numpy.dot(skew_mat, numpy.array((xData, yData)))
+ xData, yData = coords
+
+ if self.xAxis.isLog:
+ xData = pow(10, xData)
+ if self.yAxis.isLog:
+ yData = pow(10, yData)
+
+ return xData, yData
+
+ def _buildGridVerticesWithTest(self, test):
+ vertices = []
+
+ if self.baseVectors == self.DEFAULT_BASE_VECTORS:
+ for axis in self.axes:
+ for (xPixel, yPixel), data, text in axis.ticks:
+ if test(text):
+ vertices.append((xPixel, yPixel))
+ if axis == self.xAxis:
+ vertices.append((xPixel, self.margins.top))
+ elif axis == self.yAxis:
+ vertices.append((self.size[0] - self.margins.right,
+ yPixel))
+ else: # axis == self.y2Axis
+ vertices.append((self.margins.left, yPixel))
+
+ else:
+ # Get plot corners in data coords
+ plotLeft, plotTop = self.plotOrigin
+ plotWidth, plotHeight = self.plotSize
+
+ corners = [(plotLeft, plotTop),
+ (plotLeft, plotTop + plotHeight),
+ (plotLeft + plotWidth, plotTop + plotHeight),
+ (plotLeft + plotWidth, plotTop)]
+
+ for axis in self.axes:
+ if axis == self.xAxis:
+ cornersInData = numpy.array([
+ self.pixelToData(x, y) for (x, y) in corners])
+ borders = ((cornersInData[0], cornersInData[3]), # top
+ (cornersInData[1], cornersInData[0]), # left
+ (cornersInData[3], cornersInData[2])) # right
+
+ for (xPixel, yPixel), data, text in axis.ticks:
+ if test(text):
+ for (x0, y0), (x1, y1) in borders:
+ if min(x0, x1) <= data < max(x0, x1):
+ yIntersect = (data - x0) * \
+ (y1 - y0) / (x1 - x0) + y0
+
+ pixelPos = self.dataToPixel(
+ data, yIntersect)
+ if pixelPos is not None:
+ vertices.append((xPixel, yPixel))
+ vertices.append(pixelPos)
+ break # Stop at first intersection
+
+ else: # y or y2 axes
+ if axis == self.yAxis:
+ axis_name = 'left'
+ cornersInData = numpy.array([
+ self.pixelToData(x, y) for (x, y) in corners])
+ borders = (
+ (cornersInData[3], cornersInData[2]), # right
+ (cornersInData[0], cornersInData[3]), # top
+ (cornersInData[2], cornersInData[1])) # bottom
+
+ else: # axis == self.y2Axis
+ axis_name = 'right'
+ corners = numpy.array([self.pixelToData(
+ x, y, axis='right') for (x, y) in corners])
+ borders = (
+ (cornersInData[1], cornersInData[0]), # left
+ (cornersInData[0], cornersInData[3]), # top
+ (cornersInData[2], cornersInData[1])) # bottom
+
+ for (xPixel, yPixel), data, text in axis.ticks:
+ if test(text):
+ for (x0, y0), (x1, y1) in borders:
+ if min(y0, y1) <= data < max(y0, y1):
+ xIntersect = (data - y0) * \
+ (x1 - x0) / (y1 - y0) + x0
+
+ pixelPos = self.dataToPixel(
+ xIntersect, data, axis=axis_name)
+ if pixelPos is not None:
+ vertices.append((xPixel, yPixel))
+ vertices.append(pixelPos)
+ break # Stop at first intersection
+
+ return vertices
+
+ def _buildVerticesAndLabels(self):
+ width, height = self.size
+
+ xCoords = (self.margins.left - 0.5,
+ width - self.margins.right + 0.5)
+ yCoords = (height - self.margins.bottom + 0.5,
+ self.margins.top - 0.5)
+
+ self.axes[0].displayCoords = ((xCoords[0], yCoords[0]),
+ (xCoords[1], yCoords[0]))
+
+ self._x2AxisCoords = ((xCoords[0], yCoords[1]),
+ (xCoords[1], yCoords[1]))
+
+ if self.isYAxisInverted:
+ # Y axes are inverted, axes coordinates are inverted
+ yCoords = yCoords[1], yCoords[0]
+
+ self.axes[1].displayCoords = ((xCoords[0], yCoords[0]),
+ (xCoords[0], yCoords[1]))
+
+ self._y2Axis.displayCoords = ((xCoords[1], yCoords[0]),
+ (xCoords[1], yCoords[1]))
+
+ super(GLPlotFrame2D, self)._buildVerticesAndLabels()
+
+ vertices, gridVertices, labels = self._renderResources
+
+ # Adds vertices for borders without axis
+ extraVertices = []
+ extraVertices += self._x2AxisCoords
+ if not self.isY2Axis:
+ extraVertices += self._y2Axis.displayCoords
+
+ extraVertices = numpy.array(
+ extraVertices, copy=False, dtype=numpy.float32)
+ vertices = numpy.append(vertices, extraVertices, axis=0)
+
+ self._renderResources = (vertices, gridVertices, labels)
diff --git a/silx/gui/plot/backends/glutils/GLPlotImage.py b/silx/gui/plot/backends/glutils/GLPlotImage.py
new file mode 100644
index 0000000..8fff82b
--- /dev/null
+++ b/silx/gui/plot/backends/glutils/GLPlotImage.py
@@ -0,0 +1,707 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ############################################################################*/
+"""
+This module provides a class to render 2D array as a colormap or RGB(A) image
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import math
+import numpy
+
+from silx.math.combo import min_max
+
+from ...._glutils import gl, Program, Texture
+from ..._utils import FLOAT32_MINPOS
+from .GLSupport import mat4Translate, mat4Scale
+from .GLTexture import Image
+
+
+class _GLPlotData2D(object):
+ def __init__(self, data, origin, scale):
+ self.data = data
+ assert len(origin) == 2
+ self.origin = tuple(origin)
+ assert len(scale) == 2
+ self.scale = tuple(scale)
+
+ def pick(self, x, y):
+ if self.xMin <= x <= self.xMax and self.yMin <= y <= self.yMax:
+ ox, oy = self.origin
+ sx, sy = self.scale
+ col = int((x - ox) / sx)
+ row = int((y - oy) / sy)
+ return col, row
+ else:
+ return None
+
+ @property
+ def xMin(self):
+ ox, sx = self.origin[0], self.scale[0]
+ return ox if sx >= 0. else ox + sx * self.data.shape[1]
+
+ @property
+ def yMin(self):
+ oy, sy = self.origin[1], self.scale[1]
+ return oy if sy >= 0. else oy + sy * self.data.shape[0]
+
+ @property
+ def xMax(self):
+ ox, sx = self.origin[0], self.scale[0]
+ return ox + sx * self.data.shape[1] if sx >= 0. else ox
+
+ @property
+ def yMax(self):
+ oy, sy = self.origin[1], self.scale[1]
+ return oy + sy * self.data.shape[0] if sy >= 0. else oy
+
+ def discard(self):
+ pass
+
+ def prepare(self):
+ pass
+
+ def render(self, matrix, isXLog, isYLog):
+ pass
+
+
+class GLPlotColormap(_GLPlotData2D):
+
+ _SHADERS = {
+ 'linear': {
+ 'vertex': """
+ #version 120
+
+ uniform mat4 matrix;
+ attribute vec2 texCoords;
+ attribute vec2 position;
+
+ varying vec2 coords;
+
+ void main(void) {
+ coords = texCoords;
+ gl_Position = matrix * vec4(position, 0.0, 1.0);
+ }
+ """,
+ 'fragTransform': """
+ vec2 textureCoords(void) {
+ return coords;
+ }
+ """},
+
+ 'log': {
+ 'vertex': """
+ #version 120
+
+ attribute vec2 position;
+ uniform mat4 matrix;
+ uniform mat4 matOffset;
+ uniform bvec2 isLog;
+
+ varying vec2 coords;
+
+ const float oneOverLog10 = 0.43429448190325176;
+
+ void main(void) {
+ vec4 dataPos = matOffset * vec4(position, 0.0, 1.0);
+ if (isLog.x) {
+ dataPos.x = oneOverLog10 * log(dataPos.x);
+ }
+ if (isLog.y) {
+ dataPos.y = oneOverLog10 * log(dataPos.y);
+ }
+ coords = dataPos.xy;
+ gl_Position = matrix * dataPos;
+ }
+ """,
+ 'fragTransform': """
+ uniform bvec2 isLog;
+ uniform struct {
+ vec2 oneOverRange;
+ vec2 originOverRange;
+ } bounds;
+
+ vec2 textureCoords(void) {
+ vec2 pos = coords;
+ if (isLog.x) {
+ pos.x = pow(10., coords.x);
+ }
+ if (isLog.y) {
+ pos.y = pow(10., coords.y);
+ }
+ return pos * bounds.oneOverRange - bounds.originOverRange;
+ // TODO texture coords in range different from [0, 1]
+ }
+ """},
+
+ 'fragment': """
+ #version 120
+
+ uniform sampler2D data;
+ uniform struct {
+ sampler2D texture;
+ bool isLog;
+ float min;
+ float oneOverRange;
+ } cmap;
+ uniform float alpha;
+
+ varying vec2 coords;
+
+ %s
+
+ const float oneOverLog10 = 0.43429448190325176;
+
+ void main(void) {
+ float value = texture2D(data, textureCoords()).r;
+ if (cmap.isLog) {
+ if (value > 0.) {
+ value = clamp(cmap.oneOverRange *
+ (oneOverLog10 * log(value) - cmap.min),
+ 0., 1.);
+ } else {
+ value = 0.;
+ }
+ } else { /*Linear mapping*/
+ value = clamp(cmap.oneOverRange * (value - cmap.min), 0., 1.);
+ }
+
+ gl_FragColor = texture2D(cmap.texture, vec2(value, 0.5));
+ gl_FragColor.a *= alpha;
+ }
+ """
+ }
+
+ _DATA_TEX_UNIT = 0
+ _CMAP_TEX_UNIT = 1
+
+ _INTERNAL_FORMATS = {
+ numpy.dtype(numpy.float32): gl.GL_R32F,
+ # Use normalized integer for unsigned int formats
+ numpy.dtype(numpy.uint16): gl.GL_R16,
+ numpy.dtype(numpy.uint8): gl.GL_R8,
+ }
+
+ _linearProgram = Program(_SHADERS['linear']['vertex'],
+ _SHADERS['fragment'] %
+ _SHADERS['linear']['fragTransform'],
+ attrib0='position')
+
+ _logProgram = Program(_SHADERS['log']['vertex'],
+ _SHADERS['fragment'] %
+ _SHADERS['log']['fragTransform'],
+ attrib0='position')
+
+ def __init__(self, data, origin, scale,
+ colormap, cmapIsLog=False, cmapRange=None,
+ alpha=1.0):
+ """Create a 2D colormap
+
+ :param data: The 2D scalar data array to display
+ :type data: numpy.ndarray with 2 dimensions (dtype=numpy.float32)
+ :param origin: (x, y) coordinates of the origin of the data array
+ :type origin: 2-tuple of floats.
+ :param scale: (sx, sy) scale factors of the data array.
+ This is the size of a data pixel in plot data space.
+ :type scale: 2-tuple of floats.
+ :param str colormap: Name of the colormap to use
+ TODO: Accept a 1D scalar array as the colormap
+ :param bool cmapIsLog: If True, uses log10 of the data value
+ :param cmapRange: The range of colormap or None for autoscale colormap
+ For logarithmic colormap, the range is in the untransformed data
+ TODO: check consistency with matplotlib
+ :type cmapRange: (float, float) or None
+ :param float alpha: Opacity from 0 (transparent) to 1 (opaque)
+ """
+ assert data.dtype in self._INTERNAL_FORMATS
+
+ super(GLPlotColormap, self).__init__(data, origin, scale)
+ self.colormap = numpy.array(colormap, copy=False)
+ self.cmapIsLog = cmapIsLog
+ self._cmapRange = None # User-provided range info
+ self._cmapRangeCache = None # Store extra data for range
+ self.cmapRange = cmapRange # Update _cmapRange
+ self._alpha = numpy.clip(alpha, 0., 1.)
+
+ self._cmap_texture = None
+ self._texture = None
+ self._textureIsDirty = False
+
+ def discard(self):
+ if self._cmap_texture is not None:
+ self._cmap_texture.discard()
+ self._cmap_texture = None
+
+ if self._texture is not None:
+ self._texture.discard()
+ self._texture = None
+ self._textureIsDirty = False
+
+ @property
+ def cmapRange(self):
+ if self._cmapRange is None: # Auto-scale mode
+ if self._cmapRangeCache is None:
+ # Build data , positive ranges
+ result = min_max(self.data, min_positive=True)
+ min_ = result.minimum
+ minPos = result.min_positive
+ max_ = result.maximum
+ maxPos = max_ if max_ > 0. else 1.
+ if minPos is None:
+ minPos = maxPos
+ self._cmapRangeCache = {'range': (min_, max_),
+ 'pos': (minPos, maxPos)}
+
+ return self._cmapRangeCache['pos' if self.cmapIsLog else 'range']
+
+ else:
+ if not self.cmapIsLog:
+ return self._cmapRange # Return range as is
+ else:
+ if self._cmapRangeCache is None:
+ # Build a strictly positive range from cmapRange
+ min_, max_ = self._cmapRange
+ if min_ > 0. and max_ > 0.:
+ minPos, maxPos = min_, max_
+ else:
+ result = min_max(self.data, min_positive=True)
+ minPos = result.min_positive
+ dataMax = result.maximum
+ if max_ > 0.:
+ maxPos = max_
+ elif dataMax > 0.:
+ maxPos = dataMax
+ else:
+ maxPos = 1. # Arbitrary fallback
+ if minPos is None:
+ minPos = maxPos
+ self._cmapRangeCache = minPos, maxPos
+ return self._cmapRangeCache # Strictly positive range
+
+ @cmapRange.setter
+ def cmapRange(self, cmapRange):
+ self._cmapRangeCache = None
+ if cmapRange is None:
+ self._cmapRange = None
+ else:
+ assert len(cmapRange) == 2
+ assert cmapRange[0] <= cmapRange[1]
+ self._cmapRange = tuple(cmapRange)
+
+ @property
+ def alpha(self):
+ return self._alpha
+
+ def updateData(self, data):
+ assert data.dtype in self._INTERNAL_FORMATS
+ oldData = self.data
+ self.data = data
+
+ self._cmapRangeCache = None
+
+ if self._texture is not None:
+ if (self.data.shape != oldData.shape or
+ self.data.dtype != oldData.dtype):
+ self.discard()
+ else:
+ self._textureIsDirty = True
+
+ def prepare(self):
+ if self._cmap_texture is None:
+ # TODO share cmap texture accross Images
+ # put all cmaps in one texture
+ colormap = numpy.empty((16, 256, self.colormap.shape[1]),
+ dtype=self.colormap.dtype)
+ colormap[:] = self.colormap
+ format_ = gl.GL_RGBA if colormap.shape[-1] == 4 else gl.GL_RGB
+ self._cmap_texture = Texture(internalFormat=format_,
+ data=colormap,
+ format_=format_,
+ texUnit=self._CMAP_TEX_UNIT,
+ minFilter=gl.GL_NEAREST,
+ magFilter=gl.GL_NEAREST,
+ wrap=(gl.GL_CLAMP_TO_EDGE,
+ gl.GL_CLAMP_TO_EDGE))
+
+ if self._texture is None:
+ internalFormat = self._INTERNAL_FORMATS[self.data.dtype]
+
+ self._texture = Image(internalFormat,
+ self.data,
+ format_=gl.GL_RED,
+ texUnit=self._DATA_TEX_UNIT)
+ elif self._textureIsDirty:
+ self._textureIsDirty = True
+ self._texture.updateAll(format_=gl.GL_RED, data=self.data)
+
+ def _setCMap(self, prog):
+ dataMin, dataMax = self.cmapRange # If log, it is stricly positive
+
+ if self.data.dtype in (numpy.uint16, numpy.uint8):
+ # Using unsigned int as normalized integer in OpenGL
+ # So normalize range
+ maxInt = float(numpy.iinfo(self.data.dtype).max)
+ dataMin, dataMax = dataMin / maxInt, dataMax / maxInt
+
+ if self.cmapIsLog:
+ dataMin = math.log10(dataMin)
+ dataMax = math.log10(dataMax)
+
+ gl.glUniform1i(prog.uniforms['cmap.texture'],
+ self._cmap_texture.texUnit)
+ gl.glUniform1i(prog.uniforms['cmap.isLog'], self.cmapIsLog)
+ gl.glUniform1f(prog.uniforms['cmap.min'], dataMin)
+ if dataMax > dataMin:
+ oneOverRange = 1. / (dataMax - dataMin)
+ else:
+ oneOverRange = 0. # Fall-back
+ gl.glUniform1f(prog.uniforms['cmap.oneOverRange'], oneOverRange)
+
+ self._cmap_texture.bind()
+
+ def _renderLinear(self, matrix):
+ self.prepare()
+
+ prog = self._linearProgram
+ prog.use()
+
+ gl.glUniform1i(prog.uniforms['data'], self._DATA_TEX_UNIT)
+
+ mat = matrix * mat4Translate(*self.origin) * mat4Scale(*self.scale)
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, mat)
+
+ gl.glUniform1f(prog.uniforms['alpha'], self.alpha)
+
+ self._setCMap(prog)
+
+ self._texture.render(prog.attributes['position'],
+ prog.attributes['texCoords'],
+ self._DATA_TEX_UNIT)
+
+ def _renderLog10(self, matrix, isXLog, isYLog):
+ xMin, yMin = self.xMin, self.yMin
+ if ((isXLog and xMin < FLOAT32_MINPOS) or
+ (isYLog and yMin < FLOAT32_MINPOS)):
+ # Do not render images that are partly or totally <= 0
+ return
+
+ self.prepare()
+
+ prog = self._logProgram
+ prog.use()
+
+ ox, oy = self.origin
+
+ gl.glUniform1i(prog.uniforms['data'], self._DATA_TEX_UNIT)
+
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, matrix)
+ mat = mat4Translate(ox, oy) * mat4Scale(*self.scale)
+ gl.glUniformMatrix4fv(prog.uniforms['matOffset'], 1, gl.GL_TRUE, mat)
+
+ gl.glUniform2i(prog.uniforms['isLog'], isXLog, isYLog)
+
+ ex = ox + self.scale[0] * self.data.shape[1]
+ ey = oy + self.scale[1] * self.data.shape[0]
+
+ xOneOverRange = 1. / (ex - ox)
+ yOneOverRange = 1. / (ey - oy)
+ gl.glUniform2f(prog.uniforms['bounds.originOverRange'],
+ ox * xOneOverRange, oy * yOneOverRange)
+ gl.glUniform2f(prog.uniforms['bounds.oneOverRange'],
+ xOneOverRange, yOneOverRange)
+
+ gl.glUniform1f(prog.uniforms['alpha'], self.alpha)
+
+ self._setCMap(prog)
+
+ try:
+ tiles = self._texture.tiles
+ except AttributeError:
+ raise RuntimeError("No texture, discard has already been called")
+ if len(tiles) > 1:
+ raise NotImplementedError(
+ "Image over multiple textures not supported with log scale")
+
+ texture, vertices, info = tiles[0]
+
+ texture.bind(self._DATA_TEX_UNIT)
+
+ posAttrib = prog.attributes['position']
+ stride = vertices.shape[-1] * vertices.itemsize
+ gl.glEnableVertexAttribArray(posAttrib)
+ gl.glVertexAttribPointer(posAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ stride, vertices)
+
+ gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, len(vertices))
+
+ def render(self, matrix, isXLog, isYLog):
+ if any((isXLog, isYLog)):
+ self._renderLog10(matrix, isXLog, isYLog)
+ else:
+ self._renderLinear(matrix)
+
+ # Unbind colormap texture
+ gl.glActiveTexture(gl.GL_TEXTURE0 + self._cmap_texture.texUnit)
+ gl.glBindTexture(self._cmap_texture.target, 0)
+
+
+# image #######################################################################
+
+class GLPlotRGBAImage(_GLPlotData2D):
+
+ _SHADERS = {
+ 'linear': {
+ 'vertex': """
+ #version 120
+
+ attribute vec2 position;
+ attribute vec2 texCoords;
+ uniform mat4 matrix;
+
+ varying vec2 coords;
+
+ void main(void) {
+ gl_Position = matrix * vec4(position, 0.0, 1.0);
+ coords = texCoords;
+ }
+ """,
+ 'fragment': """
+ #version 120
+
+ uniform sampler2D tex;
+ uniform float alpha;
+
+ varying vec2 coords;
+
+ void main(void) {
+ gl_FragColor = texture2D(tex, coords);
+ gl_FragColor.a *= alpha;
+ }
+ """},
+
+ 'log': {
+ 'vertex': """
+ #version 120
+
+ attribute vec2 position;
+ uniform mat4 matrix;
+ uniform mat4 matOffset;
+ uniform bvec2 isLog;
+
+ varying vec2 coords;
+
+ const float oneOverLog10 = 0.43429448190325176;
+
+ void main(void) {
+ vec4 dataPos = matOffset * vec4(position, 0.0, 1.0);
+ if (isLog.x) {
+ dataPos.x = oneOverLog10 * log(dataPos.x);
+ }
+ if (isLog.y) {
+ dataPos.y = oneOverLog10 * log(dataPos.y);
+ }
+ coords = dataPos.xy;
+ gl_Position = matrix * dataPos;
+ }
+ """,
+ 'fragment': """
+ #version 120
+
+ uniform sampler2D tex;
+ uniform bvec2 isLog;
+ uniform struct {
+ vec2 oneOverRange;
+ vec2 originOverRange;
+ } bounds;
+ uniform float alpha;
+
+ varying vec2 coords;
+
+ vec2 textureCoords(void) {
+ vec2 pos = coords;
+ if (isLog.x) {
+ pos.x = pow(10., coords.x);
+ }
+ if (isLog.y) {
+ pos.y = pow(10., coords.y);
+ }
+ return pos * bounds.oneOverRange - bounds.originOverRange;
+ // TODO texture coords in range different from [0, 1]
+ }
+
+ void main(void) {
+ gl_FragColor = texture2D(tex, textureCoords());
+ gl_FragColor.a *= alpha;
+ }
+ """}
+ }
+
+ _DATA_TEX_UNIT = 0
+
+ _SUPPORTED_DTYPES = (numpy.dtype(numpy.float32),
+ numpy.dtype(numpy.uint8))
+
+ _linearProgram = Program(_SHADERS['linear']['vertex'],
+ _SHADERS['linear']['fragment'],
+ attrib0='position')
+
+ _logProgram = Program(_SHADERS['log']['vertex'],
+ _SHADERS['log']['fragment'],
+ attrib0='position')
+
+ def __init__(self, data, origin, scale, alpha):
+ """Create a 2D RGB(A) image from data
+
+ :param data: The 2D image data array to display
+ :type data: numpy.ndarray with 3 dimensions
+ (dtype=numpy.uint8 or numpy.float32)
+ :param origin: (x, y) coordinates of the origin of the data array
+ :type origin: 2-tuple of floats.
+ :param scale: (sx, sy) scale factors of the data array.
+ This is the size of a data pixel in plot data space.
+ :type scale: 2-tuple of floats.
+ :param float alpha: Opacity from 0 (transparent) to 1 (opaque)
+ """
+ assert data.dtype in self._SUPPORTED_DTYPES
+ super(GLPlotRGBAImage, self).__init__(data, origin, scale)
+ self._texture = None
+ self._textureIsDirty = False
+ self._alpha = numpy.clip(alpha, 0., 1.)
+
+ @property
+ def alpha(self):
+ return self._alpha
+
+ def discard(self):
+ if self._texture is not None:
+ self._texture.discard()
+ self._texture = None
+ self._textureIsDirty = False
+
+ def updateData(self, data):
+ assert data.dtype in self._SUPPORTED_DTYPES
+ oldData = self.data
+ self.data = data
+
+ if self._texture is not None:
+ if self.data.shape != oldData.shape:
+ self.discard()
+ else:
+ self._textureIsDirty = True
+
+ def prepare(self):
+ if self._texture is None:
+ format_ = gl.GL_RGBA if self.data.shape[2] == 4 else gl.GL_RGB
+
+ self._texture = Image(format_,
+ self.data,
+ format_=format_,
+ texUnit=self._DATA_TEX_UNIT)
+ elif self._textureIsDirty:
+ self._textureIsDirty = False
+
+ # We should check that internal format is the same
+ format_ = gl.GL_RGBA if self.data.shape[2] == 4 else gl.GL_RGB
+ self._texture.updateAll(format_=format_, data=self.data)
+
+ def _renderLinear(self, matrix):
+ self.prepare()
+
+ prog = self._linearProgram
+ prog.use()
+
+ gl.glUniform1i(prog.uniforms['tex'], self._DATA_TEX_UNIT)
+
+ mat = matrix * mat4Translate(*self.origin) * mat4Scale(*self.scale)
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, mat)
+
+ gl.glUniform1f(prog.uniforms['alpha'], self.alpha)
+
+ self._texture.render(prog.attributes['position'],
+ prog.attributes['texCoords'],
+ self._DATA_TEX_UNIT)
+
+ def _renderLog(self, matrix, isXLog, isYLog):
+ self.prepare()
+
+ prog = self._logProgram
+ prog.use()
+
+ ox, oy = self.origin
+
+ gl.glUniform1i(prog.uniforms['tex'], self._DATA_TEX_UNIT)
+
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE, matrix)
+ mat = mat4Translate(ox, oy) * mat4Scale(*self.scale)
+ gl.glUniformMatrix4fv(prog.uniforms['matOffset'], 1, gl.GL_TRUE, mat)
+
+ gl.glUniform2i(prog.uniforms['isLog'], isXLog, isYLog)
+
+ gl.glUniform1f(prog.uniforms['alpha'], self.alpha)
+
+ ex = ox + self.scale[0] * self.data.shape[1]
+ ey = oy + self.scale[1] * self.data.shape[0]
+
+ xOneOverRange = 1. / (ex - ox)
+ yOneOverRange = 1. / (ey - oy)
+ gl.glUniform2f(prog.uniforms['bounds.originOverRange'],
+ ox * xOneOverRange, oy * yOneOverRange)
+ gl.glUniform2f(prog.uniforms['bounds.oneOverRange'],
+ xOneOverRange, yOneOverRange)
+
+ try:
+ tiles = self._texture.tiles
+ except AttributeError:
+ raise RuntimeError("No texture, discard has already been called")
+ if len(tiles) > 1:
+ raise NotImplementedError(
+ "Image over multiple textures not supported with log scale")
+
+ texture, vertices, info = tiles[0]
+
+ texture.bind(self._DATA_TEX_UNIT)
+
+ posAttrib = prog.attributes['position']
+ stride = vertices.shape[-1] * vertices.itemsize
+ gl.glEnableVertexAttribArray(posAttrib)
+ gl.glVertexAttribPointer(posAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ stride, vertices)
+
+ gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, len(vertices))
+
+ def render(self, matrix, isXLog, isYLog):
+ if any((isXLog, isYLog)):
+ self._renderLog(matrix, isXLog, isYLog)
+ else:
+ self._renderLinear(matrix)
diff --git a/silx/gui/plot/backends/glutils/GLSupport.py b/silx/gui/plot/backends/glutils/GLSupport.py
new file mode 100644
index 0000000..3f473be
--- /dev/null
+++ b/silx/gui/plot/backends/glutils/GLSupport.py
@@ -0,0 +1,192 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ############################################################################*/
+"""
+This module provides convenient classes and functions for OpenGL rendering.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import numpy
+
+from ...._glutils import gl
+
+
+def buildFillMaskIndices(nIndices):
+ if nIndices <= numpy.iinfo(numpy.uint16).max + 1:
+ dtype = numpy.uint16
+ else:
+ dtype = numpy.uint32
+
+ lastIndex = nIndices - 1
+ splitIndex = lastIndex // 2 + 1
+ indices = numpy.empty(nIndices, dtype=dtype)
+ indices[::2] = numpy.arange(0, splitIndex, step=1, dtype=dtype)
+ indices[1::2] = numpy.arange(lastIndex, splitIndex - 1, step=-1,
+ dtype=dtype)
+ return indices
+
+
+class Shape2D(object):
+ _NO_HATCH = 0
+ _HATCH_STEP = 20
+
+ def __init__(self, points, fill='solid', stroke=True,
+ fillColor=(0., 0., 0., 1.), strokeColor=(0., 0., 0., 1.),
+ strokeClosed=True):
+ self.vertices = numpy.array(points, dtype=numpy.float32, copy=False)
+ self.strokeClosed = strokeClosed
+
+ self._indices = buildFillMaskIndices(len(self.vertices))
+
+ tVertex = numpy.transpose(self.vertices)
+ xMin, xMax = min(tVertex[0]), max(tVertex[0])
+ yMin, yMax = min(tVertex[1]), max(tVertex[1])
+ self.bboxVertices = numpy.array(((xMin, yMin), (xMin, yMax),
+ (xMax, yMin), (xMax, yMax)),
+ dtype=numpy.float32)
+ self._xMin, self._xMax = xMin, xMax
+ self._yMin, self._yMax = yMin, yMax
+
+ self.fill = fill
+ self.fillColor = fillColor
+ self.stroke = stroke
+ self.strokeColor = strokeColor
+
+ @property
+ def xMin(self):
+ return self._xMin
+
+ @property
+ def xMax(self):
+ return self._xMax
+
+ @property
+ def yMin(self):
+ return self._yMin
+
+ @property
+ def yMax(self):
+ return self._yMax
+
+ def prepareFillMask(self, posAttrib):
+ gl.glEnableVertexAttribArray(posAttrib)
+ gl.glVertexAttribPointer(posAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0, self.vertices)
+
+ gl.glEnable(gl.GL_STENCIL_TEST)
+ gl.glStencilMask(1)
+ gl.glStencilFunc(gl.GL_ALWAYS, 1, 1)
+ gl.glStencilOp(gl.GL_INVERT, gl.GL_INVERT, gl.GL_INVERT)
+ gl.glColorMask(gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE)
+ gl.glDepthMask(gl.GL_FALSE)
+
+ gl.glDrawElements(gl.GL_TRIANGLE_STRIP, len(self._indices),
+ gl.GL_UNSIGNED_SHORT, self._indices)
+
+ gl.glStencilFunc(gl.GL_EQUAL, 1, 1)
+ # Reset stencil while drawing
+ gl.glStencilOp(gl.GL_ZERO, gl.GL_ZERO, gl.GL_ZERO)
+ gl.glColorMask(gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE)
+ gl.glDepthMask(gl.GL_TRUE)
+
+ def renderFill(self, posAttrib):
+ self.prepareFillMask(posAttrib)
+
+ gl.glVertexAttribPointer(posAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0, self.bboxVertices)
+ gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, len(self.bboxVertices))
+
+ gl.glDisable(gl.GL_STENCIL_TEST)
+
+ def renderStroke(self, posAttrib):
+ gl.glEnableVertexAttribArray(posAttrib)
+ gl.glVertexAttribPointer(posAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0, self.vertices)
+ gl.glLineWidth(1)
+ drawMode = gl.GL_LINE_LOOP if self.strokeClosed else gl.GL_LINE_STRIP
+ gl.glDrawArrays(drawMode, 0, len(self.vertices))
+
+ def render(self, posAttrib, colorUnif, hatchStepUnif):
+ assert self.fill in ['hatch', 'solid', None]
+ if self.fill is not None:
+ gl.glUniform4f(colorUnif, *self.fillColor)
+ step = self._HATCH_STEP if self.fill == 'hatch' else self._NO_HATCH
+ gl.glUniform1i(hatchStepUnif, step)
+ self.renderFill(posAttrib)
+
+ if self.stroke:
+ gl.glUniform4f(colorUnif, *self.strokeColor)
+ gl.glUniform1i(hatchStepUnif, self._NO_HATCH)
+ self.renderStroke(posAttrib)
+
+
+# matrix ######################################################################
+
+def mat4Ortho(left, right, bottom, top, near, far):
+ """Orthographic projection matrix (row-major)"""
+ return numpy.matrix((
+ (2./(right - left), 0., 0., -(right+left)/float(right-left)),
+ (0., 2./(top - bottom), 0., -(top+bottom)/float(top-bottom)),
+ (0., 0., -2./(far-near), -(far+near)/float(far-near)),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+
+def mat4Translate(x=0., y=0., z=0.):
+ """Translation matrix (row-major)"""
+ return numpy.matrix((
+ (1., 0., 0., x),
+ (0., 1., 0., y),
+ (0., 0., 1., z),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+
+def mat4Scale(sx=1., sy=1., sz=1.):
+ """Scale matrix (row-major)"""
+ return numpy.matrix((
+ (sx, 0., 0., 0.),
+ (0., sy, 0., 0.),
+ (0., 0., sz, 0.),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+
+def mat4Identity():
+ """Identity matrix"""
+ return numpy.matrix((
+ (1., 0., 0., 0.),
+ (0., 1., 0., 0.),
+ (0., 0., 1., 0.),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
diff --git a/silx/gui/plot/backends/glutils/GLText.py b/silx/gui/plot/backends/glutils/GLText.py
new file mode 100644
index 0000000..495882c
--- /dev/null
+++ b/silx/gui/plot/backends/glutils/GLText.py
@@ -0,0 +1,222 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ############################################################################*/
+"""
+This module provides minimalistic text support for OpenGL.
+It provides Latin-1 (ISO8859-1) characters for one monospace font at one size.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import numpy
+
+from ...._glutils import font, gl, getGLContext, Program, Texture
+from .GLSupport import mat4Translate
+
+
+# TODO: Font should be configurable by the main program: using mpl.rcParams?
+
+
+# Text2D ######################################################################
+
+LEFT, CENTER, RIGHT = 'left', 'center', 'right'
+TOP, BASELINE, BOTTOM = 'top', 'baseline', 'bottom'
+ROTATE_90, ROTATE_180, ROTATE_270 = 90, 180, 270
+
+
+class Text2D(object):
+
+ _SHADERS = {
+ 'vertex': """
+ #version 120
+
+ attribute vec2 position;
+ attribute vec2 texCoords;
+ uniform mat4 matrix;
+
+ varying vec2 vCoords;
+
+ void main(void) {
+ gl_Position = matrix * vec4(position, 0.0, 1.0);
+ vCoords = texCoords;
+ }
+ """,
+ 'fragment': """
+ #version 120
+
+ uniform sampler2D texText;
+ uniform vec4 color;
+ uniform vec4 bgColor;
+
+ varying vec2 vCoords;
+
+ void main(void) {
+ gl_FragColor = mix(bgColor, color, texture2D(texText, vCoords).r);
+ }
+ """
+ }
+
+ _TEX_COORDS = numpy.array(((0., 0.), (1., 0.), (0., 1.), (1., 1.)),
+ dtype=numpy.float32).ravel()
+
+ _program = Program(_SHADERS['vertex'],
+ _SHADERS['fragment'],
+ attrib0='position')
+
+ _textures = {}
+
+ _rasterTextCache = {}
+ """Internal cache storing already rasterized text"""
+ # TODO limit cache size and discard least recent used
+
+ def __init__(self, text, x=0, y=0,
+ color=(0., 0., 0., 1.),
+ bgColor=None,
+ align=LEFT, valign=BASELINE,
+ rotate=0):
+ self._vertices = None
+ self._text = text
+ self.x = x
+ self.y = y
+ self.color = color
+ self.bgColor = bgColor
+
+ if align not in (LEFT, CENTER, RIGHT):
+ raise ValueError(
+ "Horizontal alignment not supported: {0}".format(align))
+ self._align = align
+
+ if valign not in (TOP, CENTER, BASELINE, BOTTOM):
+ raise ValueError(
+ "Vertical alignment not supported: {0}".format(valign))
+ self._valign = valign
+
+ self._rotate = numpy.radians(rotate)
+
+ @classmethod
+ def _getTexture(cls, text):
+ key = getGLContext(), text
+ if key not in cls._textures:
+ image, offset = font.rasterText(text,
+ font.getDefaultFontFamily())
+ cls._textures[key] = (Texture(gl.GL_RED,
+ data=image,
+ minFilter=gl.GL_NEAREST,
+ magFilter=gl.GL_NEAREST,
+ wrap=(gl.GL_CLAMP_TO_EDGE,
+ gl.GL_CLAMP_TO_EDGE)),
+ offset)
+
+ return cls._textures[key]
+
+ @property
+ def text(self):
+ return self._text
+
+ @property
+ def size(self): # TODO very poor implementation
+ image, offset = font.rasterText(self.text,
+ font.getDefaultFontFamily())
+ return image.shape[1], image.shape[0]
+
+ def getVertices(self, offset, shape):
+ height, width = shape
+
+ if self._align == LEFT:
+ xOrig = 0
+ elif self._align == RIGHT:
+ xOrig = - width
+ else: # CENTER
+ xOrig = - width // 2
+
+ if self._valign == BASELINE:
+ yOrig = - offset
+ elif self._valign == TOP:
+ yOrig = 0
+ elif self._valign == BOTTOM:
+ yOrig = - height
+ else: # CENTER
+ yOrig = - height // 2
+
+ vertices = numpy.array((
+ (xOrig, yOrig),
+ (xOrig + width, yOrig),
+ (xOrig, yOrig + height),
+ (xOrig + width, yOrig + height)), dtype=numpy.float32)
+
+ cos, sin = numpy.cos(self._rotate), numpy.sin(self._rotate)
+ vertices = numpy.ascontiguousarray(numpy.transpose(numpy.array((
+ cos * vertices[:, 0] - sin * vertices[:, 1],
+ sin * vertices[:, 0] + cos * vertices[:, 1]),
+ dtype=numpy.float32)))
+
+ return vertices
+
+ def render(self, matrix):
+ if not self.text:
+ return
+
+ prog = self._program
+ prog.use()
+
+ texUnit = 0
+ texture, offset = self._getTexture(self.text)
+
+ gl.glUniform1i(prog.uniforms['texText'], texUnit)
+
+ gl.glUniformMatrix4fv(prog.uniforms['matrix'], 1, gl.GL_TRUE,
+ matrix * mat4Translate(int(self.x), int(self.y)))
+
+ gl.glUniform4f(prog.uniforms['color'], *self.color)
+ if self.bgColor is not None:
+ bgColor = self.bgColor
+ else:
+ bgColor = self.color[0], self.color[1], self.color[2], 0.
+ gl.glUniform4f(prog.uniforms['bgColor'], *bgColor)
+
+ vertices = self.getVertices(offset, texture.shape)
+
+ posAttrib = prog.attributes['position']
+ gl.glEnableVertexAttribArray(posAttrib)
+ gl.glVertexAttribPointer(posAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0,
+ vertices)
+
+ texAttrib = prog.attributes['texCoords']
+ gl.glEnableVertexAttribArray(texAttrib)
+ gl.glVertexAttribPointer(texAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0,
+ self._TEX_COORDS)
+
+ with texture:
+ gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4)
diff --git a/silx/gui/plot/backends/glutils/GLTexture.py b/silx/gui/plot/backends/glutils/GLTexture.py
new file mode 100644
index 0000000..25dd9f1
--- /dev/null
+++ b/silx/gui/plot/backends/glutils/GLTexture.py
@@ -0,0 +1,239 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ############################################################################*/
+"""This module provides classes wrapping OpenGL texture."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+from ctypes import c_void_p
+import logging
+
+import numpy
+
+from ...._glutils import gl, Texture, numpyToGLType
+
+
+_logger = logging.getLogger(__name__)
+
+
+def _checkTexture2D(internalFormat, shape,
+ format_=None, type_=gl.GL_FLOAT, border=0):
+ """Check if texture size with provided parameters is supported
+
+ :rtype: bool
+ """
+ height, width = shape
+ gl.glTexImage2D(gl.GL_PROXY_TEXTURE_2D, 0, internalFormat,
+ width, height, border,
+ format_ or internalFormat,
+ type_, c_void_p(0))
+ width = gl.glGetTexLevelParameteriv(
+ gl.GL_PROXY_TEXTURE_2D, 0, gl.GL_TEXTURE_WIDTH)
+ return bool(width)
+
+
+MIN_TEXTURE_SIZE = 64
+
+
+def _getMaxSquareTexture2DSize(internalFormat=gl.GL_RGBA,
+ format_=None,
+ type_=gl.GL_FLOAT,
+ border=0):
+ """Returns a supported size for a corresponding square texture
+
+ :returns: GL_MAX_TEXTURE_SIZE or a smaller supported size (not optimal)
+ :rtype: int
+ """
+ # Is this useful?
+ maxTexSize = gl.glGetIntegerv(gl.GL_MAX_TEXTURE_SIZE)
+ while maxTexSize > MIN_TEXTURE_SIZE and \
+ not _checkTexture2D(internalFormat, (maxTexSize, maxTexSize),
+ format_, type_, border):
+ maxTexSize //= 2
+ return max(MIN_TEXTURE_SIZE, maxTexSize)
+
+
+class Image(object):
+ """Image of any size eventually using multiple textures or larger texture
+ """
+
+ _WRAP = (gl.GL_CLAMP_TO_EDGE, gl.GL_CLAMP_TO_EDGE)
+ _MIN_FILTER = gl.GL_NEAREST
+ _MAG_FILTER = gl.GL_NEAREST
+
+ def __init__(self, internalFormat, data, format_=None, texUnit=0):
+ self.internalFormat = internalFormat
+ self.height, self.width = data.shape[0:2]
+ type_ = numpyToGLType(data.dtype)
+
+ if _checkTexture2D(internalFormat, data.shape[0:2], format_, type_):
+ texture = Texture(internalFormat,
+ data,
+ format_,
+ texUnit=texUnit,
+ minFilter=self._MIN_FILTER,
+ magFilter=self._MAG_FILTER,
+ wrap=self._WRAP)
+ vertices = numpy.array((
+ (0., 0., 0., 0.),
+ (self.width, 0., 1., 0.),
+ (0., self.height, 0., 1.),
+ (self.width, self.height, 1., 1.)), dtype=numpy.float32)
+ self.tiles = ((texture, vertices,
+ {'xOrigData': 0, 'yOrigData': 0,
+ 'wData': self.width, 'hData': self.height}),)
+
+ else:
+ # Handle dimension too large: make tiles
+ maxTexSize = _getMaxSquareTexture2DSize(internalFormat,
+ format_, type_)
+
+ nCols = (self.width+maxTexSize-1) // maxTexSize
+ colWidths = [self.width // nCols] * nCols
+ colWidths[-1] += self.width % nCols
+
+ nRows = (self.height+maxTexSize-1) // maxTexSize
+ rowHeights = [self.height//nRows] * nRows
+ rowHeights[-1] += self.height % nRows
+
+ tiles = []
+ yOrig = 0
+ for hData in rowHeights:
+ xOrig = 0
+ for wData in colWidths:
+ if (hData < MIN_TEXTURE_SIZE or wData < MIN_TEXTURE_SIZE) \
+ and not _checkTexture2D(internalFormat,
+ (hData, wData),
+ format_,
+ type_):
+ # Ensure texture size is at least MIN_TEXTURE_SIZE
+ tH = max(hData, MIN_TEXTURE_SIZE)
+ tW = max(wData, MIN_TEXTURE_SIZE)
+
+ uMax, vMax = float(wData)/tW, float(hData)/tH
+
+ # TODO issue with type_ and alignment
+ texture = Texture(internalFormat,
+ data=None,
+ format_=format_,
+ shape=(tH, tW),
+ texUnit=texUnit,
+ minFilter=self._MIN_FILTER,
+ magFilter=self._MAG_FILTER,
+ wrap=self._WRAP)
+ # TODO handle unpack
+ texture.update(format_,
+ data[yOrig:yOrig+hData,
+ xOrig:xOrig+wData])
+ # texture.update(format_, type_, data,
+ # width=wData, height=hData,
+ # unpackRowLength=width,
+ # unpackSkipPixels=xOrig,
+ # unpackSkipRows=yOrig)
+ else:
+ uMax, vMax = 1, 1
+ # TODO issue with type_ and unpacking tiles
+ # TODO idea to handle unpack: use array strides
+ # As it is now, it will make a copy
+ texture = Texture(internalFormat,
+ data[yOrig:yOrig+hData,
+ xOrig:xOrig+wData],
+ format_,
+ shape=(hData, wData),
+ texUnit=texUnit,
+ minFilter=self._MIN_FILTER,
+ magFilter=self._MAG_FILTER,
+ wrap=self._WRAP)
+ # TODO
+ # unpackRowLength=width,
+ # unpackSkipPixels=xOrig,
+ # unpackSkipRows=yOrig)
+ vertices = numpy.array((
+ (xOrig, yOrig, 0., 0.),
+ (xOrig + wData, yOrig, uMax, 0.),
+ (xOrig, yOrig + hData, 0., vMax),
+ (xOrig + wData, yOrig + hData, uMax, vMax)),
+ dtype=numpy.float32)
+ tiles.append((texture, vertices,
+ {'xOrigData': xOrig, 'yOrigData': yOrig,
+ 'wData': wData, 'hData': hData}))
+ xOrig += wData
+ yOrig += hData
+ self.tiles = tuple(tiles)
+
+ def discard(self):
+ for texture, vertices, _ in self.tiles:
+ texture.discard()
+ del self.tiles
+
+ def updateAll(self, format_, data, texUnit=0):
+ if not hasattr(self, 'tiles'):
+ raise RuntimeError("No texture, discard has already been called")
+
+ assert data.shape[:2] == (self.height, self.width)
+ if len(self.tiles) == 1:
+ self.tiles[0][0].update(format_, data, texUnit=texUnit)
+ else:
+ for texture, _, info in self.tiles:
+ yOrig, xOrig = info['yOrigData'], info['xOrigData']
+ height, width = info['hData'], info['wData']
+ texture.update(format_,
+ data[yOrig:yOrig+height, xOrig:xOrig+width],
+ texUnit=texUnit)
+ # TODO check
+ # width=info['wData'], height=info['hData'],
+ # texUnit=texUnit, unpackAlign=unpackAlign,
+ # unpackRowLength=self.width,
+ # unpackSkipPixels=info['xOrigData'],
+ # unpackSkipRows=info['yOrigData'])
+
+ def render(self, posAttrib, texAttrib, texUnit=0):
+ try:
+ tiles = self.tiles
+ except AttributeError:
+ raise RuntimeError("No texture, discard has already been called")
+
+ for texture, vertices, _ in tiles:
+ texture.bind(texUnit)
+
+ stride = vertices.shape[-1] * vertices.itemsize
+ gl.glEnableVertexAttribArray(posAttrib)
+ gl.glVertexAttribPointer(posAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ stride, vertices)
+
+ texCoordsPtr = c_void_p(vertices.ctypes.data +
+ 2 * vertices.itemsize)
+ gl.glEnableVertexAttribArray(texAttrib)
+ gl.glVertexAttribPointer(texAttrib,
+ 2,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ stride, texCoordsPtr)
+ gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, len(vertices))
diff --git a/silx/gui/plot/backends/glutils/PlotImageFile.py b/silx/gui/plot/backends/glutils/PlotImageFile.py
new file mode 100644
index 0000000..e4ebe24
--- /dev/null
+++ b/silx/gui/plot/backends/glutils/PlotImageFile.py
@@ -0,0 +1,149 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ############################################################################*/
+"""Function to save an image to a file."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import base64
+import struct
+import sys
+import zlib
+
+
+# Image writer ################################################################
+
+def convertRGBDataToPNG(data):
+ """Convert a RGB bitmap to PNG.
+
+ It only supports RGB bitmap with one byte per channel stored as a 3D array.
+ See `Definitive Guide <http://www.libpng.org/pub/png/book/>`_ and
+ `Specification <http://www.libpng.org/pub/png/spec/1.2/>`_ for details.
+
+ :param data: A 3D array (h, w, rgb) storing an RGB image
+ :type data: numpy.ndarray of unsigned bytes
+ :returns: The PNG encoded data
+ :rtype: bytes
+ """
+ height, width = data.shape[0], data.shape[1]
+ depth = 8 # 8 bit per channel
+ colorType = 2 # 'truecolor' = RGB
+ interlace = 0 # No
+
+ IHDRdata = struct.pack(">ccccIIBBBBB", b'I', b'H', b'D', b'R',
+ width, height, depth, colorType,
+ 0, 0, interlace)
+
+ # Add filter 'None' before each scanline
+ preparedData = b'\x00' + b'\x00'.join(line.tostring() for line in data)
+ compressedData = zlib.compress(preparedData, 8)
+
+ IDATdata = struct.pack("cccc", b'I', b'D', b'A', b'T')
+ IDATdata += compressedData
+
+ return b''.join([
+ b'\x89PNG\r\n\x1a\n', # PNG signature
+ # IHDR chunk: Image Header
+ struct.pack(">I", 13), # length
+ IHDRdata,
+ struct.pack(">I", zlib.crc32(IHDRdata) & 0xffffffff), # CRC
+ # IDAT chunk: Payload
+ struct.pack(">I", len(compressedData)),
+ IDATdata,
+ struct.pack(">I", zlib.crc32(IDATdata) & 0xffffffff), # CRC
+ b'\x00\x00\x00\x00IEND\xaeB`\x82' # IEND chunk: footer
+ ])
+
+
+def saveImageToFile(data, fileNameOrObj, fileFormat):
+ """Save a RGB image to a file.
+
+ :param data: A 3D array (h, w, 3) storing an RGB image.
+ :type data: numpy.ndarray with of unsigned bytes.
+ :param fileNameOrObj: Filename or object to use to write the image.
+ :type fileNameOrObj: A str or a 'file-like' object with a 'write' method.
+ :param str fileFormat: The type of the file in: 'png', 'ppm', 'svg', 'tiff'.
+ """
+ assert len(data.shape) == 3
+ assert data.shape[2] == 3
+ assert fileFormat in ('png', 'ppm', 'svg', 'tiff')
+
+ if not hasattr(fileNameOrObj, 'write'):
+ if sys.version < "3.0":
+ fileObj = open(fileNameOrObj, "wb")
+ else:
+ fileObj = open(fileNameOrObj, "w", newline='')
+ else: # Use as a file-like object
+ fileObj = fileNameOrObj
+
+ if fileFormat == 'svg':
+ height, width = data.shape[:2]
+ base64Data = base64.b64encode(convertRGBDataToPNG(data))
+
+ fileObj.write(
+ '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
+ fileObj.write('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"\n')
+ fileObj.write(
+ ' "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
+ fileObj.write('<svg xmlns:xlink="http://www.w3.org/1999/xlink"\n')
+ fileObj.write(' xmlns="http://www.w3.org/2000/svg"\n')
+ fileObj.write(' version="1.1"\n')
+ fileObj.write(' width="%d"\n' % width)
+ fileObj.write(' height="%d">\n' % height)
+ fileObj.write(' <image xlink:href="data:image/png;base64,')
+ fileObj.write(base64Data.decode('ascii'))
+ fileObj.write('"\n')
+ fileObj.write(' x="0"\n')
+ fileObj.write(' y="0"\n')
+ fileObj.write(' width="%d"\n' % width)
+ fileObj.write(' height="%d"\n' % height)
+ fileObj.write(' id="image" />\n')
+ fileObj.write('</svg>')
+
+ elif fileFormat == 'ppm':
+ height, width = data.shape[:2]
+
+ fileObj.write('P6\n')
+ fileObj.write('%d %d\n' % (width, height))
+ fileObj.write('255\n')
+ fileObj.write(data.tostring())
+
+ elif fileFormat == 'png':
+ fileObj.write(convertRGBDataToPNG(data))
+
+ elif fileFormat == 'tiff':
+ if fileObj == fileNameOrObj:
+ raise NotImplementedError(
+ 'Save TIFF to a file-like object not implemented')
+
+ from silx.third_party.TiffIO import TiffIO
+
+ tif = TiffIO(fileNameOrObj, mode='wb+')
+ tif.writeImage(data, info={'Title': 'PyMCA GL Snapshot'})
+
+ if fileObj != fileNameOrObj:
+ fileObj.close()
diff --git a/silx/gui/plot/backends/glutils/__init__.py b/silx/gui/plot/backends/glutils/__init__.py
new file mode 100644
index 0000000..771de39
--- /dev/null
+++ b/silx/gui/plot/backends/glutils/__init__.py
@@ -0,0 +1,44 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2014-2017 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.
+#
+# ############################################################################*/
+"""This module provides convenient classes for the OpenGL rendering backend.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import logging
+
+
+_logger = logging.getLogger(__name__)
+
+
+from .GLPlotCurve import * # noqa
+from .GLPlotFrame import * # noqa
+from .GLPlotImage import * # noqa
+from .GLSupport import * # noqa
+from .GLText import * # noqa
+from .GLTexture import * # noqa
diff --git a/silx/gui/plot/items/__init__.py b/silx/gui/plot/items/__init__.py
new file mode 100644
index 0000000..b16fe40
--- /dev/null
+++ b/silx/gui/plot/items/__init__.py
@@ -0,0 +1,43 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This package provides classes that describes :class:`.Plot` content.
+
+Instances of those classes are returned by :class:`.Plot` methods that give
+access to its content such as :meth:`.Plot.getCurve`, :meth:`.Plot.getImage`.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "06/03/2017"
+
+from .core import (Item, LabelsMixIn, DraggableMixIn, ColormapMixIn, # noqa
+ SymbolMixIn, ColorMixIn, YAxisMixIn, FillMixIn, # noqa
+ AlphaMixIn, LineMixIn) # noqa
+from .curve import Curve # noqa
+from .histogram import Histogram # noqa
+from .image import ImageBase, ImageData, ImageRgba # noqa
+from .shape import Shape # noqa
+from .scatter import Scatter # noqa
+from .marker import Marker, XMarker, YMarker # noqa
diff --git a/silx/gui/plot/items/core.py b/silx/gui/plot/items/core.py
new file mode 100644
index 0000000..72bfd9a
--- /dev/null
+++ b/silx/gui/plot/items/core.py
@@ -0,0 +1,839 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module provides the base class for items of the :class:`Plot`.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+from copy import deepcopy
+import logging
+import weakref
+import numpy
+from silx.third_party import six
+
+from .. import Colors
+
+
+
+_logger = logging.getLogger(__name__)
+
+
+class Item(object):
+ """Description of an item of the plot"""
+
+ _DEFAULT_Z_LAYER = 0
+ """Default layer for overlay rendering"""
+
+ _DEFAULT_LEGEND = ''
+ """Default legend of items"""
+
+ _DEFAULT_SELECTABLE = False
+ """Default selectable state of items"""
+
+ def __init__(self):
+ self._dirty = True
+ self._plotRef = None
+ self._visible = True
+ self._legend = self._DEFAULT_LEGEND
+ self._selectable = self._DEFAULT_SELECTABLE
+ self._z = self._DEFAULT_Z_LAYER
+ self._info = None
+ self._xlabel = None
+ self._ylabel = None
+
+ self._backendRenderer = None
+
+ def getPlot(self):
+ """Returns Plot this item belongs to.
+
+ :rtype: Plot or None
+ """
+ return None if self._plotRef is None else self._plotRef()
+
+ def _setPlot(self, plot):
+ """Set the plot this item belongs to.
+
+ WARNING: This should only be called from the Plot.
+
+ :param Plot plot: The Plot instance.
+ """
+ if plot is not None and self._plotRef is not None:
+ raise RuntimeError('Trying to add a node at two places.')
+ self._plotRef = None if plot is None else weakref.ref(plot)
+ self._updated()
+
+ def getBounds(self): # TODO return a Bounds object rather than a tuple
+ """Returns the bounding box of this item in data coordinates
+
+ :returns: (xmin, xmax, ymin, ymax) or None
+ :rtype: 4-tuple of float or None
+ """
+ return self._getBounds()
+
+ def _getBounds(self):
+ """:meth:`getBounds` implementation to override by sub-class"""
+ return None
+
+ def isVisible(self):
+ """True if item is visible, False otherwise
+
+ :rtype: bool
+ """
+ return self._visible
+
+ def setVisible(self, visible):
+ """Set visibility of item.
+
+ :param bool visible: True to display it, False otherwise
+ """
+ visible = bool(visible)
+ if visible != self._visible:
+ self._visible = visible
+ # When visibility has changed, always mark as dirty
+ self._updated(checkVisibility=False)
+
+ def isOverlay(self):
+ """Return true if item is drawn as an overlay.
+
+ :rtype: bool
+ """
+ return False
+
+ def getLegend(self):
+ """Returns the legend of this item (str)"""
+ return self._legend
+
+ def _setLegend(self, legend):
+ """Set the legend.
+
+ This is private as it is used by the plot as an identifier
+
+ :param str legend: Item legend
+ """
+ legend = str(legend) if legend is not None else self._DEFAULT_LEGEND
+ self._legend = legend
+
+ def isSelectable(self):
+ """Returns true if item is selectable (bool)"""
+ return self._selectable
+
+ def _setSelectable(self, selectable): # TODO support update
+ """Set whether item is selectable or not.
+
+ This is private for now as change is not handled.
+
+ :param bool selectable: True to make item selectable
+ """
+ self._selectable = bool(selectable)
+
+ def getZValue(self):
+ """Returns the layer on which to draw this item (int)"""
+ return self._z
+
+ def setZValue(self, z):
+ z = int(z) if z is not None else self._DEFAULT_Z_LAYER
+ if z != self._z:
+ self._z = z
+ self._updated()
+
+ def getInfo(self, copy=True):
+ """Returns the info associated to this item
+
+ :param bool copy: True to get a deepcopy, False otherwise.
+ """
+ return deepcopy(self._info) if copy else self._info
+
+ def setInfo(self, info, copy=True):
+ if copy:
+ info = deepcopy(info)
+ self._info = info
+
+ def _updated(self, checkVisibility=True):
+ """Mark the item as dirty (i.e., needing update).
+
+ This also triggers Plot.replot.
+
+ :param bool checkVisibility: True to only mark as dirty if visible,
+ False to always mark as dirty.
+ """
+ if not checkVisibility or self.isVisible():
+ if not self._dirty:
+ self._dirty = True
+ # TODO: send event instead of explicit call
+ plot = self.getPlot()
+ if plot is not None:
+ plot._itemRequiresUpdate(self)
+
+ def _update(self, backend):
+ """Called by Plot to update the backend for this item.
+
+ This is meant to be called asynchronously from _updated.
+ This optimizes the number of call to _update.
+
+ :param backend: The backend to update
+ """
+ if self._dirty:
+ # Remove previous renderer from backend if any
+ self._removeBackendRenderer(backend)
+
+ # If not visible, do not add renderer to backend
+ if self.isVisible():
+ self._backendRenderer = self._addBackendRenderer(backend)
+
+ self._dirty = False
+
+ def _addBackendRenderer(self, backend):
+ """Override in subclass to add specific backend renderer.
+
+ :param BackendBase backend: The backend to update
+ :return: The renderer handle to store or None if no renderer in backend
+ """
+ return None
+
+ def _removeBackendRenderer(self, backend):
+ """Override in subclass to remove specific backend renderer.
+
+ :param BackendBase backend: The backend to update
+ """
+ if self._backendRenderer is not None:
+ backend.remove(self._backendRenderer)
+ self._backendRenderer = None
+
+
+# Mix-in classes ##############################################################
+
+class LabelsMixIn(object):
+ """Mix-in class for items with x and y labels
+
+ Setters are private, otherwise it needs to check the plot
+ current active curve and access the internal current labels.
+ """
+
+ def __init__(self):
+ self._xlabel = None
+ self._ylabel = None
+
+ def getXLabel(self):
+ """Return the X axis label associated to this curve
+
+ :rtype: str or None
+ """
+ return self._xlabel
+
+ def _setXLabel(self, label):
+ """Set the X axis label associated with this curve
+
+ :param str label: The X axis label
+ """
+ self._xlabel = str(label)
+
+ def getYLabel(self):
+ """Return the Y axis label associated to this curve
+
+ :rtype: str or None
+ """
+ return self._ylabel
+
+ def _setYLabel(self, label):
+ """Set the Y axis label associated with this curve
+
+ :param str label: The Y axis label
+ """
+ self._ylabel = str(label)
+
+
+class DraggableMixIn(object):
+ """Mix-in class for draggable items"""
+
+ def __init__(self):
+ self._draggable = False
+
+ def isDraggable(self):
+ """Returns true if image is draggable
+
+ :rtype: bool
+ """
+ return self._draggable
+
+ def _setDraggable(self, draggable): # TODO support update
+ """Set if image is draggable or not.
+
+ This is private for not as it does not support update.
+
+ :param bool draggable:
+ """
+ self._draggable = bool(draggable)
+
+
+class ColormapMixIn(object):
+ """Mix-in class for items with colormap"""
+
+ _DEFAULT_COLORMAP = {'name': 'gray', 'normalization': 'linear',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0}
+ """Default colormap of the item"""
+
+ def __init__(self):
+ self._colormap = self._DEFAULT_COLORMAP
+
+ def getColormap(self):
+ """Return the used colormap"""
+ return self._colormap.copy()
+
+ def setColormap(self, colormap):
+ """Set the colormap of this image
+
+ :param dict colormap: colormap description
+ """
+ self._colormap = colormap.copy()
+ # TODO colormap comparison + colormap object and events on modification
+ self._updated()
+
+
+class SymbolMixIn(object):
+ """Mix-in class for items with symbol type"""
+
+ _DEFAULT_SYMBOL = ''
+ """Default marker of the item"""
+
+ _DEFAULT_SYMBOL_SIZE = 6.0
+ """Default marker size of the item"""
+
+ def __init__(self):
+ self._symbol = self._DEFAULT_SYMBOL
+ self._symbol_size = self._DEFAULT_SYMBOL_SIZE
+
+ def getSymbol(self):
+ """Return the point marker type.
+
+ Marker type::
+
+ - 'o' circle
+ - '.' point
+ - ',' pixel
+ - '+' cross
+ - 'x' x-cross
+ - 'd' diamond
+ - 's' square
+
+ :rtype: str
+ """
+ return self._symbol
+
+ def setSymbol(self, symbol):
+ """Set the marker type
+
+ See :meth:`getSymbol`.
+
+ :param str symbol: Marker type
+ """
+ assert symbol in ('o', '.', ',', '+', 'x', 'd', 's', '', None)
+ if symbol is None:
+ symbol = self._DEFAULT_SYMBOL
+ if symbol != self._symbol:
+ self._symbol = symbol
+ self._updated()
+
+ def getSymbolSize(self):
+ """Return the point marker size in points.
+
+ :rtype: float
+ """
+ return self._symbol_size
+
+ def setSymbolSize(self, size):
+ """Set the point marker size in points.
+
+ See :meth:`getSymbolSize`.
+
+ :param str symbol: Marker type
+ """
+ if size is None:
+ size = self._DEFAULT_SYMBOL_SIZE
+ if size != self._symbol_size:
+ self._symbol_size = size
+ self._updated()
+
+
+class LineMixIn(object):
+ """Mix-in class for item with line"""
+
+ _DEFAULT_LINEWIDTH = 1.
+ """Default line width"""
+
+ _DEFAULT_LINESTYLE = '-'
+ """Default line style"""
+
+ def __init__(self):
+ self._linewidth = self._DEFAULT_LINEWIDTH
+ self._linestyle = self._DEFAULT_LINESTYLE
+
+ def getLineWidth(self):
+ """Return the curve line width in pixels (int)"""
+ return self._linewidth
+
+ def setLineWidth(self, width):
+ """Set the width in pixel of the curve line
+
+ See :meth:`getLineWidth`.
+
+ :param float width: Width in pixels
+ """
+ width = float(width)
+ if width != self._linewidth:
+ self._linewidth = width
+ self._updated()
+
+ def getLineStyle(self):
+ """Return the type of the line
+
+ Type of line::
+
+ - ' ' no line
+ - '-' solid line
+ - '--' dashed line
+ - '-.' dash-dot line
+ - ':' dotted line
+
+ :rtype: str
+ """
+ return self._linestyle
+
+ def setLineStyle(self, style):
+ """Set the style of the curve line.
+
+ See :meth:`getLineStyle`.
+
+ :param str style: Line style
+ """
+ style = str(style)
+ assert style in ('', ' ', '-', '--', '-.', ':', None)
+ if style is None:
+ style = self._DEFAULT_LINESTYLE
+ if style != self._linestyle:
+ self._linestyle = style
+ self._updated()
+
+
+class ColorMixIn(object):
+ """Mix-in class for item with color"""
+
+ _DEFAULT_COLOR = (0., 0., 0., 1.)
+ """Default color of the item"""
+
+ def __init__(self):
+ self._color = self._DEFAULT_COLOR
+
+ def getColor(self):
+ """Returns the RGBA color of the item
+
+ :rtype: 4-tuple of float in [0, 1]
+ """
+ return self._color
+
+ def setColor(self, color, copy=True):
+ """Set item color
+
+ :param color: color(s) to be used
+ :type color: str ("#RRGGBB") or (npoints, 4) unsigned byte array or
+ one of the predefined color names defined in Colors.py
+ :param bool copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ """
+ if isinstance(color, six.string_types):
+ color = Colors.rgba(color)
+ else:
+ color = numpy.array(color, copy=copy)
+ # TODO more checks + improve color array support
+ if color.ndim == 1: # Single RGBA color
+ color = Colors.rgba(color)
+ else: # Array of colors
+ assert color.ndim == 2
+
+ self._color = color
+ self._updated()
+
+
+class YAxisMixIn(object):
+ """Mix-in class for item with yaxis"""
+
+ _DEFAULT_YAXIS = 'left'
+ """Default Y axis the item belongs to"""
+
+ def __init__(self):
+ self._yaxis = self._DEFAULT_YAXIS
+
+ def getYAxis(self):
+ """Returns the Y axis this curve belongs to.
+
+ Either 'left' or 'right'.
+
+ :rtype: str
+ """
+ return self._yaxis
+
+ def setYAxis(self, yaxis):
+ """Set the Y axis this curve belongs to.
+
+ :param str yaxis: 'left' or 'right'
+ """
+ yaxis = str(yaxis)
+ assert yaxis in ('left', 'right')
+ if yaxis != self._yaxis:
+ self._yaxis = yaxis
+ self._updated()
+
+
+class FillMixIn(object):
+ """Mix-in class for item with fill"""
+
+ def __init__(self):
+ self._fill = False
+
+ def isFill(self):
+ """Returns whether the item is filled or not.
+
+ :rtype: bool
+ """
+ return self._fill
+
+ def setFill(self, fill):
+ """Set whether to fill the item or not.
+
+ :param bool fill:
+ """
+ fill = bool(fill)
+ if fill != self._fill:
+ self._fill = fill
+ self._updated()
+
+
+class AlphaMixIn(object):
+ """Mix-in class for item with opacity"""
+
+ def __init__(self):
+ self._alpha = 1.
+
+ def getAlpha(self):
+ """Returns the opacity of the item
+
+ :rtype: float in [0, 1.]
+ """
+ return self._alpha
+
+ def setAlpha(self, alpha):
+ """Set the opacity of the item
+
+ .. note::
+
+ If the colormap already has some transparency, this alpha
+ adds additional transparency. The alpha channel of the colormap
+ is multiplied by this value.
+
+ :param alpha: Opacity of the item, between 0 (full transparency)
+ and 1. (full opacity)
+ :type alpha: float
+ """
+ alpha = float(alpha)
+ alpha = max(0., min(alpha, 1.)) # Clip alpha to [0., 1.] range
+ if alpha != self._alpha:
+ self._alpha = alpha
+ self._updated()
+
+
+class Points(Item, SymbolMixIn, AlphaMixIn):
+ """Base class for :class:`Curve` and :class:`Scatter`"""
+ # note: _logFilterData must be overloaded if you overload
+ # getData to change its signature
+
+ _DEFAULT_Z_LAYER = 1
+ """Default overlay layer for points,
+ on top of images."""
+
+ def __init__(self):
+ Item.__init__(self)
+ SymbolMixIn.__init__(self)
+ AlphaMixIn.__init__(self)
+ self._x = ()
+ self._y = ()
+ self._xerror = None
+ self._yerror = None
+
+ # Store filtered data for x > 0 and/or y > 0
+ self._filteredCache = {}
+ self._clippedCache = {}
+
+ # Store bounds depending on axes filtering >0:
+ # key is (isXPositiveFilter, isYPositiveFilter)
+ self._boundsCache = {}
+
+ @staticmethod
+ def _logFilterError(value, error):
+ """Filter/convert error values if they go <= 0.
+
+ Replace error leading to negative values by nan
+
+ :param numpy.ndarray value: 1D array of values
+ :param numpy.ndarray error:
+ Array of errors: scalar, N, Nx1 or 2xN or None.
+ :return: Filtered error so error bars are never negative
+ """
+ if error is not None:
+ # Convert Nx1 to N
+ if error.ndim == 2 and error.shape[1] == 1 and len(value) != 1:
+ error = numpy.ravel(error)
+
+ # Supports error being scalar, N or 2xN array
+ errorClipped = (value - numpy.atleast_2d(error)[0]) <= 0
+
+ if numpy.any(errorClipped): # Need filtering
+
+ # expand errorbars to 2xN
+ if error.size == 1: # Scalar
+ error = numpy.full(
+ (2, len(value)), error, dtype=numpy.float)
+
+ elif error.ndim == 1: # N array
+ newError = numpy.empty((2, len(value)),
+ dtype=numpy.float)
+ newError[0, :] = error
+ newError[1, :] = error
+ error = newError
+
+ elif error.size == 2 * len(value): # 2xN array
+ error = numpy.array(
+ error, copy=True, dtype=numpy.float)
+
+ else:
+ _logger.error("Unhandled error array")
+ return error
+
+ error[0, errorClipped] = numpy.nan
+
+ return error
+
+ def _getClippingBoolArray(self, xPositive, yPositive):
+ """Compute a boolean array to filter out points with negative
+ coordinates on log axes.
+
+ :param bool xPositive: True to filter arrays according to X coords.
+ :param bool yPositive: True to filter arrays according to Y coords.
+ :rtype: boolean numpy.ndarray
+ """
+ assert xPositive or yPositive
+ if (xPositive, yPositive) not in self._clippedCache:
+ x = self.getXData(copy=False)
+ y = self.getYData(copy=False)
+ xclipped = (x <= 0) if xPositive else False
+ yclipped = (y <= 0) if yPositive else False
+ self._clippedCache[(xPositive, yPositive)] = \
+ numpy.logical_or(xclipped, yclipped)
+ return self._clippedCache[(xPositive, yPositive)]
+
+ def _logFilterData(self, xPositive, yPositive):
+ """Filter out values with x or y <= 0 on log axes
+
+ :param bool xPositive: True to filter arrays according to X coords.
+ :param bool yPositive: True to filter arrays according to Y coords.
+ :return: The filter arrays or unchanged object if filtering not needed
+ :rtype: (x, y, xerror, yerror)
+ """
+ x = self.getXData(copy=False)
+ y = self.getYData(copy=False)
+ xerror = self.getXErrorData(copy=False)
+ yerror = self.getYErrorData(copy=False)
+
+ if xPositive or yPositive:
+ clipped = self._getClippingBoolArray(xPositive, yPositive)
+
+ if numpy.any(clipped):
+ # copy to keep original array and convert to float
+ x = numpy.array(x, copy=True, dtype=numpy.float)
+ x[clipped] = numpy.nan
+ y = numpy.array(y, copy=True, dtype=numpy.float)
+ y[clipped] = numpy.nan
+
+ if xPositive and xerror is not None:
+ xerror = self._logFilterError(x, xerror)
+
+ if yPositive and yerror is not None:
+ yerror = self._logFilterError(y, yerror)
+
+ return x, y, xerror, yerror
+
+ def _getBounds(self):
+ if self.getXData(copy=False).size == 0: # Empty data
+ return None
+
+ plot = self.getPlot()
+ if plot is not None:
+ xPositive = plot.isXAxisLogarithmic()
+ yPositive = plot.isYAxisLogarithmic()
+ else:
+ xPositive = False
+ yPositive = False
+
+ # TODO bounds do not take error bars into account
+ if (xPositive, yPositive) not in self._boundsCache:
+ # use the getData class method because instance method can be
+ # overloaded to return additional arrays
+ data = Points.getData(self, copy=False,
+ displayed=True)
+ if len(data) == 5:
+ # hack to avoid duplicating caching mechanism in Scatter
+ # (happens when cached data is used, caching done using
+ # Scatter._logFilterData)
+ x, y, xerror, yerror = data[0], data[1], data[3], data[4]
+ else:
+ x, y, xerror, yerror = data
+
+ self._boundsCache[(xPositive, yPositive)] = (
+ numpy.nanmin(x),
+ numpy.nanmax(x),
+ numpy.nanmin(y),
+ numpy.nanmax(y)
+ )
+ return self._boundsCache[(xPositive, yPositive)]
+
+ def _getCachedData(self):
+ """Return cached filtered data if applicable,
+ i.e. if any axis is in log scale.
+ Return None if caching is not applicable."""
+ plot = self.getPlot()
+ if plot is not None:
+ xPositive = plot.isXAxisLogarithmic()
+ yPositive = plot.isYAxisLogarithmic()
+ if xPositive or yPositive:
+ # At least one axis has log scale, filter data
+ if (xPositive, yPositive) not in self._filteredCache:
+ self._filteredCache[(xPositive, yPositive)] = \
+ self._logFilterData(xPositive, yPositive)
+ return self._filteredCache[(xPositive, yPositive)]
+ return None
+
+ def getData(self, copy=True, displayed=False):
+ """Returns the x, y values of the curve points and xerror, yerror
+
+ :param bool copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :param bool displayed: True to only get curve points that are displayed
+ in the plot. Default: False
+ Note: If plot has log scale, negative points
+ are not displayed.
+ :returns: (x, y, xerror, yerror)
+ :rtype: 4-tuple of numpy.ndarray
+ """
+ if displayed: # filter data according to plot state
+ cached_data = self._getCachedData()
+ if cached_data is not None:
+ return cached_data
+
+ return (self.getXData(copy),
+ self.getYData(copy),
+ self.getXErrorData(copy),
+ self.getYErrorData(copy))
+
+ def getXData(self, copy=True):
+ """Returns the x coordinates of the data points
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :rtype: numpy.ndarray
+ """
+ return numpy.array(self._x, copy=copy)
+
+ def getYData(self, copy=True):
+ """Returns the y coordinates of the data points
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :rtype: numpy.ndarray
+ """
+ return numpy.array(self._y, copy=copy)
+
+ def getXErrorData(self, copy=True):
+ """Returns the x error of the points
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :rtype: numpy.ndarray or None
+ """
+ if self._xerror is None:
+ return None
+ else:
+ return numpy.array(self._xerror, copy=copy)
+
+ def getYErrorData(self, copy=True):
+ """Returns the y error of the points
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :rtype: numpy.ndarray or None
+ """
+ if self._yerror is None:
+ return None
+ else:
+ return numpy.array(self._yerror, copy=copy)
+
+ def setData(self, x, y, xerror=None, yerror=None, copy=True):
+ """Set the data of the curve.
+
+ :param numpy.ndarray x: The data corresponding to the x coordinates.
+ :param numpy.ndarray y: The data corresponding to the y coordinates.
+ :param xerror: Values with the uncertainties on the x values
+ :type xerror: A float, or a numpy.ndarray of float32.
+ If it is an array, it can either be a 1D array of
+ same length as the data or a 2D array with 2 rows
+ of same length as the data: row 0 for positive errors,
+ row 1 for negative errors.
+ :param yerror: Values with the uncertainties on the y values.
+ :type yerror: A float, or a numpy.ndarray of float32. See xerror.
+ :param bool copy: True make a copy of the data (default),
+ False to use provided arrays.
+ """
+ x = numpy.array(x, copy=copy)
+ y = numpy.array(y, copy=copy)
+ assert len(x) == len(y)
+ assert x.ndim == y.ndim == 1
+
+ if xerror is not None:
+ xerror = numpy.array(xerror, copy=copy)
+ if yerror is not None:
+ yerror = numpy.array(yerror, copy=copy)
+ # TODO checks on xerror, yerror
+ self._x, self._y = x, y
+ self._xerror, self._yerror = xerror, yerror
+
+ self._boundsCache = {} # Reset cached bounds
+ self._filteredCache = {} # Reset cached filtered data
+ self._clippedCache = {} # Reset cached clipped bool array
+
+ self._updated()
+ # TODO hackish data range implementation
+ if self.isVisible():
+ plot = self.getPlot()
+ if plot is not None:
+ plot._invalidateDataRange()
diff --git a/silx/gui/plot/items/curve.py b/silx/gui/plot/items/curve.py
new file mode 100644
index 0000000..d25ae00
--- /dev/null
+++ b/silx/gui/plot/items/curve.py
@@ -0,0 +1,192 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module provides the :class:`Curve` item of the :class:`Plot`.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "06/03/2017"
+
+
+import logging
+
+import numpy
+
+from .. import Colors
+from .core import (Points, LabelsMixIn, SymbolMixIn,
+ ColorMixIn, YAxisMixIn, FillMixIn, LineMixIn)
+
+
+_logger = logging.getLogger(__name__)
+
+
+class Curve(Points, ColorMixIn, YAxisMixIn, FillMixIn, LabelsMixIn, LineMixIn):
+ """Description of a curve"""
+
+ _DEFAULT_Z_LAYER = 1
+ """Default overlay layer for curves"""
+
+ _DEFAULT_SELECTABLE = True
+ """Default selectable state for curves"""
+
+ _DEFAULT_LINEWIDTH = 1.
+ """Default line width of the curve"""
+
+ _DEFAULT_LINESTYLE = '-'
+ """Default line style of the curve"""
+
+ _DEFAULT_HIGHLIGHT_COLOR = (0, 0, 0, 255)
+ """Default highlight color of the item"""
+
+ def __init__(self):
+ Points.__init__(self)
+ ColorMixIn.__init__(self)
+ YAxisMixIn.__init__(self)
+ FillMixIn.__init__(self)
+ LabelsMixIn.__init__(self)
+ LineMixIn.__init__(self)
+
+ self._highlightColor = self._DEFAULT_HIGHLIGHT_COLOR
+ self._highlighted = False
+
+ def _addBackendRenderer(self, backend):
+ """Update backend renderer"""
+ # Filter-out values <= 0
+ xFiltered, yFiltered, xerror, yerror = self.getData(
+ copy=False, displayed=True)
+
+ if len(xFiltered) == 0:
+ return None # No data to display, do not add renderer to backend
+
+ return backend.addCurve(xFiltered, yFiltered, self.getLegend(),
+ color=self.getCurrentColor(),
+ symbol=self.getSymbol(),
+ linestyle=self.getLineStyle(),
+ linewidth=self.getLineWidth(),
+ yaxis=self.getYAxis(),
+ xerror=xerror,
+ yerror=yerror,
+ z=self.getZValue(),
+ selectable=self.isSelectable(),
+ fill=self.isFill(),
+ alpha=self.getAlpha(),
+ symbolsize=self.getSymbolSize())
+
+ def __getitem__(self, item):
+ """Compatibility with PyMca and silx <= 0.4.0"""
+ if isinstance(item, slice):
+ return [self[index] for index in range(*item.indices(5))]
+ elif item == 0:
+ return self.getXData(copy=False)
+ elif item == 1:
+ return self.getYData(copy=False)
+ elif item == 2:
+ return self.getLegend()
+ elif item == 3:
+ info = self.getInfo(copy=False)
+ return {} if info is None else info
+ elif item == 4:
+ params = {
+ 'info': self.getInfo(),
+ 'color': self.getColor(),
+ 'symbol': self.getSymbol(),
+ 'linewidth': self.getLineWidth(),
+ 'linestyle': self.getLineStyle(),
+ 'xlabel': self.getXLabel(),
+ 'ylabel': self.getYLabel(),
+ 'yaxis': self.getYAxis(),
+ 'xerror': self.getXErrorData(copy=False),
+ 'yerror': self.getYErrorData(copy=False),
+ 'z': self.getZValue(),
+ 'selectable': self.isSelectable(),
+ 'fill': self.isFill()
+ }
+ return params
+ else:
+ raise IndexError("Index out of range: %s", str(item))
+
+ def setVisible(self, visible):
+ """Set visibility of item.
+
+ :param bool visible: True to display it, False otherwise
+ """
+ visibleChanged = self.isVisible() != bool(visible)
+ super(Curve, self).setVisible(visible)
+
+ # TODO hackish data range implementation
+ if visibleChanged:
+ plot = self.getPlot()
+ if plot is not None:
+ plot._invalidateDataRange()
+
+ def isHighlighted(self):
+ """Returns True if curve is highlighted.
+
+ :rtype: bool
+ """
+ return self._highlighted
+
+ def setHighlighted(self, highlighted):
+ """Set the highlight state of the curve
+
+ :param bool highlighted:
+ """
+ highlighted = bool(highlighted)
+ if highlighted != self._highlighted:
+ self._highlighted = highlighted
+ # TODO inefficient: better to use backend's setCurveColor
+ self._updated()
+
+ def getHighlightedColor(self):
+ """Returns the RGBA highlight color of the item
+
+ :rtype: 4-tuple of int in [0, 255]
+ """
+ return self._highlightColor
+
+ def setHighlightedColor(self, color):
+ """Set the color to use when highlighted
+
+ :param color: color(s) to be used for highlight
+ :type color: str ("#RRGGBB") or (npoints, 4) unsigned byte array or
+ one of the predefined color names defined in Colors.py
+ """
+ color = Colors.rgba(color)
+ if color != self._highlightColor:
+ self._highlightColor = color
+ self._updated()
+
+ def getCurrentColor(self):
+ """Returns the current color of the curve.
+
+ This color is either the color of the curve or the highlighted color,
+ depending on the highlight state.
+
+ :rtype: 4-tuple of int in [0, 255]
+ """
+ if self.isHighlighted():
+ return self.getHighlightedColor()
+ else:
+ return self.getColor()
diff --git a/silx/gui/plot/items/histogram.py b/silx/gui/plot/items/histogram.py
new file mode 100644
index 0000000..c3821bc
--- /dev/null
+++ b/silx/gui/plot/items/histogram.py
@@ -0,0 +1,288 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module provides the :class:`Histogram` item of the :class:`Plot`.
+"""
+
+__authors__ = ["H. Payno", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "02/05/2017"
+
+
+import logging
+
+import numpy
+
+from .core import (Item, AlphaMixIn, ColorMixIn, FillMixIn,
+ LineMixIn, YAxisMixIn)
+
+
+_logger = logging.getLogger(__name__)
+
+
+def _computeEdges(x, histogramType):
+ """Compute the edges from a set of xs and a rule to generate the edges
+
+ :param x: the x value of the curve to transform into an histogram
+ :param histogramType: the type of histogram we wan't to generate.
+ This define the way to center the histogram values compared to the
+ curve value. Possible values can be::
+
+ - 'left'
+ - 'right'
+ - 'center'
+
+ :return: the edges for the given x and the histogramType
+ """
+ # for now we consider that the spaces between xs are constant
+ edges = x.copy()
+ if histogramType is 'left':
+ width = 1
+ if len(x) > 1:
+ width = x[1] - x[0]
+ edges = numpy.append(x[0] - width, edges)
+ if histogramType is 'center':
+ edges = _computeEdges(edges, 'right')
+ widths = (edges[1:] - edges[0:-1]) / 2.0
+ widths = numpy.append(widths, widths[-1])
+ edges = edges - widths
+ if histogramType is 'right':
+ width = 1
+ if len(x) > 1:
+ width = x[-1] - x[-2]
+ edges = numpy.append(edges, x[-1] + width)
+
+ return edges
+
+
+def _getHistogramCurve(histogram, edges):
+ """Returns the x and y value of a curve corresponding to the histogram
+
+ :param numpy.ndarray histogram: The values of the histogram
+ :param numpy.ndarray edges: The bin edges of the histogram
+ :return: a tuple(x, y) which contains the value of the curve to use
+ to display the histogram
+ """
+ assert len(histogram) + 1 == len(edges)
+ x = numpy.empty(len(histogram) * 2, dtype=edges.dtype)
+ y = numpy.empty(len(histogram) * 2, dtype=histogram.dtype)
+ # Make a curve with stairs
+ x[:-1:2] = edges[:-1]
+ x[1::2] = edges[1:]
+ y[:-1:2] = histogram
+ y[1::2] = histogram
+
+ return x, y
+
+
+# TODO: Yerror, test log scale
+class Histogram(Item, AlphaMixIn, ColorMixIn, FillMixIn,
+ LineMixIn, YAxisMixIn):
+ """Description of an histogram"""
+
+ _DEFAULT_Z_LAYER = 1
+ """Default overlay layer for histograms"""
+
+ _DEFAULT_SELECTABLE = False
+ """Default selectable state for histograms"""
+
+ _DEFAULT_LINEWIDTH = 1.
+ """Default line width of the histogram"""
+
+ _DEFAULT_LINESTYLE = '-'
+ """Default line style of the histogram"""
+
+ def __init__(self):
+ Item.__init__(self)
+ AlphaMixIn.__init__(self)
+ ColorMixIn.__init__(self)
+ FillMixIn.__init__(self)
+ LineMixIn.__init__(self)
+ YAxisMixIn.__init__(self)
+
+ self._histogram = ()
+ self._edges = ()
+
+ def _addBackendRenderer(self, backend):
+ """Update backend renderer"""
+ values, edges = self.getData(copy=False)
+
+ if values.size == 0:
+ return None # No data to display, do not add renderer
+
+ if values.size == 0:
+ return None # No data to display, do not add renderer to backend
+
+ x, y = _getHistogramCurve(values, edges)
+
+ # Filter-out values <= 0
+ plot = self.getPlot()
+ if plot is not None:
+ xPositive = plot.isXAxisLogarithmic()
+ yPositive = plot.isYAxisLogarithmic()
+ else:
+ xPositive = False
+ yPositive = False
+
+ if xPositive or yPositive:
+ clipped = numpy.logical_or(
+ (x <= 0) if xPositive else False,
+ (y <= 0) if yPositive else False)
+ # Make a copy and replace negative points by NaN
+ x = numpy.array(x, dtype=numpy.float)
+ y = numpy.array(y, dtype=numpy.float)
+ x[clipped] = numpy.nan
+ y[clipped] = numpy.nan
+
+ return backend.addCurve(x, y, self.getLegend(),
+ color=self.getColor(),
+ symbol='',
+ linestyle=self.getLineStyle(),
+ linewidth=self.getLineWidth(),
+ yaxis=self.getYAxis(),
+ xerror=None,
+ yerror=None,
+ z=self.getZValue(),
+ selectable=self.isSelectable(),
+ fill=self.isFill(),
+ alpha=self.getAlpha(),
+ symbolsize=1)
+
+ def _getBounds(self):
+ values, edges = self.getData(copy=False)
+
+ plot = self.getPlot()
+ if plot is not None:
+ xPositive = plot.isXAxisLogarithmic()
+ yPositive = plot.isYAxisLogarithmic()
+ else:
+ xPositive = False
+ yPositive = False
+
+ if xPositive or yPositive:
+ values = numpy.array(values, copy=True, dtype=numpy.float)
+
+ if xPositive:
+ # Replace edges <= 0 by NaN and corresponding values by NaN
+ clipped = (edges <= 0)
+ edges = numpy.array(edges, copy=True, dtype=numpy.float)
+ edges[clipped] = numpy.nan
+ values[numpy.logical_or(clipped[:-1], clipped[1:])] = numpy.nan
+
+ if yPositive:
+ # Replace values <= 0 by NaN, do not modify edges
+ values[values <= 0] = numpy.nan
+
+ if xPositive or yPositive:
+ return (numpy.nanmin(edges),
+ numpy.nanmax(edges),
+ numpy.nanmin(values),
+ numpy.nanmax(values))
+
+ else: # No log scale, include 0 in bounds
+ return (numpy.nanmin(edges),
+ numpy.nanmax(edges),
+ min(0, numpy.nanmin(values)),
+ max(0, numpy.nanmax(values)))
+
+ def setVisible(self, visible):
+ """Set visibility of item.
+
+ :param bool visible: True to display it, False otherwise
+ """
+ visibleChanged = self.isVisible() != bool(visible)
+ super(Histogram, self).setVisible(visible)
+
+ # TODO hackish data range implementation
+ if visibleChanged:
+ plot = self.getPlot()
+ if plot is not None:
+ plot._invalidateDataRange()
+
+ def getValueData(self, copy=True):
+ """The values of the histogram
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :returns: The bin edges of the histogram
+ :rtype: numpy.ndarray
+ """
+ return numpy.array(self._histogram, copy=copy)
+
+ def getBinEdgesData(self, copy=True):
+ """The bin edges of the histogram (number of histogram values + 1)
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :returns: The bin edges of the histogram
+ :rtype: numpy.ndarray
+ """
+ return numpy.array(self._edges, copy=copy)
+
+ def getData(self, copy=True):
+ """Return the histogram values and the bin edges
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :returns: (N histogram value, N+1 bin edges)
+ :rtype: 2-tuple of numpy.nadarray
+ """
+ return (self.getValueData(copy), self.getBinEdgesData(copy))
+
+ def setData(self, histogram, edges, align='center', copy=True):
+ """Set the histogram values and bin edges.
+
+ :param numpy.ndarray histogram: The values of the histogram.
+ :param numpy.ndarray edges:
+ The bin edges of the histogram.
+ If histogram and edges have the same length, the bin edges
+ are computed according to the align parameter.
+ :param str align:
+ In case histogram values and edges have the same length N,
+ the N+1 bin edges are computed according to the alignment in:
+ 'center' (default), 'left', 'right'.
+ :param bool copy: True make a copy of the data (default),
+ False to use provided arrays.
+ """
+ histogram = numpy.array(histogram, copy=copy)
+ edges = numpy.array(edges, copy=copy)
+
+ assert histogram.ndim == 1
+ assert edges.ndim == 1
+ assert edges.size in (histogram.size, histogram.size + 1)
+ assert align in ('center', 'left', 'right')
+
+ if histogram.size == 0: # No data
+ self._histogram = ()
+ self._edges = ()
+ else:
+ if edges.size == histogram.size: # Compute true bin edges
+ edges = _computeEdges(edges, align)
+
+ # Check that bin edges are monotonic
+ edgesDiff = numpy.diff(edges)
+ assert numpy.all(edgesDiff >= 0) or numpy.all(edgesDiff <= 0)
+
+ self._histogram = histogram
+ self._edges = edges
diff --git a/silx/gui/plot/items/image.py b/silx/gui/plot/items/image.py
new file mode 100644
index 0000000..7e1dd8b
--- /dev/null
+++ b/silx/gui/plot/items/image.py
@@ -0,0 +1,385 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module provides the :class:`ImageData` and :class:`ImageRgba` items
+of the :class:`Plot`.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "06/03/2017"
+
+
+from collections import Sequence
+import logging
+
+import numpy
+
+from .core import Item, LabelsMixIn, DraggableMixIn, ColormapMixIn, AlphaMixIn
+from ..Colors import applyColormapToData
+
+
+_logger = logging.getLogger(__name__)
+
+
+def _convertImageToRgba32(image, copy=True):
+ """Convert an RGB or RGBA image to RGBA32.
+
+ It converts from floats in [0, 1], bool, integer and uint in [0, 255]
+
+ If the input image is already an RGBA32 image,
+ the returned image shares the same data.
+
+ :param image: Image to convert to
+ :type image: numpy.ndarray with 3 dimensions: height, width, color channels
+ :param bool copy: True (Default) to get a copy, False, avoid copy if possible
+ :return: The image converted to RGBA32 with dimension: (height, width, 4)
+ :rtype: numpy.ndarray of uint8
+ """
+ assert image.ndim == 3
+ assert image.shape[-1] in (3, 4)
+
+ # Convert type to uint8
+ if image.dtype.name != 'uin8':
+ if image.dtype.kind == 'f': # Float in [0, 1]
+ image = (numpy.clip(image, 0., 1.) * 255).astype(numpy.uint8)
+ elif image.dtype.kind == 'b': # boolean
+ image = image.astype(numpy.uint8) * 255
+ elif image.dtype.kind in ('i', 'u'): # int, uint
+ image = numpy.clip(image, 0, 255).astype(numpy.uint8)
+ else:
+ raise ValueError('Unsupported image dtype: %s', image.dtype.name)
+ copy = False # A copy as already been done, avoid next one
+
+ # Convert RGB to RGBA
+ if image.shape[-1] == 3:
+ new_image = numpy.empty((image.shape[0], image.shape[1], 4),
+ dtype=numpy.uint8)
+ new_image[:, :, :3] = image
+ new_image[:, :, 3] = 255
+ return new_image # This is a copy anyway
+ else:
+ return numpy.array(image, copy=copy)
+
+
+class ImageBase(Item, LabelsMixIn, DraggableMixIn, AlphaMixIn):
+ """Description of an image"""
+
+ def __init__(self):
+ Item.__init__(self)
+ LabelsMixIn.__init__(self)
+ DraggableMixIn.__init__(self)
+ AlphaMixIn.__init__(self)
+ self._data = numpy.zeros((0, 0, 4), dtype=numpy.uint8)
+
+ self._origin = (0., 0.)
+ self._scale = (1., 1.)
+
+ def __getitem__(self, item):
+ """Compatibility with PyMca and silx <= 0.4.0"""
+ if isinstance(item, slice):
+ return [self[index] for index in range(*item.indices(5))]
+ elif item == 0:
+ return self.getData(copy=False)
+ elif item == 1:
+ return self.getLegend()
+ elif item == 2:
+ info = self.getInfo(copy=False)
+ return {} if info is None else info
+ elif item == 3:
+ return None
+ elif item == 4:
+ params = {
+ 'info': self.getInfo(),
+ 'origin': self.getOrigin(),
+ 'scale': self.getScale(),
+ 'z': self.getZValue(),
+ 'selectable': self.isSelectable(),
+ 'draggable': self.isDraggable(),
+ 'colormap': None,
+ 'xlabel': self.getXLabel(),
+ 'ylabel': self.getYLabel(),
+ }
+ return params
+ else:
+ raise IndexError("Index out of range: %s" % str(item))
+
+ def setVisible(self, visible):
+ """Set visibility of item.
+
+ :param bool visible: True to display it, False otherwise
+ """
+ visibleChanged = self.isVisible() != bool(visible)
+ super(ImageBase, self).setVisible(visible)
+
+ # TODO hackish data range implementation
+ if visibleChanged:
+ plot = self.getPlot()
+ if plot is not None:
+ plot._invalidateDataRange()
+
+ def _getBounds(self):
+ if self.getData(copy=False).size == 0: # Empty data
+ return None
+
+ height, width = self.getData(copy=False).shape[:2]
+ origin = self.getOrigin()
+ scale = self.getScale()
+ # Taking care of scale might be < 0
+ xmin, xmax = origin[0], origin[0] + width * scale[0]
+ if xmin > xmax:
+ xmin, xmax = xmax, xmin
+ # Taking care of scale might be < 0
+ ymin, ymax = origin[1], origin[1] + height * scale[1]
+ if ymin > ymax:
+ ymin, ymax = ymax, ymin
+
+ plot = self.getPlot()
+ if (plot is not None and
+ plot.isXAxisLogarithmic() or plot.isYAxisLogarithmic()):
+ return None
+ else:
+ return xmin, xmax, ymin, ymax
+
+ def getData(self, copy=True):
+ """Returns the image data
+
+ :param bool copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :rtype: numpy.ndarray
+ """
+ return numpy.array(self._data, copy=copy)
+
+ def getRgbaImageData(self, copy=True):
+ """Get the displayed RGB(A) image
+
+ :returns: numpy.ndarray of uint8 of shape (height, width, 4)
+ """
+ raise NotImplementedError('This MUST be implemented in sub-class')
+
+ def getOrigin(self):
+ """Returns the offset from origin at which to display the image.
+
+ :rtype: 2-tuple of float
+ """
+ return self._origin
+
+ def setOrigin(self, origin):
+ """Set the offset from origin at which to display the image.
+
+ :param origin: (ox, oy) Offset from origin
+ :type origin: float or 2-tuple of float
+ """
+ if isinstance(origin, Sequence):
+ origin = float(origin[0]), float(origin[1])
+ else: # single value origin
+ origin = float(origin), float(origin)
+ if origin != self._origin:
+ self._origin = origin
+ self._updated()
+
+ # TODO hackish data range implementation
+ if self.isVisible():
+ plot = self.getPlot()
+ if plot is not None:
+ plot._invalidateDataRange()
+
+ def getScale(self):
+ """Returns the scale of the image in data coordinates.
+
+ :rtype: 2-tuple of float
+ """
+ return self._scale
+
+ def setScale(self, scale):
+ """Set the scale of the image
+
+ :param scale: (sx, sy) Scale of the image
+ :type scale: float or 2-tuple of float
+ """
+ if isinstance(scale, Sequence):
+ scale = float(scale[0]), float(scale[1])
+ else: # single value scale
+ scale = float(scale), float(scale)
+ if scale != self._scale:
+ self._scale = scale
+ self._updated()
+
+
+class ImageData(ImageBase, ColormapMixIn):
+ """Description of a data image with a colormap"""
+
+ def __init__(self):
+ ImageBase.__init__(self)
+ ColormapMixIn.__init__(self)
+ self._data = numpy.zeros((0, 0), dtype=numpy.float32)
+ self._alternativeImage = None
+
+ def _addBackendRenderer(self, backend):
+ """Update backend renderer"""
+ plot = self.getPlot()
+ assert plot is not None
+ if plot.isXAxisLogarithmic() or plot.isYAxisLogarithmic():
+ return None # Do not render with log scales
+
+ if self.getAlternativeImageData(copy=False) is not None:
+ dataToUse = self.getAlternativeImageData(copy=False)
+ else:
+ dataToUse = self.getData(copy=False)
+
+ if dataToUse.size == 0:
+ return None # No data to display
+
+ return backend.addImage(dataToUse,
+ legend=self.getLegend(),
+ origin=self.getOrigin(),
+ scale=self.getScale(),
+ z=self.getZValue(),
+ selectable=self.isSelectable(),
+ draggable=self.isDraggable(),
+ colormap=self.getColormap(),
+ alpha=self.getAlpha())
+
+ def __getitem__(self, item):
+ """Compatibility with PyMca and silx <= 0.4.0"""
+ if item == 3:
+ return self.getAlternativeImageData(copy=False)
+
+ params = ImageBase.__getitem__(self, item)
+ if item == 4:
+ params['colormap'] = self.getColormap()
+
+ return params
+
+ def getRgbaImageData(self, copy=True):
+ """Get the displayed RGB(A) image
+
+ :returns: numpy.ndarray of uint8 of shape (height, width, 4)
+ """
+ if self._alternativeImage is not None:
+ return _convertImageToRgba32(
+ self.getAlternativeImageData(copy=False), copy=copy)
+ else:
+ # Apply colormap, in this case an new array is always returned
+ colormap = self.getColormap()
+ image = applyColormapToData(self.getData(copy=False),
+ **colormap)
+ return image
+
+ def getAlternativeImageData(self, copy=True):
+ """Get the optional RGBA image that is displayed instead of the data
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :returns: None or numpy.ndarray
+ :rtype: numpy.ndarray or None
+ """
+ if self._alternativeImage is None:
+ return None
+ else:
+ return numpy.array(self._alternativeImage, copy=copy)
+
+ def setData(self, data, alternative=None, copy=True):
+ """"Set the image data and optionally an alternative RGB(A) representation
+
+ :param numpy.ndarray data: Data array with 2 dimensions (h, w)
+ :param alternative: RGB(A) image to display instead of data,
+ shape: (h, w, 3 or 4)
+ :type alternative: None or numpy.ndarray
+ :param bool copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ """
+ data = numpy.array(data, copy=copy)
+ assert data.ndim == 2
+ self._data = data
+
+ if alternative is not None:
+ alternative = numpy.array(alternative, copy=copy)
+ assert alternative.ndim == 3
+ assert alternative.shape[2] in (3, 4)
+ assert alternative.shape[:2] == data.shape[:2]
+ self._alternativeImage = alternative
+ self._updated()
+
+ # TODO hackish data range implementation
+ if self.isVisible():
+ plot = self.getPlot()
+ if plot is not None:
+ plot._invalidateDataRange()
+
+
+class ImageRgba(ImageBase):
+ """Description of an RGB(A) image"""
+
+ def __init__(self):
+ ImageBase.__init__(self)
+
+ def _addBackendRenderer(self, backend):
+ """Update backend renderer"""
+ plot = self.getPlot()
+ assert plot is not None
+ if plot.isXAxisLogarithmic() or plot.isYAxisLogarithmic():
+ return None # Do not render with log scales
+
+ data = self.getData(copy=False)
+
+ if data.size == 0:
+ return None # No data to display
+
+ return backend.addImage(data,
+ legend=self.getLegend(),
+ origin=self.getOrigin(),
+ scale=self.getScale(),
+ z=self.getZValue(),
+ selectable=self.isSelectable(),
+ draggable=self.isDraggable(),
+ colormap=None,
+ alpha=self.getAlpha())
+
+ def getRgbaImageData(self, copy=True):
+ """Get the displayed RGB(A) image
+
+ :returns: numpy.ndarray of uint8 of shape (height, width, 4)
+ """
+ return _convertImageToRgba32(self.getData(copy=False), copy=copy)
+
+ def setData(self, data, copy=True):
+ """Set the image data
+
+ :param data: RGB(A) image data to set
+ :param bool copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ """
+ data = numpy.array(data, copy=copy)
+ assert data.ndim == 3
+ assert data.shape[-1] in (3, 4)
+ self._data = data
+
+ self._updated()
+
+ # TODO hackish data range implementation
+ if self.isVisible():
+ plot = self.getPlot()
+ if plot is not None:
+ plot._invalidateDataRange()
diff --git a/silx/gui/plot/items/marker.py b/silx/gui/plot/items/marker.py
new file mode 100644
index 0000000..c05558b
--- /dev/null
+++ b/silx/gui/plot/items/marker.py
@@ -0,0 +1,241 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module provides markers item of the :class:`Plot`.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "06/03/2017"
+
+
+import logging
+
+from .core import Item, DraggableMixIn, ColorMixIn, SymbolMixIn
+
+
+_logger = logging.getLogger(__name__)
+
+
+class _BaseMarker(Item, DraggableMixIn, ColorMixIn):
+ """Base class for markers"""
+
+ _DEFAULT_COLOR = (0., 0., 0., 1.)
+ """Default color of the markers"""
+
+ def __init__(self):
+ Item.__init__(self)
+ DraggableMixIn.__init__(self)
+ ColorMixIn.__init__(self)
+
+ self._text = ''
+ self._x = None
+ self._y = None
+ self._constraint = self._defaultConstraint
+
+ def _addBackendRenderer(self, backend):
+ """Update backend renderer"""
+ # TODO not very nice way to do it, but simple
+ symbol = self.getSymbol() if isinstance(self, Marker) else None
+
+ return backend.addMarker(
+ x=self.getXPosition(),
+ y=self.getYPosition(),
+ legend=self.getLegend(),
+ text=self.getText(),
+ color=self.getColor(),
+ selectable=self.isSelectable(),
+ draggable=self.isDraggable(),
+ symbol=symbol,
+ constraint=self.getConstraint(),
+ overlay=self.isOverlay())
+
+ def isOverlay(self):
+ """Return true if marker is drawn as an overlay.
+
+ A marker is an overlay if it is draggable.
+
+ :rtype: bool
+ """
+ return self.isDraggable()
+
+ def getText(self):
+ """Returns marker text.
+
+ :rtype: str
+ """
+ return self._text
+
+ def setText(self, text):
+ """Set the text of the marker.
+
+ :param str text: The text to use
+ """
+ text = str(text)
+ if text != self._text:
+ self._text = text
+ self._updated()
+
+ def getXPosition(self):
+ """Returns the X position of the marker line in data coordinates
+
+ :rtype: float or None
+ """
+ return self._x
+
+ def getYPosition(self):
+ """Returns the Y position of the marker line in data coordinates
+
+ :rtype: float or None
+ """
+ return self._y
+
+ def getPosition(self):
+ """Returns the (x, y) position of the marker in data coordinates
+
+ :rtype: 2-tuple of float or None
+ """
+ return self._x, self._y
+
+ def setPosition(self, x, y):
+ """Set marker position in data coordinates
+
+ Constraint are applied if any.
+
+ :param float x: X coordinates in data frame
+ :param float y: Y coordinates in data frame
+ """
+ x, y = self.getConstraint()(x, y)
+ x, y = float(x), float(y)
+ if x != self._x or y != self._y:
+ self._x, self._y = x, y
+ self._updated()
+
+ def getConstraint(self):
+ """Returns the dragging constraint of this item"""
+ return self._constraint
+
+ def _setConstraint(self, constraint): # TODO support update
+ """Set the constraint.
+
+ This is private for now as update is not handled.
+
+ :param callable constraint:
+ :param constraint: A function filtering item displacement by
+ dragging operations or None for no filter.
+ This function is called each time the item is
+ moved.
+ This is only used if isDraggable returns True.
+ :type constraint: None or a callable that takes the coordinates of
+ the current cursor position in the plot as input
+ and that returns the filtered coordinates.
+ """
+ if constraint is None:
+ constraint = self._defaultConstraint
+ assert callable(constraint)
+ self._constraint = constraint
+
+ @staticmethod
+ def _defaultConstraint(*args):
+ """Default constraint not doing anything"""
+ return args
+
+
+class Marker(_BaseMarker, SymbolMixIn):
+ """Description of a marker"""
+
+ _DEFAULT_SYMBOL = '+'
+ """Default symbol of the marker"""
+
+ def __init__(self):
+ _BaseMarker.__init__(self)
+ SymbolMixIn.__init__(self)
+
+ self._x = 0.
+ self._y = 0.
+
+ def _setConstraint(self, constraint):
+ """Set the constraint function of the marker drag.
+
+ It also supports 'horizontal' and 'vertical' str as constraint.
+
+ :param constraint: The constraint of the dragging of this marker
+ :type: constraint: callable or str
+ """
+ if constraint == 'horizontal':
+ constraint = self._horizontalConstraint
+ elif constraint == 'vertical':
+ constraint = self._verticalConstraint
+
+ super(Marker, self)._setConstraint(constraint)
+
+ def _horizontalConstraint(self, _, y):
+ return self.getXPosition(), y
+
+ def _verticalConstraint(self, x, _):
+ return x, self.getYPosition()
+
+
+class XMarker(_BaseMarker):
+ """Description of a marker"""
+
+ def __init__(self):
+ _BaseMarker.__init__(self)
+ self._x = 0.
+
+ def setPosition(self, x, y):
+ """Set marker line position in data coordinates
+
+ Constraint are applied if any.
+
+ :param float x: X coordinates in data frame
+ :param float y: Y coordinates in data frame
+ """
+ x, _ = self.getConstraint()(x, y)
+ x = float(x)
+ if x != self._x:
+ self._x = x
+ self._updated()
+
+
+class YMarker(_BaseMarker):
+ """Description of a marker"""
+
+ def __init__(self):
+ _BaseMarker.__init__(self)
+ self._y = 0.
+
+ def setPosition(self, x, y):
+ """Set marker line position in data coordinates
+
+ Constraint are applied if any.
+
+ :param float x: X coordinates in data frame
+ :param float y: Y coordinates in data frame
+ """
+ _, y = self.getConstraint()(x, y)
+ y = float(y)
+ if y != self._y:
+ self._y = y
+ self._updated()
diff --git a/silx/gui/plot/items/scatter.py b/silx/gui/plot/items/scatter.py
new file mode 100644
index 0000000..3897dc1
--- /dev/null
+++ b/silx/gui/plot/items/scatter.py
@@ -0,0 +1,169 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module provides the :class:`Scatter` item of the :class:`Plot`.
+"""
+
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "29/03/2017"
+
+
+import logging
+
+import numpy
+
+from .core import Points, ColormapMixIn
+from silx.gui.plot.Colors import applyColormapToData # TODO: cherry-pick commit or wait for PR merge
+
+_logger = logging.getLogger(__name__)
+
+
+class Scatter(Points, ColormapMixIn):
+ """Description of a scatter"""
+ _DEFAULT_SYMBOL = 'o'
+ """Default symbol of the scatter plots"""
+
+ def __init__(self):
+ Points.__init__(self)
+ ColormapMixIn.__init__(self)
+ self._value = ()
+
+ def _addBackendRenderer(self, backend):
+ """Update backend renderer"""
+ # Filter-out values <= 0
+ xFiltered, yFiltered, valueFiltered, xerror, yerror = self.getData(
+ copy=False, displayed=True)
+
+ if len(xFiltered) == 0:
+ return None # No data to display, do not add renderer to backend
+
+ cmap = self.getColormap()
+ rgbacolors = applyColormapToData(self._value,
+ cmap["name"],
+ cmap["normalization"],
+ cmap["autoscale"],
+ cmap["vmin"],
+ cmap["vmax"],
+ cmap.get("colors"))
+
+ return backend.addCurve(xFiltered, yFiltered, self.getLegend(),
+ color=rgbacolors,
+ symbol=self.getSymbol(),
+ linewidth=0,
+ linestyle="",
+ yaxis='left',
+ xerror=xerror,
+ yerror=yerror,
+ z=self.getZValue(),
+ selectable=self.isSelectable(),
+ fill=False,
+ alpha=self.getAlpha(),
+ symbolsize=self.getSymbolSize())
+
+ def _logFilterData(self, xPositive, yPositive):
+ """Filter out values with x or y <= 0 on log axes
+
+ :param bool xPositive: True to filter arrays according to X coords.
+ :param bool yPositive: True to filter arrays according to Y coords.
+ :return: The filtered arrays or unchanged object if not filtering needed
+ :rtype: (x, y, value, xerror, yerror)
+ """
+ # overloaded from Points to filter also value.
+ value = self.getValueData(copy=False)
+
+ if xPositive or yPositive:
+ clipped = self._getClippingBoolArray(xPositive, yPositive)
+
+ if numpy.any(clipped):
+ # copy to keep original array and convert to float
+ value = numpy.array(value, copy=True, dtype=numpy.float)
+ value[clipped] = numpy.nan
+
+ x, y, xerror, yerror = Points._logFilterData(self, xPositive, yPositive)
+
+ return x, y, value, xerror, yerror
+
+ def getValueData(self, copy=True):
+ """Returns the value assigned to the scatter data points.
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :rtype: numpy.ndarray
+ """
+ return numpy.array(self._value, copy=copy)
+
+ def getData(self, copy=True, displayed=False):
+ """Returns the x, y coordinates and the value of the data points
+
+ :param copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :param bool displayed: True to only get curve points that are displayed
+ in the plot. Default: False.
+ Note: If plot has log scale, negative points
+ are not displayed.
+ :returns: (x, y, value, xerror, yerror)
+ :rtype: 5-tuple of numpy.ndarray
+ """
+ if displayed:
+ data = self._getCachedData()
+ if data is not None:
+ assert len(data) == 5
+ return data
+
+ return (self.getXData(copy),
+ self.getYData(copy),
+ self.getValueData(copy),
+ self.getXErrorData(copy),
+ self.getYErrorData(copy))
+
+ # reimplemented from Points to handle `value`
+ def setData(self, x, y, value, xerror=None, yerror=None, copy=True):
+ """Set the data of the scatter.
+
+ :param numpy.ndarray x: The data corresponding to the x coordinates.
+ :param numpy.ndarray y: The data corresponding to the y coordinates.
+ :param numpy.ndarray value: The data corresponding to the value of
+ the data points.
+ :param xerror: Values with the uncertainties on the x values
+ :type xerror: A float, or a numpy.ndarray of float32.
+ If it is an array, it can either be a 1D array of
+ same length as the data or a 2D array with 2 rows
+ of same length as the data: row 0 for positive errors,
+ row 1 for negative errors.
+ :param yerror: Values with the uncertainties on the y values
+ :type yerror: A float, or a numpy.ndarray of float32. See xerror.
+ :param bool copy: True make a copy of the data (default),
+ False to use provided arrays.
+ """
+ value = numpy.array(value, copy=copy)
+ assert value.ndim == 1
+ assert len(x) == len(value)
+
+ self._value = value
+
+ # set x, y, xerror, yerror
+
+ # call self._updated + plot._invalidateDataRange()
+ Points.setData(self, x, y, xerror, yerror, copy)
diff --git a/silx/gui/plot/items/shape.py b/silx/gui/plot/items/shape.py
new file mode 100644
index 0000000..b663989
--- /dev/null
+++ b/silx/gui/plot/items/shape.py
@@ -0,0 +1,121 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module provides the :class:`Shape` item of the :class:`Plot`.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "06/03/2017"
+
+
+import logging
+
+import numpy
+
+from .core import Item, ColorMixIn, FillMixIn
+
+
+_logger = logging.getLogger(__name__)
+
+
+# TODO probably make one class for each kind of shape
+# TODO check fill:polygon/polyline + fill = duplicated
+class Shape(Item, ColorMixIn, FillMixIn):
+ """Description of a shape item
+
+ :param str type_: The type of shape in:
+ 'hline', 'polygon', 'rectangle', 'vline', 'polyline'
+ """
+
+ def __init__(self, type_):
+ Item.__init__(self)
+ ColorMixIn.__init__(self)
+ FillMixIn.__init__(self)
+ self._overlay = False
+ assert type_ in ('hline', 'polygon', 'rectangle', 'vline', 'polyline')
+ self._type = type_
+ self._points = ()
+
+ self._handle = None
+
+ def _addBackendRenderer(self, backend):
+ """Update backend renderer"""
+ points = self.getPoints(copy=False)
+ x, y = points.T[0], points.T[1]
+ return backend.addItem(x,
+ y,
+ legend=self.getLegend(),
+ shape=self.getType(),
+ color=self.getColor(),
+ fill=self.isFill(),
+ overlay=self.isOverlay(),
+ z=self.getZValue())
+
+ def isOverlay(self):
+ """Return true if shape is drawn as an overlay
+
+ :rtype: bool
+ """
+ return self._overlay
+
+ def setOverlay(self, overlay):
+ """Set the overlay state of the shape
+
+ :param bool overlay: True to make it an overlay
+ """
+ overlay = bool(overlay)
+ if overlay != self._overlay:
+ self._overlay = overlay
+ self._updated()
+
+ def getType(self):
+ """Returns the type of shape to draw.
+
+ One of: 'hline', 'polygon', 'rectangle', 'vline', 'polyline'
+
+ :rtype: str
+ """
+ return self._type
+
+ def getPoints(self, copy=True):
+ """Get the control points of the shape.
+
+ :param bool copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :return: Array of point coordinates
+ :rtype: numpy.ndarray with 2 dimensions
+ """
+ return numpy.array(self._points, copy=copy)
+
+ def setPoints(self, points, copy=True):
+ """Set the point coordinates
+
+ :param numpy.ndarray points: Array of point coordinates
+ :param bool copy: True (Default) to get a copy,
+ False to use internal representation (do not modify!)
+ :return:
+ """
+ self._points = numpy.array(points, copy=copy)
+ self._updated()
diff --git a/silx/gui/plot/setup.py b/silx/gui/plot/setup.py
new file mode 100644
index 0000000..6408113
--- /dev/null
+++ b/silx/gui/plot/setup.py
@@ -0,0 +1,47 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "16/02/2016"
+
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('plot', parent_package, top_path)
+ config.add_subpackage('_utils')
+ config.add_subpackage('backends')
+ config.add_subpackage('backends.glutils')
+ config.add_subpackage('items')
+ config.add_subpackage('test')
+
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/gui/plot/test/__init__.py b/silx/gui/plot/test/__init__.py
new file mode 100644
index 0000000..b4378c7
--- /dev/null
+++ b/silx/gui/plot/test/__init__.py
@@ -0,0 +1,71 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/02/2016"
+
+
+import unittest
+
+from .._utils.test import suite as testUtilsSuite
+from .testColorBar import suite as testColorBarSuite
+from .testColormapDialog import suite as testColormapDialogSuite
+from .testColors import suite as testColorsSuite
+from .testCurvesROIWidget import suite as testCurvesROIWidgetSuite
+from .testAlphaSlider import suite as testAlphaSliderSuite
+from .testInteraction import suite as testInteractionSuite
+from .testLegendSelector import suite as testLegendSelectorSuite
+from .testMaskToolsWidget import suite as testMaskToolsWidgetSuite
+from .testScatterMaskToolsWidget import suite as testScatterMaskToolsWidgetSuite
+from .testPlotInteraction import suite as testPlotInteractionSuite
+from .testPlotTools import suite as testPlotToolsSuite
+from .testPlotWidget import suite as testPlotWidgetSuite
+from .testPlotWindow import suite as testPlotWindowSuite
+from .testPlot import suite as testPlotSuite
+from .testProfile import suite as testProfileSuite
+from .testStackView import suite as testStackViewSuite
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTests(
+ [testUtilsSuite(),
+ testColorBarSuite(),
+ testColorsSuite(),
+ testColormapDialogSuite(),
+ testCurvesROIWidgetSuite(),
+ testAlphaSliderSuite(),
+ testInteractionSuite(),
+ testLegendSelectorSuite(),
+ testMaskToolsWidgetSuite(),
+ testScatterMaskToolsWidgetSuite(),
+ testPlotInteractionSuite(),
+ testPlotSuite(),
+ testPlotToolsSuite(),
+ testPlotWidgetSuite(),
+ testPlotWindowSuite(),
+ testProfileSuite(),
+ testStackViewSuite()])
+ return test_suite
diff --git a/silx/gui/plot/test/testAlphaSlider.py b/silx/gui/plot/test/testAlphaSlider.py
new file mode 100644
index 0000000..304a562
--- /dev/null
+++ b/silx/gui/plot/test/testAlphaSlider.py
@@ -0,0 +1,221 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""Tests for ImageAlphaSlider"""
+
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "28/03/2017"
+
+import numpy
+import unittest
+
+from silx.gui import qt
+from silx.gui.test.utils import TestCaseQt
+from silx.gui.plot import PlotWidget
+from silx.gui.plot import AlphaSlider
+
+# Makes sure a QApplication exists
+_qapp = qt.QApplication.instance() or qt.QApplication([])
+
+
+class TestActiveImageAlphaSlider(TestCaseQt):
+ def setUp(self):
+ super(TestActiveImageAlphaSlider, self).setUp()
+ self.plot = PlotWidget()
+ self.aslider = AlphaSlider.ActiveImageAlphaSlider(plot=self.plot)
+ self.aslider.setOrientation(qt.Qt.Horizontal)
+
+ toolbar = qt.QToolBar("plot", self.plot)
+ toolbar.addWidget(self.aslider)
+ self.plot.addToolBar(toolbar)
+
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+
+ self.mouseMove(self.plot) # Move to center
+ self.qapp.processEvents()
+
+ def tearDown(self):
+ self.qapp.processEvents()
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+ del self.aslider
+
+ super(TestActiveImageAlphaSlider, self).tearDown()
+
+ def testWidgetEnabled(self):
+ # no active image initially, slider must be deactivate
+ self.assertFalse(self.aslider.isEnabled())
+
+ self.plot.addImage(numpy.array([[0, 1, 2], [3, 4, 5]]))
+ # now we have an active image
+ self.assertTrue(self.aslider.isEnabled())
+
+ self.plot.setActiveImage(None)
+ self.assertFalse(self.aslider.isEnabled())
+
+ def testGetImage(self):
+ self.plot.addImage(numpy.array([[0, 1, 2], [3, 4, 5]]))
+ self.assertEqual(self.plot.getActiveImage(),
+ self.aslider.getItem())
+
+ self.plot.addImage(numpy.array([[0, 1, 3], [2, 4, 6]]), legend="2")
+ self.plot.setActiveImage("2")
+ self.assertEqual(self.plot.getImage("2"),
+ self.aslider.getItem())
+
+ def testGetAlpha(self):
+ self.plot.addImage(numpy.array([[0, 1, 2], [3, 4, 5]]), legend="1")
+ self.aslider.setValue(137)
+ self.assertAlmostEqual(self.aslider.getAlpha(),
+ 137. / 255)
+
+
+class TestNamedImageAlphaSlider(TestCaseQt):
+ def setUp(self):
+ super(TestNamedImageAlphaSlider, self).setUp()
+ self.plot = PlotWidget()
+ self.aslider = AlphaSlider.NamedImageAlphaSlider(plot=self.plot)
+ self.aslider.setOrientation(qt.Qt.Horizontal)
+
+ toolbar = qt.QToolBar("plot", self.plot)
+ toolbar.addWidget(self.aslider)
+ self.plot.addToolBar(toolbar)
+
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+
+ self.mouseMove(self.plot) # Move to center
+ self.qapp.processEvents()
+
+ def tearDown(self):
+ self.qapp.processEvents()
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+ del self.aslider
+
+ super(TestNamedImageAlphaSlider, self).tearDown()
+
+ def testWidgetEnabled(self):
+ # no image set initially, slider must be deactivate
+ self.assertFalse(self.aslider.isEnabled())
+
+ self.plot.addImage(numpy.array([[0, 1, 2], [3, 4, 5]]), legend="1")
+ self.aslider.setLegend("1")
+ # now we have an image set
+ self.assertTrue(self.aslider.isEnabled())
+
+ def testGetImage(self):
+ self.plot.addImage(numpy.array([[0, 1, 2], [3, 4, 5]]), legend="1")
+ self.plot.addImage(numpy.array([[0, 1, 3], [2, 4, 6]]), legend="2")
+ self.aslider.setLegend("1")
+ self.assertEqual(self.plot.getImage("1"),
+ self.aslider.getItem())
+
+ self.aslider.setLegend("2")
+ self.assertEqual(self.plot.getImage("2"),
+ self.aslider.getItem())
+
+ def testGetAlpha(self):
+ self.plot.addImage(numpy.array([[0, 1, 2], [3, 4, 5]]), legend="1")
+ self.aslider.setLegend("1")
+ self.aslider.setValue(128)
+ self.assertAlmostEqual(self.aslider.getAlpha(),
+ 128. / 255)
+
+
+class TestNamedScatterAlphaSlider(TestCaseQt):
+ def setUp(self):
+ super(TestNamedScatterAlphaSlider, self).setUp()
+ self.plot = PlotWidget()
+ self.aslider = AlphaSlider.NamedScatterAlphaSlider(plot=self.plot)
+ self.aslider.setOrientation(qt.Qt.Horizontal)
+
+ toolbar = qt.QToolBar("plot", self.plot)
+ toolbar.addWidget(self.aslider)
+ self.plot.addToolBar(toolbar)
+
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+
+ self.mouseMove(self.plot) # Move to center
+ self.qapp.processEvents()
+
+ def tearDown(self):
+ self.qapp.processEvents()
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+ del self.aslider
+
+ super(TestNamedScatterAlphaSlider, self).tearDown()
+
+ def testWidgetEnabled(self):
+ # no Scatter set initially, slider must be deactivate
+ self.assertFalse(self.aslider.isEnabled())
+
+ self.plot.addScatter([0, 1, 2], [2, 3, 4], [5, 6, 7],
+ legend="1")
+ self.aslider.setLegend("1")
+ # now we have an image set
+ self.assertTrue(self.aslider.isEnabled())
+
+ def testGetScatter(self):
+ self.plot.addScatter([0, 1, 2], [2, 3, 4], [5, 6, 7],
+ legend="1")
+ self.plot.addScatter([0, 10, 20], [20, 30, 40], [50, 60, 70],
+ legend="2")
+ self.aslider.setLegend("1")
+ self.assertEqual(self.plot.getScatter("1"),
+ self.aslider.getItem())
+
+ self.aslider.setLegend("2")
+ self.assertEqual(self.plot.getScatter("2"),
+ self.aslider.getItem())
+
+ def testGetAlpha(self):
+ self.plot.addScatter([0, 10, 20], [20, 30, 40], [50, 60, 70],
+ legend="1")
+ self.aslider.setLegend("1")
+ self.aslider.setValue(128)
+ self.assertAlmostEqual(self.aslider.getAlpha(),
+ 128. / 255)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ # test_suite.addTest(positionInfoTestSuite)
+ for testClass in (TestActiveImageAlphaSlider, TestNamedImageAlphaSlider,
+ TestNamedScatterAlphaSlider):
+ test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(
+ testClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testColorBar.py b/silx/gui/plot/test/testColorBar.py
new file mode 100644
index 0000000..797ff03
--- /dev/null
+++ b/silx/gui/plot/test/testColorBar.py
@@ -0,0 +1,240 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Basic tests for ColorBar featues and sub widgets of Colorbar module"""
+
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "11/04/2017"
+
+import unittest
+from silx.gui.test.utils import TestCaseQt
+from silx.gui.plot.ColorBar import _ColorScale
+from silx.gui.plot.ColorBar import ColorBarWidget
+from silx.gui.plot import Plot2D
+import numpy
+
+
+class TestColorScale(unittest.TestCase):
+ """Test that interaction with the colorScale is correct"""
+ def setUp(self):
+ self.colorScaleWidget = _ColorScale(colormap=None, parent=None)
+
+ def tearDown(self):
+ self.colorScaleWidget.deleteLater()
+ self.colorScaleWidget = None
+
+ def testRelativePositionLinear(self):
+ self.colorMapLin1 = { 'name': 'gray', 'normalization': 'linear',
+ 'autoscale': False, 'vmin': 0.0, 'vmax': 1.0 }
+ self.colorScaleWidget.setColormap(self.colorMapLin1)
+
+ self.assertTrue(
+ self.colorScaleWidget.getValueFromRelativePosition(0.25) == 0.25)
+ self.assertTrue(
+ self.colorScaleWidget.getValueFromRelativePosition(0.5) == 0.5)
+ self.assertTrue(
+ self.colorScaleWidget.getValueFromRelativePosition(1.0) == 1.0)
+
+ self.colorMapLin2 = { 'name': 'viridis', 'normalization': 'linear',
+ 'autoscale': False, 'vmin': -10, 'vmax': 0 }
+ self.colorScaleWidget.setColormap(self.colorMapLin2)
+
+ self.assertTrue(
+ self.colorScaleWidget.getValueFromRelativePosition(0.25) == -7.5)
+ self.assertTrue(
+ self.colorScaleWidget.getValueFromRelativePosition(0.5) == -5.0)
+ self.assertTrue(
+ self.colorScaleWidget.getValueFromRelativePosition(1.0) == 0.0)
+
+ def testRelativePositionLog(self):
+ self.colorMapLog1 = { 'name': 'temperature', 'normalization': 'log',
+ 'autoscale': False, 'vmin': 1.0, 'vmax': 100.0 }
+
+ self.colorScaleWidget.setColormap(self.colorMapLog1)
+
+ val = self.colorScaleWidget.getValueFromRelativePosition(1.0)
+ self.assertTrue(val == 100.0)
+
+ val = self.colorScaleWidget.getValueFromRelativePosition(0.5)
+ self.assertTrue(val == 10.0)
+
+ val = self.colorScaleWidget.getValueFromRelativePosition(0.0)
+ self.assertTrue(val == 1.0)
+
+ def testNegativeLogMin(self):
+ colormap = { 'name': 'gray', 'normalization': 'log',
+ 'autoscale': False, 'vmin': -1.0, 'vmax': 1.0 }
+
+ with self.assertRaises(ValueError):
+ self.colorScaleWidget.setColormap(colormap)
+
+ def testNegativeLogMax(self):
+ colormap = { 'name': 'gray', 'normalization': 'log',
+ 'autoscale': False, 'vmin': 1.0, 'vmax': -1.0 }
+
+ with self.assertRaises(ValueError):
+ self.colorScaleWidget.setColormap(colormap)
+
+class TestNoAutoscale(unittest.TestCase):
+ """Test that ticks and color displayed are correct in the case of a colormap
+ with no autoscale
+ """
+
+ def setUp(self):
+ self.plot = Plot2D()
+ self.colorBar = ColorBarWidget(parent=None, plot=self.plot)
+ self.tickBar = self.colorBar.getColorScaleBar().getTickBar()
+ self.colorScale = self.colorBar.getColorScaleBar().getColorScale()
+
+ def tearDown(self):
+ self.tickBar = None
+ self.colorScale = None
+ del self.colorBar
+ self.plot.close()
+ del self.plot
+
+ def testLogNormNoAutoscale(self):
+ colormapLog = { 'name': 'gray', 'normalization': 'log',
+ 'autoscale': False, 'vmin': 1.0, 'vmax': 100.0 }
+
+ data = numpy.linspace(10, 1e10, 9).reshape(3, 3)
+ self.plot.addImage(data=data, colormap=colormapLog, legend='toto')
+ self.plot.setActiveImage('toto')
+
+ # test Ticks
+ self.tickBar.setTicksNumber(10)
+ self.tickBar.computeTicks()
+
+ ticksTh = numpy.linspace(1.0, 100.0, 10)
+ ticksTh = 10**ticksTh
+ numpy.array_equal(self.tickBar.ticks, ticksTh)
+
+ # test ColorScale
+ val = self.colorScale.getValueFromRelativePosition(1.0)
+ self.assertTrue(val == 100.0)
+
+ val = self.colorScale.getValueFromRelativePosition(0.0)
+ self.assertTrue(val == 1.0)
+
+ def testLinearNormNoAutoscale(self):
+ colormapLog = { 'name': 'gray', 'normalization': 'linear',
+ 'autoscale': False, 'vmin': -4, 'vmax': 5 }
+
+ data = numpy.linspace(1, 9, 9).reshape(3, 3)
+ self.plot.addImage(data=data, colormap=colormapLog, legend='toto')
+ self.plot.setActiveImage('toto')
+
+ # test Ticks
+ self.tickBar.setTicksNumber(10)
+ self.tickBar.computeTicks()
+
+ numpy.array_equal(self.tickBar.ticks, numpy.linspace(-4, 5, 10))
+
+ # test ColorScale
+ val = self.colorScale.getValueFromRelativePosition(1.0)
+ self.assertTrue(val == 5.0)
+
+ val = self.colorScale.getValueFromRelativePosition(0.0)
+ self.assertTrue(val == -4.0)
+
+class TestColorbarWidget(TestCaseQt):
+ """Test interaction with the ColorScaleBar"""
+
+ def setUp(self):
+ super(TestColorbarWidget, self).setUp()
+ self.plot = Plot2D()
+ self.colorBar = ColorBarWidget(parent=None, plot=self.plot)
+
+ def tearDown(self):
+ del self.colorBar
+ self.plot.close()
+ del self.plot
+
+ super(TestColorbarWidget, self).tearDown()
+
+ def testEmptyColorBar(self):
+ colorBar = ColorBarWidget(parent=None)
+ colorBar.show()
+ self.qWaitForWindowExposed(colorBar)
+
+ def testNegativeColormaps(self):
+ """test the behavior of the ColorBarWidget in the case of negative
+ values
+
+ Note : colorbar is modified by the Plot directly not ColorBarWidget
+ """
+ colormapLog = { 'name': 'gray', 'normalization': 'log',
+ 'autoscale': True, 'vmin': -1.0, 'vmax': 1.0 }
+
+ colormapLog2 = { 'name': 'gray', 'normalization': 'log',
+ 'autoscale': False, 'vmin': -1.0, 'vmax': 1.0 }
+
+ data = numpy.array([-5, -4, 0, 2, 3, 5, 10, 20, 30])
+ data = data.reshape(3, 3)
+ self.plot.addImage(data=data, colormap=colormapLog, legend='toto')
+ self.plot.setActiveImage('toto')
+
+ # default behavior when autoscale : set to minmal positive value
+ data[data<1] = data.max()
+ self.assertTrue(self.colorBar._colormap['vmin'] == data.min())
+ self.assertTrue(self.colorBar._colormap['vmax'] == data.max())
+
+ data = numpy.linspace(-9, -2, 100).reshape(10, 10)
+
+ self.plot.addImage(data=data, colormap=colormapLog2, legend='toto')
+ self.plot.setActiveImage('toto')
+ # if negative values, changing bounds for default : 1, 10
+ self.assertTrue(self.colorBar._colormap['vmin'] == 1)
+ self.assertTrue(self.colorBar._colormap['vmax'] == 10)
+
+ def testPlotAssocation(self):
+ """Make sure the ColorBarWidget is proparly connected with the plot"""
+ colormap = { 'name': 'gray', 'normalization': 'linear',
+ 'autoscale': True, 'vmin': -1.0, 'vmax': 1.0 }
+
+ # make sure that default settings are the same
+ self.assertTrue(
+ self.colorBar.getColormap() == self.plot.getDefaultColormap())
+
+ data = numpy.linspace(0, 10, 100).reshape(10, 10)
+ self.plot.addImage(data=data, colormap=colormap, legend='toto')
+ self.plot.setActiveImage('toto')
+
+ # make sure the modification of the colormap has been done
+ self.assertFalse(
+ self.colorBar.getColormap() == self.plot.getDefaultColormap())
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for ui in (TestColorScale, TestNoAutoscale, TestColorbarWidget):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(ui))
+
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite') \ No newline at end of file
diff --git a/silx/gui/plot/test/testColormapDialog.py b/silx/gui/plot/test/testColormapDialog.py
new file mode 100644
index 0000000..d016548
--- /dev/null
+++ b/silx/gui/plot/test/testColormapDialog.py
@@ -0,0 +1,68 @@
+# 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.
+#
+# ###########################################################################*/
+"""Basic tests for ColormapDialog"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import doctest
+import unittest
+
+from silx.gui.test.utils import qWaitForWindowExposedAndActivate
+from silx.gui import qt
+from silx.gui.plot import ColormapDialog
+
+
+# Makes sure a QApplication exists
+_qapp = qt.QApplication.instance() or qt.QApplication([])
+
+
+def _tearDownQt(docTest):
+ """Tear down to use for test from docstring.
+
+ Checks that dialog widget is displayed
+ """
+ dialogWidget = docTest.globs['dialog']
+ qWaitForWindowExposedAndActivate(dialogWidget)
+ dialogWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
+ dialogWidget.close()
+ del dialogWidget
+ _qapp.processEvents()
+
+
+cmapDocTestSuite = doctest.DocTestSuite(ColormapDialog, tearDown=_tearDownQt)
+"""Test suite of tests from the module's docstrings."""
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(cmapDocTestSuite)
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testColors.py b/silx/gui/plot/test/testColors.py
new file mode 100644
index 0000000..94c22f3
--- /dev/null
+++ b/silx/gui/plot/test/testColors.py
@@ -0,0 +1,94 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Basic tests for Colors"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import numpy
+
+import unittest
+from silx.test.utils import ParametricTestCase
+
+from silx.gui.plot import Colors
+
+
+class TestRGBA(ParametricTestCase):
+ """Basic tests of rgba function"""
+
+ def testRGBA(self):
+ """"Test rgba function with accepted values"""
+ tests = { # name: (colors, expected values)
+ 'blue': ('blue', (0., 0., 1., 1.)),
+ '#010203': ('#010203', (1. / 255., 2. / 255., 3. / 255., 1.)),
+ '#01020304': ('#01020304', (1. / 255., 2. / 255., 3. / 255., 4. / 255.)),
+ '3 x uint8': (numpy.array((1, 255, 0), dtype=numpy.uint8),
+ (1 / 255., 1., 0., 1.)),
+ '4 x uint8': (numpy.array((1, 255, 0, 1), dtype=numpy.uint8),
+ (1 / 255., 1., 0., 1 / 255.)),
+ '3 x float overflow': ((3., 0.5, 1.), (1., 0.5, 1., 1.)),
+ }
+
+ for name, test in tests.items():
+ color, expected = test
+ with self.subTest(msg=name):
+ result = Colors.rgba(color)
+ self.assertEqual(result, expected)
+
+
+class TestApplyColormapToData(ParametricTestCase):
+ """Tests of applyColormapToData function"""
+
+ def testApplyColormapToData(self):
+ """Simple test of applyColormapToData function"""
+ colormap = dict(name='gray', normalization='linear',
+ autoscale=False, vmin=0, vmax=255)
+
+ size = 10
+ expected = numpy.empty((size, 4), dtype='uint8')
+ expected[:, 0] = numpy.arange(size, dtype='uint8')
+ expected[:, 1] = expected[:, 0]
+ expected[:, 2] = expected[:, 0]
+ expected[:, 3] = 255
+
+ for dtype in ('uint8', 'int32', 'float32', 'float64'):
+ with self.subTest(dtype=dtype):
+ array = numpy.arange(size, dtype=dtype)
+ result = Colors.applyColormapToData(array, **colormap)
+ self.assertTrue(numpy.all(numpy.equal(result, expected)))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for testClass in (TestRGBA, TestApplyColormapToData):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(testClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testCurvesROIWidget.py b/silx/gui/plot/test/testCurvesROIWidget.py
new file mode 100644
index 0000000..3c6f2ba
--- /dev/null
+++ b/silx/gui/plot/test/testCurvesROIWidget.py
@@ -0,0 +1,153 @@
+# 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.
+#
+# ###########################################################################*/
+"""Basic tests for CurvesROIWidget"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import logging
+import os.path
+import unittest
+
+import numpy
+
+from silx.gui import qt
+from silx.test.utils import temp_dir
+from silx.gui.test.utils import TestCaseQt
+from silx.gui.plot import PlotWindow, CurvesROIWidget
+
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+
+class TestCurvesROIWidget(TestCaseQt):
+ """Basic test for CurvesROIWidget"""
+
+ def setUp(self):
+ super(TestCurvesROIWidget, self).setUp()
+ self.plot = PlotWindow()
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+
+ self.widget = CurvesROIWidget.CurvesROIDockWidget(plot=self.plot, name='TEST')
+ self.widget.show()
+ self.qWaitForWindowExposed(self.widget)
+
+ def tearDown(self):
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+
+ self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.widget.close()
+ del self.widget
+
+ super(TestCurvesROIWidget, self).tearDown()
+
+ def testEmptyPlot(self):
+ """Empty plot, display ROI widget"""
+ pass
+
+ def testWithCurves(self):
+ """Plot with curves: test all ROI widget buttons"""
+ for offset in range(2):
+ self.plot.addCurve(numpy.arange(1000),
+ offset + numpy.random.random(1000),
+ legend=str(offset))
+
+ # Add two ROI
+ self.mouseClick(self.widget.roiWidget.addButton, qt.Qt.LeftButton)
+ self.mouseClick(self.widget.roiWidget.addButton, qt.Qt.LeftButton)
+
+ # Change active curve
+ self.plot.setActiveCurve(str(1))
+
+ # Delete a ROI
+ self.mouseClick(self.widget.roiWidget.delButton, qt.Qt.LeftButton)
+
+ with temp_dir() as tmpDir:
+ self.tmpFile = os.path.join(tmpDir, 'test.ini')
+
+ # Save ROIs
+ self.widget.roiWidget.save(self.tmpFile)
+ self.assertTrue(os.path.isfile(self.tmpFile))
+
+ # Reset ROIs
+ self.mouseClick(self.widget.roiWidget.resetButton,
+ qt.Qt.LeftButton)
+
+ # Load ROIs
+ self.widget.roiWidget.load(self.tmpFile)
+
+ del self.tmpFile
+
+ def testCalculation(self):
+ x = numpy.arange(100.)
+ y = numpy.arange(100.)
+
+ # Add two curves
+ self.plot.addCurve(x, y, legend="positive")
+ self.plot.addCurve(-x, y, legend="negative")
+
+ # Make sure there is an active curve and it is the positive one
+ self.plot.setActiveCurve("positive")
+
+ # Add two ROIs
+ ddict = {}
+ ddict["positive"] = {"from": 10, "to": 20, "type":"X"}
+ ddict["negative"] = {"from": -20, "to": -10, "type":"X"}
+ self.widget.roiWidget.setRois(ddict)
+
+ # And calculate the expected output
+ self.widget.calculateROIs()
+
+ output = self.widget.roiWidget.getRois()
+ self.assertEqual(output["positive"]["rawcounts"],
+ y[ddict["positive"]["from"]:ddict["positive"]["to"]+1].sum(),
+ "Calculation failed on positive X coordinates")
+
+ # Set the curve with negative X coordinates as active
+ self.plot.setActiveCurve("negative")
+
+ # the ROIs should have been automatically updated
+ output = self.widget.roiWidget.getRois()
+ selection = numpy.nonzero((-x >= output["negative"]["from"]) & \
+ (-x <= output["negative"]["to"]))[0]
+ self.assertEqual(output["negative"]["rawcounts"],
+ y[selection].sum(), "Calculation failed on negative X coordinates")
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for TestClass in (TestCurvesROIWidget,):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testInteraction.py b/silx/gui/plot/test/testInteraction.py
new file mode 100644
index 0000000..074a7cd
--- /dev/null
+++ b/silx/gui/plot/test/testInteraction.py
@@ -0,0 +1,89 @@
+# 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.
+#
+# ###########################################################################*/
+"""Tests from interaction state machines"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/02/2016"
+
+
+import unittest
+
+from silx.gui.plot import Interaction
+
+
+class TestInteraction(unittest.TestCase):
+ def testClickOrDrag(self):
+ """Minimalistic test for click or drag state machine."""
+ events = []
+
+ class TestClickOrDrag(Interaction.ClickOrDrag):
+ def click(self, x, y, btn):
+ events.append(('click', x, y, btn))
+
+ def beginDrag(self, x, y):
+ events.append(('beginDrag', x, y))
+
+ def drag(self, x, y):
+ events.append(('drag', x, y))
+
+ def endDrag(self, x, y):
+ events.append(('endDrag', x, y))
+
+ clickOrDrag = TestClickOrDrag()
+
+ # click
+ clickOrDrag.handleEvent('press', 10, 10, Interaction.LEFT_BTN)
+ self.assertEqual(len(events), 0)
+
+ clickOrDrag.handleEvent('release', 10, 10, Interaction.LEFT_BTN)
+ self.assertEqual(len(events), 1)
+ self.assertEqual(events[0], ('click', 10, 10, Interaction.LEFT_BTN))
+
+ # drag
+ events = []
+ clickOrDrag.handleEvent('press', 10, 10, Interaction.LEFT_BTN)
+ self.assertEqual(len(events), 0)
+ clickOrDrag.handleEvent('move', 15, 10)
+ self.assertEqual(len(events), 2) # Received beginDrag and drag
+ self.assertEqual(events[0], ('beginDrag', 10, 10))
+ self.assertEqual(events[1], ('drag', 15, 10))
+ clickOrDrag.handleEvent('move', 20, 10)
+ self.assertEqual(len(events), 3)
+ self.assertEqual(events[-1], ('drag', 20, 10))
+ clickOrDrag.handleEvent('release', 20, 10, Interaction.LEFT_BTN)
+ self.assertEqual(len(events), 4)
+ self.assertEqual(events[-1], ('endDrag', (10, 10), (20, 10)))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestInteraction))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testLegendSelector.py b/silx/gui/plot/test/testLegendSelector.py
new file mode 100644
index 0000000..371197f
--- /dev/null
+++ b/silx/gui/plot/test/testLegendSelector.py
@@ -0,0 +1,143 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+# ###########################################################################*/
+"""Basic tests for PlotWidget"""
+
+__authors__ = ["T. Rueter", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import logging
+import unittest
+
+from silx.gui import qt
+from silx.gui.test.utils import TestCaseQt
+from silx.gui.plot import LegendSelector
+
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+
+class TestLegendSelector(TestCaseQt):
+ """Basic test for LegendSelector"""
+
+ def testLegendSelector(self):
+ """Test copied from __main__ of LegendSelector in PyMca"""
+ class Notifier(qt.QObject):
+ def __init__(self):
+ qt.QObject.__init__(self)
+ self.chk = True
+
+ def signalReceived(self, **kw):
+ obj = self.sender()
+ _logger.info('NOTIFIER -- signal received\n\tsender: %s',
+ str(obj))
+
+ notifier = Notifier()
+
+ legends = ['Legend0',
+ 'Legend1',
+ 'Long Legend 2',
+ 'Foo Legend 3',
+ 'Even Longer Legend 4',
+ 'Short Leg 5',
+ 'Dot symbol 6',
+ 'Comma symbol 7']
+ colors = [qt.Qt.darkRed, qt.Qt.green, qt.Qt.yellow, qt.Qt.darkCyan,
+ qt.Qt.blue, qt.Qt.darkBlue, qt.Qt.red, qt.Qt.darkYellow]
+ symbols = ['o', 't', '+', 'x', 's', 'd', '.', ',']
+
+ win = LegendSelector.LegendListView()
+ # win = LegendListContextMenu()
+ # win = qt.QWidget()
+ # layout = qt.QVBoxLayout()
+ # layout.setContentsMargins(0,0,0,0)
+ llist = []
+
+ for _idx, (l, c, s) in enumerate(zip(legends, colors, symbols)):
+ ddict = {
+ 'color': qt.QColor(c),
+ 'linewidth': 4,
+ 'symbol': s,
+ }
+ legend = l
+ llist.append((legend, ddict))
+ # item = qt.QListWidgetItem(win)
+ # legendWidget = LegendListItemWidget(l)
+ # legendWidget.icon.setSymbol(s)
+ # legendWidget.icon.setColor(qt.QColor(c))
+ # layout.addWidget(legendWidget)
+ # win.setItemWidget(item, legendWidget)
+
+ # win = LegendListItemWidget('Some Legend 1')
+ # print(llist)
+ model = LegendSelector.LegendModel(legendList=llist)
+ win.setModel(model)
+ win.setSelectionModel(qt.QItemSelectionModel(model))
+ win.setContextMenu()
+ # print('Edit triggers: %d'%win.editTriggers())
+
+ # win = LegendListWidget(None, legends)
+ # win[0].updateItem(ddict)
+ # win.setLayout(layout)
+ win.sigLegendSignal.connect(notifier.signalReceived)
+ win.show()
+
+ win.clear()
+ win.setLegendList(llist)
+
+ self.qWaitForWindowExposed(win)
+
+
+class TestRenameCurveDialog(TestCaseQt):
+ """Basic test for RenameCurveDialog"""
+
+ def testDialog(self):
+ """Create dialog, change name and press OK"""
+ self.dialog = LegendSelector.RenameCurveDialog(
+ None, 'curve1', ['curve1', 'curve2', 'curve3'])
+ self.dialog.open()
+ self.qWaitForWindowExposed(self.dialog)
+ self.keyClicks(self.dialog.lineEdit, 'changed')
+ self.mouseClick(self.dialog.okButton, qt.Qt.LeftButton)
+ self.qapp.processEvents()
+ ret = self.dialog.result()
+ self.assertEqual(ret, qt.QDialog.Accepted)
+ newName = self.dialog.getText()
+ self.assertEqual(newName, 'curve1changed')
+ del self.dialog
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for TestClass in (TestLegendSelector, TestRenameCurveDialog):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testMaskToolsWidget.py b/silx/gui/plot/test/testMaskToolsWidget.py
new file mode 100644
index 0000000..0c11928
--- /dev/null
+++ b/silx/gui/plot/test/testMaskToolsWidget.py
@@ -0,0 +1,295 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Basic tests for MaskToolsWidget"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "24/01/2017"
+
+
+import logging
+import os.path
+import unittest
+
+import numpy
+
+from silx.gui import qt
+from silx.test.utils import temp_dir, ParametricTestCase
+from silx.gui.test.utils import TestCaseQt, getQToolButtonFromAction
+from silx.gui.plot import PlotWindow, MaskToolsWidget
+
+try:
+ import fabio
+except ImportError:
+ fabio = None
+
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+
+class TestMaskToolsWidget(TestCaseQt, ParametricTestCase):
+ """Basic test for MaskToolsWidget"""
+
+ def setUp(self):
+ super(TestMaskToolsWidget, self).setUp()
+ self.plot = PlotWindow()
+
+ self.widget = MaskToolsWidget.MaskToolsDockWidget(plot=self.plot, name='TEST')
+ self.plot.addDockWidget(qt.Qt.BottomDockWidgetArea, self.widget)
+
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+
+ self.maskWidget = self.widget.widget()
+
+ def tearDown(self):
+ del self.maskWidget
+ del self.widget
+
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+
+ super(TestMaskToolsWidget, self).tearDown()
+
+ def testEmptyPlot(self):
+ """Empty plot, display MaskToolsDockWidget, toggle multiple masks"""
+ self.maskWidget.setMultipleMasks('single')
+ self.qapp.processEvents()
+
+ self.maskWidget.setMultipleMasks('exclusive')
+ self.qapp.processEvents()
+
+ def _drag(self):
+ """Drag from plot center to offset position"""
+ plot = self.plot.centralWidget()
+ xCenter, yCenter = plot.width() // 2, plot.height() // 2
+ offset = min(plot.width(), plot.height()) // 10
+
+ pos0 = xCenter, yCenter
+ pos1 = xCenter + offset, yCenter + offset
+
+ self.mouseMove(plot, pos=pos0)
+ self.mousePress(plot, qt.Qt.LeftButton, pos=pos0)
+ self.mouseMove(plot, pos=pos1)
+ self.mouseRelease(plot, qt.Qt.LeftButton, pos=pos1)
+
+ def _drawPolygon(self):
+ """Draw a star polygon in the plot"""
+ plot = self.plot.centralWidget()
+ x, y = plot.width() // 2, plot.height() // 2
+ offset = min(plot.width(), plot.height()) // 10
+
+ star = [(x, y + offset),
+ (x - offset, y - offset),
+ (x + offset, y),
+ (x - offset, y),
+ (x + offset, y - offset)]
+
+ for pos in star:
+ self.mouseMove(plot, pos=pos)
+ btn = qt.Qt.LeftButton if pos != star[-1] else qt.Qt.RightButton
+ self.mouseClick(plot, btn, pos=pos)
+
+ def _drawPencil(self):
+ """Draw a star polygon in the plot"""
+ plot = self.plot.centralWidget()
+ x, y = plot.width() // 2, plot.height() // 2
+ offset = min(plot.width(), plot.height()) // 10
+
+ star = [(x, y + offset),
+ (x - offset, y - offset),
+ (x + offset, y),
+ (x - offset, y),
+ (x + offset, y - offset)]
+
+ self.mouseMove(plot, pos=star[0])
+ self.mousePress(plot, qt.Qt.LeftButton, pos=star[0])
+ for pos in star:
+ self.mouseMove(plot, pos=pos)
+ self.mouseRelease(
+ plot, qt.Qt.LeftButton, pos=star[-1])
+
+ def testWithAnImage(self):
+ """Plot with an image: test MaskToolsWidget interactions"""
+
+ # Add and remove a image (this should enable/disable GUI + change mask)
+ self.plot.addImage(numpy.random.random(1024**2).reshape(1024, 1024),
+ legend='test')
+ self.qapp.processEvents()
+
+ self.plot.remove('test', kind='image')
+ self.qapp.processEvents()
+
+ tests = [((0, 0), (1, 1)),
+ ((1000, 1000), (1, 1)),
+ ((0, 0), (-1, -1)),
+ ((1000, 1000), (-1, -1))]
+
+ for origin, scale in tests:
+ with self.subTest(origin=origin, scale=scale):
+ self.plot.addImage(numpy.arange(1024**2).reshape(1024, 1024),
+ legend='test',
+ origin=origin,
+ scale=scale)
+ self.qapp.processEvents()
+
+ # Test draw rectangle #
+ toolButton = getQToolButtonFromAction(self.maskWidget.rectAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ # mask
+ self.maskWidget.maskStateGroup.button(1).click()
+ self.qapp.processEvents()
+ self._drag()
+ self.assertFalse(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # unmask same region
+ self.maskWidget.maskStateGroup.button(0).click()
+ self.qapp.processEvents()
+ self._drag()
+ self.assertTrue(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # Test draw polygon #
+ toolButton = getQToolButtonFromAction(self.maskWidget.polygonAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ # mask
+ self.maskWidget.maskStateGroup.button(1).click()
+ self.qapp.processEvents()
+ self._drawPolygon()
+ self.assertFalse(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # unmask same region
+ self.maskWidget.maskStateGroup.button(0).click()
+ self.qapp.processEvents()
+ self._drawPolygon()
+ self.assertTrue(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # Test draw pencil #
+ toolButton = getQToolButtonFromAction(self.maskWidget.pencilAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ self.maskWidget.pencilSpinBox.setValue(10)
+ self.qapp.processEvents()
+
+ # mask
+ self.maskWidget.maskStateGroup.button(1).click()
+ self.qapp.processEvents()
+ self._drawPencil()
+ self.assertFalse(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # unmask same region
+ self.maskWidget.maskStateGroup.button(0).click()
+ self.qapp.processEvents()
+ self._drawPencil()
+ self.assertTrue(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # Test no draw tool #
+ toolButton = getQToolButtonFromAction(self.maskWidget.browseAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ self.plot.clear()
+
+ def __loadSave(self, file_format):
+ """Plot with an image: test MaskToolsWidget operations"""
+ self.plot.addImage(numpy.arange(1024**2).reshape(1024, 1024),
+ legend='test')
+ self.qapp.processEvents()
+
+ # Draw a polygon mask
+ toolButton = getQToolButtonFromAction(self.maskWidget.polygonAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+ self._drawPolygon()
+
+ ref_mask = self.maskWidget.getSelectionMask()
+ self.assertFalse(numpy.all(numpy.equal(ref_mask, 0)))
+
+ with temp_dir() as tmp:
+ mask_filename = os.path.join(tmp, 'mask.' + file_format)
+ self.maskWidget.save(mask_filename, file_format)
+
+ self.maskWidget.resetSelectionMask()
+ self.assertTrue(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ self.maskWidget.load(mask_filename)
+ self.assertTrue(numpy.all(numpy.equal(
+ self.maskWidget.getSelectionMask(), ref_mask)))
+
+ def testLoadSaveNpy(self):
+ self.__loadSave("npy")
+
+ def testLoadSaveFit2D(self):
+ if fabio is None:
+ self.skipTest("Fabio is missing")
+ self.__loadSave("msk")
+
+ def testSigMaskChangedEmitted(self):
+ self.plot.addImage(numpy.arange(512**2).reshape(512, 512),
+ legend='test')
+ self.plot.resetZoom()
+ self.qapp.processEvents()
+
+ l = []
+
+ def slot():
+ l.append(1)
+
+ self.maskWidget.sigMaskChanged.connect(slot)
+
+ # rectangle mask
+ toolButton = getQToolButtonFromAction(self.maskWidget.rectAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+ self.maskWidget.maskStateGroup.button(1).click()
+ self.qapp.processEvents()
+ self._drag()
+
+ self.assertGreater(len(l), 0)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for TestClass in (TestMaskToolsWidget,):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testPlot.py b/silx/gui/plot/test/testPlot.py
new file mode 100644
index 0000000..25e7511
--- /dev/null
+++ b/silx/gui/plot/test/testPlot.py
@@ -0,0 +1,633 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Basic tests for Plot"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import unittest
+from functools import reduce
+from silx.test.utils import ParametricTestCase
+
+import numpy
+
+from silx.gui.plot.Plot import Plot
+from silx.gui.plot.items.histogram import _getHistogramCurve, _computeEdges
+
+
+class TestPlot(unittest.TestCase):
+ """Basic tests of Plot without backend"""
+
+ def testPlotTitleLabels(self):
+ """Create a Plot and set the labels"""
+
+ plot = Plot(backend='none')
+
+ title, xlabel, ylabel = 'the title', 'x label', 'y label'
+ plot.setGraphTitle(title)
+ plot.setGraphXLabel(xlabel)
+ plot.setGraphYLabel(ylabel)
+
+ self.assertEqual(plot.getGraphTitle(), title)
+ self.assertEqual(plot.getGraphXLabel(), xlabel)
+ self.assertEqual(plot.getGraphYLabel(), ylabel)
+
+ def testAddNoRemove(self):
+ """add objects to the Plot"""
+
+ plot = Plot(backend='none')
+ plot.addCurve(x=(1, 2, 3), y=(3, 2, 1))
+ plot.addImage(numpy.arange(100.).reshape(10, -1))
+ plot.addItem(
+ numpy.array((1., 10.)), numpy.array((10., 10.)), shape="rectangle")
+ plot.addXMarker(10.)
+
+
+class TestPlotRanges(ParametricTestCase):
+ """Basic tests of Plot data ranges without backend"""
+
+ _getValidValues = {True: lambda ar: ar > 0,
+ False: lambda ar: numpy.ones(shape=ar.shape,
+ dtype=bool)}
+
+ @staticmethod
+ def _getRanges(arrays, are_logs):
+ gen = (TestPlotRanges._getValidValues[is_log](ar)
+ for (ar, is_log) in zip(arrays, are_logs))
+ indices = numpy.where(reduce(numpy.logical_and, gen))[0]
+ if len(indices) > 0:
+ ranges = [(ar[indices[0]], ar[indices[-1]]) for ar in arrays]
+ else:
+ ranges = [None] * len(arrays)
+
+ return ranges
+
+ @staticmethod
+ def _getRangesMinmax(ranges):
+ # TODO : error if None in ranges.
+ rangeMin = numpy.min([rng[0] for rng in ranges])
+ rangeMax = numpy.max([rng[1] for rng in ranges])
+ return rangeMin, rangeMax
+
+ def testDataRangeNoPlot(self):
+ """empty plot data range"""
+
+ plot = Plot(backend='none')
+
+ for logX, logY in ((False, False),
+ (True, False),
+ (True, True),
+ (False, True),
+ (False, False)):
+ with self.subTest(logX=logX, logY=logY):
+ plot.setXAxisLogarithmic(logX)
+ plot.setYAxisLogarithmic(logY)
+ dataRange = plot.getDataRange()
+ self.assertIsNone(dataRange.x)
+ self.assertIsNone(dataRange.y)
+ self.assertIsNone(dataRange.yright)
+
+ def testDataRangeLeft(self):
+ """left axis range"""
+
+ plot = Plot(backend='none')
+
+ xData = numpy.arange(10) - 4.9 # range : -4.9 , 4.1
+ yData = numpy.arange(10) - 6.9 # range : -6.9 , 2.1
+
+ plot.addCurve(x=xData,
+ y=yData,
+ legend='plot_0',
+ yaxis='left')
+
+ for logX, logY in ((False, False),
+ (True, False),
+ (True, True),
+ (False, True),
+ (False, False)):
+ with self.subTest(logX=logX, logY=logY):
+ plot.setXAxisLogarithmic(logX)
+ plot.setYAxisLogarithmic(logY)
+ dataRange = plot.getDataRange()
+ xRange, yRange = self._getRanges([xData, yData],
+ [logX, logY])
+ self.assertSequenceEqual(dataRange.x, xRange)
+ self.assertSequenceEqual(dataRange.y, yRange)
+ self.assertIsNone(dataRange.yright)
+
+ def testDataRangeRight(self):
+ """right axis range"""
+
+ plot = Plot(backend='none')
+ xData = numpy.arange(10) - 4.9 # range : -4.9 , 4.1
+ yData = numpy.arange(10) - 6.9 # range : -6.9 , 2.1
+ plot.addCurve(x=xData,
+ y=yData,
+ legend='plot_0',
+ yaxis='right')
+
+ for logX, logY in ((False, False),
+ (True, False),
+ (True, True),
+ (False, True),
+ (False, False)):
+ with self.subTest(logX=logX, logY=logY):
+ plot.setXAxisLogarithmic(logX)
+ plot.setYAxisLogarithmic(logY)
+ dataRange = plot.getDataRange()
+ xRange, yRange = self._getRanges([xData, yData],
+ [logX, logY])
+ self.assertSequenceEqual(dataRange.x, xRange)
+ self.assertIsNone(dataRange.y)
+ self.assertSequenceEqual(dataRange.yright, yRange)
+
+ def testDataRangeImage(self):
+ """image data range"""
+
+ origin = (-10, 25)
+ scale = (3., 8.)
+ image = numpy.arange(100.).reshape(20, 5)
+
+ plot = Plot(backend='none')
+ plot.addImage(image,
+ origin=origin, scale=scale)
+
+ xRange = numpy.array([0., image.shape[1] * scale[0]]) + origin[0]
+ yRange = numpy.array([0., image.shape[0] * scale[1]]) + origin[1]
+
+ ranges = {(False, False): (xRange, yRange),
+ (True, False): (None, None),
+ (True, True): (None, None),
+ (False, True): (None, None)}
+
+ for logX, logY in ((False, False),
+ (True, False),
+ (True, True),
+ (False, True),
+ (False, False)):
+ with self.subTest(logX=logX, logY=logY):
+ plot.setXAxisLogarithmic(logX)
+ plot.setYAxisLogarithmic(logY)
+ dataRange = plot.getDataRange()
+ xRange, yRange = ranges[logX, logY]
+ self.assertTrue(numpy.array_equal(dataRange.x, xRange),
+ msg='{0} != {1}'.format(dataRange.x, xRange))
+ self.assertTrue(numpy.array_equal(dataRange.y, yRange),
+ msg='{0} != {1}'.format(dataRange.y, yRange))
+ self.assertIsNone(dataRange.yright)
+
+ def testDataRangeLeftRight(self):
+ """right+left axis range"""
+
+ plot = Plot(backend='none')
+
+ xData_l = numpy.arange(10) - 0.9 # range : -0.9 , 8.1
+ yData_l = numpy.arange(10) - 1.9 # range : -1.9 , 7.1
+ plot.addCurve(x=xData_l,
+ y=yData_l,
+ legend='plot_l',
+ yaxis='left')
+
+ xData_r = numpy.arange(10) - 4.9 # range : -4.9 , 4.1
+ yData_r = numpy.arange(10) - 6.9 # range : -6.9 , 2.1
+ plot.addCurve(x=xData_r,
+ y=yData_r,
+ legend='plot_r',
+ yaxis='right')
+
+ for logX, logY in ((False, False),
+ (True, False),
+ (True, True),
+ (False, True),
+ (False, False)):
+ with self.subTest(logX=logX, logY=logY):
+ plot.setXAxisLogarithmic(logX)
+ plot.setYAxisLogarithmic(logY)
+ dataRange = plot.getDataRange()
+ xRangeL, yRangeL = self._getRanges([xData_l, yData_l],
+ [logX, logY])
+ xRangeR, yRangeR = self._getRanges([xData_r, yData_r],
+ [logX, logY])
+ xRangeLR = self._getRangesMinmax([xRangeL, xRangeR])
+ self.assertSequenceEqual(dataRange.x, xRangeLR)
+ self.assertSequenceEqual(dataRange.y, yRangeL)
+ self.assertSequenceEqual(dataRange.yright, yRangeR)
+
+ def testDataRangeCurveImage(self):
+ """right+left+image axis range"""
+
+ # overlapping ranges :
+ # image sets x min and y max
+ # plot_left sets y min
+ # plot_right sets x max (and yright)
+ plot = Plot(backend='none')
+
+ origin = (-10, 5)
+ scale = (3., 8.)
+ image = numpy.arange(100.).reshape(20, 5)
+
+ plot.addImage(image,
+ origin=origin, scale=scale, legend='image')
+
+ xData_l = numpy.arange(10) - 0.9 # range : -0.9 , 8.1
+ yData_l = numpy.arange(10) - 1.9 # range : -1.9 , 7.1
+ plot.addCurve(x=xData_l,
+ y=yData_l,
+ legend='plot_l',
+ yaxis='left')
+
+ xData_r = numpy.arange(10) + 4.1 # range : 4.1 , 13.1
+ yData_r = numpy.arange(10) - 0.9 # range : -0.9 , 8.1
+ plot.addCurve(x=xData_r,
+ y=yData_r,
+ legend='plot_r',
+ yaxis='right')
+
+ imgXRange = numpy.array([0., image.shape[1] * scale[0]]) + origin[0]
+ imgYRange = numpy.array([0., image.shape[0] * scale[1]]) + origin[1]
+
+ for logX, logY in ((False, False),
+ (True, False),
+ (True, True),
+ (False, True),
+ (False, False)):
+ with self.subTest(logX=logX, logY=logY):
+ plot.setXAxisLogarithmic(logX)
+ plot.setYAxisLogarithmic(logY)
+ dataRange = plot.getDataRange()
+ xRangeL, yRangeL = self._getRanges([xData_l, yData_l],
+ [logX, logY])
+ xRangeR, yRangeR = self._getRanges([xData_r, yData_r],
+ [logX, logY])
+ if logX or logY:
+ xRangeLR = self._getRangesMinmax([xRangeL, xRangeR])
+ else:
+ xRangeLR = self._getRangesMinmax([xRangeL,
+ xRangeR,
+ imgXRange])
+ yRangeL = self._getRangesMinmax([yRangeL, imgYRange])
+ self.assertSequenceEqual(dataRange.x, xRangeLR)
+ self.assertSequenceEqual(dataRange.y, yRangeL)
+ self.assertSequenceEqual(dataRange.yright, yRangeR)
+
+ def testDataRangeImageNegativeScaleX(self):
+ """image data range, negative scale"""
+
+ origin = (-10, 25)
+ scale = (-3., 8.)
+ image = numpy.arange(100.).reshape(20, 5)
+
+ plot = Plot(backend='none')
+ plot.addImage(image,
+ origin=origin, scale=scale)
+
+ xRange = numpy.array([0., image.shape[1] * scale[0]]) + origin[0]
+ xRange.sort() # negative scale!
+ yRange = numpy.array([0., image.shape[0] * scale[1]]) + origin[1]
+
+ ranges = {(False, False): (xRange, yRange),
+ (True, False): (None, None),
+ (True, True): (None, None),
+ (False, True): (None, None)}
+
+ for logX, logY in ((False, False),
+ (True, False),
+ (True, True),
+ (False, True),
+ (False, False)):
+ with self.subTest(logX=logX, logY=logY):
+ plot.setXAxisLogarithmic(logX)
+ plot.setYAxisLogarithmic(logY)
+ dataRange = plot.getDataRange()
+ xRange, yRange = ranges[logX, logY]
+ self.assertTrue(numpy.array_equal(dataRange.x, xRange),
+ msg='{0} != {1}'.format(dataRange.x, xRange))
+ self.assertTrue(numpy.array_equal(dataRange.y, yRange),
+ msg='{0} != {1}'.format(dataRange.y, yRange))
+ self.assertIsNone(dataRange.yright)
+
+ def testDataRangeImageNegativeScaleY(self):
+ """image data range, negative scale"""
+
+ origin = (-10, 25)
+ scale = (3., -8.)
+ image = numpy.arange(100.).reshape(20, 5)
+
+ plot = Plot(backend='none')
+ plot.addImage(image,
+ origin=origin, scale=scale)
+
+ xRange = numpy.array([0., image.shape[1] * scale[0]]) + origin[0]
+ yRange = numpy.array([0., image.shape[0] * scale[1]]) + origin[1]
+ yRange.sort() # negative scale!
+
+ ranges = {(False, False): (xRange, yRange),
+ (True, False): (None, None),
+ (True, True): (None, None),
+ (False, True): (None, None)}
+
+ for logX, logY in ((False, False),
+ (True, False),
+ (True, True),
+ (False, True),
+ (False, False)):
+ with self.subTest(logX=logX, logY=logY):
+ plot.setXAxisLogarithmic(logX)
+ plot.setYAxisLogarithmic(logY)
+ dataRange = plot.getDataRange()
+ xRange, yRange = ranges[logX, logY]
+ self.assertTrue(numpy.array_equal(dataRange.x, xRange),
+ msg='{0} != {1}'.format(dataRange.x, xRange))
+ self.assertTrue(numpy.array_equal(dataRange.y, yRange),
+ msg='{0} != {1}'.format(dataRange.y, yRange))
+ self.assertIsNone(dataRange.yright)
+
+ def testDataRangeHiddenCurve(self):
+ """curves with a hidden curve"""
+ plot = Plot(backend='none')
+ plot.addCurve((0, 1), (0, 1), legend='shown')
+ plot.addCurve((0, 1, 2), (5, 5, 5), legend='hidden')
+ range1 = plot.getDataRange()
+ self.assertEqual(range1.x, (0, 2))
+ self.assertEqual(range1.y, (0, 5))
+ plot.hideCurve('hidden')
+ range2 = plot.getDataRange()
+ self.assertEqual(range2.x, (0, 1))
+ self.assertEqual(range2.y, (0, 1))
+
+
+class TestPlotGetCurveImage(unittest.TestCase):
+ """Test of plot getCurve and getImage methods"""
+
+ def testGetCurve(self):
+ """Plot.getCurve and Plot.getActiveCurve tests"""
+
+ plot = Plot(backend='none')
+
+ # No curve
+ curve = plot.getCurve()
+ self.assertIsNone(curve) # No curve
+
+ plot.setActiveCurveHandling(True)
+ plot.addCurve(x=(0, 1), y=(0, 1), legend='curve 0')
+ plot.addCurve(x=(0, 1), y=(0, 1), legend='curve 1')
+ plot.addCurve(x=(0, 1), y=(0, 1), legend='curve 2')
+ plot.setActiveCurve('curve 0')
+
+ # Active curve
+ active = plot.getActiveCurve()
+ self.assertEqual(active.getLegend(), 'curve 0')
+ curve = plot.getCurve()
+ self.assertEqual(curve.getLegend(), 'curve 0')
+
+ # No active curve and curves
+ plot.setActiveCurveHandling(False)
+ active = plot.getActiveCurve()
+ self.assertIsNone(active) # No active curve
+ curve = plot.getCurve()
+ self.assertEqual(curve.getLegend(), 'curve 2') # Last added curve
+
+ # Last curve hidden
+ plot.hideCurve('curve 2', True)
+ curve = plot.getCurve()
+ self.assertEqual(curve.getLegend(), 'curve 1') # Last added curve
+
+ # All curves hidden
+ plot.hideCurve('curve 1', True)
+ plot.hideCurve('curve 0', True)
+ curve = plot.getCurve()
+ self.assertIsNone(curve)
+
+ def testGetCurveOldApi(self):
+ """old API Plot.getCurve and Plot.getActiveCurve tests"""
+
+ plot = Plot(backend='none')
+
+ # No curve
+ curve = plot.getCurve()
+ self.assertIsNone(curve) # No curve
+
+ plot.setActiveCurveHandling(True)
+ x = numpy.arange(10.).astype(numpy.float32)
+ y = x * x;
+ plot.addCurve(x=x, y=y, legend='curve 0', info=["whatever"])
+ plot.addCurve(x=x, y=2*x, legend='curve 1', info="anything")
+ plot.setActiveCurve('curve 0')
+
+ # Active curve (4 elements)
+ xOut, yOut, legend, info = plot.getActiveCurve()[:4]
+ self.assertEqual(legend, 'curve 0')
+ self.assertTrue(numpy.allclose(xOut, x), 'curve 0 wrong x data')
+ self.assertTrue(numpy.allclose(yOut, y), 'curve 0 wrong y data')
+
+ # Active curve (5 elements)
+ xOut, yOut, legend, info, params = plot.getCurve("curve 1")
+ self.assertEqual(legend, 'curve 1')
+ self.assertEqual(info, 'anything')
+ self.assertTrue(numpy.allclose(xOut, x), 'curve 1 wrong x data')
+ self.assertTrue(numpy.allclose(yOut, 2*x), 'curve 1 wrong y data')
+
+ def testGetImage(self):
+ """Plot.getImage and Plot.getActiveImage tests"""
+
+ plot = Plot(backend='none')
+
+ # No image
+ image = plot.getImage()
+ self.assertIsNone(image)
+
+ plot.addImage(((0, 1), (2, 3)), legend='image 0', replace=False)
+ plot.addImage(((0, 1), (2, 3)), legend='image 1', replace=False)
+
+ # Active image
+ active = plot.getActiveImage()
+ self.assertEqual(active.getLegend(), 'image 0')
+ image = plot.getImage()
+ self.assertEqual(image.getLegend(), 'image 0')
+
+ # No active image
+ plot.addImage(((0, 1), (2, 3)), legend='image 2', replace=False)
+ plot.setActiveImage(None)
+ active = plot.getActiveImage()
+ self.assertIsNone(active)
+ image = plot.getImage()
+ self.assertEqual(image.getLegend(), 'image 2')
+
+ # Active image
+ plot.setActiveImage('image 1')
+ active = plot.getActiveImage()
+ self.assertEqual(active.getLegend(), 'image 1')
+ image = plot.getImage()
+ self.assertEqual(image.getLegend(), 'image 1')
+
+ def testGetImageOldApi(self):
+ """Plot.getImage and Plot.getActiveImage old API tests"""
+
+ plot = Plot(backend='none')
+
+ # No image
+ image = plot.getImage()
+ self.assertIsNone(image)
+
+ image = numpy.arange(10).astype(numpy.float32)
+ image.shape = 5, 2
+
+ plot.addImage(image, legend='image 0', info=["Hi!"], replace=False)
+
+ # Active image
+ data, legend, info, something, params = plot.getActiveImage()
+ self.assertEqual(legend, 'image 0')
+ self.assertEqual(info, ["Hi!"])
+ self.assertTrue(numpy.allclose(data, image), "image 0 data not correct")
+
+ def testGetAllImages(self):
+ """Plot.getAllImages test"""
+
+ plot = Plot(backend='none')
+
+ # No image
+ images = plot.getAllImages()
+ self.assertEqual(len(images), 0)
+
+ # 2 images
+ data = numpy.arange(100).reshape(10, 10)
+ plot.addImage(data, legend='1', replace=False)
+ plot.addImage(data, origin=(10, 10), legend='2', replace=False)
+ images = plot.getAllImages(just_legend=True)
+ self.assertEqual(list(images), ['1', '2'])
+ images = plot.getAllImages(just_legend=False)
+ self.assertEqual(len(images), 2)
+ self.assertEqual(images[0].getLegend(), '1')
+ self.assertEqual(images[1].getLegend(), '2')
+
+
+class TestPlotAddScatter(unittest.TestCase):
+ """Test of plot addScatter"""
+
+ def testAddGetScatter(self):
+
+ plot = Plot(backend='none')
+
+ # No curve
+ scatter = plot._getItem(kind="scatter")
+ self.assertIsNone(scatter) # No curve
+
+ plot.addScatter(x=(0, 1), y=(0, 1), value=(0, 1), legend='scatter 0')
+ plot.addScatter(x=(0, 1), y=(0, 1), value=(0, 1), legend='scatter 1')
+ plot.addScatter(x=(0, 1), y=(0, 1), value=(0, 1), legend='scatter 2')
+ plot._setActiveItem('scatter', 'scatter 0')
+
+ # Active scatter
+ active = plot._getActiveItem(kind='scatter')
+ self.assertEqual(active.getLegend(), 'scatter 0')
+
+ # check default values
+ self.assertAlmostEqual(active.getSymbolSize(), active._DEFAULT_SYMBOL_SIZE)
+ self.assertEqual(active.getSymbol(), "o")
+ self.assertAlmostEqual(active.getAlpha(), 1.0)
+
+ # modify parameters
+ active.setSymbolSize(20.5)
+ active.setSymbol("d")
+ active.setAlpha(0.777)
+
+ s0 = plot.getScatter("scatter 0")
+
+ self.assertAlmostEqual(s0.getSymbolSize(), 20.5)
+ self.assertEqual(s0.getSymbol(), "d")
+ self.assertAlmostEqual(s0.getAlpha(), 0.777)
+
+ scatter1 = plot._getItem(kind='scatter', legend='scatter 1')
+ self.assertEqual(scatter1.getLegend(), 'scatter 1')
+
+ def testGetAllScatters(self):
+ """Plot.getAllImages test"""
+
+ plot = Plot(backend='none')
+
+ scatters = plot._getItems(kind='scatter')
+ self.assertEqual(len(scatters), 0)
+
+ plot.addScatter(x=(0, 1), y=(0, 1), value=(0, 1), legend='scatter 0')
+ plot.addScatter(x=(0, 1), y=(0, 1), value=(0, 1), legend='scatter 1')
+ plot.addScatter(x=(0, 1), y=(0, 1), value=(0, 1), legend='scatter 2')
+
+ scatters = plot._getItems(kind='scatter')
+ self.assertEqual(len(scatters), 3)
+ self.assertEqual(scatters[0].getLegend(), 'scatter 0')
+ self.assertEqual(scatters[2].getLegend(), 'scatter 2')
+
+ scatters = plot._getItems(kind='scatter', just_legend=True)
+ self.assertEqual(len(scatters), 3)
+ self.assertEqual(list(scatters), ['scatter 0', 'scatter 1', 'scatter 2'])
+
+
+class TestPlotHistogram(unittest.TestCase):
+ """Basic tests for histogram."""
+
+ def testEdges(self):
+ x = numpy.array([0, 1, 2])
+ edgesRight = numpy.array([0, 1, 2, 3])
+ edgesLeft = numpy.array([-1, 0, 1, 2])
+ edgesCenter = numpy.array([-0.5, 0.5, 1.5, 2.5])
+
+ # testing x values for right
+ edges = _computeEdges(x, 'right')
+ numpy.testing.assert_array_equal(edges, edgesRight)
+
+ edges = _computeEdges(x, 'center')
+ numpy.testing.assert_array_equal(edges, edgesCenter)
+
+ edges = _computeEdges(x, 'left')
+ numpy.testing.assert_array_equal(edges, edgesLeft)
+
+ def testHistogramCurve(self):
+ y = numpy.array([3, 2, 5])
+ edges = numpy.array([0, 1, 2, 3])
+
+ xHisto, yHisto = _getHistogramCurve(y, edges)
+ numpy.testing.assert_array_equal(
+ yHisto, numpy.array([3, 3, 2, 2, 5, 5]))
+
+ y = numpy.array([-3, 2, 5, 0])
+ edges = numpy.array([-2, -1, 0, 1, 2])
+ xHisto, yHisto = _getHistogramCurve(y, edges)
+ numpy.testing.assert_array_equal(
+ yHisto, numpy.array([-3, -3, 2, 2, 5, 5, 0, 0]))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for TestClass in (TestPlot, TestPlotRanges, TestPlotGetCurveImage,
+ TestPlotHistogram, TestPlotAddScatter):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testPlotInteraction.py b/silx/gui/plot/test/testPlotInteraction.py
new file mode 100644
index 0000000..25f57a9
--- /dev/null
+++ b/silx/gui/plot/test/testPlotInteraction.py
@@ -0,0 +1,167 @@
+# 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.
+#
+# ###########################################################################*/
+"""Tests of plot interaction, through a PlotWidget"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "13/10/2016"
+
+
+import unittest
+from silx.gui import qt
+from silx.gui.plot.test.testPlotWidget import _PlotWidgetTest
+
+
+class _SignalDump(object):
+ """Callable object that store passed arguments in a list"""
+
+ def __init__(self):
+ self._received = []
+
+ def __call__(self, *args):
+ self._received.append(args)
+
+ @property
+ def received(self):
+ """Return a shallow copy of the list of received arguments"""
+ return list(self._received)
+
+
+class TestSelectPolygon(_PlotWidgetTest):
+ """Test polygon selection interaction"""
+
+ def _interactionModeChanged(self, source):
+ """Check that source received in event is the correct one"""
+ self.assertEqual(source, self)
+
+ def _draw(self, polygon):
+ """Draw a polygon in the plot
+
+ :param polygon: List of points (x, y) of the polygon (not closed)
+ """
+ plot = self.plot.centralWidget()
+
+ dump = _SignalDump()
+ self.plot.sigPlotSignal.connect(dump)
+
+ for pos in polygon:
+ self.mouseMove(plot, pos=pos)
+ btn = qt.Qt.LeftButton if pos != polygon[-1] else qt.Qt.RightButton
+ self.mouseClick(plot, btn, pos=pos)
+
+ self.plot.sigPlotSignal.disconnect(dump)
+ return [args[0] for args in dump.received]
+
+ def test(self):
+ """Test draw polygons + events"""
+ self.plot.sigInteractiveModeChanged.connect(
+ self._interactionModeChanged)
+
+ self.plot.setInteractiveMode(
+ 'draw', shape='polygon', label='test', source=self)
+ interaction = self.plot.getInteractiveMode()
+
+ self.assertEqual(interaction['mode'], 'draw')
+ self.assertEqual(interaction['shape'], 'polygon')
+
+ self.plot.sigInteractiveModeChanged.disconnect(
+ self._interactionModeChanged)
+
+ plot = self.plot.centralWidget()
+ xCenter, yCenter = plot.width() // 2, plot.height() // 2
+ offset = min(plot.width(), plot.height()) // 10
+
+ # Star polygon
+ star = [(xCenter, yCenter + offset),
+ (xCenter - offset, yCenter - offset),
+ (xCenter + offset, yCenter),
+ (xCenter - offset, yCenter),
+ (xCenter + offset, yCenter - offset)]
+
+ # Draw while dumping signals
+ events = self._draw(star)
+
+ # Test last event
+ drawEvents = [event for event in events
+ if event['event'].startswith('drawing')]
+ self.assertEqual(drawEvents[-1]['event'], 'drawingFinished')
+ self.assertEqual(len(drawEvents[-1]['points']), 6)
+
+ # Large square
+ largeSquare = [(xCenter - offset, yCenter - offset),
+ (xCenter + offset, yCenter - offset),
+ (xCenter + offset, yCenter + offset),
+ (xCenter - offset, yCenter + offset)]
+
+ # Draw while dumping signals
+ events = self._draw(largeSquare)
+
+ # Test last event
+ drawEvents = [event for event in events
+ if event['event'].startswith('drawing')]
+ self.assertEqual(drawEvents[-1]['event'], 'drawingFinished')
+ self.assertEqual(len(drawEvents[-1]['points']), 5)
+
+ # Rectangle too thin along X: Some points are ignored
+ thinRectX = [(xCenter, yCenter - offset),
+ (xCenter, yCenter + offset),
+ (xCenter + 1, yCenter + offset),
+ (xCenter + 1, yCenter - offset)]
+
+ # Draw while dumping signals
+ events = self._draw(thinRectX)
+
+ # Test last event
+ drawEvents = [event for event in events
+ if event['event'].startswith('drawing')]
+ self.assertEqual(drawEvents[-1]['event'], 'drawingFinished')
+ self.assertEqual(len(drawEvents[-1]['points']), 3)
+
+ # Rectangle too thin along Y: Some points are ignored
+ thinRectY = [(xCenter - offset, yCenter),
+ (xCenter + offset, yCenter),
+ (xCenter + offset, yCenter + 1),
+ (xCenter - offset, yCenter + 1)]
+
+ # Draw while dumping signals
+ events = self._draw(thinRectY)
+
+ # Test last event
+ drawEvents = [event for event in events
+ if event['event'].startswith('drawing')]
+ self.assertEqual(drawEvents[-1]['event'], 'drawingFinished')
+ self.assertEqual(len(drawEvents[-1]['points']), 3)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for TestClass in (TestSelectPolygon,):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testPlotTools.py b/silx/gui/plot/test/testPlotTools.py
new file mode 100644
index 0000000..1d5e148
--- /dev/null
+++ b/silx/gui/plot/test/testPlotTools.py
@@ -0,0 +1,203 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Basic tests for PlotTools"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import numpy
+import unittest
+
+from silx.test.utils import ParametricTestCase, TestLogging
+from silx.gui.test.utils import (
+ qWaitForWindowExposedAndActivate, TestCaseQt, getQToolButtonFromAction)
+from silx.gui import qt
+from silx.gui.plot import Plot2D, PlotWindow, PlotTools
+
+
+# Makes sure a QApplication exists
+_qapp = qt.QApplication.instance() or qt.QApplication([])
+
+
+def _tearDownDocTest(docTest):
+ """Tear down to use for test from docstring.
+
+ Checks that plot widget is displayed
+ """
+ plot = docTest.globs['plot']
+ qWaitForWindowExposedAndActivate(plot)
+ plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ plot.close()
+ del plot
+
+# Disable doctest because of
+# "NameError: name 'numpy' is not defined"
+#
+# import doctest
+# positionInfoTestSuite = doctest.DocTestSuite(
+# PlotTools, tearDown=_tearDownDocTest,
+# optionflags=doctest.ELLIPSIS)
+# """Test suite of tests from PlotTools docstrings.
+#
+# Test PositionInfo and ProfileToolBar docstrings.
+# """
+
+
+class TestPositionInfo(TestCaseQt):
+ """Tests for PositionInfo widget."""
+
+ def setUp(self):
+ super(TestPositionInfo, self).setUp()
+ self.plot = PlotWindow()
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+ self.mouseMove(self.plot, pos=(1, 1))
+ self.qapp.processEvents()
+ self.qWait(100)
+
+ def tearDown(self):
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+
+ super(TestPositionInfo, self).tearDown()
+
+ def _test(self, positionWidget, converterNames, **kwargs):
+ """General test of PositionInfo.
+
+ - Add it to a toolbar and
+ - Move mouse around the center of the PlotWindow.
+ """
+ toolBar = qt.QToolBar()
+ self.plot.addToolBar(qt.Qt.BottomToolBarArea, toolBar)
+
+ toolBar.addWidget(positionWidget)
+
+ converters = positionWidget.getConverters()
+ self.assertEqual(len(converters), len(converterNames))
+ for index, name in enumerate(converterNames):
+ self.assertEqual(converters[index][0], name)
+
+ with TestLogging(PlotTools.__name__, **kwargs):
+ # Move mouse to center
+ self.mouseMove(self.plot)
+ self.mouseMove(self.plot, pos=(1, 1))
+ self.qapp.processEvents()
+ self.qWait(100)
+
+ def testDefaultConverters(self):
+ """Test PositionInfo with default converters"""
+ positionWidget = PlotTools.PositionInfo(plot=self.plot)
+ self._test(positionWidget, ('X', 'Y'))
+
+ def testCustomConverters(self):
+ """Test PositionInfo with custom converters"""
+ converters = [
+ ('Coords', lambda x, y: (int(x), int(y))),
+ ('Radius', lambda x, y: numpy.sqrt(x * x + y * y)),
+ ('Angle', lambda x, y: numpy.degrees(numpy.arctan2(y, x)))
+ ]
+ positionWidget = PlotTools.PositionInfo(plot=self.plot,
+ converters=converters)
+ self._test(positionWidget, ('Coords', 'Radius', 'Angle'))
+
+ def testFailingConverters(self):
+ """Test PositionInfo with failing custom converters"""
+ def raiseException(x, y):
+ raise RuntimeError()
+
+ positionWidget = PlotTools.PositionInfo(
+ plot=self.plot,
+ converters=[('Exception', raiseException)])
+ self._test(positionWidget, ['Exception'], error=2)
+
+
+class TestPixelIntensitiesHisto(TestCaseQt, ParametricTestCase):
+ """Tests for ProfileToolBar widget."""
+
+ def setUp(self):
+ super(TestPixelIntensitiesHisto, self).setUp()
+ self.image = numpy.random.rand(100, 100)
+ self.plotImage = Plot2D()
+ self.plotImage.getIntensityHistogramAction().setVisible(True)
+
+ def tearDown(self):
+ del self.plotImage
+ super(TestPixelIntensitiesHisto, self).tearDown()
+
+ def testShowAndHide(self):
+ """Simple test that the plot is showing and hiding when activating the
+ action"""
+ self.plotImage.addImage(self.image, origin=(0, 0), legend='sino')
+ self.plotImage.show()
+
+ histoAction = self.plotImage.getIntensityHistogramAction()
+
+ # test the pixel intensity diagram is showing
+ button = getQToolButtonFromAction(histoAction)
+ self.assertIsNot(button, None)
+ self.mouseMove(button)
+ self.mouseClick(button, qt.Qt.LeftButton)
+ self.qapp.processEvents()
+ self.assertTrue(histoAction.getHistogramPlotWidget().isVisible())
+
+ # test the pixel intensity diagram is hiding
+ self.qapp.setActiveWindow(self.plotImage)
+ self.qapp.processEvents()
+ self.mouseMove(button)
+ self.mouseClick(button, qt.Qt.LeftButton)
+ self.qapp.processEvents()
+ self.assertFalse(histoAction.getHistogramPlotWidget().isVisible())
+
+ def testImageFormatInput(self):
+ """Test multiple type as image input"""
+ typesToTest = [numpy.uint8, numpy.int8, numpy.int16, numpy.int32,
+ numpy.float32, numpy.float64]
+ self.plotImage.addImage(self.image, origin=(0, 0), legend='sino')
+ self.plotImage.show()
+ button = getQToolButtonFromAction(
+ self.plotImage.getIntensityHistogramAction())
+ self.mouseMove(button)
+ self.mouseClick(button, qt.Qt.LeftButton)
+ self.qapp.processEvents()
+ for typeToTest in typesToTest:
+ with self.subTest(typeToTest=typeToTest):
+ self.plotImage.addImage(self.image.astype(typeToTest),
+ origin=(0, 0), legend='sino')
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ # test_suite.addTest(positionInfoTestSuite)
+ for testClass in (TestPositionInfo, TestPixelIntensitiesHisto):
+ test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(
+ testClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testPlotWidget.py b/silx/gui/plot/test/testPlotWidget.py
new file mode 100644
index 0000000..2de18a8
--- /dev/null
+++ b/silx/gui/plot/test/testPlotWidget.py
@@ -0,0 +1,967 @@
+# 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.
+#
+# ###########################################################################*/
+"""Basic tests for PlotWidget"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import unittest
+
+import numpy
+
+from silx.test.utils import ParametricTestCase
+from silx.gui.test.utils import TestCaseQt
+
+from silx.gui import qt
+from silx.gui.plot import PlotWidget
+
+
+SIZE = 1024
+"""Size of the test image"""
+
+DATA_2D = numpy.arange(SIZE ** 2).reshape(SIZE, SIZE)
+"""Image data set"""
+
+
+class _PlotWidgetTest(TestCaseQt):
+ """Base class for tests of PlotWidget, not a TestCase in itself.
+
+ plot attribute is the PlotWidget created for the test.
+ """
+
+ def setUp(self):
+ super(_PlotWidgetTest, self).setUp()
+ self.plot = PlotWidget()
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+
+ def tearDown(self):
+ self.qapp.processEvents()
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+ super(_PlotWidgetTest, self).tearDown()
+
+
+class TestPlotWidget(_PlotWidgetTest, ParametricTestCase):
+ """Basic tests for PlotWidget"""
+
+ def testShow(self):
+ """Most basic test"""
+ pass
+
+ def testSetTitleLabels(self):
+ """Set title and axes labels"""
+
+ title, xlabel, ylabel = 'the title', 'x label', 'y label'
+ self.plot.setGraphTitle(title)
+ self.plot.setGraphXLabel(xlabel)
+ self.plot.setGraphYLabel(ylabel)
+ self.qapp.processEvents()
+
+ self.assertEqual(self.plot.getGraphTitle(), title)
+ self.assertEqual(self.plot.getGraphXLabel(), xlabel)
+ self.assertEqual(self.plot.getGraphYLabel(), ylabel)
+
+ def testChangeLimitsWithAspectRatio(self):
+ def checkLimits(expectedXLim=None, expectedYLim=None,
+ expectedRatio=None):
+ xlim = self.plot.getGraphXLimits()
+ ylim = self.plot.getGraphYLimits()
+ ratio = abs(xlim[1] - xlim[0]) / abs(ylim[1] - ylim[0])
+
+ if expectedXLim is not None:
+ self.assertEqual(expectedXLim, xlim)
+
+ if expectedYLim is not None:
+ self.assertEqual(expectedYLim, ylim)
+
+ if expectedRatio is not None:
+ self.assertTrue(
+ numpy.allclose(expectedRatio, ratio, atol=0.01))
+
+ self.plot.setKeepDataAspectRatio()
+ self.qapp.processEvents()
+ xlim = self.plot.getGraphXLimits()
+ ylim = self.plot.getGraphYLimits()
+ defaultRatio = abs(xlim[1] - xlim[0]) / abs(ylim[1] - ylim[0])
+
+ self.plot.setGraphXLimits(1., 10.)
+ checkLimits(expectedXLim=(1., 10.), expectedRatio=defaultRatio)
+ self.qapp.processEvents()
+ checkLimits(expectedXLim=(1., 10.), expectedRatio=defaultRatio)
+
+ self.plot.setGraphYLimits(1., 10.)
+ checkLimits(expectedYLim=(1., 10.), expectedRatio=defaultRatio)
+ self.qapp.processEvents()
+ checkLimits(expectedYLim=(1., 10.), expectedRatio=defaultRatio)
+
+
+class TestPlotImage(_PlotWidgetTest, ParametricTestCase):
+ """Basic tests for addImage"""
+
+ def setUp(self):
+ super(TestPlotImage, self).setUp()
+
+ self.plot.setGraphYLabel('Rows')
+ self.plot.setGraphXLabel('Columns')
+
+ def testPlotColormapTemperature(self):
+ self.plot.setGraphTitle('Temp. Linear')
+
+ colormap = {'name': 'temperature', 'normalization': 'linear',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0}
+ self.plot.addImage(DATA_2D, legend="image 1", colormap=colormap)
+
+ def testPlotColormapGray(self):
+ self.plot.setKeepDataAspectRatio(False)
+ self.plot.setGraphTitle('Gray Linear')
+
+ colormap = {'name': 'gray', 'normalization': 'linear',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0}
+ self.plot.addImage(DATA_2D, legend="image 1", colormap=colormap)
+
+ def testPlotColormapTemperatureLog(self):
+ self.plot.setGraphTitle('Temp. Log')
+
+ colormap = {'name': 'temperature', 'normalization': 'log',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0}
+ self.plot.addImage(DATA_2D, legend="image 1", colormap=colormap)
+
+ def testPlotRgbRgba(self):
+ self.plot.setKeepDataAspectRatio(False)
+ self.plot.setGraphTitle('RGB + RGBA')
+
+ rgb = numpy.array(
+ (((0, 0, 0), (128, 0, 0), (255, 0, 0)),
+ ((0, 128, 0), (0, 128, 128), (0, 128, 256))),
+ dtype=numpy.uint8)
+
+ self.plot.addImage(rgb, legend="rgb",
+ origin=(0, 0), scale=(10, 10),
+ replace=False, resetzoom=False)
+
+ rgba = numpy.array(
+ (((0, 0, 0, .5), (.5, 0, 0, 1), (1, 0, 0, .5)),
+ ((0, .5, 0, 1), (0, .5, .5, 1), (0, 1, 1, .5))),
+ dtype=numpy.float32)
+
+ self.plot.addImage(rgba, legend="rgba",
+ origin=(5, 5), scale=(10, 10),
+ replace=False, resetzoom=False)
+
+ self.plot.resetZoom()
+
+ def testPlotColormapCustom(self):
+ self.plot.setKeepDataAspectRatio(False)
+ self.plot.setGraphTitle('Custom colormap')
+
+ colormap = {'name': None, 'normalization': 'linear',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0,
+ 'colors': ((0., 0., 0.), (1., 0., 0.),
+ (0., 1., 0.), (0., 0., 1.))}
+ self.plot.addImage(DATA_2D, legend="image 1", colormap=colormap,
+ replace=False, resetzoom=False)
+
+ colormap = {'name': None, 'normalization': 'linear',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0,
+ 'colors': numpy.array(
+ ((0, 0, 0, 0), (0, 0, 0, 128),
+ (128, 128, 128, 128), (255, 255, 255, 255)),
+ dtype=numpy.uint8)}
+ self.plot.addImage(DATA_2D, legend="image 2", colormap=colormap,
+ origin=(DATA_2D.shape[0], 0),
+ replace=False, resetzoom=False)
+ self.plot.resetZoom()
+
+ def testImageOriginScale(self):
+ """Test of image with different origin and scale"""
+ self.plot.setGraphTitle('origin and scale')
+
+ tests = [ # (origin, scale)
+ ((10, 20), (1, 1)),
+ ((10, 20), (-1, -1)),
+ ((-10, 20), (2, 1)),
+ ((10, -20), (-1, -2)),
+ (100, 2),
+ (-100, (1, 1)),
+ ((10, 20), 2),
+ ]
+
+ for origin, scale in tests:
+ with self.subTest(origin=origin, scale=scale):
+ self.plot.addImage(DATA_2D, origin=origin, scale=scale)
+
+ try:
+ ox, oy = origin
+ except TypeError:
+ ox, oy = origin, origin
+ try:
+ sx, sy = scale
+ except TypeError:
+ sx, sy = scale, scale
+ xbounds = ox, ox + DATA_2D.shape[1] * sx
+ ybounds = oy, oy + DATA_2D.shape[0] * sy
+
+ # Check limits without aspect ratio
+ xmin, xmax = self.plot.getGraphXLimits()
+ ymin, ymax = self.plot.getGraphYLimits()
+ self.assertEqual(xmin, min(xbounds))
+ self.assertEqual(xmax, max(xbounds))
+ self.assertEqual(ymin, min(ybounds))
+ self.assertEqual(ymax, max(ybounds))
+
+ # Check limits with aspect ratio
+ self.plot.setKeepDataAspectRatio(True)
+ xmin, xmax = self.plot.getGraphXLimits()
+ ymin, ymax = self.plot.getGraphYLimits()
+ self.assertTrue(xmin <= min(xbounds))
+ self.assertTrue(xmax >= max(xbounds))
+ self.assertTrue(ymin <= min(ybounds))
+ self.assertTrue(ymax >= max(ybounds))
+
+ self.plot.setKeepDataAspectRatio(False) # Reset aspect ratio
+ self.plot.clear()
+ self.plot.resetZoom()
+
+
+class TestPlotCurve(_PlotWidgetTest):
+ """Basic tests for addCurve."""
+
+ # Test data sets
+ xData = numpy.arange(1000)
+ yData = -500 + 100 * numpy.sin(xData)
+ xData2 = xData + 1000
+ yData2 = xData - 1000 + 200 * numpy.random.random(1000)
+
+ def setUp(self):
+ super(TestPlotCurve, self).setUp()
+ self.plot.setGraphTitle('Curve')
+ self.plot.setGraphYLabel('Rows')
+ self.plot.setGraphXLabel('Columns')
+
+ self.plot.setActiveCurveHandling(False)
+
+ def testPlotCurveColorFloat(self):
+ color = numpy.array(numpy.random.random(3 * 1000),
+ dtype=numpy.float32).reshape(1000, 3)
+
+ self.plot.addCurve(self.xData, self.yData,
+ legend="curve 1",
+ replace=False, resetzoom=False,
+ color=color,
+ linestyle="", symbol="s")
+ self.plot.addCurve(self.xData2, self.yData2,
+ legend="curve 2",
+ replace=False, resetzoom=False,
+ color='green', linestyle="-", symbol='o')
+ self.plot.resetZoom()
+
+ def testPlotCurveColorByte(self):
+ color = numpy.array(255 * numpy.random.random(3 * 1000),
+ dtype=numpy.uint8).reshape(1000, 3)
+
+ self.plot.addCurve(self.xData, self.yData,
+ legend="curve 1",
+ replace=False, resetzoom=False,
+ color=color,
+ linestyle="", symbol="s")
+ self.plot.addCurve(self.xData2, self.yData2,
+ legend="curve 2",
+ replace=False, resetzoom=False,
+ color='green', linestyle="-", symbol='o')
+ self.plot.resetZoom()
+
+ def testPlotCurveColors(self):
+ color = numpy.array(numpy.random.random(3 * 1000),
+ dtype=numpy.float32).reshape(1000, 3)
+
+ self.plot.addCurve(self.xData, self.yData,
+ legend="curve 2",
+ replace=False, resetzoom=False,
+ color=color, linestyle="-", symbol='o')
+ self.plot.resetZoom()
+
+
+class TestPlotMarker(_PlotWidgetTest):
+ """Basic tests for add*Marker"""
+
+ def setUp(self):
+ super(TestPlotMarker, self).setUp()
+ self.plot.setGraphYLabel('Rows')
+ self.plot.setGraphXLabel('Columns')
+
+ self.plot.setXAxisAutoScale(False)
+ self.plot.setYAxisAutoScale(False)
+ self.plot.setKeepDataAspectRatio(False)
+ self.plot.setLimits(0., 100., -100., 100.)
+
+ def testPlotMarkerX(self):
+ self.plot.setGraphTitle('Markers X')
+
+ markers = [
+ (10., 'blue', False, False),
+ (20., 'red', False, False),
+ (40., 'green', True, False),
+ (60., 'gray', True, True),
+ (80., 'black', False, True),
+ ]
+
+ for x, color, select, drag in markers:
+ name = str(x)
+ if select:
+ name += " sel."
+ if drag:
+ name += " drag"
+ self.plot.addXMarker(x, name, name, color, select, drag)
+ self.plot.resetZoom()
+
+ def testPlotMarkerY(self):
+ self.plot.setGraphTitle('Markers Y')
+
+ markers = [
+ (-50., 'blue', False, False),
+ (-30., 'red', False, False),
+ (0., 'green', True, False),
+ (10., 'gray', True, True),
+ (80., 'black', False, True),
+ ]
+
+ for y, color, select, drag in markers:
+ name = str(y)
+ if select:
+ name += " sel."
+ if drag:
+ name += " drag"
+ self.plot.addYMarker(y, name, name, color, select, drag)
+ self.plot.resetZoom()
+
+ def testPlotMarkerPt(self):
+ self.plot.setGraphTitle('Markers Pt')
+
+ markers = [
+ (10., -50., 'blue', False, False),
+ (40., -30., 'red', False, False),
+ (50., 0., 'green', True, False),
+ (50., 20., 'gray', True, True),
+ (70., 50., 'black', False, True),
+ ]
+ for x, y, color, select, drag in markers:
+ name = "{0},{1}".format(x, y)
+ if select:
+ name += " sel."
+ if drag:
+ name += " drag"
+ self.plot.addMarker(x, y, name, name, color, select, drag)
+
+ self.plot.resetZoom()
+
+ def testPlotMarkerWithoutLegend(self):
+ self.plot.setGraphTitle('Markers without legend')
+ self.plot.setYAxisInverted(True)
+
+ # Markers without legend
+ self.plot.addMarker(10, 10)
+ self.plot.addMarker(10, 20)
+ self.plot.addMarker(40, 50, text='test', symbol=None)
+ self.plot.addMarker(40, 50, text='test', symbol='+')
+ self.plot.addXMarker(25)
+ self.plot.addXMarker(35)
+ self.plot.addXMarker(45, text='test')
+ self.plot.addYMarker(55)
+ self.plot.addYMarker(65)
+ self.plot.addYMarker(75, text='test')
+
+ self.plot.resetZoom()
+
+
+# TestPlotItem ################################################################
+
+class TestPlotItem(_PlotWidgetTest):
+ """Basic tests for addItem."""
+
+ # Polygon coordinates and color
+ polygons = [ # legend, x coords, y coords, color
+ ('triangle', numpy.array((10, 30, 50)),
+ numpy.array((55, 70, 55)), 'red'),
+ ('square', numpy.array((10, 10, 50, 50)),
+ numpy.array((10, 50, 50, 10)), 'green'),
+ ('star', numpy.array((60, 70, 80, 60, 80)),
+ numpy.array((25, 50, 25, 40, 40)), 'blue'),
+ ]
+
+ # Rectangle coordinantes and color
+ rectangles = [ # legend, x coords, y coords, color
+ ('square 1', numpy.array((1., 10.)),
+ numpy.array((1., 10.)), 'red'),
+ ('square 2', numpy.array((10., 20.)),
+ numpy.array((10., 20.)), 'green'),
+ ('square 3', numpy.array((20., 30.)),
+ numpy.array((20., 30.)), 'blue'),
+ ('rect 1', numpy.array((1., 30.)),
+ numpy.array((35., 40.)), 'black'),
+ ('line h', numpy.array((1., 30.)),
+ numpy.array((45., 45.)), 'darkRed'),
+ ]
+
+ def setUp(self):
+ super(TestPlotItem, self).setUp()
+
+ self.plot.setGraphYLabel('Rows')
+ self.plot.setGraphXLabel('Columns')
+ self.plot.setXAxisAutoScale(False)
+ self.plot.setYAxisAutoScale(False)
+ self.plot.setKeepDataAspectRatio(False)
+ self.plot.setLimits(0., 100., -100., 100.)
+
+ def testPlotItemPolygonFill(self):
+ self.plot.setGraphTitle('Item Fill')
+
+ for legend, xList, yList, color in self.polygons:
+ self.plot.addItem(xList, yList, legend=legend,
+ replace=False,
+ shape="polygon", fill=True, color=color)
+ self.plot.resetZoom()
+
+ def testPlotItemPolygonNoFill(self):
+ self.plot.setGraphTitle('Item No Fill')
+
+ for legend, xList, yList, color in self.polygons:
+ self.plot.addItem(xList, yList, legend=legend,
+ replace=False,
+ shape="polygon", fill=False, color=color)
+ self.plot.resetZoom()
+
+ def testPlotItemRectangleFill(self):
+ self.plot.setGraphTitle('Rectangle Fill')
+
+ for legend, xList, yList, color in self.rectangles:
+ self.plot.addItem(xList, yList, legend=legend,
+ replace=False,
+ shape="rectangle", fill=True, color=color)
+ self.plot.resetZoom()
+
+ def testPlotItemRectangleNoFill(self):
+ self.plot.setGraphTitle('Rectangle No Fill')
+
+ for legend, xList, yList, color in self.rectangles:
+ self.plot.addItem(xList, yList, legend=legend,
+ replace=False,
+ shape="rectangle", fill=False, color=color)
+ self.plot.resetZoom()
+
+
+class TestPlotActiveCurveImage(_PlotWidgetTest):
+ """Basic tests for active image handling"""
+
+ def testActiveCurveAndLabels(self):
+ # Active curve handling off, no label change
+ self.plot.setActiveCurveHandling(False)
+ self.plot.setGraphXLabel('XLabel')
+ self.plot.setGraphYLabel('YLabel')
+ self.plot.addCurve((1, 2), (1, 2))
+ self.assertEqual(self.plot.getGraphXLabel(), 'XLabel')
+ self.assertEqual(self.plot.getGraphYLabel(), 'YLabel')
+
+ self.plot.addCurve((1, 2), (2, 3), xlabel='x1', ylabel='y1')
+ self.assertEqual(self.plot.getGraphXLabel(), 'XLabel')
+ self.assertEqual(self.plot.getGraphYLabel(), 'YLabel')
+
+ self.plot.clear()
+ self.assertEqual(self.plot.getGraphXLabel(), 'XLabel')
+ self.assertEqual(self.plot.getGraphYLabel(), 'YLabel')
+
+ # Active curve handling on, label changes
+ self.plot.setActiveCurveHandling(True)
+ self.plot.setGraphXLabel('XLabel')
+ self.plot.setGraphYLabel('YLabel')
+
+ # labels changed as active curve
+ self.plot.addCurve((1, 2), (1, 2), legend='1',
+ xlabel='x1', ylabel='y1')
+ self.assertEqual(self.plot.getGraphXLabel(), 'x1')
+ self.assertEqual(self.plot.getGraphYLabel(), 'y1')
+
+ # labels not changed as not active curve
+ self.plot.addCurve((1, 2), (2, 3), legend='2')
+ self.assertEqual(self.plot.getGraphXLabel(), 'x1')
+ self.assertEqual(self.plot.getGraphYLabel(), 'y1')
+
+ # labels changed
+ self.plot.setActiveCurve('2')
+ self.assertEqual(self.plot.getGraphXLabel(), 'XLabel')
+ self.assertEqual(self.plot.getGraphYLabel(), 'YLabel')
+
+ self.plot.setActiveCurve('1')
+ self.assertEqual(self.plot.getGraphXLabel(), 'x1')
+ self.assertEqual(self.plot.getGraphYLabel(), 'y1')
+
+ self.plot.clear()
+ self.assertEqual(self.plot.getGraphXLabel(), 'XLabel')
+ self.assertEqual(self.plot.getGraphYLabel(), 'YLabel')
+
+ def testActiveImageAndLabels(self):
+ # Active image handling always on, no API for toggling it
+ self.plot.setGraphXLabel('XLabel')
+ self.plot.setGraphYLabel('YLabel')
+
+ # labels changed as active curve
+ self.plot.addImage(numpy.arange(100).reshape(10, 10), replace=False,
+ legend='1', xlabel='x1', ylabel='y1')
+ self.assertEqual(self.plot.getGraphXLabel(), 'x1')
+ self.assertEqual(self.plot.getGraphYLabel(), 'y1')
+
+ # labels not changed as not active curve
+ self.plot.addImage(numpy.arange(100).reshape(10, 10), replace=False,
+ legend='2')
+ self.assertEqual(self.plot.getGraphXLabel(), 'x1')
+ self.assertEqual(self.plot.getGraphYLabel(), 'y1')
+
+ # labels changed
+ self.plot.setActiveImage('2')
+ self.assertEqual(self.plot.getGraphXLabel(), 'XLabel')
+ self.assertEqual(self.plot.getGraphYLabel(), 'YLabel')
+
+ self.plot.setActiveImage('1')
+ self.assertEqual(self.plot.getGraphXLabel(), 'x1')
+ self.assertEqual(self.plot.getGraphYLabel(), 'y1')
+
+ self.plot.clear()
+ self.assertEqual(self.plot.getGraphXLabel(), 'XLabel')
+ self.assertEqual(self.plot.getGraphYLabel(), 'YLabel')
+
+
+##############################################################################
+# Log
+##############################################################################
+
+class TestPlotEmptyLog(_PlotWidgetTest):
+ """Basic tests for log plot"""
+ def testEmptyPlotTitleLabelsLog(self):
+ self.plot.setGraphTitle('Empty Log Log')
+ self.plot.setGraphXLabel('X')
+ self.plot.setGraphYLabel('Y')
+ self.plot.setXAxisLogarithmic(True)
+ self.plot.setYAxisLogarithmic(True)
+ self.plot.resetZoom()
+
+
+class TestPlotCurveLog(_PlotWidgetTest, ParametricTestCase):
+ """Basic tests for addCurve with log scale axes"""
+
+ # Test data
+ xData = numpy.arange(1000) + 1
+ yData = xData ** 2
+
+ def _setLabels(self):
+ self.plot.setGraphXLabel('X')
+ self.plot.setGraphYLabel('X * X')
+
+ def testPlotCurveLogX(self):
+ self._setLabels()
+ self.plot.setXAxisLogarithmic(True)
+ self.plot.setGraphTitle('Curve X: Log Y: Linear')
+
+ self.plot.addCurve(self.xData, self.yData,
+ legend="curve",
+ replace=False, resetzoom=True,
+ color='green', linestyle="-", symbol='o')
+
+ def testPlotCurveLogY(self):
+ self._setLabels()
+ self.plot.setYAxisLogarithmic(True)
+
+ self.plot.setGraphTitle('Curve X: Linear Y: Log')
+
+ self.plot.addCurve(self.xData, self.yData,
+ legend="curve",
+ replace=False, resetzoom=True,
+ color='green', linestyle="-", symbol='o')
+
+ def testPlotCurveLogXY(self):
+ self._setLabels()
+ self.plot.setXAxisLogarithmic(True)
+ self.plot.setYAxisLogarithmic(True)
+
+ self.plot.setGraphTitle('Curve X: Log Y: Log')
+
+ self.plot.addCurve(self.xData, self.yData,
+ legend="curve",
+ replace=False, resetzoom=True,
+ color='green', linestyle="-", symbol='o')
+
+ def testPlotCurveErrorLogXY(self):
+ self.plot.setXAxisLogarithmic(True)
+ self.plot.setYAxisLogarithmic(True)
+
+ # Every second error leads to negative number
+ errors = numpy.ones_like(self.xData)
+ errors[::2] = self.xData[::2] + 1
+
+ tests = [ # name, xerror, yerror
+ ('xerror=3', 3, None),
+ ('xerror=N array', errors, None),
+ ('xerror=Nx1 array', errors.reshape(len(errors), 1), None),
+ ('xerror=2xN array', numpy.array((errors, errors)), None),
+ ('yerror=6', None, 6),
+ ('yerror=N array', None, errors ** 2),
+ ('yerror=Nx1 array', None, (errors ** 2).reshape(len(errors), 1)),
+ ('yerror=2xN array', None, numpy.array((errors, errors)) ** 2),
+ ]
+
+ for name, xError, yError in tests:
+ with self.subTest(name):
+ self.plot.setGraphTitle(name)
+ self.plot.addCurve(self.xData, self.yData,
+ legend=name,
+ xerror=xError, yerror=yError,
+ replace=False, resetzoom=True,
+ color='green', linestyle="-", symbol='o')
+
+ self.qapp.processEvents()
+
+ self.plot.clear()
+ self.plot.resetZoom()
+ self.qapp.processEvents()
+
+ def testPlotCurveToggleLog(self):
+ """Add a curve with negative data and toggle log axis"""
+ arange = numpy.arange(1000) + 1
+ tests = [ # name, xData, yData
+ ('x>0, some negative y', arange, arange - 500),
+ ('x>0, y<0', arange, -arange),
+ ('some negative x, y>0', arange - 500, arange),
+ ('x<0, y>0', -arange, arange),
+ ('some negative x and y', arange - 500, arange - 500),
+ ('x<0, y<0', -arange, -arange),
+ ]
+
+ for name, xData, yData in tests:
+ with self.subTest(name):
+ self.plot.addCurve(xData, yData, resetzoom=True)
+ self.qapp.processEvents()
+
+ # no log axis
+ xLim = self.plot.getGraphXLimits()
+ self.assertEqual(xLim, (min(xData), max(xData)))
+ yLim = self.plot.getGraphYLimits()
+ self.assertEqual(yLim, (min(yData), max(yData)))
+
+ # x axis log
+ self.plot.setXAxisLogarithmic(True)
+ self.qapp.processEvents()
+
+ xLim = self.plot.getGraphXLimits()
+ yLim = self.plot.getGraphYLimits()
+ positives = xData > 0
+ if numpy.any(positives):
+ self.assertTrue(numpy.allclose(
+ xLim, (min(xData[positives]), max(xData[positives]))))
+ self.assertEqual(
+ yLim, (min(yData[positives]), max(yData[positives])))
+ else: # No positive x in the curve
+ self.assertEqual(xLim, (1., 100.))
+ self.assertEqual(yLim, (1., 100.))
+
+ # x axis and y axis log
+ self.plot.setYAxisLogarithmic(True)
+ self.qapp.processEvents()
+
+ xLim = self.plot.getGraphXLimits()
+ yLim = self.plot.getGraphYLimits()
+ positives = numpy.logical_and(xData > 0, yData > 0)
+ if numpy.any(positives):
+ self.assertTrue(numpy.allclose(
+ xLim, (min(xData[positives]), max(xData[positives]))))
+ self.assertTrue(numpy.allclose(
+ yLim, (min(yData[positives]), max(yData[positives]))))
+ else: # No positive x and y in the curve
+ self.assertEqual(xLim, (1., 100.))
+ self.assertEqual(yLim, (1., 100.))
+
+ # y axis log
+ self.plot.setXAxisLogarithmic(False)
+ self.qapp.processEvents()
+
+ xLim = self.plot.getGraphXLimits()
+ yLim = self.plot.getGraphYLimits()
+ positives = yData > 0
+ if numpy.any(positives):
+ self.assertEqual(
+ xLim, (min(xData[positives]), max(xData[positives])))
+ self.assertTrue(numpy.allclose(
+ yLim, (min(yData[positives]), max(yData[positives]))))
+ else: # No positive y in the curve
+ self.assertEqual(xLim, (1., 100.))
+ self.assertEqual(yLim, (1., 100.))
+
+ # no log axis
+ self.plot.setYAxisLogarithmic(False)
+ self.qapp.processEvents()
+
+ xLim = self.plot.getGraphXLimits()
+ self.assertEqual(xLim, (min(xData), max(xData)))
+ yLim = self.plot.getGraphYLimits()
+ self.assertEqual(yLim, (min(yData), max(yData)))
+
+ self.plot.clear()
+ self.plot.resetZoom()
+ self.qapp.processEvents()
+
+
+class TestPlotImageLog(_PlotWidgetTest):
+ """Basic tests for addImage with log scale axes."""
+
+ def setUp(self):
+ super(TestPlotImageLog, self).setUp()
+
+ self.plot.setGraphXLabel('Columns')
+ self.plot.setGraphYLabel('Rows')
+
+ def testPlotColormapGrayLogX(self):
+ self.plot.setXAxisLogarithmic(True)
+ self.plot.setGraphTitle('CMap X: Log Y: Linear')
+
+ colormap = {'name': 'gray', 'normalization': 'linear',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0}
+ self.plot.addImage(DATA_2D, legend="image 1",
+ origin=(1., 1.), scale=(1., 1.),
+ replace=False, resetzoom=False, colormap=colormap)
+ self.plot.resetZoom()
+
+ def testPlotColormapGrayLogY(self):
+ self.plot.setYAxisLogarithmic(True)
+ self.plot.setGraphTitle('CMap X: Linear Y: Log')
+
+ colormap = {'name': 'gray', 'normalization': 'linear',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0}
+ self.plot.addImage(DATA_2D, legend="image 1",
+ origin=(1., 1.), scale=(1., 1.),
+ replace=False, resetzoom=False, colormap=colormap)
+ self.plot.resetZoom()
+
+ def testPlotColormapGrayLogXY(self):
+ self.plot.setXAxisLogarithmic(True)
+ self.plot.setYAxisLogarithmic(True)
+ self.plot.setGraphTitle('CMap X: Log Y: Log')
+
+ colormap = {'name': 'gray', 'normalization': 'linear',
+ 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0}
+ self.plot.addImage(DATA_2D, legend="image 1",
+ origin=(1., 1.), scale=(1., 1.),
+ replace=False, resetzoom=False, colormap=colormap)
+ self.plot.resetZoom()
+
+ def testPlotRgbRgbaLogXY(self):
+ self.plot.setXAxisLogarithmic(True)
+ self.plot.setYAxisLogarithmic(True)
+ self.plot.setGraphTitle('RGB + RGBA X: Log Y: Log')
+
+ rgb = numpy.array(
+ (((0, 0, 0), (128, 0, 0), (255, 0, 0)),
+ ((0, 128, 0), (0, 128, 128), (0, 128, 256))),
+ dtype=numpy.uint8)
+
+ self.plot.addImage(rgb, legend="rgb",
+ origin=(1, 1), scale=(10, 10),
+ replace=False, resetzoom=False)
+
+ rgba = numpy.array(
+ (((0, 0, 0, .5), (.5, 0, 0, 1), (1, 0, 0, .5)),
+ ((0, .5, 0, 1), (0, .5, .5, 1), (0, 1, 1, .5))),
+ dtype=numpy.float32)
+
+ self.plot.addImage(rgba, legend="rgba",
+ origin=(5., 5.), scale=(10., 10.),
+ replace=False, resetzoom=False)
+ self.plot.resetZoom()
+
+
+class TestPlotMarkerLog(_PlotWidgetTest):
+ """Basic tests for markers on log scales"""
+
+ # Test marker parameters
+ markers = [ # x, y, color, selectable, draggable
+ (10., 10., 'blue', False, False),
+ (20., 20., 'red', False, False),
+ (40., 100., 'green', True, False),
+ (40., 500., 'gray', True, True),
+ (60., 800., 'black', False, True),
+ ]
+
+ def setUp(self):
+ super(TestPlotMarkerLog, self).setUp()
+
+ self.plot.setGraphYLabel('Rows')
+ self.plot.setGraphXLabel('Columns')
+ self.plot.setXAxisAutoScale(False)
+ self.plot.setYAxisAutoScale(False)
+ self.plot.setKeepDataAspectRatio(False)
+ self.plot.setLimits(1., 100., 1., 1000.)
+ self.plot.setXAxisLogarithmic(True)
+ self.plot.setYAxisLogarithmic(True)
+
+ def testPlotMarkerXLog(self):
+ self.plot.setGraphTitle('Markers X, Log axes')
+
+ for x, _, color, select, drag in self.markers:
+ name = str(x)
+ if select:
+ name += " sel."
+ if drag:
+ name += " drag"
+ self.plot.addXMarker(x, name, name, color, select, drag)
+ self.plot.resetZoom()
+
+ def testPlotMarkerYLog(self):
+ self.plot.setGraphTitle('Markers Y, Log axes')
+
+ for _, y, color, select, drag in self.markers:
+ name = str(y)
+ if select:
+ name += " sel."
+ if drag:
+ name += " drag"
+ self.plot.addYMarker(y, name, name, color, select, drag)
+ self.plot.resetZoom()
+
+ def testPlotMarkerPtLog(self):
+ self.plot.setGraphTitle('Markers Pt, Log axes')
+
+ for x, y, color, select, drag in self.markers:
+ name = "{0},{1}".format(x, y)
+ if select:
+ name += " sel."
+ if drag:
+ name += " drag"
+ self.plot.addMarker(x, y, name, name, color, select, drag)
+ self.plot.resetZoom()
+
+
+class TestPlotItemLog(_PlotWidgetTest):
+ """Basic tests for items with log scale axes"""
+
+ # Polygon coordinates and color
+ polygons = [ # legend, x coords, y coords, color
+ ('triangle', numpy.array((10, 30, 50)),
+ numpy.array((55, 70, 55)), 'red'),
+ ('square', numpy.array((10, 10, 50, 50)),
+ numpy.array((10, 50, 50, 10)), 'green'),
+ ('star', numpy.array((60, 70, 80, 60, 80)),
+ numpy.array((25, 50, 25, 40, 40)), 'blue'),
+ ]
+
+ # Rectangle coordinantes and color
+ rectangles = [ # legend, x coords, y coords, color
+ ('square 1', numpy.array((1., 10.)),
+ numpy.array((1., 10.)), 'red'),
+ ('square 2', numpy.array((10., 20.)),
+ numpy.array((10., 20.)), 'green'),
+ ('square 3', numpy.array((20., 30.)),
+ numpy.array((20., 30.)), 'blue'),
+ ('rect 1', numpy.array((1., 30.)),
+ numpy.array((35., 40.)), 'black'),
+ ('line h', numpy.array((1., 30.)),
+ numpy.array((45., 45.)), 'darkRed'),
+ ]
+
+ def setUp(self):
+ super(TestPlotItemLog, self).setUp()
+
+ self.plot.setGraphYLabel('Rows')
+ self.plot.setGraphXLabel('Columns')
+ self.plot.setXAxisAutoScale(False)
+ self.plot.setYAxisAutoScale(False)
+ self.plot.setKeepDataAspectRatio(False)
+ self.plot.setLimits(1., 100., 1., 100.)
+ self.plot.setXAxisLogarithmic(True)
+ self.plot.setYAxisLogarithmic(True)
+
+ def testPlotItemPolygonLogFill(self):
+ self.plot.setGraphTitle('Item Fill Log')
+
+ for legend, xList, yList, color in self.polygons:
+ self.plot.addItem(xList, yList, legend=legend,
+ replace=False,
+ shape="polygon", fill=True, color=color)
+ self.plot.resetZoom()
+
+ def testPlotItemPolygonLogNoFill(self):
+ self.plot.setGraphTitle('Item No Fill Log')
+
+ for legend, xList, yList, color in self.polygons:
+ self.plot.addItem(xList, yList, legend=legend,
+ replace=False,
+ shape="polygon", fill=False, color=color)
+ self.plot.resetZoom()
+
+ def testPlotItemRectangleLogFill(self):
+ self.plot.setGraphTitle('Rectangle Fill Log')
+
+ for legend, xList, yList, color in self.rectangles:
+ self.plot.addItem(xList, yList, legend=legend,
+ replace=False,
+ shape="rectangle", fill=True, color=color)
+ self.plot.resetZoom()
+
+ def testPlotItemRectangleLogNoFill(self):
+ self.plot.setGraphTitle('Rectangle No Fill Log')
+
+ for legend, xList, yList, color in self.rectangles:
+ self.plot.addItem(xList, yList, legend=legend,
+ replace=False,
+ shape="rectangle", fill=False, color=color)
+ self.plot.resetZoom()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotWidget))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotImage))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotCurve))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotMarker))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotItem))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotEmptyLog))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotCurveLog))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotImageLog))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotMarkerLog))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotItemLog))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testPlotWindow.py b/silx/gui/plot/test/testPlotWindow.py
new file mode 100644
index 0000000..5afd53a
--- /dev/null
+++ b/silx/gui/plot/test/testPlotWindow.py
@@ -0,0 +1,138 @@
+# 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.
+#
+# ###########################################################################*/
+"""Basic tests for PlotWindow"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import doctest
+import unittest
+
+from silx.gui.test.utils import TestCaseQt, getQToolButtonFromAction
+
+from silx.gui import qt
+from silx.gui.plot import PlotWindow
+
+
+# Test of the docstrings #
+
+# Makes sure a QApplication exists
+_qapp = qt.QApplication.instance() or qt.QApplication([])
+
+
+def _tearDownQt(docTest):
+ """Tear down to use for test from docstring.
+
+ Checks that plt widget is displayed
+ """
+ _qapp.processEvents()
+ for obj in docTest.globs.values():
+ if isinstance(obj, PlotWindow):
+ # Commented out as it takes too long
+ # qWaitForWindowExposedAndActivate(obj)
+ obj.setAttribute(qt.Qt.WA_DeleteOnClose)
+ obj.close()
+ del obj
+
+
+plotWindowDocTestSuite = doctest.DocTestSuite('silx.gui.plot.PlotWindow',
+ tearDown=_tearDownQt)
+"""Test suite of tests from the module's docstrings."""
+
+
+class TestPlotWindow(TestCaseQt):
+ """Base class for tests of PlotWindow."""
+
+ def setUp(self):
+ super(TestPlotWindow, self).setUp()
+ self.plot = PlotWindow()
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+
+ def tearDown(self):
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+ super(TestPlotWindow, self).tearDown()
+
+ def testActions(self):
+ """Test the actions QToolButtons"""
+ self.plot.setLimits(1, 100, 1, 100)
+
+ checkList = [ # QAction, Plot state getter
+ (self.plot.xAxisAutoScaleAction, self.plot.isXAxisAutoScale),
+ (self.plot.yAxisAutoScaleAction, self.plot.isYAxisAutoScale),
+ (self.plot.xAxisLogarithmicAction, self.plot.isXAxisLogarithmic),
+ (self.plot.yAxisLogarithmicAction, self.plot.isYAxisLogarithmic),
+ (self.plot.gridAction, self.plot.getGraphGrid),
+ ]
+
+ for action, getter in checkList:
+ self.mouseMove(self.plot)
+ initialState = getter()
+ toolButton = getQToolButtonFromAction(action)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+ self.assertNotEqual(getter(), initialState,
+ msg='"%s" state not changed' % action.text())
+
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+ self.assertEqual(getter(), initialState,
+ msg='"%s" state not changed' % action.text())
+
+ # Trigger a zoom reset
+ self.mouseMove(self.plot)
+ resetZoomAction = self.plot.resetZoomAction
+ toolButton = getQToolButtonFromAction(resetZoomAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ def testToolAspectRatio(self):
+ self.plot.toolBar()
+ self.plot.keepDataAspectRatioButton.keepDataAspectRatio()
+ self.assertTrue(self.plot.isKeepDataAspectRatio())
+ self.plot.keepDataAspectRatioButton.dontKeepDataAspectRatio()
+ self.assertFalse(self.plot.isKeepDataAspectRatio())
+
+ def testToolYAxisOrigin(self):
+ self.plot.toolBar()
+ self.plot.yAxisInvertedButton.setYAxisUpward()
+ self.assertFalse(self.plot.isYAxisInverted())
+ self.plot.yAxisInvertedButton.setYAxisDownward()
+ self.assertTrue(self.plot.isYAxisInverted())
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(plotWindowDocTestSuite)
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPlotWindow))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testProfile.py b/silx/gui/plot/test/testProfile.py
new file mode 100644
index 0000000..43d3329
--- /dev/null
+++ b/silx/gui/plot/test/testProfile.py
@@ -0,0 +1,183 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Basic tests for Profile"""
+
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "23/02/2017"
+
+import numpy
+import unittest
+
+from silx.test.utils import ParametricTestCase
+from silx.gui.test.utils import (
+ TestCaseQt, getQToolButtonFromAction)
+from silx.gui import qt
+from silx.gui.plot import PlotWindow, Plot1D, Plot2D, Profile
+from silx.gui.plot.StackView import StackView
+
+
+# Makes sure a QApplication exists
+_qapp = qt.QApplication.instance() or qt.QApplication([])
+
+
+class TestProfileToolBar(TestCaseQt, ParametricTestCase):
+ """Tests for ProfileToolBar widget."""
+
+ def setUp(self):
+ super(TestProfileToolBar, self).setUp()
+ profileWindow = PlotWindow()
+ self.plot = PlotWindow()
+ self.toolBar = Profile.ProfileToolBar(
+ plot=self.plot, profileWindow=profileWindow)
+ self.plot.addToolBar(self.toolBar)
+
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+ profileWindow.show()
+ self.qWaitForWindowExposed(profileWindow)
+
+ self.mouseMove(self.plot) # Move to center
+ self.qapp.processEvents()
+
+ def tearDown(self):
+ self.qapp.processEvents()
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+ del self.toolBar
+
+ super(TestProfileToolBar, self).tearDown()
+
+ def testAlignedProfile(self):
+ """Test horizontal and vertical profile, without and with image"""
+ # Use Plot backend widget to submit mouse events
+ widget = self.plot.getWidgetHandle()
+
+ # 2 positions to use for mouse events
+ pos1 = widget.width() * 0.4, widget.height() * 0.4
+ pos2 = widget.width() * 0.6, widget.height() * 0.6
+
+ for action in (self.toolBar.hLineAction, self.toolBar.vLineAction):
+ with self.subTest(mode=action.text()):
+ # Trigger tool button for mode
+ toolButton = getQToolButtonFromAction(action)
+ self.assertIsNot(toolButton, None)
+ self.mouseMove(toolButton)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ # Without image
+ self.mouseMove(widget, pos=pos1)
+ self.mouseClick(widget, qt.Qt.LeftButton, pos=pos1)
+
+ # with image
+ self.plot.addImage(numpy.arange(100 * 100).reshape(100, -1))
+ self.mousePress(widget, qt.Qt.LeftButton, pos=pos1)
+ self.mouseMove(widget, pos=pos2)
+ self.mouseRelease(widget, qt.Qt.LeftButton, pos=pos2)
+
+ self.mouseMove(widget)
+ self.mouseClick(widget, qt.Qt.LeftButton)
+
+ def testDiagonalProfile(self):
+ """Test diagonal profile, without and with image"""
+ # Use Plot backend widget to submit mouse events
+ widget = self.plot.getWidgetHandle()
+
+ # 2 positions to use for mouse events
+ pos1 = widget.width() * 0.4, widget.height() * 0.4
+ pos2 = widget.width() * 0.6, widget.height() * 0.6
+
+ # Trigger tool button for diagonal profile mode
+ toolButton = getQToolButtonFromAction(self.toolBar.lineAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseMove(toolButton)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ for image in (False, True):
+ with self.subTest(image=image):
+ if image:
+ self.plot.addImage(numpy.arange(100 * 100).reshape(100, -1))
+
+ self.mouseMove(widget, pos=pos1)
+ self.mousePress(widget, qt.Qt.LeftButton, pos=pos1)
+ self.mouseMove(widget, pos=pos2)
+ self.mouseRelease(widget, qt.Qt.LeftButton, pos=pos2)
+
+ self.plot.clear()
+
+
+class TestGetProfilePlot(TestCaseQt):
+
+ def testProfile1D(self):
+ plot = Plot2D()
+ plot.show()
+ self.qWaitForWindowExposed(plot)
+ plot.addImage([[0, 1], [2, 3]])
+ self.assertIsInstance(plot.getProfileToolbar().getProfileMainWindow(),
+ qt.QMainWindow)
+ self.assertIsInstance(plot.getProfilePlot(),
+ Plot1D)
+ plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ plot.close()
+ del plot
+
+ def testProfile2D(self):
+ """Test that the profile plot associated to a stack view is either a
+ Plot1D or a plot 2D instance."""
+ plot = StackView()
+ plot.show()
+ self.qWaitForWindowExposed(plot)
+
+ plot.setStack(numpy.array([[[0, 1], [2, 3]],
+ [[4, 5], [6, 7]]]))
+
+ self.assertIsInstance(plot.getProfileToolbar().getProfileMainWindow(),
+ qt.QMainWindow)
+
+ # plot.getProfileToolbar().profile3dAction.computeProfileIn2D() # default
+
+ self.assertIsInstance(plot.getProfileToolbar().getProfilePlot(),
+ Plot2D)
+ plot.getProfileToolbar().profile3dAction.computeProfileIn1D()
+ self.assertIsInstance(plot.getProfileToolbar().getProfilePlot(),
+ Plot1D)
+
+ plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ plot.close()
+ del plot
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ # test_suite.addTest(positionInfoTestSuite)
+ for testClass in (TestProfileToolBar, TestGetProfilePlot):
+ test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(
+ testClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testScatterMaskToolsWidget.py b/silx/gui/plot/test/testScatterMaskToolsWidget.py
new file mode 100644
index 0000000..8b5f2ad
--- /dev/null
+++ b/silx/gui/plot/test/testScatterMaskToolsWidget.py
@@ -0,0 +1,313 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Basic tests for MaskToolsWidget"""
+
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "10/07/2017"
+
+
+import logging
+import os.path
+import unittest
+
+import numpy
+
+from silx.gui import qt
+from silx.test.utils import temp_dir, ParametricTestCase
+from silx.gui.test.utils import TestCaseQt, getQToolButtonFromAction
+from silx.gui.plot import PlotWindow, ScatterMaskToolsWidget
+
+try:
+ import fabio
+except ImportError:
+ fabio = None
+
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+
+class TestScatterMaskToolsWidget(TestCaseQt, ParametricTestCase):
+ """Basic test for MaskToolsWidget"""
+
+ def setUp(self):
+ super(TestScatterMaskToolsWidget, self).setUp()
+ self.plot = PlotWindow()
+
+ self.widget = ScatterMaskToolsWidget.ScatterMaskToolsDockWidget(
+ plot=self.plot, name='TEST')
+ self.plot.addDockWidget(qt.Qt.BottomDockWidgetArea, self.widget)
+
+ self.plot.show()
+ self.qWaitForWindowExposed(self.plot)
+
+ self.maskWidget = self.widget.widget()
+
+ def tearDown(self):
+ del self.maskWidget
+ del self.widget
+
+ self.plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.plot.close()
+ del self.plot
+
+ super(TestScatterMaskToolsWidget, self).tearDown()
+
+ def testEmptyPlot(self):
+ """Empty plot, display MaskToolsDockWidget, toggle multiple masks"""
+ self.maskWidget.setMultipleMasks('single')
+ self.qapp.processEvents()
+
+ self.maskWidget.setMultipleMasks('exclusive')
+ self.qapp.processEvents()
+
+ def _drag(self):
+ """Drag from plot center to offset position"""
+ plot = self.plot.centralWidget()
+ xCenter, yCenter = plot.width() // 2, plot.height() // 2
+ offset = min(plot.width(), plot.height()) // 10
+
+ pos0 = xCenter, yCenter
+ pos1 = xCenter + offset, yCenter + offset
+
+ self.mouseMove(plot, pos=pos0)
+ self.mousePress(plot, qt.Qt.LeftButton, pos=pos0)
+ self.mouseMove(plot, pos=pos1)
+ self.mouseRelease(plot, qt.Qt.LeftButton, pos=pos1)
+
+ def _drawPolygon(self):
+ """Draw a star polygon in the plot"""
+ plot = self.plot.centralWidget()
+ x, y = plot.width() // 2, plot.height() // 2
+ offset = min(plot.width(), plot.height()) // 10
+
+ star = [(x, y + offset),
+ (x - offset, y - offset),
+ (x + offset, y),
+ (x - offset, y),
+ (x + offset, y - offset)]
+
+ for pos in star:
+ self.mouseMove(plot, pos=pos)
+ btn = qt.Qt.LeftButton if pos != star[-1] else qt.Qt.RightButton
+ self.mouseClick(plot, btn, pos=pos)
+
+ def _drawPencil(self):
+ """Draw a star polygon in the plot"""
+ plot = self.plot.centralWidget()
+ x, y = plot.width() // 2, plot.height() // 2
+ offset = min(plot.width(), plot.height()) // 10
+
+ star = [(x, y + offset),
+ (x - offset, y - offset),
+ (x + offset, y),
+ (x - offset, y),
+ (x + offset, y - offset)]
+
+ self.mouseMove(plot, pos=star[0])
+ self.mousePress(plot, qt.Qt.LeftButton, pos=star[0])
+ for pos in star:
+ self.mouseMove(plot, pos=pos)
+ self.mouseRelease(
+ plot, qt.Qt.LeftButton, pos=star[-1])
+
+ def testWithAScatter(self):
+ """Plot with a Scatter: test MaskToolsWidget interactions"""
+
+ # Add and remove a scatter (this should enable/disable GUI + change mask)
+ self.plot.addScatter(
+ x=numpy.arange(256),
+ y=numpy.arange(256),
+ value=numpy.random.random(256),
+ legend='test')
+ self.plot._setActiveItem(kind="scatter", legend="test")
+ self.qapp.processEvents()
+
+ self.plot.remove('test', kind='scatter')
+ self.qapp.processEvents()
+
+ self.plot.addScatter(
+ x=numpy.arange(1000),
+ y=1000 * (numpy.arange(1000) % 20),
+ value=numpy.random.random(1000),
+ legend='test')
+ self.plot._setActiveItem(kind="scatter", legend="test")
+ self.plot.resetZoom()
+ self.qapp.processEvents()
+
+ # Test draw rectangle #
+ toolButton = getQToolButtonFromAction(self.maskWidget.rectAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ # mask
+ self.maskWidget.maskStateGroup.button(1).click()
+ self.qapp.processEvents()
+ self._drag()
+
+ self.assertFalse(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # unmask same region
+ self.maskWidget.maskStateGroup.button(0).click()
+ self.qapp.processEvents()
+ self._drag()
+ self.assertTrue(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # Test draw polygon #
+ toolButton = getQToolButtonFromAction(self.maskWidget.polygonAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ # mask
+ self.maskWidget.maskStateGroup.button(1).click()
+ self.qapp.processEvents()
+ self._drawPolygon()
+ self.assertFalse(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # unmask same region
+ self.maskWidget.maskStateGroup.button(0).click()
+ self.qapp.processEvents()
+ self._drawPolygon()
+ self.assertTrue(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # Test draw pencil #
+ toolButton = getQToolButtonFromAction(self.maskWidget.pencilAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ self.maskWidget.pencilSpinBox.setValue(10)
+ self.qapp.processEvents()
+
+ # mask
+ self.maskWidget.maskStateGroup.button(1).click()
+ self.qapp.processEvents()
+ self._drawPencil()
+ self.assertFalse(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # unmask same region
+ self.maskWidget.maskStateGroup.button(0).click()
+ self.qapp.processEvents()
+ self._drawPencil()
+ self.assertTrue(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ # Test no draw tool #
+ toolButton = getQToolButtonFromAction(self.maskWidget.browseAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+
+ self.plot.clear()
+
+ def __loadSave(self, file_format):
+ self.plot.addScatter(
+ x=numpy.arange(256),
+ y=25 * (numpy.arange(256) % 10),
+ value=numpy.random.random(256),
+ legend='test')
+ self.plot._setActiveItem(kind="scatter", legend="test")
+ self.plot.resetZoom()
+ self.qapp.processEvents()
+
+ # Draw a polygon mask
+ toolButton = getQToolButtonFromAction(self.maskWidget.polygonAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+ self._drawPolygon()
+
+ ref_mask = self.maskWidget.getSelectionMask()
+ self.assertFalse(numpy.all(numpy.equal(ref_mask, 0)))
+
+ with temp_dir() as tmp:
+ mask_filename = os.path.join(tmp, 'mask.' + file_format)
+ self.maskWidget.save(mask_filename, file_format)
+
+ self.maskWidget.resetSelectionMask()
+ self.assertTrue(
+ numpy.all(numpy.equal(self.maskWidget.getSelectionMask(), 0)))
+
+ self.maskWidget.load(mask_filename)
+ self.assertTrue(numpy.all(numpy.equal(
+ self.maskWidget.getSelectionMask(), ref_mask)))
+
+ def testLoadSaveNpy(self):
+ self.__loadSave("npy")
+
+ def testLoadSaveCsv(self):
+ self.__loadSave("csv")
+
+ def testSigMaskChangedEmitted(self):
+ self.qapp.processEvents()
+ self.plot.addScatter(
+ x=numpy.arange(1000),
+ y=1000 * (numpy.arange(1000) % 20),
+ value=numpy.ones((1000,)),
+ legend='test')
+ self.plot._setActiveItem(kind="scatter", legend="test")
+ self.plot.resetZoom()
+ self.qapp.processEvents()
+
+ self.plot.remove('test', kind='scatter')
+ self.qapp.processEvents()
+
+ self.plot.addScatter(
+ x=numpy.arange(1000),
+ y=1000 * (numpy.arange(1000) % 20),
+ value=numpy.random.random(1000),
+ legend='test')
+
+ l = []
+
+ def slot():
+ l.append(1)
+
+ self.maskWidget.sigMaskChanged.connect(slot)
+
+ # rectangle mask
+ toolButton = getQToolButtonFromAction(self.maskWidget.rectAction)
+ self.assertIsNot(toolButton, None)
+ self.mouseClick(toolButton, qt.Qt.LeftButton)
+ self.maskWidget.maskStateGroup.button(1).click()
+ self.qapp.processEvents()
+ self._drag()
+
+ self.assertGreater(len(l), 0)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for TestClass in (TestScatterMaskToolsWidget,):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot/test/testStackView.py b/silx/gui/plot/test/testStackView.py
new file mode 100644
index 0000000..69584cd
--- /dev/null
+++ b/silx/gui/plot/test/testStackView.py
@@ -0,0 +1,209 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Basic tests for StackView"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "20/03/2017"
+
+
+import unittest
+import numpy
+
+from silx.gui.test.utils import TestCaseQt
+
+from silx.gui import qt
+from silx.gui.plot import StackView
+from silx.gui.plot.StackView import StackViewMainWindow
+
+from silx.utils.array_like import ListOfImages
+
+
+# Makes sure a QApplication exists
+_qapp = qt.QApplication.instance() or qt.QApplication([])
+
+
+class TestStackView(TestCaseQt):
+ """Base class for tests of StackView."""
+
+ def setUp(self):
+ super(TestStackView, self).setUp()
+ self.stackview = StackView()
+ self.stackview.show()
+ self.qWaitForWindowExposed(self.stackview)
+ self.mystack = numpy.fromfunction(
+ lambda i, j, k: numpy.sin(i/15.) + numpy.cos(j/4.) + 2 * numpy.sin(k/6.),
+ (10, 20, 30)
+ )
+
+ def tearDown(self):
+ self.stackview.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.stackview.close()
+ del self.stackview
+ super(TestStackView, self).tearDown()
+
+ def testSetStack(self):
+ self.stackview.setStack(self.mystack)
+ self.stackview.setColormap("viridis", autoscale=True)
+ my_trans_stack, params = self.stackview.getStack()
+ self.assertEqual(my_trans_stack.shape, self.mystack.shape)
+ self.assertTrue(numpy.array_equal(self.mystack,
+ my_trans_stack))
+ self.assertEqual(params["colormap"]["name"],
+ "viridis")
+
+ def testSetStackPerspective(self):
+ self.stackview.setStack(self.mystack, perspective=1)
+ # my_orig_stack, params = self.stackview.getStack()
+ my_trans_stack, params = self.stackview.getCurrentView()
+
+ # get stack returns the transposed data, depending on the perspective
+ self.assertEqual(my_trans_stack.shape,
+ (self.mystack.shape[1], self.mystack.shape[0], self.mystack.shape[2]))
+ self.assertTrue(numpy.array_equal(numpy.transpose(self.mystack, axes=(1, 0, 2)),
+ my_trans_stack))
+
+ def testSetStackListOfImages(self):
+ loi = [self.mystack[i] for i in range(self.mystack.shape[0])]
+
+ self.stackview.setStack(loi)
+ my_orig_stack, params = self.stackview.getStack(returnNumpyArray=True)
+ my_trans_stack, params = self.stackview.getStack(returnNumpyArray=True)
+ self.assertEqual(my_trans_stack.shape, self.mystack.shape)
+ self.assertTrue(numpy.array_equal(self.mystack,
+ my_trans_stack))
+ self.assertTrue(numpy.array_equal(self.mystack,
+ my_orig_stack))
+ self.assertIsInstance(my_trans_stack, numpy.ndarray)
+
+ self.stackview.setStack(loi, perspective=2)
+ my_orig_stack, params = self.stackview.getStack(copy=False)
+ my_trans_stack, params = self.stackview.getCurrentView(copy=False)
+ # getStack(copy=False) must return the object set in setStack
+ self.assertIs(my_orig_stack, loi)
+ # getCurrentView(copy=False) returns a ListOfImages whose .images
+ # attr is the original data
+ self.assertEqual(my_trans_stack.shape,
+ (self.mystack.shape[2], self.mystack.shape[0], self.mystack.shape[1]))
+ self.assertTrue(numpy.array_equal(numpy.array(my_trans_stack),
+ numpy.transpose(self.mystack, axes=(2, 0, 1))))
+ self.assertIsInstance(my_trans_stack,
+ ListOfImages) # returnNumpyArray=False by default in getStack
+ self.assertIs(my_trans_stack.images, loi)
+
+ def testPerspective(self):
+ self.stackview.setStack(numpy.arange(24).reshape((2, 3, 4)))
+ self.assertEqual(self.stackview._perspective, 0,
+ "Default perspective is not 0 (dim1-dim2).")
+
+ self.stackview._StackView__planeSelection.setPerspective(1)
+ self.assertEqual(self.stackview._perspective, 1,
+ "Plane selection combobox not updating perspective")
+
+ self.stackview.setStack(numpy.arange(6).reshape((1, 2, 3)))
+ self.assertEqual(self.stackview._perspective, 0,
+ "Default perspective not restored in setStack.")
+
+ self.stackview.setStack(numpy.arange(24).reshape((2, 3, 4)), perspective=2)
+ self.assertEqual(self.stackview._perspective, 2,
+ "Perspective not set in setStack(..., perspective=2).")
+
+ def testTitle(self):
+ """Test that the plot title contains the proper Z information"""
+ self.stackview.setStack(numpy.arange(24).reshape((4, 3, 2)),
+ calibrations=[(0, 1), (-10, 10), (3.14, 3.14)])
+ self.assertEqual(self.stackview._plot.getGraphTitle(),
+ "Image z=0")
+ self.stackview.setFrameNumber(2)
+ self.assertEqual(self.stackview._plot.getGraphTitle(),
+ "Image z=2")
+
+ self.stackview._StackView__planeSelection.setPerspective(1)
+ self.stackview.setFrameNumber(0)
+ self.assertEqual(self.stackview._plot.getGraphTitle(),
+ "Image z=-10")
+ self.stackview.setFrameNumber(2)
+ self.assertEqual(self.stackview._plot.getGraphTitle(),
+ "Image z=10")
+
+ self.stackview._StackView__planeSelection.setPerspective(2)
+ self.stackview.setFrameNumber(0)
+ self.assertEqual(self.stackview._plot.getGraphTitle(),
+ "Image z=3.14")
+ self.stackview.setFrameNumber(1)
+ self.assertEqual(self.stackview._plot.getGraphTitle(),
+ "Image z=6.28")
+
+
+class TestStackViewMainWindow(TestCaseQt):
+ """Base class for tests of StackView."""
+
+ def setUp(self):
+ super(TestStackViewMainWindow, self).setUp()
+ self.stackview = StackViewMainWindow()
+ self.stackview.show()
+ self.qWaitForWindowExposed(self.stackview)
+ self.mystack = numpy.fromfunction(
+ lambda i, j, k: numpy.sin(i/15.) + numpy.cos(j/4.) + 2 * numpy.sin(k/6.),
+ (10, 20, 30)
+ )
+
+ def tearDown(self):
+ self.stackview.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.stackview.close()
+ del self.stackview
+ super(TestStackViewMainWindow, self).tearDown()
+
+ def testSetStack(self):
+ self.stackview.setStack(self.mystack)
+ self.stackview.setColormap("viridis", autoscale=True)
+ my_trans_stack, params = self.stackview.getStack()
+ self.assertEqual(my_trans_stack.shape, self.mystack.shape)
+ self.assertTrue(numpy.array_equal(self.mystack,
+ my_trans_stack))
+ self.assertEqual(params["colormap"]["name"],
+ "viridis")
+
+ def testSetStackPerspective(self):
+ self.stackview.setStack(self.mystack, perspective=1)
+ my_trans_stack, params = self.stackview.getCurrentView()
+ # get stack returns the transposed data, depending on the perspective
+ self.assertEqual(my_trans_stack.shape,
+ (self.mystack.shape[1], self.mystack.shape[0], self.mystack.shape[2]))
+ self.assertTrue(numpy.array_equal(numpy.transpose(self.mystack, axes=(1, 0, 2)),
+ my_trans_stack))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestStackView))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestStackViewMainWindow))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot3d/Plot3DActions.py b/silx/gui/plot3d/Plot3DActions.py
new file mode 100644
index 0000000..2ae2750
--- /dev/null
+++ b/silx/gui/plot3d/Plot3DActions.py
@@ -0,0 +1,362 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module provides QAction that can be attached to a plot3DWidget."""
+
+from __future__ import absolute_import, division
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "26/01/2017"
+
+
+import logging
+import os
+import weakref
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.plot.PlotActions import PrintAction as _PrintAction
+from silx.gui.icons import getQIcon
+from .utils import mng
+from .._utils import convertQImageToArray
+
+
+_logger = logging.getLogger(__name__)
+
+
+class Plot3DAction(qt.QAction):
+ """QAction associated to a Plot3DWidget
+
+ :param parent: See :class:`QAction`
+ :param Plot3DWidget plot3d: Plot3DWidget the action is associated with
+ """
+
+ def __init__(self, parent, plot3d=None):
+ super(Plot3DAction, self).__init__(parent)
+ self._plot3d = None
+ self.setPlot3DWidget(plot3d)
+
+ def setPlot3DWidget(self, widget):
+ """Set the Plot3DWidget this action is associated with
+
+ :param Plot3DWidget widget: The Plot3DWidget to use
+ """
+ self._plot3d = None if widget is None else weakref.ref(widget)
+
+ def getPlot3DWidget(self):
+ """Return the Plot3DWidget associated to this action.
+
+ If no widget is associated, it returns None.
+
+ :rtype: qt.QWidget
+ """
+ return None if self._plot3d is None else self._plot3d()
+
+
+class CopyAction(Plot3DAction):
+ """QAction to provide copy of a Plot3DWidget
+
+ :param parent: See :class:`QAction`
+ :param Plot3DWidget plot3d: Plot3DWidget the action is associated with
+ """
+
+ def __init__(self, parent, plot3d=None):
+ super(CopyAction, self).__init__(parent, plot3d)
+
+ self.setIcon(getQIcon('edit-copy'))
+ self.setText('Copy')
+ self.setToolTip('Copy a snapshot of the 3D scene to the clipboard')
+ self.setCheckable(False)
+ self.setShortcut(qt.QKeySequence.Copy)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+ self.triggered[bool].connect(self._triggered)
+
+ def _triggered(self, checked=False):
+ plot3d = self.getPlot3DWidget()
+ if plot3d is None:
+ _logger.error('Cannot copy widget, no associated Plot3DWidget')
+ else:
+ image = plot3d.grabGL()
+ qt.QApplication.clipboard().setImage(image)
+
+
+class SaveAction(Plot3DAction):
+ """QAction to provide save snapshot of a Plot3DWidget
+
+ :param parent: See :class:`QAction`
+ :param Plot3DWidget plot3d: Plot3DWidget the action is associated with
+ """
+
+ def __init__(self, parent, plot3d=None):
+ super(SaveAction, self).__init__(parent, plot3d)
+
+ self.setIcon(getQIcon('document-save'))
+ self.setText('Save...')
+ self.setToolTip('Save a snapshot of the 3D scene')
+ self.setCheckable(False)
+ self.setShortcut(qt.QKeySequence.Save)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+ self.triggered[bool].connect(self._triggered)
+
+ def _triggered(self, checked=False):
+ plot3d = self.getPlot3DWidget()
+ if plot3d is None:
+ _logger.error('Cannot save widget, no associated Plot3DWidget')
+ else:
+ dialog = qt.QFileDialog(self.parent())
+ dialog.setWindowTitle('Save snapshot as')
+ dialog.setModal(True)
+ dialog.setNameFilters(('Plot3D Snapshot PNG (*.png)',
+ 'Plot3D Snapshot JPEG (*.jpg)'))
+
+ dialog.setFileMode(qt.QFileDialog.AnyFile)
+ dialog.setAcceptMode(qt.QFileDialog.AcceptSave)
+
+ if not dialog.exec_():
+ return
+
+ nameFilter = dialog.selectedNameFilter()
+ filename = dialog.selectedFiles()[0]
+ dialog.close()
+
+ # Forces the filename extension to match the chosen filter
+ extension = nameFilter.split()[-1][2:-1]
+ if (len(filename) <= len(extension) or
+ filename[-len(extension):].lower() != extension.lower()):
+ filename += extension
+
+ image = plot3d.grabGL()
+ if not image.save(filename):
+ _logger.error('Failed to save image as %s', filename)
+ qt.QMessageBox.critical(
+ self.parent(),
+ 'Save snapshot as',
+ 'Failed to save snapshot')
+
+
+class PrintAction(Plot3DAction):
+ """QAction to provide printing of a Plot3DWidget
+
+ :param parent: See :class:`QAction`
+ :param Plot3DWidget plot3d: Plot3DWidget the action is associated with
+ """
+
+ def __init__(self, parent, plot3d=None):
+ super(PrintAction, self).__init__(parent, plot3d)
+
+ self.setIcon(getQIcon('document-print'))
+ self.setText('Print...')
+ self.setToolTip('Print a snapshot of the 3D scene')
+ self.setCheckable(False)
+ self.setShortcut(qt.QKeySequence.Print)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+ self.triggered[bool].connect(self._triggered)
+
+ def getPrinter(self):
+ """Return the QPrinter instance used for printing.
+
+ :rtype: qt.QPrinter
+ """
+ # TODO This is a hack to sync with silx plot PrintAction
+ # This needs to be centralized
+ if _PrintAction._printer is None:
+ _PrintAction._printer = qt.QPrinter()
+ return _PrintAction._printer
+
+ def _triggered(self, checked=False):
+ plot3d = self.getPlot3DWidget()
+ if plot3d is None:
+ _logger.error('Cannot print widget, no associated Plot3DWidget')
+ else:
+ printer = self.getPrinter()
+ dialog = qt.QPrintDialog(printer, plot3d)
+ dialog.setWindowTitle('Print Plot3D snapshot')
+ if not dialog.exec_():
+ return
+
+ image = plot3d.grabGL()
+
+ # Draw pixmap with painter
+ painter = qt.QPainter()
+ if not painter.begin(printer):
+ return
+
+ if (printer.pageRect().width() < image.width() or
+ printer.pageRect().height() < image.height()):
+ # Downscale to page
+ xScale = printer.pageRect().width() / image.width()
+ yScale = printer.pageRect().height() / image.height()
+ scale = min(xScale, yScale)
+ else:
+ scale = 1.
+
+ rect = qt.QRectF(0,
+ 0,
+ scale * image.width(),
+ scale * image.height())
+ painter.drawImage(rect, image)
+ painter.end()
+
+
+class VideoAction(Plot3DAction):
+ """This action triggers the recording of a video of the scene.
+
+ The scene is rotated 360 degrees around a vertical axis.
+
+ :param parent: Action parent see :class:`QAction`.
+ """
+
+ PNG_SERIE_FILTER = 'Serie of PNG files (*.png)'
+ MNG_FILTER = 'Multiple-image Network Graphics file (*.mng)'
+
+ def __init__(self, parent, plot3d=None):
+ super(VideoAction, self).__init__(parent, plot3d)
+ self.setText('Record video..')
+ self.setIcon(getQIcon('camera'))
+ self.setToolTip(
+ 'Record a video of a 360 degrees rotation of the 3D scene.')
+ self.setCheckable(False)
+ self.triggered[bool].connect(self._triggered)
+
+ def _triggered(self, checked=False):
+ """Action triggered callback"""
+ plot3d = self.getPlot3DWidget()
+ if plot3d is None:
+ _logger.warning(
+ 'Ignoring action triggered without Plot3DWidget set')
+ return
+
+ dialog = qt.QFileDialog(parent=plot3d)
+ dialog.setWindowTitle('Save video as...')
+ dialog.setModal(True)
+ dialog.setNameFilters([self.PNG_SERIE_FILTER,
+ self.MNG_FILTER])
+ dialog.setFileMode(dialog.AnyFile)
+ dialog.setAcceptMode(dialog.AcceptSave)
+
+ if not dialog.exec_():
+ return
+
+ nameFilter = dialog.selectedNameFilter()
+ filename = dialog.selectedFiles()[0]
+
+ # Forces the filename extension to match the chosen filter
+ extension = nameFilter.split()[-1][2:-1]
+ if (len(filename) <= len(extension) or
+ filename[-len(extension):].lower() != extension.lower()):
+ filename += extension
+
+ nbFrames = int(4. * 25) # 4 seconds, 25 fps
+
+ if nameFilter == self.PNG_SERIE_FILTER:
+ self._saveAsPNGSerie(filename, nbFrames)
+ elif nameFilter == self.MNG_FILTER:
+ self._saveAsMNG(filename, nbFrames)
+ else:
+ _logger.error('Unsupported file filter: %s', nameFilter)
+
+ def _saveAsPNGSerie(self, filename, nbFrames):
+ """Save video as serie of PNG files.
+
+ It adds a counter to the provided filename before the extension.
+
+ :param str filename: filename to use as template
+ :param int nbFrames: Number of frames to generate
+ """
+ plot3d = self.getPlot3DWidget()
+ assert plot3d is not None
+
+ # Define filename template
+ nbDigits = int(numpy.log10(nbFrames)) + 1
+ indexFormat = '%%0%dd' % nbDigits
+ extensionIndex = filename.rfind('.')
+ filenameFormat = \
+ filename[:extensionIndex] + indexFormat + filename[extensionIndex:]
+
+ try:
+ for index, image in enumerate(self._video360(nbFrames)):
+ image.save(filenameFormat % index)
+ except GeneratorExit:
+ pass
+
+ def _saveAsMNG(self, filename, nbFrames):
+ """Save video as MNG file.
+
+ :param str filename: filename to use
+ :param int nbFrames: Number of frames to generate
+ """
+ plot3d = self.getPlot3DWidget()
+ assert plot3d is not None
+
+ frames = (convertQImageToArray(im) for im in self._video360(nbFrames))
+ try:
+ with open(filename, 'wb') as file_:
+ for chunk in mng.convert(frames, nb_images=nbFrames):
+ file_.write(chunk)
+ except GeneratorExit:
+ os.remove(filename) # Saving aborted, delete file
+
+ def _video360(self, nbFrames):
+ """Run the video and provides the images
+
+ :param int nbFrames: The number of frames to generate for
+ :return: Iterator of QImage of the video sequence
+ """
+ plot3d = self.getPlot3DWidget()
+ assert plot3d is not None
+
+ angleStep = 360. / nbFrames
+
+ # Create progress bar dialog
+ dialog = qt.QDialog(plot3d)
+ dialog.setWindowTitle('Record Video')
+ layout = qt.QVBoxLayout(dialog)
+ progress = qt.QProgressBar()
+ progress.setRange(0, nbFrames)
+ layout.addWidget(progress)
+
+ btnBox = qt.QDialogButtonBox(qt.QDialogButtonBox.Abort)
+ btnBox.rejected.connect(dialog.reject)
+ layout.addWidget(btnBox)
+
+ dialog.setModal(True)
+ dialog.show()
+
+ qapp = qt.QApplication.instance()
+
+ for frame in range(nbFrames):
+ progress.setValue(frame)
+ image = plot3d.grabGL()
+ yield image
+ plot3d.viewport.orbitCamera('left', angleStep)
+ qapp.processEvents()
+ if not dialog.isVisible():
+ break # It as been rejected by the abort button
+ else:
+ dialog.accept()
+
+ if dialog.result() == qt.QDialog.Rejected:
+ raise GeneratorExit('Aborted')
diff --git a/silx/gui/plot3d/Plot3DToolBar.py b/silx/gui/plot3d/Plot3DToolBar.py
new file mode 100644
index 0000000..cf11362
--- /dev/null
+++ b/silx/gui/plot3d/Plot3DToolBar.py
@@ -0,0 +1,119 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a toolbar with tools for a Plot3DWidget.
+
+It provides:
+
+- Copy
+- Save
+- Print
+"""
+
+from __future__ import absolute_import
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "10/01/2017"
+
+import logging
+
+from silx.gui import qt
+
+from . import Plot3DActions
+
+_logger = logging.getLogger(__name__)
+
+
+class Plot3DToolBar(qt.QToolBar):
+ """Toolbar providing icons to copy, save and print the OpenGL scene
+
+ :param parent: See :class:`QWidget`
+ :param str title: Title of the toolbar.
+ """
+
+ def __init__(self, parent=None, title='Plot3D'):
+ super(Plot3DToolBar, self).__init__(title, parent)
+
+ self._plot3d = None
+
+ self._copyAction = Plot3DActions.CopyAction(parent=self)
+ self.addAction(self._copyAction)
+
+ self._saveAction = Plot3DActions.SaveAction(parent=self)
+ self.addAction(self._saveAction)
+
+ self._videoAction = Plot3DActions.VideoAction(parent=self)
+ self.addAction(self._videoAction)
+
+ self._printAction = Plot3DActions.PrintAction(parent=self)
+ self.addAction(self._printAction)
+
+ def setPlot3DWidget(self, widget):
+ """Set the Plot3DWidget this toolbar is associated with
+
+ :param Plot3DWidget widget: The widget to copy/save/print
+ """
+ self._plot3d = widget
+ self.getCopyAction().setPlot3DWidget(widget)
+ self.getSaveAction().setPlot3DWidget(widget)
+ self.getVideoRecordAction().setPlot3DWidget(widget)
+ self.getPrintAction().setPlot3DWidget(widget)
+
+ def getPlot3DWidget(self):
+ """Return the Plot3DWidget associated to this toolbar.
+
+ If no widget is associated, it returns None.
+
+ :rtype: qt.QWidget
+ """
+ return self._plot3d
+
+ def getCopyAction(self):
+ """Returns the QAction performing copy to clipboard of the Plot3DWidget
+
+ :rtype: qt.QAction
+ """
+ return self._copyAction
+
+ def getSaveAction(self):
+ """Returns the QAction performing save to file of the Plot3DWidget
+
+ :rtype: qt.QAction
+ """
+ return self._saveAction
+
+ def getVideoRecordAction(self):
+ """Returns the QAction performing record video of the Plot3DWidget
+
+ :rtype: qt.QAction
+ """
+ return self._videoAction
+
+ def getPrintAction(self):
+ """Returns the QAction performing printing of the Plot3DWidget
+
+ :rtype: qt.QAction
+ """
+ return self._printAction
diff --git a/silx/gui/plot3d/Plot3DWidget.py b/silx/gui/plot3d/Plot3DWidget.py
new file mode 100644
index 0000000..9c9da0c
--- /dev/null
+++ b/silx/gui/plot3d/Plot3DWidget.py
@@ -0,0 +1,341 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a Qt widget embedding an OpenGL scene."""
+
+from __future__ import absolute_import
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "26/01/2017"
+
+
+import logging
+
+from silx.gui import qt
+from silx.gui.plot.Colors import rgba
+from silx.gui.plot3d import Plot3DActions
+from .._utils import convertArrayToQImage
+
+from .._glutils import gl
+from .scene import interaction, primitives, transform
+from . import scene
+
+import numpy
+
+
+_logger = logging.getLogger(__name__)
+
+
+class _OverviewViewport(scene.Viewport):
+ """A scene displaying the orientation of the data in another scene.
+
+ :param Camera camera: The camera to track.
+ """
+
+ def __init__(self, camera=None):
+ super(_OverviewViewport, self).__init__()
+ self.size = 100, 100
+
+ self.scene.transforms = [transform.Scale(2.5, 2.5, 2.5)]
+
+ axes = primitives.Axes()
+ self.scene.children.append(axes)
+
+ if camera is not None:
+ camera.addListener(self._cameraChanged)
+
+ def _cameraChanged(self, source):
+ """Listen to camera in other scene for transformation updates.
+
+ Sync the overview camera to point in the same direction
+ but from a sphere centered on origin.
+ """
+ position = -12. * source.extrinsic.direction
+ self.camera.extrinsic.position = position
+
+ self.camera.extrinsic.setOrientation(
+ source.extrinsic.direction, source.extrinsic.up)
+
+
+class Plot3DWidget(qt.QGLWidget):
+ """QGLWidget with a 3D viewport and an overview."""
+
+ def __init__(self, parent=None):
+ if not qt.QGLFormat.hasOpenGL(): # Check if any OpenGL is available
+ raise RuntimeError(
+ 'OpenGL is not available on this platform: 3D disabled')
+
+ self._devicePixelRatio = 1.0 # Store GL canvas/QWidget ratio
+ self._isOpenGL21 = False
+ self._firstRender = True
+
+ format_ = qt.QGLFormat()
+ format_.setRgba(True)
+ format_.setDepth(False)
+ format_.setStencil(False)
+ format_.setVersion(2, 1)
+ format_.setDoubleBuffer(True)
+
+ super(Plot3DWidget, self).__init__(format_, parent)
+ self.setAutoFillBackground(False)
+ self.setMouseTracking(True)
+
+ self.setFocusPolicy(qt.Qt.StrongFocus)
+ self._copyAction = Plot3DActions.CopyAction(parent=self, plot3d=self)
+ self.addAction(self._copyAction)
+
+ self._updating = False # True if an update is requested
+
+ # Main viewport
+ self.viewport = scene.Viewport()
+ self.viewport.background = 0.2, 0.2, 0.2, 1.
+
+ sceneScale = transform.Scale(1., 1., 1.)
+ self.viewport.scene.transforms = [sceneScale,
+ transform.Translate(0., 0., 0.)]
+
+ # Overview area
+ self.overview = _OverviewViewport(self.viewport.camera)
+
+ self.setBackgroundColor((0.2, 0.2, 0.2, 1.))
+
+ # Window describing on screen area to render
+ self.window = scene.Window(mode='framebuffer')
+ self.window.viewports = [self.viewport, self.overview]
+
+ self.eventHandler = interaction.CameraControl(
+ self.viewport, orbitAroundCenter=False,
+ mode='position', scaleTransform=sceneScale,
+ selectCB=None)
+
+ self.viewport.addListener(self._redraw)
+
+ def setProjection(self, projection):
+ """Change the projection in use.
+
+ :param str projection: In 'perspective', 'orthographic'.
+ """
+ if projection == 'orthographic':
+ projection = transform.Orthographic(size=self.viewport.size)
+ elif projection == 'perspective':
+ projection = transform.Perspective(fovy=30.,
+ size=self.viewport.size)
+ else:
+ raise RuntimeError('Unsupported projection: %s' % projection)
+
+ self.viewport.camera.intrinsic = projection
+ self.viewport.resetCamera()
+
+ def getProjection(self):
+ """Return the current camera projection mode as a str.
+
+ See :meth:`setProjection`
+ """
+ projection = self.viewport.camera.intrinsic
+ if isinstance(projection, transform.Orthographic):
+ return 'orthographic'
+ elif isinstance(projection, transform.Perspective):
+ return 'perspective'
+ else:
+ raise RuntimeError('Unknown projection in use')
+
+ def setBackgroundColor(self, color):
+ """Set the background color of the OpenGL view.
+
+ :param color: RGB color of the isosurface: name, #RRGGBB or RGB values
+ :type color:
+ QColor, str or array-like of 3 or 4 float in [0., 1.] or uint8
+ """
+ color = rgba(color)
+ self.viewport.background = color
+ self.overview.background = color[0]*0.5, color[1]*0.5, color[2]*0.5, 1.
+
+ def getBackgroundColor(self):
+ """Returns the RGBA background color (QColor)."""
+ return qt.QColor.fromRgbF(*self.viewport.background)
+
+ def centerScene(self):
+ """Position the center of the scene at the center of rotation."""
+ self.viewport.resetCamera()
+
+ def resetZoom(self, face='front'):
+ """Reset the camera position to a default.
+
+ :param str face: The direction the camera is looking at:
+ side, front, back, top, bottom, right, left.
+ Default: front.
+ """
+ self.viewport.camera.extrinsic.reset(face=face)
+ self.centerScene()
+
+ def _redraw(self, source=None):
+ """Viewport listener to require repaint"""
+ if not self._updating and self.viewport.dirty:
+ self._updating = True # Mark that an update is requested
+ self.update() # Queued repaint (i.e., asynchronous)
+
+ def sizeHint(self):
+ return qt.QSize(400, 300)
+
+ def initializeGL(self):
+ # Check if OpenGL2 is available
+ versionflags = self.format().openGLVersionFlags()
+ self._isOpenGL21 = bool(versionflags & qt.QGLFormat.OpenGL_Version_2_1)
+ if not self._isOpenGL21:
+ _logger.error(
+ '3D rendering is disabled: OpenGL 2.1 not available')
+
+ messageBox = qt.QMessageBox(parent=self)
+ messageBox.setIcon(qt.QMessageBox.Critical)
+ messageBox.setWindowTitle('Error')
+ messageBox.setText('3D rendering is disabled.\n\n'
+ 'Reason: OpenGL 2.1 is not available.')
+ messageBox.addButton(qt.QMessageBox.Ok)
+ messageBox.setWindowModality(qt.Qt.WindowModal)
+ messageBox.setAttribute(qt.Qt.WA_DeleteOnClose)
+ messageBox.show()
+
+ def paintGL(self):
+ # In case paintGL is called by the system and not through _redraw,
+ # Mark as updating.
+ self._updating = True
+
+ if hasattr(self, 'windowHandle'): # Qt 5
+ devicePixelRatio = self.windowHandle().devicePixelRatio()
+ if devicePixelRatio != self._devicePixelRatio:
+ # Move window from one screen to another one
+ self._devicePixelRatio = devicePixelRatio
+ # Resize might not be called, so call it explicitly
+ self.resizeGL(int(self.width() * devicePixelRatio),
+ int(self.height() * devicePixelRatio))
+
+ if not self._isOpenGL21:
+ # Cannot render scene, just clear the color buffer.
+ ox, oy = self.viewport.origin
+ w, h = self.viewport.size
+ gl.glViewport(ox, oy, w, h)
+
+ gl.glClearColor(*self.viewport.background)
+ gl.glClear(gl.GL_COLOR_BUFFER_BIT)
+
+ else:
+ # Update near and far planes only if viewport needs refresh
+ if self.viewport.dirty:
+ self.viewport.adjustCameraDepthExtent()
+
+ self.window.render(self.context(), self._devicePixelRatio)
+
+ if self._firstRender: # TODO remove this ugly hack
+ self._firstRender = False
+ self.centerScene()
+ self._updating = False
+
+ def resizeGL(self, width, height):
+ self.window.size = width, height
+ self.viewport.size = width, height
+ overviewWidth, overviewHeight = self.overview.size
+ self.overview.origin = width - overviewWidth, height - overviewHeight
+
+ def grabGL(self):
+ """Renders the OpenGL scene into a numpy array
+
+ :returns: OpenGL scene RGB rasterization
+ :rtype: QImage
+ """
+ if not self._isOpenGL21:
+ _logger.error('OpenGL 2.1 not available, cannot save OpenGL image')
+ height, width = self.window.shape
+ image = numpy.zeros((height, width, 3), dtype=numpy.uint8)
+
+ else:
+ self.makeCurrent()
+ image = self.window.grab(qt.QGLContext.currentContext())
+
+ return convertArrayToQImage(image)
+
+ def wheelEvent(self, event):
+ xpixel = event.x() * self._devicePixelRatio
+ ypixel = event.y() * self._devicePixelRatio
+ if hasattr(event, 'delta'): # Qt4
+ angle = event.delta() / 8.
+ else: # Qt5
+ angle = event.angleDelta().y() / 8.
+ event.accept()
+
+ if angle != 0:
+ self.makeCurrent()
+ self.eventHandler.handleEvent('wheel', xpixel, ypixel, angle)
+
+ def keyPressEvent(self, event):
+ keycode = event.key()
+ # No need to accept QKeyEvent
+
+ converter = {
+ qt.Qt.Key_Left: 'left',
+ qt.Qt.Key_Right: 'right',
+ qt.Qt.Key_Up: 'up',
+ qt.Qt.Key_Down: 'down'
+ }
+ direction = converter.get(keycode, None)
+ if direction is not None:
+ if event.modifiers() == qt.Qt.ControlModifier:
+ self.viewport.camera.rotate(direction)
+ elif event.modifiers() == qt.Qt.ShiftModifier:
+ self.viewport.moveCamera(direction)
+ else:
+ self.viewport.orbitCamera(direction)
+
+ else:
+ # Key not handled, call base class implementation
+ super(Plot3DWidget, self).keyPressEvent(event)
+
+ # Mouse events #
+ _MOUSE_BTNS = {1: 'left', 2: 'right', 4: 'middle'}
+
+ def mousePressEvent(self, event):
+ xpixel = event.x() * self._devicePixelRatio
+ ypixel = event.y() * self._devicePixelRatio
+ btn = self._MOUSE_BTNS[event.button()]
+ event.accept()
+
+ self.makeCurrent()
+ self.eventHandler.handleEvent('press', xpixel, ypixel, btn)
+
+ def mouseMoveEvent(self, event):
+ xpixel = event.x() * self._devicePixelRatio
+ ypixel = event.y() * self._devicePixelRatio
+ event.accept()
+
+ self.makeCurrent()
+ self.eventHandler.handleEvent('move', xpixel, ypixel)
+
+ def mouseReleaseEvent(self, event):
+ xpixel = event.x() * self._devicePixelRatio
+ ypixel = event.y() * self._devicePixelRatio
+ btn = self._MOUSE_BTNS[event.button()]
+ event.accept()
+
+ self.makeCurrent()
+ self.eventHandler.handleEvent('release', xpixel, ypixel, btn)
diff --git a/silx/gui/plot3d/Plot3DWindow.py b/silx/gui/plot3d/Plot3DWindow.py
new file mode 100644
index 0000000..4658d38
--- /dev/null
+++ b/silx/gui/plot3d/Plot3DWindow.py
@@ -0,0 +1,94 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a QMainWindow with a 3D scene and associated toolbar.
+"""
+
+from __future__ import absolute_import
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "26/01/2017"
+
+
+from silx.gui import qt
+
+from .Plot3DToolBar import Plot3DToolBar
+from .Plot3DWidget import Plot3DWidget
+from .ViewpointToolBar import ViewpointToolBar
+
+
+class Plot3DWindow(qt.QMainWindow):
+ """QGLWidget with a 3D viewport and an overview."""
+
+ def __init__(self, parent=None):
+ super(Plot3DWindow, self).__init__(parent)
+ if parent is not None:
+ # behave as a widget
+ self.setWindowFlags(qt.Qt.Widget)
+
+ self._plot3D = Plot3DWidget()
+ self.setCentralWidget(self._plot3D)
+ self.addToolBar(
+ ViewpointToolBar(parent=self, plot3D=self._plot3D))
+ toolbar = Plot3DToolBar(parent=self)
+ toolbar.setPlot3DWidget(self._plot3D)
+ self.addToolBar(toolbar)
+ self.addActions(toolbar.actions())
+
+ def getPlot3DWidget(self):
+ """Get the :class:`Plot3DWidget` of this window"""
+ return self._plot3D
+
+ # Proxy to Plot3DWidget
+
+ def setProjection(self, projection):
+ return self._plot3D.setProjection(projection)
+
+ setProjection.__doc__ = Plot3DWidget.setProjection.__doc__
+
+ def getProjection(self):
+ return self._plot3D.getProjection()
+
+ getProjection.__doc__ = Plot3DWidget.getProjection.__doc__
+
+ def centerScene(self):
+ return self._plot3D.centerScene()
+
+ centerScene.__doc__ = Plot3DWidget.centerScene.__doc__
+
+ def resetZoom(self):
+ return self._plot3D.resetZoom()
+
+ resetZoom.__doc__ = Plot3DWidget.resetZoom.__doc__
+
+ def getBackgroundColor(self):
+ return self._plot3D.getBackgroundColor()
+
+ getBackgroundColor.__doc__ = Plot3DWidget.getBackgroundColor.__doc__
+
+ def setBackgroundColor(self, color):
+ return self._plot3D.setBackgroundColor(color)
+
+ setBackgroundColor.__doc__ = Plot3DWidget.setBackgroundColor.__doc__
diff --git a/silx/gui/plot3d/SFViewParamTree.py b/silx/gui/plot3d/SFViewParamTree.py
new file mode 100644
index 0000000..38d4e37
--- /dev/null
+++ b/silx/gui/plot3d/SFViewParamTree.py
@@ -0,0 +1,1467 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""
+This module provides a tree widget to set/view parameters of a ScalarFieldView.
+"""
+
+from __future__ import absolute_import
+
+__authors__ = ["D. N."]
+__license__ = "MIT"
+__date__ = "10/01/2017"
+
+import logging
+import sys
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.icons import getQIcon
+
+from .ScalarFieldView import Isosurface
+
+
+_logger = logging.getLogger(__name__)
+
+
+class ModelColumns(object):
+ NameColumn, ValueColumn, ColumnMax = range(3)
+ ColumnNames = ['Name', 'Value']
+
+
+class SubjectItem(qt.QStandardItem):
+ """
+ Base class for observers items.
+
+ Subclassing:
+ ------------
+ The following method can/should be reimplemented:
+ - _init
+ - _pullData
+ - _pushData
+ - _setModelData
+ - _subjectChanged
+ - getEditor
+ - getSignals
+ - leftClicked
+ - queryRemove
+ - setEditorData
+
+ Also the following attributes are available:
+ - editable
+ - persistent
+
+ :param subject: object that this item will be observing.
+ """
+
+ editable = False
+ """ boolean: set to True to make the item editable. """
+
+ persistent = False
+ """
+ boolean: set to True to make the editor persistent.
+ See : Qt.QAbstractItemView.openPersistentEditor
+ """
+
+ def __init__(self, subject, *args):
+
+ super(SubjectItem, self).__init__(*args)
+
+ self.setEditable(self.editable)
+
+ self.__subject = None
+ self.subject = subject
+
+ def setData(self, value, role=qt.Qt.UserRole, pushData=True):
+ """
+ Overloaded method from QStandardItem. The pushData keyword tells
+ the item to push data to the subject if the role is equal to EditRole.
+ This is useful to let this method know if the setData method was called
+ internaly or from the view.
+
+ :param value: the value ti set to data
+ :param role: role in the item
+ :param pushData: if True push value in the existing data.
+ """
+ if role == qt.Qt.EditRole and pushData:
+ setValue = self._pushData(value, role)
+ if setValue != value:
+ value = setValue
+ super(SubjectItem, self).setData(value, role)
+
+ subject = property(lambda self: self.__subject)
+
+ @subject.setter
+ def subject(self, subject):
+ if self.__subject is not None:
+ raise ValueError('Subject already set '
+ ' (subject change not supported).')
+ self.__subject = subject
+ if subject is not None:
+ self._init()
+ self._connectSignals()
+
+ def _connectSignals(self):
+ """
+ Connects the signals. Called when the subject is set.
+ """
+
+ def gen_slot(_sigIdx):
+ def slotfn(*args, **kwargs):
+ self._subjectChanged(signalIdx=_sigIdx,
+ args=args,
+ kwargs=kwargs)
+ return slotfn
+
+ if self.__subject is not None:
+ self.__slots = slots = []
+
+ signals = self.getSignals()
+
+ if signals:
+ if not isinstance(signals, (list, tuple)):
+ signals = [signals]
+ for sigIdx, signal in enumerate(signals):
+ slot = gen_slot(sigIdx)
+ signal.connect(slot)
+ slots.append((signal, slot))
+
+ def _disconnectSignals(self):
+ """
+ Disconnects all subject's signal
+ """
+ if self.__slots:
+ for signal, slot in self.__slots:
+ try:
+ signal.disconnect(slot)
+ except TypeError:
+ pass
+
+ def _enableRow(self, enable):
+ """
+ Set the enabled state for this cell, or for the whole row
+ if this item has a parent.
+
+ :param bool enable: True if we wan't to enable the cell
+ """
+ parent = self.parent()
+ model = self.model()
+ if model is None or parent is None:
+ # no parent -> no siblings
+ self.setEnabled(enable)
+ return
+
+ for col in range(model.columnCount()):
+ sibling = parent.child(self.row(), col)
+ sibling.setEnabled(enable)
+
+ #################################################################
+ # Overloadable methods
+ #################################################################
+
+ def getSignals(self):
+ """
+ Returns the list of this items subject's signals that
+ this item will be listening to.
+
+ :return: list.
+ """
+ return None
+
+ def _subjectChanged(self, signalIdx=None, args=None, kwargs=None):
+ """
+ Called when one of the signals is triggered. Default implementation
+ just calls _pullData, compares the result to the current value stored
+ as Qt.EditRole, and stores the new value if it is different. It also
+ stores its str representation as Qt.DisplayRole
+
+ :param signalIdx: index of the triggered signal. The value passed
+ is the same as the signal position in the list returned by
+ SubjectItem.getSignals.
+ :param args: arguments received from the signal
+ :param kwargs: keyword arguments received from the signal
+ """
+ data = self._pullData()
+ if data == self.data(qt.Qt.EditRole):
+ return
+ self.setData(data, role=qt.Qt.DisplayRole, pushData=False)
+ self.setData(data, role=qt.Qt.EditRole, pushData=False)
+
+ def _pullData(self):
+ """
+ Pulls data from the subject.
+
+ :return: subject data
+ """
+ return None
+
+ def _pushData(self, value, role=qt.Qt.UserRole):
+ """
+ Pushes data to the subject and returns the actual value that was stored
+
+ :return: the value that was stored
+ """
+ return value
+
+ def _init(self):
+ """
+ Called when the subject is set.
+ :return:
+ """
+ self._subjectChanged()
+
+ def getEditor(self, parent, option, index):
+ """
+ Returns the editor widget used to edit this item's data. The arguments
+ are the one passed to the QStyledItemDelegate.createEditor method.
+
+ :param parent: the Qt parent of the editor
+ :param option:
+ :param index:
+ :return:
+ """
+ return None
+
+ def setEditorData(self, editor):
+ """
+ This is called by the View's delegate just before the editor is shown,
+ its purpose it to setup the editors contents. Return False to use
+ the delegate's default behaviour.
+
+ :param editor:
+ :return:
+ """
+ return True
+
+ def _setModelData(self, editor):
+ """
+ This is called by the View's delegate just before the editor is closed,
+ its allows this item to update itself with data from the editor.
+
+ :param editor:
+ :return:
+ """
+ return False
+
+ def queryRemove(self, view=None):
+ """
+ This is called by the view to ask this items if it (the view) can
+ remove it. Return True to let the view know that the item can be
+ removed.
+
+ :param view:
+ :return:
+ """
+ return False
+
+ def leftClicked(self):
+ """
+ This method is called by the view when the item's cell if left clicked.
+
+ :return:
+ """
+ pass
+
+
+# View settings ###############################################################
+
+class ColorItem(SubjectItem):
+ """color item."""
+ editable = True
+ persistent = True
+
+ def getEditor(self, parent, option, index):
+ editor = QColorEditor(parent)
+ editor.color = self.getColor()
+ editor.sigColorChanged.connect(self._editorSlot)
+ return editor
+
+ def _editorSlot(self, color):
+ self.setData(color, qt.Qt.EditRole)
+
+ def _pushData(self, value, role=qt.Qt.UserRole):
+ self.setColor(value)
+ return self.getColor()
+
+ def _pullData(self):
+ self.getColor()
+
+ def setColor(self, color):
+ """Override to implement actual color setter"""
+ pass
+
+
+class BackgroundColorItem(ColorItem):
+ itemName = 'Background'
+
+ def setColor(self, color):
+ self.subject.setBackgroundColor(color)
+
+ def getColor(self):
+ return self.subject.getBackgroundColor()
+
+
+class ForegroundColorItem(ColorItem):
+ itemName = 'Foreground'
+
+ def setColor(self, color):
+ self.subject.setForegroundColor(color)
+
+ def getColor(self):
+ return self.subject.getForegroundColor()
+
+
+class HighlightColorItem(ColorItem):
+ itemName = 'Highlight'
+
+ def setColor(self, color):
+ self.subject.setHighlightColor(color)
+
+ def getColor(self):
+ return self.subject.getHighlightColor()
+
+
+class ViewSettingsItem(qt.QStandardItem):
+ """Viewport settings"""
+
+ def __init__(self, subject, *args):
+
+ super(ViewSettingsItem, self).__init__(*args)
+
+ self.setEditable(False)
+
+ classes = BackgroundColorItem, ForegroundColorItem, HighlightColorItem
+ for cls in classes:
+ titleItem = qt.QStandardItem(cls.itemName)
+ titleItem.setEditable(False)
+ self.appendRow([titleItem, cls(subject)])
+
+
+# Data information ############################################################
+
+class DataChangedItem(SubjectItem):
+ """
+ Base class for items listening to ScalarFieldView.sigDataChanged
+ """
+
+ def getSignals(self):
+ subject = self.subject
+ if subject:
+ return subject.sigDataChanged
+ return None
+
+ def _init(self):
+ self._subjectChanged()
+
+
+class DataTypeItem(DataChangedItem):
+ itemName = 'dtype'
+
+ def _pullData(self):
+ data = self.subject.getData(copy=False)
+ return ((data is not None) and str(data.dtype)) or 'N/A'
+
+
+class DataShapeItem(DataChangedItem):
+ itemName = 'size'
+
+ def _pullData(self):
+ data = self.subject.getData(copy=False)
+ if data is None:
+ return 'N/A'
+ else:
+ return str(list(reversed(data.shape)))
+
+
+class OffsetItem(DataChangedItem):
+ itemName = 'offset'
+
+ def _pullData(self):
+ offset = self.subject.getTranslation()
+ return ((offset is not None) and str(offset)) or 'N/A'
+
+
+class ScaleItem(DataChangedItem):
+ itemName = 'scale'
+
+ def _pullData(self):
+ scale = self.subject.getScale()
+ return ((scale is not None) and str(scale)) or 'N/A'
+
+
+class DataSetItem(qt.QStandardItem):
+
+ def __init__(self, subject, *args):
+
+ super(DataSetItem, self).__init__(*args)
+
+ self.setEditable(False)
+
+ klasses = [DataTypeItem, DataShapeItem, OffsetItem, ScaleItem]
+ for klass in klasses:
+ titleItem = qt.QStandardItem(klass.itemName)
+ titleItem.setEditable(False)
+ self.appendRow([titleItem, klass(subject)])
+
+
+# Isosurface ##################################################################
+
+class IsoSurfaceRootItem(SubjectItem):
+ """
+ Root (i.e : column index 0) Isosurface item.
+ """
+
+ def getSignals(self):
+ subject = self.subject
+ return [subject.sigColorChanged,
+ subject.sigVisibilityChanged]
+
+ def _subjectChanged(self, signalIdx=None, args=None, kwargs=None):
+ if signalIdx == 0:
+ color = self.subject.getColor()
+ self.setData(color, qt.Qt.DecorationRole)
+ elif signalIdx == 1:
+ visible = args[0]
+ self.setCheckState((visible and qt.Qt.Checked) or qt.Qt.Unchecked)
+
+ def _init(self):
+ self.setCheckable(True)
+
+ isosurface = self.subject
+ color = isosurface.getColor()
+ visible = isosurface.isVisible()
+ self.setData(color, qt.Qt.DecorationRole)
+ self.setCheckState((visible and qt.Qt.Checked) or qt.Qt.Unchecked)
+
+ nameItem = qt.QStandardItem('Level')
+ sliderItem = IsoSurfaceLevelSlider(self.subject)
+ self.appendRow([nameItem, sliderItem])
+
+ nameItem = qt.QStandardItem('Color')
+ nameItem.setEditable(False)
+ valueItem = IsoSurfaceColorItem(self.subject)
+ self.appendRow([nameItem, valueItem])
+
+ nameItem = qt.QStandardItem('Opacity')
+ nameItem.setTextAlignment(qt.Qt.AlignLeft | qt.Qt.AlignTop)
+ nameItem.setEditable(False)
+ valueItem = IsoSurfaceAlphaItem(self.subject)
+ self.appendRow([nameItem, valueItem])
+
+ nameItem = qt.QStandardItem()
+ nameItem.setEditable(False)
+ valueItem = IsoSurfaceAlphaLegendItem(self.subject)
+ valueItem.setEditable(False)
+ self.appendRow([nameItem, valueItem])
+
+ def queryRemove(self, view=None):
+ buttons = qt.QMessageBox.Ok | qt.QMessageBox.Cancel
+ ans = qt.QMessageBox.question(view,
+ 'Remove isosurface',
+ 'Remove the selected iso-surface?',
+ buttons=buttons)
+ if ans == qt.QMessageBox.Ok:
+ sfview = self.subject.parent()
+ if sfview:
+ sfview.removeIsosurface(self.subject)
+ return False
+ return False
+
+ def leftClicked(self):
+ checked = (self.checkState() == qt.Qt.Checked)
+ visible = self.subject.isVisible()
+ if checked != visible:
+ self.subject.setVisible(checked)
+
+
+class IsoSurfaceLevelItem(SubjectItem):
+ """
+ Base class for the isosurface level items.
+ """
+ editable = True
+
+ def getSignals(self):
+ subject = self.subject
+ return [subject.sigLevelChanged,
+ subject.sigVisibilityChanged]
+
+ def setEditorData(self, editor):
+ return False
+
+ def _pullData(self):
+ return self.subject.getLevel()
+
+ def _pushData(self, value, role=qt.Qt.UserRole):
+ self.subject.setLevel(value)
+ return self.subject.getLevel()
+
+
+class _IsoLevelSlider(qt.QSlider):
+ """QSlider used for iso-surface level"""
+
+ def __init__(self, parent, subject):
+ super(_IsoLevelSlider, self).__init__(parent=parent)
+ self.subject = subject
+
+ self.sliderReleased.connect(self.__sliderReleased)
+
+ self.subject.sigLevelChanged.connect(self.setLevel)
+ self.subject.parent().sigDataChanged.connect(self.__dataChanged)
+
+ def setLevel(self, level):
+ """Set slider from iso-surface level"""
+ dataRange = self.subject.parent().getDataRange()
+
+ if dataRange is not None and None not in dataRange:
+ width = dataRange[1] - dataRange[0]
+ if width > 0:
+ sliderWidth = self.maximum() - self.minimum()
+ sliderPosition = sliderWidth * (level - dataRange[0]) / width
+ self.setValue(sliderPosition)
+
+ def __dataChanged(self):
+ """Handles data update to refresh slider range if needed"""
+ self.setLevel(self.subject.getLevel())
+
+ def __sliderReleased(self):
+ value = self.value()
+ dataRange = self.subject.parent().getDataRange()
+ width = dataRange[1] - dataRange[0]
+ sliderWidth = self.maximum() - self.minimum()
+ level = dataRange[0] + width * value / sliderWidth
+ self.subject.setLevel(level)
+
+
+class IsoSurfaceLevelSlider(IsoSurfaceLevelItem):
+ """
+ Isosurface level item with a slider editor.
+ """
+ nTicks = 1000
+ persistent = True
+
+ def getEditor(self, parent, option, index):
+ editor = _IsoLevelSlider(parent, self.subject)
+ editor.setOrientation(qt.Qt.Horizontal)
+ editor.setMinimum(0)
+ editor.setMaximum(self.nTicks)
+
+ editor.setSingleStep(1)
+
+ editor.setLevel(self.subject.getLevel())
+ return editor
+
+ def setEditorData(self, editor):
+ return True
+
+ def _setModelData(self, editor):
+ return True
+
+
+class IsoSurfaceColorItem(SubjectItem):
+ """
+ Isosurface color item.
+ """
+ editable = True
+ persistent = True
+
+ def getSignals(self):
+ return self.subject.sigColorChanged
+
+ def getEditor(self, parent, option, index):
+ editor = QColorEditor(parent)
+ color = self.subject.getColor()
+ color.setAlpha(255)
+ editor.color = color
+ editor.sigColorChanged.connect(self.__editorChanged)
+ return editor
+
+ def __editorChanged(self, color):
+ color.setAlpha(self.subject.getColor().alpha())
+ self.subject.setColor(color)
+
+ def _pushData(self, value, role=qt.Qt.UserRole):
+ self.subject.setColor(value)
+ return self.subject.getColor()
+
+
+class QColorEditor(qt.QWidget):
+ """
+ QColor editor.
+ """
+ sigColorChanged = qt.Signal(object)
+
+ color = property(lambda self: qt.QColor(self.__color))
+
+ @color.setter
+ def color(self, color):
+ self._setColor(color)
+ self.__previousColor = color
+
+ def __init__(self, *args, **kwargs):
+ super(QColorEditor, self).__init__(*args, **kwargs)
+ layout = qt.QHBoxLayout(self)
+ layout.setContentsMargins(0, 0, 0, 0)
+ button = qt.QToolButton()
+ icon = qt.QIcon(qt.QPixmap(32, 32))
+ button.setIcon(icon)
+ layout.addWidget(button)
+ button.clicked.connect(self.__showColorDialog)
+ layout.addStretch(1)
+
+ self.__color = None
+ self.__previousColor = None
+
+ def sizeHint(self):
+ return qt.QSize(0, 0)
+
+ def _setColor(self, qColor):
+ button = self.findChild(qt.QToolButton)
+ pixmap = qt.QPixmap(32, 32)
+ pixmap.fill(qColor)
+ button.setIcon(qt.QIcon(pixmap))
+ self.__color = qColor
+
+ def __showColorDialog(self):
+ dialog = qt.QColorDialog(parent=self)
+ if sys.platform == 'darwin':
+ # Use of native color dialog on macos might cause problems
+ dialog.setOption(qt.QColorDialog.DontUseNativeDialog, True)
+
+ self.__previousColor = self.__color
+ dialog.setAttribute(qt.Qt.WA_DeleteOnClose)
+ dialog.setModal(True)
+ dialog.currentColorChanged.connect(self.__colorChanged)
+ dialog.finished.connect(self.__dialogClosed)
+ dialog.show()
+
+ def __colorChanged(self, color):
+ self.__color = color
+ self._setColor(color)
+ self.sigColorChanged.emit(color)
+
+ def __dialogClosed(self, result):
+ if result == qt.QDialog.Rejected:
+ self.__colorChanged(self.__previousColor)
+ self.__previousColor = None
+
+
+class IsoSurfaceAlphaItem(SubjectItem):
+ """
+ Isosurface alpha item.
+ """
+ editable = True
+ persistent = True
+
+ def _init(self):
+ pass
+
+ def getSignals(self):
+ return self.subject.sigColorChanged
+
+ def getEditor(self, parent, option, index):
+ editor = qt.QSlider(parent)
+ editor.setOrientation(qt.Qt.Horizontal)
+ editor.setMinimum(0)
+ editor.setMaximum(255)
+
+ color = self.subject.getColor()
+ editor.setValue(color.alpha())
+
+ editor.valueChanged.connect(self.__editorChanged)
+
+ return editor
+
+ def __editorChanged(self, value):
+ color = self.subject.getColor()
+ color.setAlpha(value)
+ self.subject.setColor(color)
+
+ def setEditorData(self, editor):
+ return True
+
+ def _setModelData(self, editor):
+ return True
+
+
+class IsoSurfaceAlphaLegendItem(SubjectItem):
+ """Legend to place under opacity slider"""
+
+ editable = False
+ persistent = True
+
+ def getEditor(self, parent, option, index):
+ layout = qt.QHBoxLayout()
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setSpacing(0)
+ layout.addWidget(qt.QLabel('0'))
+ layout.addStretch(1)
+ layout.addWidget(qt.QLabel('1'))
+
+ editor = qt.QWidget(parent)
+ editor.setLayout(layout)
+ return editor
+
+
+class IsoSurfaceCount(SubjectItem):
+ """
+ Item displaying the number of isosurfaces.
+ """
+
+ def getSignals(self):
+ subject = self.subject
+ return [subject.sigIsosurfaceAdded, subject.sigIsosurfaceRemoved]
+
+ def _pullData(self):
+ return len(self.subject.getIsosurfaces())
+
+
+class IsoSurfaceAddRemoveWidget(qt.QWidget):
+
+ sigViewTask = qt.Signal(str)
+ """Signal for the tree view to perform some task"""
+
+ def __init__(self, parent, item):
+ super(IsoSurfaceAddRemoveWidget, self).__init__(parent)
+ self._item = item
+ layout = qt.QHBoxLayout(self)
+ layout.setContentsMargins(0, 0, 0, 0)
+ layout.setSpacing(0)
+
+ addBtn = qt.QToolButton()
+ addBtn.setText('+')
+ addBtn.setToolButtonStyle(qt.Qt.ToolButtonTextOnly)
+ layout.addWidget(addBtn)
+ addBtn.clicked.connect(self.__addClicked)
+
+ removeBtn = qt.QToolButton()
+ removeBtn.setText('-')
+ removeBtn.setToolButtonStyle(qt.Qt.ToolButtonTextOnly)
+ layout.addWidget(removeBtn)
+ removeBtn.clicked.connect(self.__removeClicked)
+
+ layout.addStretch(1)
+
+ def __addClicked(self):
+ sfview = self._item.subject
+ if not sfview:
+ return
+ dataRange = sfview.getDataRange()
+ if dataRange is None:
+ dataRange = [0, 1]
+
+ sfview.addIsosurface(numpy.mean(dataRange), '#0000FF')
+
+ def __removeClicked(self):
+ self.sigViewTask.emit('remove_iso')
+
+
+class IsoSurfaceAddRemoveItem(SubjectItem):
+ """
+ Item displaying a simple QToolButton allowing to add an isosurface.
+ """
+ persistent = True
+
+ def getEditor(self, parent, option, index):
+ return IsoSurfaceAddRemoveWidget(parent, self)
+
+
+class IsoSurfaceGroup(SubjectItem):
+ """
+ Root item for the list of isosurface items.
+ """
+ def getSignals(self):
+ subject = self.subject
+ return [subject.sigIsosurfaceAdded, subject.sigIsosurfaceRemoved]
+
+ def _subjectChanged(self, signalIdx=None, args=None, kwargs=None):
+ if signalIdx == 0:
+ if len(args) >= 1:
+ isosurface = args[0]
+ if not isinstance(isosurface, Isosurface):
+ raise ValueError('Expected an isosurface instance.')
+ self.__addIsosurface(isosurface)
+ else:
+ raise ValueError('Expected an isosurface instance.')
+ elif signalIdx == 1:
+ if len(args) >= 1:
+ isosurface = args[0]
+ if not isinstance(isosurface, Isosurface):
+ raise ValueError('Expected an isosurface instance.')
+ self.__removeIsosurface(isosurface)
+ else:
+ raise ValueError('Expected an isosurface instance.')
+
+ def __addIsosurface(self, isosurface):
+ valueItem = IsoSurfaceRootItem(subject=isosurface)
+ nameItem = IsoSurfaceLevelItem(subject=isosurface)
+ self.insertRow(max(0, self.rowCount() - 1), [valueItem, nameItem])
+
+ def __removeIsosurface(self, isosurface):
+ for row in range(self.rowCount()):
+ child = self.child(row)
+ subject = getattr(child, 'subject', None)
+ if subject == isosurface:
+ self.takeRow(row)
+ break
+
+ def _init(self):
+ nameItem = IsoSurfaceAddRemoveItem(self.subject)
+ valueItem = qt.QStandardItem()
+ valueItem.setEditable(False)
+ self.appendRow([nameItem, valueItem])
+
+ subject = self.subject
+ isosurfaces = subject.getIsosurfaces()
+ for isosurface in isosurfaces:
+ self.__addIsosurface(isosurface)
+
+
+# Cutting Plane ###############################################################
+
+class ColormapBase(SubjectItem):
+ """
+ Mixin class for colormap items.
+ """
+
+ def getSignals(self):
+ return [self.subject.getCutPlanes()[0].sigColormapChanged]
+
+
+class PlaneMinRangeItem(ColormapBase):
+ """
+ colormap minVal item.
+ Editor is a QLineEdit with a QDoubleValidator
+ """
+ editable = True
+
+ def _pullData(self):
+ colormap = self.subject.getCutPlanes()[0].getColormap()
+ auto = colormap.isAutoscale()
+ if auto == self.isEnabled():
+ self._enableRow(not auto)
+ return colormap.getVMin()
+
+ def _pushData(self, value, role=qt.Qt.UserRole):
+ self._setVMin(value)
+
+ def _setVMin(self, value):
+ cutPlane = self.subject.getCutPlanes()[0]
+ colormap = cutPlane.getColormap()
+ vMin = value
+ vMax = colormap.getVMax()
+
+ if vMax is not None and value > vMax:
+ vMin = vMax
+ vMax = value
+ cutPlane.setColormap(name=colormap.getName(),
+ norm=colormap.getNorm(),
+ vmin=vMin,
+ vmax=vMax)
+
+ def getEditor(self, parent, option, index):
+ editor = qt.QLineEdit(parent)
+ editor.setValidator(qt.QDoubleValidator())
+ return editor
+
+ def setEditorData(self, editor):
+ editor.setText(str(self._pullData()))
+ return True
+
+ def _setModelData(self, editor):
+ value = float(editor.text())
+ self._setVMin(value)
+ return True
+
+
+class PlaneMaxRangeItem(ColormapBase):
+ """
+ colormap maxVal item.
+ Editor is a QLineEdit with a QDoubleValidator
+ """
+ editable = True
+
+ def _pullData(self):
+ colormap = self.subject.getCutPlanes()[0].getColormap()
+ auto = colormap.isAutoscale()
+ if auto == self.isEnabled():
+ self._enableRow(not auto)
+ return self.subject.getCutPlanes()[0].getColormap().getVMax()
+
+ def _setVMax(self, value):
+ cutPlane = self.subject.getCutPlanes()[0]
+ colormap = cutPlane.getColormap()
+ vMin = colormap.getVMin()
+ vMax = value
+ if vMin is not None and value < vMin:
+ vMax = vMin
+ vMin = value
+ cutPlane.setColormap(name=colormap.getName(),
+ norm=colormap.getNorm(),
+ vmin=vMin,
+ vmax=vMax)
+
+ def getEditor(self, parent, option, index):
+ editor = qt.QLineEdit(parent)
+ editor.setValidator(qt.QDoubleValidator())
+ return editor
+
+ def setEditorData(self, editor):
+ editor.setText(str(self._pullData()))
+ return True
+
+ def _setModelData(self, editor):
+ value = float(editor.text())
+ self._setVMax(value)
+ return True
+
+
+class PlaneOrientationItem(SubjectItem):
+ """
+ Plane orientation item.
+ Editor is a QComboBox.
+ """
+ editable = True
+
+ _PLANE_ACTIONS = (
+ ('3d-plane-normal-x', 'Plane 0',
+ 'Set plane perpendicular to red axis', (1., 0., 0.)),
+ ('3d-plane-normal-y', 'Plane 1',
+ 'Set plane perpendicular to green axis', (0., 1., 0.)),
+ ('3d-plane-normal-z', 'Plane 2',
+ 'Set plane perpendicular to blue axis', (0., 0., 1.)),
+ )
+
+ def getSignals(self):
+ return [self.subject.getCutPlanes()[0].sigPlaneChanged]
+
+ def _pullData(self):
+ currentNormal = self.subject.getCutPlanes()[0].getNormal()
+ for _, text, _, normal in self._PLANE_ACTIONS:
+ if numpy.array_equal(normal, currentNormal):
+ return text
+ return ''
+
+ def getEditor(self, parent, option, index):
+ editor = qt.QComboBox(parent)
+ for iconName, text, tooltip, normal in self._PLANE_ACTIONS:
+ editor.addItem(getQIcon(iconName), text)
+ editor.currentIndexChanged[int].connect(self.__editorChanged)
+ return editor
+
+ def __editorChanged(self, index):
+ normal = self._PLANE_ACTIONS[index][3]
+ plane = self.subject.getCutPlanes()[0]
+ plane.setNormal(normal)
+ plane.moveToCenter()
+
+ def setEditorData(self, editor):
+ currentText = self._pullData()
+ index = 0
+ for normIdx, (_, text, _, _) in enumerate(self._PLANE_ACTIONS):
+ if text == currentText:
+ index = normIdx
+ break
+ editor.setCurrentIndex(index)
+ return True
+
+ def _setModelData(self, editor):
+ return True
+
+
+class PlaneInterpolationItem(SubjectItem):
+ """Toggle cut plane interpolation method: nearest or linear.
+
+ Item is checkable
+ """
+
+ def _init(self):
+ interpolation = self.subject.getCutPlanes()[0].getInterpolation()
+ self.setCheckable(True)
+ self.setCheckState(
+ qt.Qt.Checked if interpolation == 'linear' else qt.Qt.Unchecked)
+ self.setData(self._pullData(), role=qt.Qt.DisplayRole, pushData=False)
+
+ def getSignals(self):
+ return [self.subject.getCutPlanes()[0].sigInterpolationChanged]
+
+ def leftClicked(self):
+ checked = self.checkState() == qt.Qt.Checked
+ self._setInterpolation('linear' if checked else 'nearest')
+
+ def _pullData(self):
+ interpolation = self.subject.getCutPlanes()[0].getInterpolation()
+ self._setInterpolation(interpolation)
+ return interpolation[0].upper() + interpolation[1:]
+
+ def _setInterpolation(self, interpolation):
+ self.subject.getCutPlanes()[0].setInterpolation(interpolation)
+
+
+class PlaneColormapItem(ColormapBase):
+ """
+ colormap name item.
+ Editor is a QComboBox
+ """
+ editable = True
+
+ listValues = ['gray', 'reversed gray',
+ 'temperature', 'red',
+ 'green', 'blue']
+
+ def getEditor(self, parent, option, index):
+ editor = qt.QComboBox(parent)
+ editor.addItems(self.listValues)
+ editor.currentIndexChanged[int].connect(self.__editorChanged)
+
+ return editor
+
+ def __editorChanged(self, index):
+ colorMapName = self.listValues[index]
+ colorMap = self.subject.getCutPlanes()[0].getColormap()
+ self.subject.getCutPlanes()[0].setColormap(name=colorMapName,
+ norm=colorMap.getNorm(),
+ vmin=colorMap.getVMin(),
+ vmax=colorMap.getVMax())
+
+ def setEditorData(self, editor):
+ colormapName = self.subject.getCutPlanes()[0].getColormap().getName()
+ index = self.listValues.index(colormapName)
+ editor.setCurrentIndex(index)
+ return True
+
+ def _setModelData(self, editor):
+ self.__editorChanged(editor.currentIndex())
+ return True
+
+ def _pullData(self):
+ return self.subject.getCutPlanes()[0].getColormap().getName()
+
+
+class PlaneAutoScaleItem(ColormapBase):
+ """
+ colormap autoscale item.
+ Item is checkable.
+ """
+
+ def _init(self):
+ colorMap = self.subject.getCutPlanes()[0].getColormap()
+ self.setCheckable(True)
+ self.setCheckState((colorMap.isAutoscale() and qt.Qt.Checked)
+ or qt.Qt.Unchecked)
+ self.setData(self._pullData(), role=qt.Qt.DisplayRole, pushData=False)
+
+ def leftClicked(self):
+ checked = (self.checkState() == qt.Qt.Checked)
+ self._setAutoScale(checked)
+
+ def _setAutoScale(self, auto):
+ view3d = self.subject
+ cutPlane = view3d.getCutPlanes()[0]
+ colormap = cutPlane.getColormap()
+
+ if auto != colormap.isAutoscale():
+ if auto:
+ vMin = vMax = None
+ else:
+ dataRange = view3d.getDataRange()
+ if dataRange is None or None in dataRange:
+ vMin = vMax = None
+ else:
+ vMin, vMax = dataRange
+ cutPlane.setColormap(colormap.getName(),
+ colormap.getNorm(),
+ vMin,
+ vMax)
+
+ def _pullData(self):
+ auto = self.subject.getCutPlanes()[0].getColormap().isAutoscale()
+ self._setAutoScale(auto)
+ if auto:
+ data = 'Auto'
+ else:
+ data = 'User'
+ return data
+
+
+class NormalizationNode(ColormapBase):
+ """
+ colormap normalization item.
+ Item is a QComboBox.
+ """
+ editable = True
+ listValues = ['linear', 'log']
+
+ def getEditor(self, parent, option, index):
+ editor = qt.QComboBox(parent)
+ editor.addItems(self.listValues)
+ editor.currentIndexChanged[int].connect(self.__editorChanged)
+
+ return editor
+
+ def __editorChanged(self, index):
+ colorMap = self.subject.getCutPlanes()[0].getColormap()
+ normalization = self.listValues[index]
+ self.subject.getCutPlanes()[0].setColormap(name=colorMap.getName(),
+ norm=normalization,
+ vmin=colorMap.getVMin(),
+ vmax=colorMap.getVMax())
+
+ def setEditorData(self, editor):
+ normalization = self.subject.getCutPlanes()[0].getColormap().getNorm()
+ index = self.listValues.index(normalization)
+ editor.setCurrentIndex(index)
+ return True
+
+ def _setModelData(self, editor):
+ self.__editorChanged(editor.currentIndex())
+ return True
+
+ def _pullData(self):
+ return self.subject.getCutPlanes()[0].getColormap().getNorm()
+
+
+class PlaneGroup(SubjectItem):
+ """
+ Root Item for the plane items.
+ """
+ def _init(self):
+ valueItem = qt.QStandardItem()
+ valueItem.setEditable(False)
+ nameItem = PlaneVisibleItem(self.subject, 'Visible')
+ self.appendRow([nameItem, valueItem])
+
+ nameItem = qt.QStandardItem('Colormap')
+ nameItem.setEditable(False)
+ valueItem = PlaneColormapItem(self.subject)
+ self.appendRow([nameItem, valueItem])
+
+ nameItem = qt.QStandardItem('Normalization')
+ nameItem.setEditable(False)
+ valueItem = NormalizationNode(self.subject)
+ self.appendRow([nameItem, valueItem])
+
+ nameItem = qt.QStandardItem('Orientation')
+ nameItem.setEditable(False)
+ valueItem = PlaneOrientationItem(self.subject)
+ self.appendRow([nameItem, valueItem])
+
+ nameItem = qt.QStandardItem('Interpolation')
+ nameItem.setEditable(False)
+ valueItem = PlaneInterpolationItem(self.subject)
+ self.appendRow([nameItem, valueItem])
+
+ nameItem = qt.QStandardItem('Autoscale')
+ nameItem.setEditable(False)
+ valueItem = PlaneAutoScaleItem(self.subject)
+ self.appendRow([nameItem, valueItem])
+
+ nameItem = qt.QStandardItem('Min')
+ nameItem.setEditable(False)
+ valueItem = PlaneMinRangeItem(self.subject)
+ self.appendRow([nameItem, valueItem])
+
+ nameItem = qt.QStandardItem('Max')
+ nameItem.setEditable(False)
+ valueItem = PlaneMaxRangeItem(self.subject)
+ self.appendRow([nameItem, valueItem])
+
+
+class PlaneVisibleItem(SubjectItem):
+ """
+ Plane visibility item.
+ Item is checkable.
+ """
+ def _init(self):
+ plane = self.subject.getCutPlanes()[0]
+ self.setCheckable(True)
+ self.setCheckState((plane.isVisible() and qt.Qt.Checked)
+ or qt.Qt.Unchecked)
+
+ def leftClicked(self):
+ plane = self.subject.getCutPlanes()[0]
+ checked = (self.checkState() == qt.Qt.Checked)
+ if checked != plane.isVisible():
+ plane.setVisible(checked)
+ if plane.isVisible():
+ plane.moveToCenter()
+
+
+# Tree ########################################################################
+
+class ItemDelegate(qt.QStyledItemDelegate):
+ """
+ Delegate for the QTreeView filled with SubjectItems.
+ """
+
+ sigDelegateEvent = qt.Signal(str)
+
+ def __init__(self, parent=None):
+ super(ItemDelegate, self).__init__(parent)
+
+ def createEditor(self, parent, option, index):
+ item = index.model().itemFromIndex(index)
+ if item:
+ if isinstance(item, SubjectItem):
+ editor = item.getEditor(parent, option, index)
+ if editor:
+ editor.setAutoFillBackground(True)
+ if hasattr(editor, 'sigViewTask'):
+ editor.sigViewTask.connect(self.__viewTask)
+ return editor
+
+ editor = super(ItemDelegate, self).createEditor(parent,
+ option,
+ index)
+ return editor
+
+ def updateEditorGeometry(self, editor, option, index):
+ editor.setGeometry(option.rect)
+
+ def setEditorData(self, editor, index):
+ item = index.model().itemFromIndex(index)
+ if item:
+ if isinstance(item, SubjectItem) and item.setEditorData(editor):
+ return
+ super(ItemDelegate, self).setEditorData(editor, index)
+
+ def setModelData(self, editor, model, index):
+ item = index.model().itemFromIndex(index)
+ if isinstance(item, SubjectItem) and item._setModelData(editor):
+ return
+ super(ItemDelegate, self).setModelData(editor, model, index)
+
+ def __viewTask(self, task):
+ self.sigDelegateEvent.emit(task)
+
+
+class TreeView(qt.QTreeView):
+ """
+ TreeView displaying the SubjectItems for the ScalarFieldView.
+ """
+
+ def __init__(self, parent=None):
+ super(TreeView, self).__init__(parent)
+ self.__openedIndex = None
+
+ self.setIconSize(qt.QSize(16, 16))
+
+ header = self.header()
+ if hasattr(header, 'setSectionResizeMode'): # Qt5
+ header.setSectionResizeMode(qt.QHeaderView.ResizeToContents)
+ else: # Qt4
+ header.setResizeMode(qt.QHeaderView.ResizeToContents)
+
+ delegate = ItemDelegate()
+ self.setItemDelegate(delegate)
+ delegate.sigDelegateEvent.connect(self.__delegateEvent)
+ self.setSelectionBehavior(qt.QAbstractItemView.SelectRows)
+ self.setSelectionMode(qt.QAbstractItemView.SingleSelection)
+
+ self.clicked.connect(self.__clicked)
+
+ def setSfView(self, sfView):
+ """
+ Sets the ScalarFieldView this view is controlling.
+
+ :param sfView: A `ScalarFieldView`
+ """
+ model = qt.QStandardItemModel()
+ model.setColumnCount(ModelColumns.ColumnMax)
+ model.setHorizontalHeaderLabels(['Name', 'Value'])
+
+ item = qt.QStandardItem()
+ item.setEditable(False)
+ model.appendRow([ViewSettingsItem(sfView, 'Style'), item])
+
+ item = qt.QStandardItem()
+ item.setEditable(False)
+ model.appendRow([DataSetItem(sfView, 'Data'), item])
+
+ item = IsoSurfaceCount(sfView)
+ item.setEditable(False)
+ model.appendRow([IsoSurfaceGroup(sfView, 'Isosurfaces'), item])
+
+ item = qt.QStandardItem()
+ item.setEditable(False)
+ model.appendRow([PlaneGroup(sfView, 'Cutting Plane'), item])
+
+ self.setModel(model)
+
+ def setModel(self, model):
+ """
+ Reimplementation of the QTreeView.setModel method. It connects the
+ rowsRemoved signal and opens the persistent editors.
+
+ :param qt.QStandardItemModel model: the model
+ """
+
+ prevModel = self.model()
+ if prevModel:
+ self.__openPersistentEditors(qt.QModelIndex(), False)
+ try:
+ prevModel.rowsRemoved.disconnect(self.rowsRemoved)
+ except TypeError:
+ pass
+
+ super(TreeView, self).setModel(model)
+ model.rowsRemoved.connect(self.rowsRemoved)
+ self.__openPersistentEditors(qt.QModelIndex())
+
+ def __openPersistentEditors(self, parent=None, openEditor=True):
+ """
+ Opens or closes the items persistent editors.
+
+ :param qt.QModelIndex parent: starting index, or None if the whole tree
+ is to be considered.
+ :param bool openEditor: True to open the editors, False to close them.
+ """
+ model = self.model()
+
+ if not model:
+ return
+
+ if not parent or not parent.isValid():
+ parent = self.model().invisibleRootItem().index()
+
+ if openEditor:
+ meth = self.openPersistentEditor
+ else:
+ meth = self.closePersistentEditor
+
+ curParent = parent
+ children = [model.index(row, 0, curParent)
+ for row in range(model.rowCount(curParent))]
+
+ columnCount = model.columnCount()
+
+ while len(children) > 0:
+ curParent = children.pop(-1)
+
+ children.extend([model.index(row, 0, curParent)
+ for row in range(model.rowCount(curParent))])
+
+ for colIdx in range(columnCount):
+ sibling = model.sibling(curParent.row(),
+ colIdx,
+ curParent)
+ item = model.itemFromIndex(sibling)
+ if isinstance(item, SubjectItem) and item.persistent:
+ meth(sibling)
+
+ def rowsAboutToBeRemoved(self, parent, start, end):
+ """
+ Reimplementation of the QTreeView.rowsAboutToBeRemoved. Closes all
+ persistent editors under parent.
+
+ :param qt.QModelIndex parent: Parent index
+ :param int start: Start index from parent index (inclusive)
+ :param int end: End index from parent index (inclusive)
+ """
+ self.__openPersistentEditors(parent, False)
+ super(TreeView, self).rowsAboutToBeRemoved(parent, start, end)
+
+ def rowsRemoved(self, parent, start, end):
+ """
+ Called when QTreeView.rowsRemoved is emitted. Opens all persistent
+ editors under parent.
+
+ :param qt.QModelIndex parent: Parent index
+ :param int start: Start index from parent index (inclusive)
+ :param int end: End index from parent index (inclusive)
+ """
+ super(TreeView, self).rowsRemoved(parent, start, end)
+ self.__openPersistentEditors(parent, True)
+
+ def rowsInserted(self, parent, start, end):
+ """
+ Reimplementation of the QTreeView.rowsInserted. Opens all persistent
+ editors under parent.
+
+ :param qt.QModelIndex parent: Parent index
+ :param int start: Start index from parent index
+ :param int end: End index from parent index
+ """
+ self.__openPersistentEditors(parent, False)
+ super(TreeView, self).rowsInserted(parent, start, end)
+ self.__openPersistentEditors(parent)
+
+ def keyReleaseEvent(self, event):
+ """
+ Reimplementation of the QTreeView.keyReleaseEvent.
+ At the moment only Key_Delete is handled. It calls the selected item's
+ queryRemove method, and deleted the item if needed.
+
+ :param qt.QKeyEvent event: A key event
+ """
+
+ # TODO : better filtering
+ key = event.key()
+ modifiers = event.modifiers()
+
+ if key == qt.Qt.Key_Delete and modifiers == qt.Qt.NoModifier:
+ self.__removeIsosurfaces()
+
+ super(TreeView, self).keyReleaseEvent(event)
+
+ def __removeIsosurfaces(self):
+ model = self.model()
+ selected = self.selectedIndexes()
+ items = []
+ # WARNING : the selection mode is set to single, so we re not
+ # supposed to have more than one item here.
+ # Multiple selection deletion has not been tested.
+ # Watch out for index invalidation
+ for index in selected:
+ leftIndex = model.sibling(index.row(), 0, index)
+ leftItem = model.itemFromIndex(leftIndex)
+ if isinstance(leftItem, SubjectItem) and leftItem not in items:
+ items.append(leftItem)
+
+ isos = [item for item in items if isinstance(item, IsoSurfaceRootItem)]
+ if isos:
+ for iso in isos:
+ if iso.queryRemove(self):
+ parentItem = iso.parent()
+ parentItem.removeRow(iso.row())
+ else:
+ qt.QMessageBox.information(
+ self,
+ 'Remove isosurface',
+ 'Select an iso-surface to remove it')
+
+ def __clicked(self, index):
+ """
+ Called when the QTreeView.clicked signal is emitted. Calls the item's
+ leftClick method.
+
+ :param qt.QIndex index: An index
+ """
+ item = self.model().itemFromIndex(index)
+ if isinstance(item, SubjectItem):
+ item.leftClicked()
+
+ def __delegateEvent(self, task):
+ if task == 'remove_iso':
+ self.__removeIsosurfaces()
diff --git a/silx/gui/plot3d/ScalarFieldView.py b/silx/gui/plot3d/ScalarFieldView.py
new file mode 100644
index 0000000..2eb54a3
--- /dev/null
+++ b/silx/gui/plot3d/ScalarFieldView.py
@@ -0,0 +1,1385 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a window to view a 3D scalar field.
+
+It supports iso-surfaces, a cutting plane and the definition of
+a region of interest.
+"""
+
+from __future__ import absolute_import
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "10/01/2017"
+
+import re
+import logging
+import time
+from collections import deque
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.plot.Colors import rgba
+
+from silx.math.marchingcubes import MarchingCubes
+
+from .scene import axes, cutplane, function, interaction, primitives, transform
+from . import scene
+from .Plot3DWindow import Plot3DWindow
+
+
+_logger = logging.getLogger(__name__)
+
+
+class _BoundedGroup(scene.Group):
+ """Group with data bounds"""
+
+ _shape = None # To provide a default value without overriding __init__
+
+ @property
+ def shape(self):
+ """Data shape (depth, height, width) of this group or None"""
+ return self._shape
+
+ @shape.setter
+ def shape(self, shape):
+ if shape is None:
+ self._shape = None
+ else:
+ depth, height, width = shape
+ self._shape = float(depth), float(height), float(width)
+
+ @property
+ def size(self):
+ """Data size (width, height, depth) of this group or None"""
+ shape = self.shape
+ if shape is None:
+ return None
+ else:
+ return shape[2], shape[1], shape[0]
+
+ @size.setter
+ def size(self, size):
+ if size is None:
+ self.shape = None
+ else:
+ self.shape = size[2], size[1], size[0]
+
+ def _bounds(self, dataBounds=False):
+ if dataBounds and self.size is not None:
+ return numpy.array(((0., 0., 0.), self.size),
+ dtype=numpy.float32)
+ else:
+ return super(_BoundedGroup, self)._bounds(dataBounds)
+
+
+class Isosurface(qt.QObject):
+ """Class representing an iso-surface
+
+ :param parent: The View widget this iso-surface belongs to
+ """
+
+ sigLevelChanged = qt.Signal(float)
+ """Signal emitted when the iso-surface level has changed.
+
+ This signal provides the new level value (might be nan).
+ """
+
+ sigColorChanged = qt.Signal()
+ """Signal emitted when the iso-surface color has changed"""
+
+ sigVisibilityChanged = qt.Signal(bool)
+ """Signal emitted when the iso-surface visibility has changed.
+
+ This signal provides the new visibility status.
+ """
+
+ def __init__(self, parent):
+ super(Isosurface, self).__init__(parent=parent)
+ self._level = float('nan')
+ self._autoLevelFunction = None
+ self._color = rgba('#FFD700FF')
+ self._data = None
+ self._group = scene.Group()
+
+ def _setData(self, data, copy=True):
+ """Set the data set from which to build the iso-surface.
+
+ :param numpy.ndarray data: The 3D dataset or None
+ :param bool copy: True to make a copy, False to use as is if possible
+ """
+ if data is None:
+ self._data = None
+ else:
+ self._data = numpy.array(data, copy=copy, order='C')
+
+ self._update()
+
+ def _get3DPrimitive(self):
+ """Return the group containing the mesh of the iso-surface if any"""
+ return self._group
+
+ def isVisible(self):
+ """Returns True if iso-surface is visible, else False"""
+ return self._group.visible
+
+ def setVisible(self, visible):
+ """Set the visibility of the iso-surface in the view.
+
+ :param bool visible: True to show the iso-surface, False to hide
+ """
+ visible = bool(visible)
+ if visible != self._group.visible:
+ self._group.visible = visible
+ self.sigVisibilityChanged.emit(visible)
+
+ def getLevel(self):
+ """Return the level of this iso-surface (float)"""
+ return self._level
+
+ def setLevel(self, level):
+ """Set the value at which to build the iso-surface.
+
+ Setting this value reset auto-level function
+
+ :param float level: The value at which to build the iso-surface
+ """
+ self._autoLevelFunction = None
+ level = float(level)
+ if level != self._level:
+ self._level = level
+ self._update()
+ self.sigLevelChanged.emit(level)
+
+ def isAutoLevel(self):
+ """True if iso-level is rebuild for each data set."""
+ return self.getAutoLevelFunction() is not None
+
+ def getAutoLevelFunction(self):
+ """Return the function computing the iso-level (callable or None)"""
+ return self._autoLevelFunction
+
+ def setAutoLevelFunction(self, autoLevel):
+ """Set the function used to compute the iso-level.
+
+ WARNING: The function might get called in a thread.
+
+ :param callable autoLevel:
+ A function taking a 3D numpy.ndarray of float32 and returning
+ a float used as iso-level.
+ Example: numpy.mean(data) + numpy.std(data)
+ """
+ assert callable(autoLevel)
+ self._autoLevelFunction = autoLevel
+ self._update()
+
+ def getColor(self):
+ """Return the color of this iso-surface (QColor)"""
+ return qt.QColor.fromRgbF(*self._color)
+
+ def setColor(self, color):
+ """Set the color of the iso-surface
+
+ :param color: RGBA color of the isosurface
+ :type color: QColor, str or array-like of 4 float in [0., 1.]
+ """
+ color = rgba(color)
+ if color != self._color:
+ self._color = color
+ if len(self._group.children) != 0:
+ self._group.children[0].setAttribute('color', self._color)
+ self.sigColorChanged.emit()
+
+ def _update(self):
+ """Update underlying mesh"""
+ self._group.children = []
+
+ if self._data is None:
+ if self.isAutoLevel():
+ self._level = float('nan')
+
+ else:
+ if self.isAutoLevel():
+ st = time.time()
+ try:
+ level = float(self.getAutoLevelFunction()(self._data))
+
+ except Exception:
+ module = self.getAutoLevelFunction().__module__
+ name = self.getAutoLevelFunction().__name__
+ _logger.error(
+ "Error while executing iso level function %s.%s",
+ module,
+ name,
+ exc_info=True)
+ level = float('nan')
+
+ else:
+ _logger.info(
+ 'Computed iso-level in %f s.', time.time() - st)
+
+ if level != self._level:
+ self._level = level
+ self.sigLevelChanged.emit(level)
+
+ if numpy.isnan(self._level):
+ return
+
+ st = time.time()
+ vertices, normals, indices = MarchingCubes(
+ self._data,
+ isolevel=self._level)
+ _logger.info('Computed iso-surface in %f s.', time.time() - st)
+
+ if len(vertices) == 0:
+ return
+ else:
+ mesh = primitives.Mesh3D(vertices,
+ colors=self._color,
+ normals=normals,
+ mode='triangles',
+ indices=indices)
+ self._group.children = [mesh]
+
+
+class Colormap(object):
+ """Description of a colormap
+
+ :param str name: Name of the colormap
+ :param str norm: Normalization: 'linear' (default) or 'log'
+ :param float vmin:
+ Lower bound of the colormap or None for autoscale (default)
+ :param float vmax:
+ Upper bounds of the colormap or None for autoscale (default)
+ """
+
+ def __init__(self, name, norm='linear', vmin=None, vmax=None):
+ assert name in function.Colormap.COLORMAPS
+ self._name = str(name)
+
+ assert norm in ('linear', 'log')
+ self._norm = str(norm)
+
+ self._vmin = float(vmin) if vmin is not None else None
+ self._vmax = float(vmax) if vmax is not None else None
+
+ def isAutoscale(self):
+ """True if both min and max are in autoscale mode"""
+ return self._vmin is None or self._vmax is None
+
+ def getName(self):
+ """Return the name of the colormap (str)"""
+ return self._name
+
+ def getNorm(self):
+ """Return the normalization of the colormap (str)"""
+ return self._norm
+
+ def getVMin(self):
+ """Return the lower bound of the colormap or None"""
+ return self._vmin
+
+ def getVMax(self):
+ """Return the upper bounds of the colormap or None"""
+ return self._vmax
+
+
+class SelectedRegion(object):
+ """Selection of a 3D region aligned with the axis.
+
+ :param arrayRange: Range of the selection in the array
+ ((zmin, zmax), (ymin, ymax), (xmin, xmax))
+ :param translation: Offset from array to data coordinates (ox, oy, oz)
+ :param scale: Scale from array to data coordinates (sx, sy, sz)
+ """
+
+ def __init__(self, arrayRange,
+ translation=(0., 0., 0.),
+ scale=(1., 1., 1.)):
+ self._arrayRange = numpy.array(arrayRange, copy=True, dtype=numpy.int)
+ assert self._arrayRange.shape == (3, 2)
+ assert numpy.all(self._arrayRange[:, 1] >= self._arrayRange[:, 0])
+ self._translation = numpy.array(translation, dtype=numpy.float32)
+ assert self._translation.shape == (3,)
+ self._scale = numpy.array(scale, dtype=numpy.float32)
+ assert self._scale.shape == (3,)
+
+ self._dataRange = (self._translation.reshape(3, -1) +
+ self._arrayRange[::-1] * self._scale.reshape(3, -1))
+
+ def getArrayRange(self):
+ """Returns array ranges of the selection: 3x2 array of int
+
+ :return: A numpy array with ((zmin, zmax), (ymin, ymax), (xmin, xmax))
+ :rtype: numpy.ndarray
+ """
+ return self._arrayRange.copy()
+
+ def getArraySlices(self):
+ """Slices corresponding to the selected range in the array
+
+ :return: A numpy array with (zslice, yslice, zslice)
+ :rtype: numpy.ndarray
+ """
+ return (slice(*self._arrayRange[0]),
+ slice(*self._arrayRange[1]),
+ slice(*self._arrayRange[2]))
+
+ def getDataRange(self):
+ """Range in the data coordinates of the selection: 3x2 array of float
+
+ :return: A numpy array with ((xmin, xmax), (ymin, ymax), (zmin, zmax))
+ :rtype: numpy.ndarray
+ """
+ return self._dataRange.copy()
+
+ def getDataScale(self):
+ """Scale from array to data coordinates: (sx, sy, sz)
+
+ :return: A numpy array with (sx, sy, sz)
+ :rtype: numpy.ndarray
+ """
+ return self._scale.copy()
+
+ def getDataTranslation(self):
+ """Offset from array to data coordinates: (ox, oy, oz)
+
+ :return: A numpy array with (ox, oy, oz)
+ :rtype: numpy.ndarray
+ """
+ return self._translation.copy()
+
+
+class CutPlane(qt.QObject):
+ """Class representing a cutting plane
+
+ :param ScalarFieldView sfView: Widget in which the cut plane is applied.
+ """
+
+ sigVisibilityChanged = qt.Signal(bool)
+ """Signal emitted when the cut visibility has changed.
+
+ This signal provides the new visibility status.
+ """
+
+ sigDataChanged = qt.Signal()
+ """Signal emitted when the data this plane is cutting has changed."""
+
+ sigPlaneChanged = qt.Signal()
+ """Signal emitted when the cut plane has moved"""
+
+ sigColormapChanged = qt.Signal(object)
+ """Signal emitted when the colormap has changed
+
+ This signal provides the new colormap.
+ """
+
+ sigInterpolationChanged = qt.Signal(str)
+ """Signal emitted when the cut plane interpolation has changed
+
+ This signal provides the new interpolation mode.
+ """
+
+ def __init__(self, sfView):
+ super(CutPlane, self).__init__(parent=sfView)
+
+ self._colormap = Colormap(
+ name='gray', norm='linear', vmin=None, vmax=None)
+
+ self._dataRange = None
+ self._positiveMin = None
+
+ self._plane = cutplane.CutPlane(normal=(0, 1, 0))
+ self._plane.alpha = 1.
+ self._plane.visible = self._visible = False
+ self._plane.addListener(self._planeChanged)
+ self._plane.plane.addListener(self._planePositionChanged)
+
+ sfView.sigDataChanged.connect(self._sfViewDataChanged)
+
+ def _get3DPrimitive(self):
+ """Return the cut plane scene node"""
+ return self._plane
+
+ def _sfViewDataChanged(self):
+ """Handle data change in the ScalarFieldView this plane belongs to"""
+ self._plane.setData(self.sender().getData(), copy=False)
+ self._dataRange = self.sender().getDataRange()
+ self._positiveMin = None
+ self.sigDataChanged.emit()
+
+ # Update colormap range when autoscale
+ if self.getColormap().isAutoscale():
+ self._updateColormapRange()
+
+ def _planeChanged(self, source, *args, **kwargs):
+ """Handle events from the plane primitive"""
+ # Using _visible for now, until scene as more info in events
+ if source.visible != self._visible:
+ self._visible = source.visible
+ self.sigVisibilityChanged.emit(source.visible)
+
+ def _planePositionChanged(self, source, *args, **kwargs):
+ """Handle update of cut plane position and normal"""
+ if self._plane.visible:
+ self.sigPlaneChanged.emit()
+
+ # Plane position
+
+ def moveToCenter(self):
+ """Move cut plane to center of data set"""
+ self._plane.moveToCenter()
+
+ def isValid(self):
+ """Returns whether the cut plane is defined or not (bool)"""
+ return self._plane.isValid
+
+ def getNormal(self):
+ """Returns the normal of the plane (as a unit vector)
+
+ :return: Normal (nx, ny, nz), vector is 0 if no plane is defined
+ :rtype: numpy.ndarray
+ """
+ return self._plane.plane.normal
+
+ def setNormal(self, normal):
+ """Set the normal of the plane
+
+ :param normal: 3-tuple of float: nx, ny, nz
+ """
+ self._plane.plane.normal = normal
+
+ def getPoint(self):
+ """Returns a point on the plane
+
+ :return: (x, y, z)
+ :rtype: numpy.ndarray
+ """
+ return self._plane.plane.point
+
+ def getParameters(self):
+ """Returns the plane equation parameters: a*x + b*y + c*z + d = 0
+
+ :return: Plane equation parameters: (a, b, c, d)
+ :rtype: numpy.ndarray
+ """
+ return self._plane.plane.parameters
+
+ # Visibility
+
+ def isVisible(self):
+ """Returns True if the plane is visible, False otherwise"""
+ return self._plane.visible
+
+ def setVisible(self, visible):
+ """Set the visibility of the plane
+
+ :param bool visible: True to make plane visible
+ """
+ self._plane.visible = visible
+
+ # Border stroke
+
+ def getStrokeColor(self):
+ """Returns the color of the plane border (QColor)"""
+ return qt.QColor.fromRgbF(*self._plane.color)
+
+ def setStrokeColor(self, color):
+ """Set the color of the plane border.
+
+ :param color: RGB color: name, #RRGGBB or RGB values
+ :type color:
+ QColor, str or array-like of 3 or 4 float in [0., 1.] or uint8
+ """
+ self._plane.color = rgba(color)
+
+ # Data
+
+ def getImageData(self):
+ """Returns the data and information corresponding to the cut plane.
+
+ The returned data is not interpolated,
+ it is a slice of the 3D scalar field.
+
+ Image data axes are so that plane normal is towards the point of view.
+
+ :return: An object containing the 2D data slice and information
+ """
+ return _CutPlaneImage(self)
+
+ # Interpolation
+
+ def getInterpolation(self):
+ """Returns the interpolation used to display to cut plane.
+
+ :return: 'nearest' or 'linear'
+ :rtype: str
+ """
+ return self._plane.interpolation
+
+ def setInterpolation(self, interpolation):
+ """Set the interpolation used to display to cut plane
+
+ The default interpolation is 'linear'
+
+ :param str interpolation: 'nearest' or 'linear'
+ """
+ if interpolation != self.getInterpolation():
+ self._plane.interpolation = interpolation
+ self.sigInterpolationChanged.emit(interpolation)
+
+ # Colormap
+
+ # def getAlpha(self):
+ # """Returns the transparency of the plane as a float in [0., 1.]"""
+ # return self._plane.alpha
+
+ # def setAlpha(self, alpha):
+ # """Set the plane transparency.
+ #
+ # :param float alpha: Transparency in [0., 1]
+ # """
+ # self._plane.alpha = alpha
+
+ def getColormap(self):
+ """Returns the colormap set by :meth:`getColormap`.
+
+ :return: The colormap
+ :rtype: Colormap
+ """
+ return self._colormap
+
+ def setColormap(self,
+ name='gray',
+ norm='linear',
+ vmin=None,
+ vmax=None):
+ """Set the colormap to use.
+
+ :param str name: Name of the colormap in
+ 'gray', 'reversed gray', 'temperature', 'red', 'green', 'blue'.
+ :param str norm: Colormap mapping: 'linear' or 'log'.
+ :param float vmin: The minimum value of the range or None for autoscale
+ :param float vmax: The maximum value of the range or None for autoscale
+ """
+ _logger.debug('setColormap %s %s (%s, %s)',
+ name, norm, str(vmin), str(vmax))
+
+ self._colormap = Colormap(
+ name=name, norm=norm, vmin=vmin, vmax=vmax)
+
+ self._updateColormapRange()
+ self.sigColormapChanged.emit(self.getColormap())
+
+ def getColormapEffectiveRange(self):
+ """Returns the currently used range of the colormap.
+
+ This range is computed from the data set if colormap is in autoscale.
+ Range is clipped to positive values when using log scale.
+
+ :return: 2-tuple of float
+ """
+ return self._plane.colormap.range_
+
+ def _updateColormapRange(self):
+ """Update the colormap range"""
+ colormap = self.getColormap()
+
+ self._plane.colormap.name = colormap.getName()
+ if colormap.isAutoscale():
+ range_ = self._dataRange
+ if range_ is None: # No data, use a default range
+ range_ = 1., 10.
+ else:
+ range_ = colormap.getVMin(), colormap.getVMax()
+
+ if colormap.getNorm() == 'linear':
+ self._plane.colormap.norm = 'linear'
+ self._plane.colormap.range_ = range_
+
+ else: # Log
+ # Make sure range is strictly positive
+ if range_[0] <= 0.:
+ data = self._plane.getData(copy=False)
+ if data is not None:
+ if self._positiveMin is None:
+ # TODO compute this with the range as a combo operation
+ self._positiveMin = numpy.min(data[data > 0.])
+ range_ = (self._positiveMin,
+ max(range_[1], self._positiveMin))
+
+ self._plane.colormap.range_ = range_
+ self._plane.colormap.norm = colormap.getNorm()
+
+
+class _CutPlaneImage(object):
+ """Object representing the data sliced by a cut plane
+
+ :param CutPlane cutPlane: The CutPlane from which to generate image info
+ """
+
+ def __init__(self, cutPlane):
+ # Init attributes with default values
+ self._isValid = False
+ self._data = numpy.array([])
+ self._xLabel = ''
+ self._yLabel = ''
+ self._normalLabel = ''
+ self._scale = 1., 1.
+ self._translation = 0., 0.
+ self._index = 0
+ self._position = 0.
+
+ sfView = cutPlane.parent()
+ if not sfView or not cutPlane.isValid():
+ _logger.info("No plane available")
+ return
+
+ data = sfView.getData(copy=False)
+ if data is None:
+ _logger.info("No data available")
+ return
+
+ normal = cutPlane.getNormal()
+ point = numpy.array(cutPlane.getPoint(), dtype=numpy.int)
+
+ if numpy.all(numpy.equal(normal, (1., 0., 0.))):
+ index = max(0, min(point[0], data.shape[2] - 1))
+ slice_ = data[:, :, index]
+ xAxisIndex, yAxisIndex, normalAxisIndex = 1, 2, 0 # y, z, x
+ elif numpy.all(numpy.equal(normal, (0., 1., 0.))):
+ index = max(0, min(point[1], data.shape[1] - 1))
+ slice_ = numpy.transpose(data[:, index, :])
+ xAxisIndex, yAxisIndex, normalAxisIndex = 2, 0, 1 # z, x, y
+ elif numpy.all(numpy.equal(normal, (0., 0., 1.))):
+ index = max(0, min(point[2], data.shape[0] - 1))
+ slice_ = data[index, :, :]
+ xAxisIndex, yAxisIndex, normalAxisIndex = 0, 1, 2 # x, y, z
+ else:
+ _logger.warning('Unsupported normal: (%f, %f, %f)',
+ normal[0], normal[1], normal[2])
+ return
+
+ # Store cut plane image info
+
+ self._isValid = True
+ self._data = numpy.array(slice_, copy=True)
+
+ labels = sfView.getAxesLabels()
+ scale = sfView.getScale()
+ translation = sfView.getTranslation()
+
+ self._xLabel = labels[xAxisIndex]
+ self._yLabel = labels[yAxisIndex]
+ self._normalLabel = labels[normalAxisIndex]
+
+ self._scale = scale[xAxisIndex], scale[yAxisIndex]
+ self._translation = translation[xAxisIndex], translation[yAxisIndex]
+
+ self._index = index
+ self._position = float(index * scale[normalAxisIndex] +
+ translation[normalAxisIndex])
+
+ def isValid(self):
+ """Returns True if the cut plane image is defined (bool)"""
+ return self._isValid
+
+ def getData(self, copy=True):
+ """Returns the image data sliced by the cut plane.
+
+ :param bool copy: True to get a copy, False otherwise
+ :return: The 2D image data corresponding to the cut plane
+ :rtype: numpy.ndarray
+ """
+ return numpy.array(self._data, copy=copy)
+
+ def getXLabel(self):
+ """Returns the label associated to the X axis of the image (str)"""
+ return self._xLabel
+
+ def getYLabel(self):
+ """Returns the label associated to the Y axis of the image (str)"""
+ return self._yLabel
+
+ def getNormalLabel(self):
+ """Returns the label of the 3D axis of the plane normal (str)"""
+ return self._normalLabel
+
+ def getScale(self):
+ """Returns the scales of the data as a 2-tuple of float (sx, sy)"""
+ return self._scale
+
+ def getTranslation(self):
+ """Returns the offset of the data as a 2-tuple of float (ox, oy)"""
+ return self._translation
+
+ def getIndex(self):
+ """Returns the index in the data array of the cut plane (int)"""
+ return self._index
+
+ def getPosition(self):
+ """Returns the cut plane position along the normal axis (flaot)"""
+ return self._position
+
+
+class ScalarFieldView(Plot3DWindow):
+ """Widget computing and displaying an iso-surface from a 3D scalar dataset.
+
+ Limitation: Currently, iso-surfaces are generated with higher values
+ than the iso-level 'inside' the surface.
+
+ :param parent: See :class:`QMainWindow`
+ """
+
+ sigDataChanged = qt.Signal()
+ """Signal emitted when the scalar data field has changed."""
+
+ sigSelectedRegionChanged = qt.Signal(object)
+ """Signal emitted when the selected region has changed.
+
+ This signal provides the new selected region.
+ """
+
+ def __init__(self, parent=None):
+ super(ScalarFieldView, self).__init__(parent)
+ self._colormap = Colormap(
+ name='gray', norm='linear', vmin=None, vmax=None)
+ self._selectedRange = None
+
+ # Store iso-surfaces
+ self._isosurfaces = []
+
+ # Transformations
+ self._dataScale = transform.Scale()
+ self._dataTranslate = transform.Translate()
+
+ self._foregroundColor = 1., 1., 1., 1.
+ self._highlightColor = 0.7, 0.7, 0., 1.
+
+ self._data = None
+ self._dataRange = None
+
+ self._group = _BoundedGroup()
+ self._group.transforms = [self._dataTranslate, self._dataScale]
+
+ self._selectionBox = primitives.Box()
+ self._selectionBox.strokeSmooth = False
+ self._selectionBox.strokeWidth = 1.
+ # self._selectionBox.fillColor = 1., 1., 1., 0.3
+ # self._selectionBox.fillCulling = 'back'
+ self._selectionBox.visible = False
+ self._group.children.append(self._selectionBox)
+
+ self._cutPlane = CutPlane(sfView=self)
+ self._cutPlane.sigVisibilityChanged.connect(
+ self._planeVisibilityChanged)
+ self._group.children.append(self._cutPlane._get3DPrimitive())
+
+ self._isogroup = primitives.GroupDepthOffset()
+ self._isogroup.transforms = [
+ # Convert from z, y, x from marching cubes to x, y, z
+ transform.Matrix((
+ (0., 0., 1., 0.),
+ (0., 1., 0., 0.),
+ (1., 0., 0., 0.),
+ (0., 0., 0., 1.))),
+ # Offset to match cutting plane coords
+ transform.Translate(0.5, 0.5, 0.5)
+ ]
+ self._group.children.append(self._isogroup)
+
+ self._bbox = axes.LabelledAxes()
+ self._bbox.children = [self._group]
+ self.getPlot3DWidget().viewport.scene.children.append(self._bbox)
+
+ self._initInteractionToolBar()
+
+ self._updateColors()
+
+ self.getPlot3DWidget().viewport.light.shininess = 32
+
+ def saveConfig(self, ioDevice):
+ """
+ Saves this view state. Only isosurfaces at the moment. Does not save
+ the isosurface's function.
+
+ :param qt.QIODevice ioDevice: A `qt.QIODevice`.
+ """
+
+ stream = qt.QDataStream(ioDevice)
+
+ stream.writeString('<ScalarFieldView>')
+
+ isoSurfaces = self.getIsosurfaces()
+
+ nIsoSurfaces = len(isoSurfaces)
+
+ # TODO : delegate the serialization to the serialized items
+ # isosurfaces
+ if nIsoSurfaces:
+ tagIn = '<IsoSurfaces nIso={0}>'.format(nIsoSurfaces)
+ stream.writeString(tagIn)
+
+ for surface in isoSurfaces:
+ color = surface.getColor()
+ level = surface.getLevel()
+ visible = surface.isVisible()
+ stream << color
+ stream.writeDouble(level)
+ stream.writeBool(visible)
+
+ stream.writeString('</IsoSurfaces>')
+
+ stream.writeString('<Style>')
+ background = self.getBackgroundColor()
+ foreground = self.getForegroundColor()
+ highlight = self.getHighlightColor()
+ stream << background << foreground << highlight
+ stream.writeString('</Style>')
+
+ stream.writeString('</ScalarFieldView>')
+
+ def loadConfig(self, ioDevice):
+ """
+ Loads this view state.
+ See ScalarFieldView.saveView to know what is supported at the moment.
+
+ :param qt.QIODevice ioDevice: A `qt.QIODevice`.
+ """
+
+ tagStack = deque()
+
+ tagInRegex = re.compile('<(?P<itemId>[^ /]*) *'
+ '(?P<args>.*)>')
+
+ tagOutRegex = re.compile('</(?P<itemId>[^ ]*)>')
+
+ tagRootInRegex = re.compile('<ScalarFieldView>')
+
+ isoSurfaceArgsRegex = re.compile('nIso=(?P<nIso>[0-9]*)')
+
+ stream = qt.QDataStream(ioDevice)
+
+ tag = stream.readString()
+ tagMatch = tagRootInRegex.match(tag)
+
+ if tagMatch is None:
+ # TODO : explicit error
+ raise ValueError('Unknown data.')
+
+ itemId = 'ScalarFieldView'
+
+ tagStack.append(itemId)
+
+ while True:
+
+ tag = stream.readString()
+
+ tagMatch = tagOutRegex.match(tag)
+ if tagMatch:
+ closeId = tagMatch.groupdict()['itemId']
+ if closeId != itemId:
+ # TODO : explicit error
+ raise ValueError('Unexpected closing tag {0} '
+ '(expected {1})'
+ ''.format(closeId, itemId))
+
+ if itemId == 'ScalarFieldView':
+ # reached end
+ break
+ else:
+ itemId = tagStack.pop()
+ # fetching next tag
+ continue
+
+ tagMatch = tagInRegex.match(tag)
+
+ if tagMatch is None:
+ # TODO : explicit error
+ raise ValueError('Unknown data.')
+
+ tagStack.append(itemId)
+
+ matchDict = tagMatch.groupdict()
+
+ itemId = matchDict['itemId']
+
+ # TODO : delegate the deserialization to the serialized items
+ if itemId == 'IsoSurfaces':
+ argsMatch = isoSurfaceArgsRegex.match(matchDict['args'])
+ if not argsMatch:
+ # TODO : explicit error
+ raise ValueError('Failed to parse args "{0}".'
+ ''.format(matchDict['args']))
+ argsDict = argsMatch.groupdict()
+ nIso = int(argsDict['nIso'])
+ if nIso:
+ for surface in self.getIsosurfaces():
+ self.removeIsosurface(surface)
+ for isoIdx in range(nIso):
+ color = qt.QColor()
+ stream >> color
+ level = stream.readDouble()
+ visible = stream.readBool()
+ surface = self.addIsosurface(level, color=color)
+ surface.setVisible(visible)
+ elif itemId == 'Style':
+ background = qt.QColor()
+ foreground = qt.QColor()
+ highlight = qt.QColor()
+ stream >> background >> foreground >> highlight
+ self.setBackgroundColor(background)
+ self.setForegroundColor(foreground)
+ self.setHighlightColor(highlight)
+ else:
+ raise ValueError('Unknown entry tag {0}.'
+ ''.format(itemId))
+
+ def _initInteractionToolBar(self):
+ self._interactionToolbar = qt.QToolBar()
+ self._interactionToolbar.setEnabled(False)
+
+ group = qt.QActionGroup(self._interactionToolbar)
+ group.setExclusive(True)
+
+ self._cameraAction = qt.QAction(None)
+ self._cameraAction.setText('camera')
+ self._cameraAction.setCheckable(True)
+ self._cameraAction.setToolTip('Control camera')
+ self._cameraAction.setChecked(True)
+ group.addAction(self._cameraAction)
+
+ self._planeAction = qt.QAction(None)
+ self._planeAction.setText('plane')
+ self._planeAction.setCheckable(True)
+ self._planeAction.setToolTip('Control cutting plane')
+ group.addAction(self._planeAction)
+ group.triggered.connect(self._interactionChanged)
+
+ self._interactionToolbar.addActions(group.actions())
+ self.addToolBar(self._interactionToolbar)
+
+ def _planeVisibilityChanged(self, visible):
+ """Handle visibility events from the plane"""
+ if visible != self._interactionToolbar.isEnabled():
+ if visible:
+ self._interactionToolbar.setEnabled(True)
+ self.setInteractiveMode('plane')
+ else:
+ self._interactionToolbar.setEnabled(False)
+ self.setInteractiveMode('camera')
+
+ def _interactionChanged(self, action):
+ self.setInteractiveMode(action.text())
+
+ def setInteractiveMode(self, mode):
+ """Choose the current interaction.
+
+ :param str mode: Either plane or camera
+ """
+ if mode == self.getInteractiveMode():
+ return
+
+ sceneScale = self.getPlot3DWidget().viewport.scene.transforms[0]
+ if mode == 'plane':
+ self.getPlot3DWidget().eventHandler = \
+ interaction.PanPlaneRotateCameraControl(
+ self.getPlot3DWidget().viewport,
+ self._cutPlane._get3DPrimitive(),
+ mode='position',
+ scaleTransform=sceneScale)
+ self._planeAction.setChecked(True)
+ elif mode == 'camera':
+ self.getPlot3DWidget().eventHandler = interaction.CameraControl(
+ self.getPlot3DWidget().viewport, orbitAroundCenter=False,
+ mode='position', scaleTransform=sceneScale,
+ selectCB=None)
+ self._cameraAction.setChecked(True)
+ else:
+ raise ValueError('Unsupported interactive mode %s', str(mode))
+ self._updateColors()
+
+ def getInteractiveMode(self):
+ """Returns the current interaction mode, see :meth:`setInteractiveMode`
+ """
+ if isinstance(self.getPlot3DWidget().eventHandler,
+ interaction.PanPlaneRotateCameraControl):
+ return 'plane'
+ elif isinstance(self.getPlot3DWidget().eventHandler,
+ interaction.CameraControl):
+ return 'camera'
+ else:
+ raise RuntimeError('Unknown interactive mode')
+
+ # Handle scalar field
+
+ def setData(self, data, copy=True):
+ """Set the 3D scalar data set to use for building the iso-surface.
+
+ Dataset order is zyx (i.e., first dimension is z).
+
+ :param data: scalar field from which to extract the iso-surface
+ :type data: 3D numpy.ndarray of float32 with shape at least (2, 2, 2)
+ :param bool copy:
+ True (default) to make a copy,
+ False to avoid copy (DO NOT MODIFY data afterwards)
+ """
+ if data is None:
+ self._data = None
+ self._dataRange = None
+ self.setSelectedRegion(zrange=None, yrange=None, xrange_=None)
+ self._group.shape = None
+ self.centerScene()
+
+ else:
+ data = numpy.array(data, copy=copy, dtype=numpy.float32, order='C')
+ assert data.ndim == 3
+ assert min(data.shape) >= 2
+
+ wasData = self._data is not None
+ previousSelectedRegion = self.getSelectedRegion()
+
+ self._data = data
+ self._dataRange = self._data.min(), self._data.max()
+
+ if previousSelectedRegion is not None:
+ # Update selected region to ensure it is clipped to array range
+ self.setSelectedRegion(*previousSelectedRegion.getArrayRange())
+
+ self._group.shape = self._data.shape
+
+ if not wasData:
+ self.centerScene() # Reset viewpoint the first time only
+
+ # Update iso-surfaces
+ for isosurface in self.getIsosurfaces():
+ isosurface._setData(self._data, copy=False)
+
+ self.sigDataChanged.emit()
+
+ def getData(self, copy=True):
+ """Get the 3D scalar data currently used to build the iso-surface.
+
+ :param bool copy:
+ True (default) to get a copy,
+ False to get the internal data (DO NOT modify!)
+ :return: The data set (or None if not set)
+ """
+ if self._data is None:
+ return None
+ else:
+ return numpy.array(self._data, copy=copy)
+
+ def getDataRange(self):
+ """Return the range of the data as a 2-tuple (min, max)"""
+ return self._dataRange
+
+ # Transformations
+
+ def setScale(self, sx=1., sy=1., sz=1.):
+ """Set the scale of the 3D scalar field (i.e., size of a voxel).
+
+ :param float sx: Scale factor along the X axis
+ :param float sy: Scale factor along the Y axis
+ :param float sz: Scale factor along the Z axis
+ """
+ scale = numpy.array((sx, sy, sz), dtype=numpy.float32)
+ if not numpy.all(numpy.equal(scale, self.getScale())):
+ self._dataScale.scale = scale
+ self.centerScene() # Reset viewpoint
+
+ def getScale(self):
+ """Returns the scales provided by :meth:`setScale` as a numpy.ndarray.
+ """
+ return self._dataScale.scale
+
+ def setTranslation(self, x=0., y=0., z=0.):
+ """Set the translation of the origin of the data array in data coordinates.
+
+ :param float x: Offset of the data origin on the X axis
+ :param float y: Offset of the data origin on the Y axis
+ :param float z: Offset of the data origin on the Z axis
+ """
+ translation = numpy.array((x, y, z), dtype=numpy.float32)
+ if not numpy.all(numpy.equal(translation, self.getTranslation())):
+ self._dataTranslate.translation = translation
+ self.centerScene() # Reset viewpoint
+
+ def getTranslation(self):
+ """Returns the offset set by :meth:`setTranslation` as a numpy.ndarray.
+ """
+ return self._dataTranslate.translation
+
+ # Axes labels
+
+ def setAxesLabels(self, xlabel=None, ylabel=None, zlabel=None):
+ """Set the text labels of the axes.
+
+ :param str xlabel: Label of the X axis, None to leave unchanged.
+ :param str ylabel: Label of the Y axis, None to leave unchanged.
+ :param str zlabel: Label of the Z axis, None to leave unchanged.
+ """
+ if xlabel is not None:
+ self._bbox.xlabel = xlabel
+
+ if ylabel is not None:
+ self._bbox.ylabel = ylabel
+
+ if zlabel is not None:
+ self._bbox.zlabel = zlabel
+
+ class _Labels(tuple):
+ """Return type of :meth:`getAxesLabels`"""
+
+ def getXLabel(self):
+ """Label of the X axis (str)"""
+ return self[0]
+
+ def getYLabel(self):
+ """Label of the Y axis (str)"""
+ return self[1]
+
+ def getZLabel(self):
+ """Label of the Z axis (str)"""
+ return self[2]
+
+ def getAxesLabels(self):
+ """Returns the text labels of the axes
+
+ >>> widget = ScalarFieldView()
+ >>> widget.setAxesLabels(xlabel='X')
+
+ You can get the labels either as a 3-tuple:
+
+ >>> xlabel, ylabel, zlabel = widget.getAxesLabels()
+
+ Or as an object with methods getXLabel, getYLabel and getZLabel:
+
+ >>> labels = widget.getAxesLabels()
+ >>> labels.getXLabel()
+ ... 'X'
+
+ :return: object describing the labels
+ """
+ return self._Labels((self._bbox.xlabel,
+ self._bbox.ylabel,
+ self._bbox.zlabel))
+
+ # Colors
+
+ def _updateColors(self):
+ """Update item depending on foreground/highlight color"""
+ self._bbox.tickColor = self._foregroundColor
+ self._selectionBox.strokeColor = self._foregroundColor
+ if self.getInteractiveMode() == 'plane':
+ self._cutPlane.setStrokeColor(self._highlightColor)
+ self._bbox.color = self._foregroundColor
+ else:
+ self._cutPlane.setStrokeColor(self._foregroundColor)
+ self._bbox.color = self._highlightColor
+
+ def getForegroundColor(self):
+ """Return color used for text and bounding box (QColor)"""
+ return qt.QColor.fromRgbF(*self._foregroundColor)
+
+ def setForegroundColor(self, color):
+ """Set the foreground color.
+
+ :param color: RGB color: name, #RRGGBB or RGB values
+ :type color:
+ QColor, str or array-like of 3 or 4 float in [0., 1.] or uint8
+ """
+ color = rgba(color)
+ if color != self._foregroundColor:
+ self._foregroundColor = color
+ self._updateColors()
+
+ def getHighlightColor(self):
+ """Return color used for highlighted item bounding box (QColor)"""
+ return qt.QColor.fromRgbF(*self._highlightColor)
+
+ def setHighlightColor(self, color):
+ """Set hightlighted item color.
+
+ :param color: RGB color: name, #RRGGBB or RGB values
+ :type color:
+ QColor, str or array-like of 3 or 4 float in [0., 1.] or uint8
+ """
+ color = rgba(color)
+ if color != self._highlightColor:
+ self._highlightColor = color
+ self._updateColors()
+
+ # Cut Plane
+
+ def getCutPlanes(self):
+ """Return an iterable of all cut planes of the view.
+
+ This includes hidden cut planes.
+
+ For now, there is always one cut plane.
+ """
+ return (self._cutPlane,)
+
+ # Selection
+
+ def setSelectedRegion(self, zrange=None, yrange=None, xrange_=None):
+ """Set the 3D selected region aligned with the axes.
+
+ Provided range are array indices range.
+ The provided ranges are clipped to the data.
+ If a range is None, the range of the array on this dimension is used.
+
+ :param zrange: (zmin, zmax) range of the selection
+ :param yrange: (ymin, ymax) range of the selection
+ :param xrange_: (xmin, xmax) range of the selection
+ """
+ # No range given: unset selection
+ if zrange is None and yrange is None and xrange_ is None:
+ selectedRange = None
+
+ else:
+ # Handle default ranges
+ if self._data is not None:
+ if zrange is None:
+ zrange = 0, self._data.shape[0]
+ if yrange is None:
+ yrange = 0, self._data.shape[1]
+ if xrange_ is None:
+ xrange_ = 0, self._data.shape[2]
+
+ elif None in (xrange_, yrange, zrange):
+ # One of the range is None and no data available
+ raise RuntimeError(
+ 'Data is not set, cannot get default range from it.')
+
+ # Clip selected region to data shape and make sure min <= max
+ selectedRange = numpy.array((
+ (max(0, min(*zrange)),
+ min(self._data.shape[0], max(*zrange))),
+ (max(0, min(*yrange)),
+ min(self._data.shape[1], max(*yrange))),
+ (max(0, min(*xrange_)),
+ min(self._data.shape[2], max(*xrange_))),
+ ), dtype=numpy.int)
+
+ # numpy.equal supports None
+ if not numpy.all(numpy.equal(selectedRange, self._selectedRange)):
+ self._selectedRange = selectedRange
+
+ # Update scene accordingly
+ if self._selectedRange is None:
+ self._selectionBox.visible = False
+ else:
+ self._selectionBox.visible = True
+ scales = self._selectedRange[:, 1] - self._selectedRange[:, 0]
+ self._selectionBox.size = scales[::-1]
+ self._selectionBox.transforms = [
+ transform.Translate(*self._selectedRange[::-1, 0])]
+
+ self.sigSelectedRegionChanged.emit(self.getSelectedRegion())
+
+ def getSelectedRegion(self):
+ """Returns the currently selected region or None."""
+ if self._selectedRange is None:
+ return None
+ else:
+ return SelectedRegion(self._selectedRange,
+ translation=self.getTranslation(),
+ scale=self.getScale())
+
+ # Handle iso-surfaces
+
+ sigIsosurfaceAdded = qt.Signal(object)
+ """Signal emitted when a new iso-surface is added to the view.
+
+ The newly added iso-surface is provided by this signal
+ """
+
+ sigIsosurfaceRemoved = qt.Signal(object)
+ """Signal emitted when an iso-surface is removed from the view
+
+ The removed iso-surface is provided by this signal.
+ """
+
+ def addIsosurface(self, level, color):
+ """Add an iso-surface to the view.
+
+ :param level:
+ The value at which to build the iso-surface or a callable
+ (e.g., a function) taking a 3D numpy.ndarray as input and
+ returning a float.
+ Example: numpy.mean(data) + numpy.std(data)
+ :type level: float or callable
+ :param color: RGBA color of the isosurface
+ :type color: str or array-like of 4 float in [0., 1.]
+ :return: Isosurface object describing this isosurface
+ """
+ isosurface = Isosurface(parent=self)
+ isosurface.setColor(color)
+ if callable(level):
+ isosurface.setAutoLevelFunction(level)
+ else:
+ isosurface.setLevel(level)
+ isosurface._setData(self._data, copy=False)
+ isosurface.sigLevelChanged.connect(self._updateIsosurfaces)
+
+ self._isosurfaces.append(isosurface)
+
+ self._updateIsosurfaces()
+
+ self.sigIsosurfaceAdded.emit(isosurface)
+ return isosurface
+
+ def getIsosurfaces(self):
+ """Return an iterable of all iso-surfaces of the view"""
+ return tuple(self._isosurfaces)
+
+ def removeIsosurface(self, isosurface):
+ """Remove an iso-surface from the view.
+
+ :param isosurface: The isosurface object to remove"""
+ if isosurface not in self.getIsosurfaces():
+ _logger.warning(
+ "Try to remove isosurface that is not in the list: %s",
+ str(isosurface))
+ else:
+ isosurface.sigLevelChanged.disconnect(self._updateIsosurfaces)
+ self._isosurfaces.remove(isosurface)
+ self._updateIsosurfaces()
+ self.sigIsosurfaceRemoved.emit(isosurface)
+
+ def clearIsosurfaces(self):
+ """Remove all iso-surfaces from the view."""
+ for isosurface in self.getIsosurfaces():
+ self.removeIsosurface(isosurface)
+
+ def _updateIsosurfaces(self, level=None):
+ """Handle updates of iso-surfaces level and add/remove"""
+ # Sorting using minus, this supposes data 'object' to be max values
+ sortedIso = sorted(self.getIsosurfaces(),
+ key=lambda iso: - iso.getLevel())
+ self._isogroup.children = [iso._get3DPrimitive() for iso in sortedIso]
diff --git a/silx/gui/plot3d/ViewpointToolBar.py b/silx/gui/plot3d/ViewpointToolBar.py
new file mode 100644
index 0000000..d062c1b
--- /dev/null
+++ b/silx/gui/plot3d/ViewpointToolBar.py
@@ -0,0 +1,114 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a toolbar to control Plot3DWidget viewpoint."""
+
+from __future__ import absolute_import
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "15/09/2016"
+
+
+from silx.gui import qt
+from silx.gui.icons import getQIcon
+
+
+class ViewpointActionGroup(qt.QActionGroup):
+ """ActionGroup of actions to reset the viewpoint.
+
+ As for QActionGroup, add group's actions to the widget with:
+ `widget.addActions(actionGroup.actions())`
+
+ :param Plot3DWidget plot3D: The widget for which to control the viewpoint
+ :param parent: See :class:`QActionGroup`
+ """
+
+ # Action information: icon name, text, tooltip
+ _RESET_CAMERA_ACTIONS = (
+ ('cube-front', 'Front', 'View along the -Z axis'),
+ ('cube-back', 'Back', 'View along the +Z axis'),
+ ('cube-top', 'Top', 'View along the -Y'),
+ ('cube-bottom', 'Bottom', 'View along the +Y'),
+ ('cube-right', 'Right', 'View along the -X'),
+ ('cube-left', 'Left', 'View along the +X'),
+ ('cube', 'Side', 'Side view')
+ )
+
+ def __init__(self, plot3D, parent=None):
+ super(ViewpointActionGroup, self).__init__(parent)
+ self.setExclusive(False)
+
+ self._plot3D = plot3D
+
+ for actionInfo in self._RESET_CAMERA_ACTIONS:
+ iconname, text, tooltip = actionInfo
+
+ action = qt.QAction(getQIcon(iconname), text, None)
+ action.setCheckable(False)
+ action.setToolTip(tooltip)
+ self.addAction(action)
+
+ self.triggered[qt.QAction].connect(self._actionGroupTriggered)
+
+ def _actionGroupTriggered(self, action):
+ actionname = action.text().lower()
+
+ self._plot3D.viewport.camera.extrinsic.reset(face=actionname)
+ self._plot3D.centerScene()
+
+
+class ViewpointToolBar(qt.QToolBar):
+ """A toolbar providing icons to reset the viewpoint.
+
+ :param parent: See :class:`QToolBar`
+ :param Plot3DWidget plot3D: The widget to control
+ :param str title: Title of the toolbar
+ """
+
+ def __init__(self, parent=None, plot3D=None, title='Viewpoint control'):
+ super(ViewpointToolBar, self).__init__(title, parent)
+
+ self._actionGroup = ViewpointActionGroup(plot3D)
+ assert plot3D is not None
+ self._plot3D = plot3D
+ self.addActions(self._actionGroup.actions())
+
+ # Choosing projection disabled for now
+ # Add projection combo box
+ # comboBoxProjection = qt.QComboBox()
+ # comboBoxProjection.addItem('Perspective')
+ # comboBoxProjection.addItem('Parallel')
+ # comboBoxProjection.setToolTip(
+ # 'Choose the projection:'
+ # ' perspective or parallel (i.e., orthographic)')
+ # comboBoxProjection.currentIndexChanged[(str)].connect(
+ # self._comboBoxProjectionCurrentIndexChanged)
+ # self.addWidget(qt.QLabel('Projection:'))
+ # self.addWidget(comboBoxProjection)
+
+ # def _comboBoxProjectionCurrentIndexChanged(self, text):
+ # """Projection combo box listener"""
+ # self._plot3D.setProjection(
+ # 'perspective' if text == 'Perspective' else 'orthographic')
diff --git a/silx/gui/plot3d/__init__.py b/silx/gui/plot3d/__init__.py
new file mode 100644
index 0000000..ad45424
--- /dev/null
+++ b/silx/gui/plot3d/__init__.py
@@ -0,0 +1,45 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""
+This package provides widgets displaying 3D content based on OpenGL.
+
+It depends on PyOpenGL and QtOpenGL.
+"""
+from __future__ import absolute_import
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/01/2017"
+
+
+from .. import qt as _qt
+
+if not _qt.HAS_OPENGL:
+ raise ImportError('Qt.QtOpenGL is not available')
+
+try:
+ import OpenGL as _OpenGL
+except ImportError:
+ raise ImportError('PyOpenGL is not installed')
diff --git a/silx/gui/plot3d/scene/__init__.py b/silx/gui/plot3d/scene/__init__.py
new file mode 100644
index 0000000..25a7171
--- /dev/null
+++ b/silx/gui/plot3d/scene/__init__.py
@@ -0,0 +1,34 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a 3D graphics scene graph structure."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "08/11/2016"
+
+
+from .core import Elem, Group, PrivateGroup # noqa
+from .viewport import Viewport # noqa
+from .window import Window # noqa
diff --git a/silx/gui/plot3d/scene/axes.py b/silx/gui/plot3d/scene/axes.py
new file mode 100644
index 0000000..528e4f7
--- /dev/null
+++ b/silx/gui/plot3d/scene/axes.py
@@ -0,0 +1,224 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Primitive displaying a text field in the scene."""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "17/10/2016"
+
+
+import logging
+import numpy
+
+from ...plot._utils import ticklayout
+
+from . import core, primitives, text, transform
+
+
+_logger = logging.getLogger(__name__)
+
+
+class LabelledAxes(primitives.GroupBBox):
+ """A group displaying a bounding box with axes labels around its children.
+ """
+
+ def __init__(self):
+ super(LabelledAxes, self).__init__()
+ self._ticksForBounds = None
+
+ self._font = text.Font()
+
+ # TODO offset labels from anchor in pixels
+
+ self._xlabel = text.Text2D(font=self._font)
+ self._xlabel.align = 'center'
+ self._xlabel.transforms = [self._boxTransforms,
+ transform.Translate(tx=0.5)]
+ self._children.insert(-1, self._xlabel)
+
+ self._ylabel = text.Text2D(font=self._font)
+ self._ylabel.align = 'center'
+ self._ylabel.transforms = [self._boxTransforms,
+ transform.Translate(ty=0.5)]
+ self._children.insert(-1, self._ylabel)
+
+ self._zlabel = text.Text2D(font=self._font)
+ self._zlabel.align = 'center'
+ self._zlabel.transforms = [self._boxTransforms,
+ transform.Translate(tz=0.5)]
+ self._children.insert(-1, self._zlabel)
+
+ # Init tick lines with dummy pos
+ self._tickLines = primitives.DashedLines(
+ positions=((0., 0., 0.), (0., 0., 0.)))
+ self._tickLines.dash = 5, 10
+ self._tickLines.visible = False
+ self._children.insert(-1, self._tickLines)
+
+ self._tickLabels = core.Group()
+ self._children.insert(-1, self._tickLabels)
+
+ # Sync color
+ self.tickColor = 1., 1., 1., 1.
+
+ @property
+ def tickColor(self):
+ """Color of ticks and text labels.
+
+ This does NOT set bounding box color.
+ Use :attr:`color` for the bounding box.
+ """
+ return self._xlabel.foreground
+
+ @tickColor.setter
+ def tickColor(self, color):
+ self._xlabel.foreground = color
+ self._ylabel.foreground = color
+ self._zlabel.foreground = color
+ transparentColor = color[0], color[1], color[2], color[3] * 0.6
+ self._tickLines.setAttribute('color', transparentColor)
+ for label in self._tickLabels.children:
+ label.foreground = color
+
+ @property
+ def font(self):
+ """Font of axes text labels (Font)"""
+ return self._font
+
+ @font.setter
+ def font(self, font):
+ self._font = font
+ self._xlabel.font = font
+ self._ylabel.font = font
+ self._zlabel.font = font
+ for label in self._tickLabels.children:
+ label.font = font
+
+ @property
+ def xlabel(self):
+ """Text label of the X axis (str)"""
+ return self._xlabel.text
+
+ @xlabel.setter
+ def xlabel(self, text):
+ self._xlabel.text = text
+
+ @property
+ def ylabel(self):
+ """Text label of the Y axis (str)"""
+ return self._ylabel.text
+
+ @ylabel.setter
+ def ylabel(self, text):
+ self._ylabel.text = text
+
+ @property
+ def zlabel(self):
+ """Text label of the Z axis (str)"""
+ return self._zlabel.text
+
+ @zlabel.setter
+ def zlabel(self, text):
+ self._zlabel.text = text
+
+ def _updateTicks(self):
+ """Check if ticks need update and update them if needed."""
+ bounds = self._group.bounds(transformed=False, dataBounds=True)
+ if bounds is None: # No content
+ if self._ticksForBounds is not None:
+ self._ticksForBounds = None
+ self._tickLines.visible = False
+ self._tickLabels.children = [] # Reset previous labels
+
+ elif (self._ticksForBounds is None or
+ not numpy.all(numpy.equal(bounds, self._ticksForBounds))):
+ self._ticksForBounds = bounds
+
+ # Update ticks
+ ticklength = numpy.abs(bounds[1] - bounds[0])
+
+ xticks, xlabels = ticklayout.ticks(*bounds[:, 0])
+ yticks, ylabels = ticklayout.ticks(*bounds[:, 1])
+ zticks, zlabels = ticklayout.ticks(*bounds[:, 2])
+
+ # Update tick lines
+ coords = numpy.empty(
+ ((len(xticks) + len(yticks) + len(zticks)), 4, 3),
+ dtype=numpy.float32)
+ coords[:, :, :] = bounds[0, :] # account for offset from origin
+
+ xcoords = coords[:len(xticks)]
+ xcoords[:, :, 0] = numpy.asarray(xticks)[:, numpy.newaxis]
+ xcoords[:, 1, 1] += ticklength[1] # X ticks on XY plane
+ xcoords[:, 3, 2] += ticklength[2] # X ticks on XZ plane
+
+ ycoords = coords[len(xticks):len(xticks) + len(yticks)]
+ ycoords[:, :, 1] = numpy.asarray(yticks)[:, numpy.newaxis]
+ ycoords[:, 1, 0] += ticklength[0] # Y ticks on XY plane
+ ycoords[:, 3, 2] += ticklength[2] # Y ticks on YZ plane
+
+ zcoords = coords[len(xticks) + len(yticks):]
+ zcoords[:, :, 2] = numpy.asarray(zticks)[:, numpy.newaxis]
+ zcoords[:, 1, 0] += ticklength[0] # Z ticks on XZ plane
+ zcoords[:, 3, 1] += ticklength[1] # Z ticks on YZ plane
+
+ self._tickLines.setPositions(coords.reshape(-1, 3))
+ self._tickLines.visible = True
+
+ # Update labels
+ color = self.tickColor
+ offsets = bounds[0] - ticklength / 20.
+ labels = []
+ for tick, label in zip(xticks, xlabels):
+ text2d = text.Text2D(text=label, font=self.font)
+ text2d.align = 'center'
+ text2d.foreground = color
+ text2d.transforms = [transform.Translate(
+ tx=tick, ty=offsets[1], tz=offsets[2])]
+ labels.append(text2d)
+
+ for tick, label in zip(yticks, ylabels):
+ text2d = text.Text2D(text=label, font=self.font)
+ text2d.align = 'center'
+ text2d.foreground = color
+ text2d.transforms = [transform.Translate(
+ tx=offsets[0], ty=tick, tz=offsets[2])]
+ labels.append(text2d)
+
+ for tick, label in zip(zticks, zlabels):
+ text2d = text.Text2D(text=label, font=self.font)
+ text2d.align = 'center'
+ text2d.foreground = color
+ text2d.transforms = [transform.Translate(
+ tx=offsets[0], ty=offsets[1], tz=tick)]
+ labels.append(text2d)
+
+ self._tickLabels.children = labels # Reset previous labels
+
+ def prepareGL2(self, context):
+ self._updateTicks()
+ super(LabelledAxes, self).prepareGL2(context)
diff --git a/silx/gui/plot3d/scene/camera.py b/silx/gui/plot3d/scene/camera.py
new file mode 100644
index 0000000..8cc279d
--- /dev/null
+++ b/silx/gui/plot3d/scene/camera.py
@@ -0,0 +1,350 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides classes to handle a perspective projection in 3D."""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import numpy
+
+from . import transform
+
+
+# CameraExtrinsic #############################################################
+
+class CameraExtrinsic(transform.Transform):
+ """Transform matrix to handle camera position and orientation.
+
+ :param position: Coordinates of the point of view.
+ :type position: numpy.ndarray-like of 3 float32.
+ :param direction: Sight direction vector.
+ :type direction: numpy.ndarray-like of 3 float32.
+ :param up: Vector pointing upward in the image plane.
+ :type up: numpy.ndarray-like of 3 float32.
+ """
+
+ def __init__(self, position=(0., 0., 0.),
+ direction=(0., 0., -1.),
+ up=(0., 1., 0.)):
+
+ super(CameraExtrinsic, self).__init__()
+ self._position = None
+ self.position = position # set _position
+ self._side = 1., 0., 0.
+ self._up = 0., 1., 0.
+ self._direction = 0., 0., -1.
+ self.setOrientation(direction=direction, up=up) # set _direction, _up
+
+ def _makeMatrix(self):
+ return transform.mat4LookAtDir(self._position,
+ self._direction, self._up)
+
+ def copy(self):
+ """Return an independent copy"""
+ return CameraExtrinsic(self.position, self.direction, self.up)
+
+ def setOrientation(self, direction=None, up=None):
+ """Set the rotation of the point of view.
+
+ :param direction: Sight direction vector or
+ None to keep the current one.
+ :type direction: numpy.ndarray-like of 3 float32 or None.
+ :param up: Vector pointing upward in the image plane or
+ None to keep the current one.
+ :type up: numpy.ndarray-like of 3 float32 or None.
+ :raises RuntimeError: if the direction and up are parallel.
+ """
+ if direction is None: # Use current direction
+ direction = self.direction
+ else:
+ assert len(direction) == 3
+ direction = numpy.array(direction, copy=True, dtype=numpy.float32)
+ direction /= numpy.linalg.norm(direction)
+
+ if up is None: # Use current up
+ up = self.up
+ else:
+ assert len(up) == 3
+ up = numpy.array(up, copy=True, dtype=numpy.float32)
+
+ # Update side and up to make sure they are perpendicular and normalized
+ side = numpy.cross(direction, up)
+ sidenormal = numpy.linalg.norm(side)
+ if sidenormal == 0.:
+ raise RuntimeError('direction and up vectors are parallel.')
+ # Alternative: when one of the input parameter is None, it is
+ # possible to guess correct vectors using previous direction and up
+ side /= sidenormal
+ up = numpy.cross(side, direction)
+ up /= numpy.linalg.norm(up)
+
+ self._side = side
+ self._up = up
+ self._direction = direction
+ self.notify()
+
+ @property
+ def position(self):
+ """Coordinates of the point of view as a numpy.ndarray of 3 float32."""
+ return self._position.copy()
+
+ @position.setter
+ def position(self, position):
+ assert len(position) == 3
+ self._position = numpy.array(position, copy=True, dtype=numpy.float32)
+ self.notify()
+
+ @property
+ def direction(self):
+ """Sight direction (ndarray of 3 float32)."""
+ return self._direction.copy()
+
+ @direction.setter
+ def direction(self, direction):
+ self.setOrientation(direction=direction)
+
+ @property
+ def up(self):
+ """Vector pointing upward in the image plane (ndarray of 3 float32).
+ """
+ return self._up.copy()
+
+ @up.setter
+ def up(self, up):
+ self.setOrientation(up=up)
+
+ @property
+ def side(self):
+ """Vector pointing towards the side of the image plane.
+
+ ndarray of 3 float32"""
+ return self._side.copy()
+
+ def move(self, direction, step=1.):
+ """Move the camera relative to the image plane.
+
+ :param str direction: Direction relative to image plane.
+ One of: 'up', 'down', 'left', 'right',
+ 'forward', 'backward'.
+ :param float step: The step of the pan to perform in the coordinate
+ in which the camera position is defined.
+ """
+ if direction in ('up', 'down'):
+ vector = self.up * (1. if direction == 'up' else -1.)
+ elif direction in ('left', 'right'):
+ vector = self.side * (1. if direction == 'right' else -1.)
+ elif direction in ('forward', 'backward'):
+ vector = self.direction * (1. if direction == 'forward' else -1.)
+ else:
+ raise ValueError('Unsupported direction: %s' % direction)
+
+ self.position += step * vector
+
+ def rotate(self, direction, angle=1.):
+ """First-person rotation of the camera towards the direction.
+
+ :param str direction: Direction of movement relative to image plane.
+ In: 'up', 'down', 'left', 'right'.
+ :param float angle: The angle in degrees of the rotation.
+ """
+ if direction in ('up', 'down'):
+ axis = self.side * (1. if direction == 'up' else -1.)
+ elif direction in ('left', 'right'):
+ axis = self.up * (1. if direction == 'left' else -1.)
+ else:
+ raise ValueError('Unsupported direction: %s' % direction)
+
+ matrix = transform.mat4RotateFromAngleAxis(numpy.radians(angle), *axis)
+ newdir = numpy.dot(matrix[:3, :3], self.direction)
+
+ if direction in ('up', 'down'):
+ # Rotate up to avoid up and new direction to be (almost) co-linear
+ newup = numpy.dot(matrix[:3, :3], self.up)
+ self.setOrientation(newdir, newup)
+ else:
+ # No need to rotate up here as it is the rotation axis
+ self.direction = newdir
+
+ def orbit(self, direction, center=(0., 0., 0.), angle=1.):
+ """Rotate the camera around a point.
+
+ :param str direction: Direction of movement relative to image plane.
+ In: 'up', 'down', 'left', 'right'.
+ :param center: Position around which to rotate the point of view.
+ :type center: numpy.ndarray-like of 3 float32.
+ :param float angle: he angle in degrees of the rotation.
+ """
+ if direction in ('up', 'down'):
+ axis = self.side * (1. if direction == 'down' else -1.)
+ elif direction in ('left', 'right'):
+ axis = self.up * (1. if direction == 'right' else -1.)
+ else:
+ raise ValueError('Unsupported direction: %s' % direction)
+
+ # Rotate viewing direction
+ rotmatrix = transform.mat4RotateFromAngleAxis(
+ numpy.radians(angle), *axis)
+ self.direction = numpy.dot(rotmatrix[:3, :3], self.direction)
+
+ # Rotate position around center
+ center = numpy.array(center, copy=False, dtype=numpy.float32)
+ matrix = numpy.dot(transform.mat4Translate(*center), rotmatrix)
+ matrix = numpy.dot(matrix, transform.mat4Translate(*(-center)))
+ position = numpy.append(self.position, 1.)
+ self.position = numpy.dot(matrix, position)[:3]
+
+ _RESET_CAMERA_ORIENTATIONS = {
+ 'side': ((-1., -1., -1.), (0., 1., 0.)),
+ 'front': ((0., 0., -1.), (0., 1., 0.)),
+ 'back': ((0., 0., 1.), (0., 1., 0.)),
+ 'top': ((0., -1., 0.), (0., 0., -1.)),
+ 'bottom': ((0., 1., 0.), (0., 0., 1.)),
+ 'right': ((-1., 0., 0.), (0., 1., 0.)),
+ 'left': ((1., 0., 0.), (0., 1., 0.))
+ }
+
+ def reset(self, face=None):
+ """Reset the camera position to pre-defined orientations.
+
+ :param str face: The direction of the camera in:
+ side, front, back, top, bottom, right, left.
+ """
+ if face not in self._RESET_CAMERA_ORIENTATIONS:
+ raise ValueError('Unsupported face: %s' % face)
+
+ distance = numpy.linalg.norm(self.position)
+ direction, up = self._RESET_CAMERA_ORIENTATIONS[face]
+ self.setOrientation(direction, up)
+ self.position = - self.direction * distance
+
+
+class Camera(transform.Transform):
+ """Combination of camera projection and position.
+
+ See :class:`Perspective` and :class:`CameraExtrinsic`.
+
+ :param float fovy: Vertical field-of-view in degrees.
+ :param float near: The near clipping plane Z coord (strictly positive).
+ :param float far: The far clipping plane Z coord (> near).
+ :param size: Viewport's size used to compute the aspect ratio.
+ :type size: 2-tuple of float (width, height).
+ :param position: Coordinates of the point of view.
+ :type position: numpy.ndarray-like of 3 float32.
+ :param direction: Sight direction vector.
+ :type direction: numpy.ndarray-like of 3 float32.
+ :param up: Vector pointing upward in the image plane.
+ :type up: numpy.ndarray-like of 3 float32.
+ """
+
+ def __init__(self, fovy=30., near=0.1, far=1., size=(1., 1.),
+ position=(0., 0., 0.),
+ direction=(0., 0., -1.), up=(0., 1., 0.)):
+ super(Camera, self).__init__()
+ self._intrinsic = transform.Perspective(fovy, near, far, size)
+ self._intrinsic.addListener(self._transformChanged)
+ self._extrinsic = CameraExtrinsic(position, direction, up)
+ self._extrinsic.addListener(self._transformChanged)
+
+ def _makeMatrix(self):
+ return numpy.dot(self.intrinsic.matrix, self.extrinsic.matrix)
+
+ def _transformChanged(self, source):
+ """Listener of intrinsic and extrinsic camera parameters instances."""
+ if source is not self:
+ self.notify()
+
+ def resetCamera(self, bounds):
+ """Change camera to have the bounds in the viewing frustum.
+
+ It updates the camera position and depth extent.
+ Camera sight direction and up are not affected.
+
+ :param bounds: The axes-aligned bounds to include.
+ :type bounds: numpy.ndarray: ((xMin, yMin, zMin), (xMax, yMax, zMax))
+ """
+
+ center = 0.5 * (bounds[0] + bounds[1])
+ radius = numpy.linalg.norm(0.5 * (bounds[1] - bounds[0]))
+
+ if isinstance(self.intrinsic, transform.Perspective):
+ # Get the viewpoint distance from the bounds center
+ minfov = numpy.radians(self.intrinsic.fovy)
+ width, height = self.intrinsic.size
+ if width < height:
+ minfov *= width / height
+
+ offset = radius / numpy.sin(0.5 * minfov)
+
+ # Update camera
+ self.extrinsic.position = \
+ center - offset * self.extrinsic.direction
+ self.intrinsic.setDepthExtent(offset - radius, offset + radius)
+
+ elif isinstance(self.intrinsic, transform.Orthographic):
+ # Y goes up
+ self.intrinsic.setClipping(
+ left=center[0] - radius,
+ right=center[0] + radius,
+ bottom=center[1] - radius,
+ top=center[1] + radius)
+
+ # Update camera
+ self.extrinsic.position = 0, 0, 0
+ self.intrinsic.setDepthExtent(center[2] - radius,
+ center[2] + radius)
+ else:
+ raise RuntimeError('Unsupported camera: %s' % self.intrinsic)
+
+ @property
+ def intrinsic(self):
+ """Intrinsic camera parameters, i.e., projection matrix."""
+ return self._intrinsic
+
+ @intrinsic.setter
+ def intrinsic(self, intrinsic):
+ self._intrinsic.removeListener(self._transformChanged)
+ self._intrinsic = intrinsic
+ self._intrinsic.addListener(self._transformChanged)
+
+ @property
+ def extrinsic(self):
+ """Extrinsic camera parameters, i.e., position and orientation."""
+ return self._extrinsic
+
+ def move(self, *args, **kwargs):
+ """See :meth:`CameraExtrinsic.move`."""
+ self.extrinsic.move(*args, **kwargs)
+
+ def rotate(self, *args, **kwargs):
+ """See :meth:`CameraExtrinsic.rotate`."""
+ self.extrinsic.rotate(*args, **kwargs)
+
+ def orbit(self, *args, **kwargs):
+ """See :meth:`CameraExtrinsic.orbit`."""
+ self.extrinsic.orbit(*args, **kwargs)
diff --git a/silx/gui/plot3d/scene/core.py b/silx/gui/plot3d/scene/core.py
new file mode 100644
index 0000000..a293f28
--- /dev/null
+++ b/silx/gui/plot3d/scene/core.py
@@ -0,0 +1,334 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides the base scene structure.
+
+This module provides the classes for describing a tree structure with
+rendering and picking API.
+All nodes inherit from :class:`Base`.
+Nodes with children are provided with :class:`PrivateGroup` and
+:class:`Group` classes.
+Leaf rendering nodes should inherit from :class:`Elem`.
+"""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import itertools
+import weakref
+
+import numpy
+
+from . import event
+from . import transform
+
+from .viewport import Viewport
+
+
+# Nodes #######################################################################
+
+class Base(event.Notifier):
+ """A scene node with common features."""
+
+ def __init__(self):
+ super(Base, self).__init__()
+ self._visible = True
+ self._pickable = False
+
+ self._parentRef = None
+
+ self._transforms = transform.TransformList()
+ self._transforms.addListener(self._transformChanged)
+
+ # notifying properties
+
+ visible = event.notifyProperty('_visible',
+ doc="Visibility flag of the node")
+ pickable = event.notifyProperty('_pickable',
+ doc="True to make node pickable")
+
+ # Access to tree path
+
+ @property
+ def parent(self):
+ """Parent or None if no parent"""
+ return None if self._parentRef is None else self._parentRef()
+
+ def _setParent(self, parent):
+ """Set the parent of this node.
+
+ For internal use.
+
+ :param Base parent: The parent.
+ """
+ if parent is not None and self._parentRef is not None:
+ raise RuntimeError('Trying to add a node at two places.')
+ # Alternative: remove it from previous children list
+ self._parentRef = None if parent is None else weakref.ref(parent)
+
+ @property
+ def path(self):
+ """Tuple of scene nodes, from the tip of the tree down to this node.
+
+ If this tree is attached to a :class:`Viewport`,
+ then the :class:`Viewport` is the first element of path.
+ """
+ if self.parent is None:
+ return self,
+ elif isinstance(self.parent, Viewport):
+ return self.parent, self
+ else:
+ return self.parent.path + (self, )
+
+ @property
+ def viewport(self):
+ """The viewport this node is attached to or None."""
+ root = self.path[0]
+ return root if isinstance(root, Viewport) else None
+
+ @property
+ def objectToNDCTransform(self):
+ """Transform from object to normalized device coordinates.
+
+ Do not forget perspective divide.
+ """
+ # Using the Viewport's transforms property to proxy the camera
+ path = self.path
+ assert isinstance(path[0], Viewport)
+ return transform.StaticTransformList(elem.transforms for elem in path)
+
+ @property
+ def objectToSceneTransform(self):
+ """Transform from object to scene.
+
+ Combine transforms up to the Viewport (not including it).
+ """
+ path = self.path
+ if isinstance(path[0], Viewport):
+ path = path[1:] # Remove viewport to remove camera transforms
+ return transform.StaticTransformList(elem.transforms for elem in path)
+
+ # transform
+
+ @property
+ def transforms(self):
+ """List of transforms defining the frame of this node relative
+ to its parent."""
+ return self._transforms
+
+ @transforms.setter
+ def transforms(self, iterable):
+ self._transforms.removeListener(self._transformChanged)
+ if isinstance(iterable, transform.TransformList):
+ # If it is a TransformList, do not create one to enable sharing.
+ self._transforms = iterable
+ else:
+ assert hasattr(iterable, '__iter__')
+ self._transforms = transform.TransformList(iterable)
+ self._transforms.addListener(self._transformChanged)
+
+ def _transformChanged(self, source):
+ self.notify() # Broadcast transform notification
+
+ # Bounds
+
+ _CUBE_CORNERS = numpy.array(list(itertools.product((0., 1.), repeat=3)),
+ dtype=numpy.float32)
+ """Unit cube corners used to transform bounds"""
+
+ def _bounds(self, dataBounds=False):
+ """Override in subclass to provide bounds in object coordinates"""
+ return None
+
+ def bounds(self, transformed=False, dataBounds=False):
+ """Returns the bounds of this node aligned with the axis,
+ with or without transform applied.
+
+ :param bool transformed: False to give bounds in object coordinates
+ (the default), True to apply this object's
+ transforms.
+ :param bool dataBounds: False to give bounds of vertices (the default),
+ True to give bounds of the represented data.
+ :return: The bounds: ((xMin, yMin, zMin), (xMax, yMax, zMax)) or None
+ if no bounds.
+ :rtype: numpy.ndarray of float
+ """
+ bounds = self._bounds(dataBounds)
+
+ if transformed and bounds is not None:
+ bounds = self.transforms.transformBounds(bounds)
+
+ return bounds
+
+ # Rendering
+
+ def prepareGL2(self, ctx):
+ """Called before the rendering to prepare OpenGL resources.
+
+ Override in subclass.
+ """
+ pass
+
+ def renderGL2(self, ctx):
+ """Called to perform the OpenGL rendering.
+
+ Override in subclass.
+ """
+ pass
+
+ def render(self, ctx):
+ """Called internally to perform rendering."""
+ if self.visible:
+ ctx.pushTransform(self.transforms)
+ self.prepareGL2(ctx)
+ self.renderGL2(ctx)
+ ctx.popTransform()
+
+ def postRender(self, ctx):
+ """Hook called when parent's node render is finished.
+
+ Called in the reverse of rendering order (i.e., last child first).
+
+ Meant for nodes that modify the :class:`RenderContext` ctx to
+ reset their modifications.
+ """
+ pass
+
+ def pick(self, ctx, x, y, depth=None):
+ """True/False picking, should be fast"""
+ if self.pickable:
+ pass
+
+ def pickRay(self, ctx, ray):
+ """Picking returning list of ray intersections."""
+ if self.pickable:
+ pass
+
+
+class Elem(Base):
+ """A scene node that does some rendering."""
+
+ def __init__(self):
+ super(Elem, self).__init__()
+ # self.showBBox = False # Here or outside scene graph?
+ # self.clipPlane = None # This needs to be handled in the shader
+
+
+class PrivateGroup(Base):
+ """A scene node that renders its (private) childern.
+
+ :param iterable children: :class:`Base` nodes to add as children
+ """
+
+ class ChildrenList(event.NotifierList):
+ """List of children with notification and children's parent update."""
+
+ def _listWillChangeHook(self, methodName, *args, **kwargs):
+ super(PrivateGroup.ChildrenList, self)._listWillChangeHook(
+ methodName, *args, **kwargs)
+ for item in self:
+ item._setParent(None)
+
+ def _listWasChangedHook(self, methodName, *args, **kwargs):
+ for item in self:
+ item._setParent(self._parentRef())
+ super(PrivateGroup.ChildrenList, self)._listWasChangedHook(
+ methodName, *args, **kwargs)
+
+ def __init__(self, parent, children):
+ self._parentRef = weakref.ref(parent)
+ super(PrivateGroup.ChildrenList, self).__init__(children)
+
+ def __init__(self, children=()):
+ super(PrivateGroup, self).__init__()
+ self.__children = PrivateGroup.ChildrenList(self, children)
+ self.__children.addListener(self._updated)
+
+ @property
+ def _children(self):
+ """List of children to be rendered.
+
+ This private attribute is meant to be used by subclass.
+ """
+ return self.__children
+
+ @_children.setter
+ def _children(self, iterable):
+ self.__children.removeListener(self._updated)
+ for item in self.__children:
+ item._setParent(None)
+ del self.__children # This is needed
+ self.__children = PrivateGroup.ChildrenList(self, iterable)
+ self.__children.addListener(self._updated)
+ self.notify()
+
+ def _updated(self, source, *args, **kwargs):
+ """Listen for updates"""
+ if source is not self: # Avoid infinite recursion
+ self.notify(*args, **kwargs)
+
+ def _bounds(self, dataBounds=False):
+ """Compute the bounds from transformed children bounds"""
+ bounds = []
+ for child in self._children:
+ if child.visible:
+ childBounds = child.bounds(
+ transformed=True, dataBounds=dataBounds)
+ if childBounds is not None:
+ bounds.append(childBounds)
+
+ if len(bounds) == 0:
+ return None
+ else:
+ bounds = numpy.array(bounds, dtype=numpy.float32)
+ return numpy.array((bounds[:, 0, :].min(axis=0),
+ bounds[:, 1, :].max(axis=0)),
+ dtype=numpy.float32)
+
+ def prepareGL2(self, ctx):
+ pass
+
+ def renderGL2(self, ctx):
+ """Render all children"""
+ for child in self._children:
+ child.render(ctx)
+ for child in reversed(self._children):
+ child.postRender(ctx)
+
+
+class Group(PrivateGroup):
+ """A scene node that renders its (public) children."""
+
+ @property
+ def children(self):
+ """List of children to be rendered."""
+ return self._children
+
+ @children.setter
+ def children(self, iterable):
+ self._children = iterable
diff --git a/silx/gui/plot3d/scene/cutplane.py b/silx/gui/plot3d/scene/cutplane.py
new file mode 100644
index 0000000..79b4168
--- /dev/null
+++ b/silx/gui/plot3d/scene/cutplane.py
@@ -0,0 +1,374 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""A cut plane in a 3D texture: hackish implementation...
+"""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/10/2016"
+
+import string
+import numpy
+
+from ... import _glutils
+from ..._glutils import gl
+
+from .function import Colormap
+from .primitives import Box, Geometry, PlaneInGroup
+from . import transform, utils
+
+
+class ColormapMesh3D(Geometry):
+ """A 3D mesh with color from a 3D texture."""
+
+ _shaders = ("""
+ attribute vec3 position;
+ attribute vec3 normal;
+
+ uniform mat4 matrix;
+ uniform mat4 transformMat;
+ //uniform mat3 matrixInvTranspose;
+ uniform vec3 dataScale;
+
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec3 vNormal;
+ varying vec3 vTexCoords;
+
+ void main(void)
+ {
+ vCameraPosition = transformMat * vec4(position, 1.0);
+ //vNormal = matrixInvTranspose * normalize(normal);
+ vPosition = position;
+ vTexCoords = dataScale * position;
+ vNormal = normal;
+ gl_Position = matrix * vec4(position, 1.0);
+ }
+ """,
+ string.Template("""
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec3 vNormal;
+ varying vec3 vTexCoords;
+ uniform sampler3D data;
+ uniform float alpha;
+
+ $colormapDecl
+
+ $clippingDecl
+ $lightingFunction
+
+ void main(void)
+ {
+ float value = texture3D(data, vTexCoords).r;
+ vec4 color = $colormapCall(value);
+ color.a = alpha;
+
+ $clippingCall(vCameraPosition);
+
+ gl_FragColor = $lightingCall(color, vPosition, vNormal);
+ }
+ """))
+
+ def __init__(self, position, normal, data, copy=True,
+ mode='triangles', indices=None, colormap=None):
+ assert mode in self._TRIANGLE_MODES
+ data = numpy.array(data, copy=copy, order='C')
+ assert data.ndim == 3
+ self._data = data
+ self._texture = None
+ self._update_texture = True
+ self._update_texture_filter = False
+ self._alpha = 1.
+ self._colormap = colormap or Colormap() # Default colormap
+ self._colormap.addListener(self._cmapChanged)
+ self._interpolation = 'linear'
+ super(ColormapMesh3D, self).__init__(mode,
+ indices,
+ position=position,
+ normal=normal)
+
+ self.isBackfaceVisible = True
+
+ def setData(self, data, copy=True):
+ data = numpy.array(data, copy=copy, order='C')
+ assert data.ndim == 3
+ self._data = data
+ self._update_texture = True
+
+ def getData(self, copy=True):
+ return numpy.array(self._data, copy=copy)
+
+ @property
+ def interpolation(self):
+ """The texture interpolation mode: 'linear' or 'nearest'"""
+ return self._interpolation
+
+ @interpolation.setter
+ def interpolation(self, interpolation):
+ assert interpolation in ('linear', 'nearest')
+ self._interpolation = interpolation
+ self._update_texture_filter = True
+ self.notify()
+
+ @property
+ def alpha(self):
+ """Transparency of the plane, float in [0, 1]"""
+ return self._alpha
+
+ @alpha.setter
+ def alpha(self, alpha):
+ self._alpha = float(alpha)
+
+ @property
+ def colormap(self):
+ """The colormap used by this primitive"""
+ return self._colormap
+
+ def _cmapChanged(self, source, *args, **kwargs):
+ """Broadcast colormap changes"""
+ self.notify(*args, **kwargs)
+
+ def prepareGL2(self, ctx):
+ if self._texture is None or self._update_texture:
+ if self._texture is not None:
+ self._texture.discard()
+
+ if self.interpolation == 'nearest':
+ filter_ = gl.GL_NEAREST
+ else:
+ filter_ = gl.GL_LINEAR
+ self._update_texture = False
+ self._update_texture_filter = False
+ self._texture = _glutils.Texture(
+ gl.GL_R32F, self._data, gl.GL_RED,
+ minFilter=filter_,
+ magFilter=filter_,
+ wrap=gl.GL_CLAMP_TO_EDGE)
+
+ if self._update_texture_filter:
+ self._update_texture_filter = False
+ if self.interpolation == 'nearest':
+ filter_ = gl.GL_NEAREST
+ else:
+ filter_ = gl.GL_LINEAR
+ self._texture.minFilter = filter_
+ self._texture.magFilter = filter_
+
+ super(ColormapMesh3D, self).prepareGL2(ctx)
+
+ def renderGL2(self, ctx):
+ fragment = self._shaders[1].substitute(
+ clippingDecl=ctx.clipper.fragDecl,
+ clippingCall=ctx.clipper.fragCall,
+ lightingFunction=ctx.viewport.light.fragmentDef,
+ lightingCall=ctx.viewport.light.fragmentCall,
+ colormapDecl=self.colormap.decl,
+ colormapCall=self.colormap.call
+ )
+ program = ctx.glCtx.prog(self._shaders[0], fragment)
+ program.use()
+
+ ctx.viewport.light.setupProgram(ctx, program)
+ self.colormap.setupProgram(ctx, program)
+
+ if not self.isBackfaceVisible:
+ gl.glCullFace(gl.GL_BACK)
+ gl.glEnable(gl.GL_CULL_FACE)
+
+ program.setUniformMatrix('matrix', ctx.objectToNDC.matrix)
+ program.setUniformMatrix('transformMat',
+ ctx.objectToCamera.matrix,
+ safe=True)
+ gl.glUniform1f(program.uniforms['alpha'], self._alpha)
+
+ shape = self._data.shape
+ scales = 1./shape[2], 1./shape[1], 1./shape[0]
+ gl.glUniform3f(program.uniforms['dataScale'], *scales)
+
+ gl.glUniform1i(program.uniforms['data'], self._texture.texUnit)
+
+ ctx.clipper.setupProgram(ctx, program)
+
+ self._texture.bind()
+ self._draw(program)
+
+ if not self.isBackfaceVisible:
+ gl.glDisable(gl.GL_CULL_FACE)
+
+
+class CutPlane(PlaneInGroup):
+ """A cutting plane in a 3D texture"""
+
+ def __init__(self, point=(0., 0., 0.), normal=(0., 0., 1.)):
+ self._data = None
+ self._mesh = None
+ self._alpha = 1.
+ self._interpolation = 'linear'
+ self._colormap = Colormap()
+ super(CutPlane, self).__init__(point, normal)
+
+ def setData(self, data, copy=True):
+ if data is None:
+ self._data = None
+ if self._mesh is not None:
+ self._children.remove(self._mesh)
+ self._mesh = None
+
+ else:
+ data = numpy.array(data, copy=copy, order='C')
+ assert data.ndim == 3
+ self._data = data
+ if self._mesh is not None:
+ self._mesh.setData(data, copy=False)
+
+ def getData(self, copy=True):
+ return None if self._mesh is None else self._mesh.getData(copy=copy)
+
+ @property
+ def alpha(self):
+ return self._alpha
+
+ @alpha.setter
+ def alpha(self, alpha):
+ self._alpha = float(alpha)
+ if self._mesh is not None:
+ self._mesh.alpha = alpha
+
+ @property
+ def colormap(self):
+ return self._colormap
+
+ @property
+ def interpolation(self):
+ """The texture interpolation mode: 'linear' (default) or 'nearest'"""
+ return self._interpolation
+
+ @interpolation.setter
+ def interpolation(self, interpolation):
+ assert interpolation in ('nearest', 'linear')
+ if interpolation != self.interpolation:
+ self._interpolation = interpolation
+ if self._mesh is not None:
+ self._mesh.interpolation = interpolation
+
+ def prepareGL2(self, ctx):
+ if self.isValid:
+
+ contourVertices = self.contourVertices
+
+ if (self.interpolation == 'nearest' and
+ contourVertices is not None and len(contourVertices)):
+ # Avoid cut plane co-linear with array bin edges
+ for index, normal in enumerate(((1., 0., 0.), (0., 1., 0.), (0., 0., 1.))):
+ if (numpy.all(numpy.equal(self.plane.normal, normal)) and
+ int(self.plane.point[index]) == self.plane.point[index]):
+ contourVertices += self.plane.normal * 0.01 # Add an offset
+ break
+
+ if self._mesh is None and self._data is not None:
+ self._mesh = ColormapMesh3D(contourVertices,
+ normal=self.plane.normal,
+ data=self._data,
+ copy=False,
+ mode='fan',
+ colormap=self.colormap)
+ self._mesh.alpha = self._alpha
+ self._interpolation = self.interpolation
+ self._children.insert(0, self._mesh)
+
+ if self._mesh is not None:
+ if (contourVertices is None or
+ len(contourVertices) == 0):
+ self._mesh.visible = False
+ else:
+ self._mesh.visible = True
+ self._mesh.setAttribute('normal', self.plane.normal)
+ self._mesh.setAttribute('position', contourVertices)
+
+ super(CutPlane, self).prepareGL2(ctx)
+
+ def renderGL2(self, ctx):
+ with self.viewport.light.turnOff():
+ super(CutPlane, self).renderGL2(ctx)
+
+ def _bounds(self, dataBounds=False):
+ if not dataBounds:
+ vertices = self.contourVertices
+ if vertices is not None:
+ return numpy.array(
+ (vertices.min(axis=0), vertices.max(axis=0)),
+ dtype=numpy.float32)
+ else:
+ return None # Plane in not slicing the data volume
+ else:
+ if self._data is None:
+ return None
+ else:
+ depth, height, width = self._data.shape
+ return numpy.array(((0., 0., 0.),
+ (width, height, depth)),
+ dtype=numpy.float32)
+
+ @property
+ def contourVertices(self):
+ """The vertices of the contour of the plane/bounds intersection."""
+ # TODO copy from PlaneInGroup, refactor all that!
+ bounds = self.bounds(dataBounds=True)
+ if bounds is None:
+ return None # No bounds: no vertices
+
+ # Check if cache is valid and return it
+ cachebounds, cachevertices = self._cache
+ if numpy.all(numpy.equal(bounds, cachebounds)):
+ return cachevertices
+
+ # Cache is not OK, rebuild it
+ boxvertices = bounds[0] + Box._vertices.copy()*(bounds[1] - bounds[0])
+ lineindices = Box._lineIndices
+ vertices = utils.boxPlaneIntersect(
+ boxvertices, lineindices, self.plane.normal, self.plane.point)
+
+ self._cache = bounds, vertices if len(vertices) != 0 else None
+
+ return self._cache[1]
+
+ # Render transforms RW, TODO refactor this!
+ @property
+ def transforms(self):
+ return self._transforms
+
+ @transforms.setter
+ def transforms(self, iterable):
+ self._transforms.removeListener(self._transformChanged)
+ if isinstance(iterable, transform.TransformList):
+ # If it is a TransformList, do not create one to enable sharing.
+ self._transforms = iterable
+ else:
+ assert hasattr(iterable, '__iter__')
+ self._transforms = transform.TransformList(iterable)
+ self._transforms.addListener(self._transformChanged)
diff --git a/silx/gui/plot3d/scene/event.py b/silx/gui/plot3d/scene/event.py
new file mode 100644
index 0000000..7b85434
--- /dev/null
+++ b/silx/gui/plot3d/scene/event.py
@@ -0,0 +1,225 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a simple generic notification system."""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import logging
+
+from silx.utils.weakref import WeakList
+
+_logger = logging.getLogger(__name__)
+
+
+# Notifier ####################################################################
+
+class Notifier(object):
+ """Base class for object with notification mechanism."""
+
+ def __init__(self):
+ self._listeners = WeakList()
+
+ def addListener(self, listener):
+ """Register a listener.
+
+ Adding an already registered listener has no effect.
+
+ :param callable listener: The function or method to register.
+ """
+ if listener not in self._listeners:
+ self._listeners.append(listener)
+ else:
+ _logger.warning('Ignoring addition of an already registered listener')
+
+ def removeListener(self, listener):
+ """Remove a previously registered listener.
+
+ :param callable listener: The function or method to unregister.
+ """
+ try:
+ self._listeners.remove(listener)
+ except ValueError:
+ _logger.warn('Trying to remove a listener that is not registered')
+
+ def notify(self, *args, **kwargs):
+ """Notify all registered listeners with the given parameters.
+
+ Listeners are called directly in this method.
+ Listeners are called in the order they were registered.
+ """
+ for listener in self._listeners:
+ listener(self, *args, **kwargs)
+
+
+def notifyProperty(attrName, copy=False, converter=None, doc=None):
+ """Create a property that adds notification to an attribute.
+
+ :param str attrName: The name of the attribute to wrap.
+ :param bool copy: Whether to return a copy of the attribute
+ or not (the default).
+ :param converter: Function converting input value to appropriate type
+ This function takes a single argument and return the
+ converted value.
+ It can be used to perform some asserts.
+ :param str doc: The docstring of the property
+ :return: A property with getter and setter
+ """
+ if copy:
+ def getter(self):
+ return getattr(self, attrName).copy()
+ else:
+ def getter(self):
+ return getattr(self, attrName)
+
+ if converter is None:
+ def setter(self, value):
+ if getattr(self, attrName) != value:
+ setattr(self, attrName, value)
+ self.notify()
+
+ else:
+ def setter(self, value):
+ value = converter(value)
+ if getattr(self, attrName) != value:
+ setattr(self, attrName, value)
+ self.notify()
+
+ return property(getter, setter, doc=doc)
+
+
+class HookList(list):
+ """List with hooks before and after modification."""
+
+ def __init__(self, iterable):
+ super(HookList, self).__init__(iterable)
+
+ self._listWasChangedHook('__init__', iterable)
+
+ def _listWillChangeHook(self, methodName, *args, **kwargs):
+ """To override. Called before modifying the list.
+
+ This method is called with the name of the method called to
+ modify the list and its parameters.
+ """
+ pass
+
+ def _listWasChangedHook(self, methodName, *args, **kwargs):
+ """To override. Called after modifying the list.
+
+ This method is called with the name of the method called to
+ modify the list and its parameters.
+ """
+ pass
+
+ # Wrapping methods that modify the list
+
+ def _wrapper(self, methodName, *args, **kwargs):
+ """Generic wrapper of list methods calling the hooks."""
+ self._listWillChangeHook(methodName, *args, **kwargs)
+ result = getattr(super(HookList, self),
+ methodName)(*args, **kwargs)
+ self._listWasChangedHook(methodName, *args, **kwargs)
+ return result
+
+ # Add methods
+
+ def __iadd__(self, *args, **kwargs):
+ return self._wrapper('__iadd__', *args, **kwargs)
+
+ def __imul__(self, *args, **kwargs):
+ return self._wrapper('__imul__', *args, **kwargs)
+
+ def append(self, *args, **kwargs):
+ return self._wrapper('append', *args, **kwargs)
+
+ def extend(self, *args, **kwargs):
+ return self._wrapper('extend', *args, **kwargs)
+
+ def insert(self, *args, **kwargs):
+ return self._wrapper('insert', *args, **kwargs)
+
+ # Remove methods
+
+ def __delitem__(self, *args, **kwargs):
+ return self._wrapper('__delitem__', *args, **kwargs)
+
+ def __delslice__(self, *args, **kwargs):
+ return self._wrapper('__delslice__', *args, **kwargs)
+
+ def remove(self, *args, **kwargs):
+ return self._wrapper('remove', *args, **kwargs)
+
+ def pop(self, *args, **kwargs):
+ return self._wrapper('pop', *args, **kwargs)
+
+ # Set methods
+
+ def __setitem__(self, *args, **kwargs):
+ return self._wrapper('__setitem__', *args, **kwargs)
+
+ def __setslice__(self, *args, **kwargs):
+ return self._wrapper('__setslice__', *args, **kwargs)
+
+ # In place methods
+
+ def sort(self, *args, **kwargs):
+ return self._wrapper('sort', *args, **kwargs)
+
+ def reverse(self, *args, **kwargs):
+ return self._wrapper('reverse', *args, **kwargs)
+
+
+class NotifierList(HookList, Notifier):
+ """List of Notifiers with notification mechanism.
+
+ This class registers itself as a listener of the list items.
+
+ The default listener method forward notification from list items
+ to the listeners of the list.
+ """
+
+ def __init__(self, iterable=()):
+ Notifier.__init__(self)
+ HookList.__init__(self, iterable)
+
+ def _listWillChangeHook(self, methodName, *args, **kwargs):
+ for item in self:
+ item.removeListener(self._notified)
+
+ def _listWasChangedHook(self, methodName, *args, **kwargs):
+ for item in self:
+ item.addListener(self._notified)
+ self.notify()
+
+ def _notified(self, source, *args, **kwargs):
+ """Default listener forwarding list item changes to its listeners."""
+ # Avoid infinite recursion if the list is listening itself
+ if source is not self:
+ self.notify(*args, **kwargs)
diff --git a/silx/gui/plot3d/scene/function.py b/silx/gui/plot3d/scene/function.py
new file mode 100644
index 0000000..80ac820
--- /dev/null
+++ b/silx/gui/plot3d/scene/function.py
@@ -0,0 +1,471 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides functions to add to shaders."""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "08/11/2016"
+
+
+import contextlib
+import logging
+import numpy
+
+from ..._glutils import gl
+
+from . import event
+from . import utils
+
+
+_logger = logging.getLogger(__name__)
+
+
+class ProgramFunction(object):
+ """Class providing a function to add to a GLProgram shaders.
+ """
+
+ def setupProgram(self, context, program):
+ """Sets-up uniforms of a program using this shader function.
+
+ :param RenderContext context: The current rendering context
+ :param GLProgram program: The program to set-up.
+ It MUST be in use and using this function.
+ """
+ pass
+
+
+class ClippingPlane(ProgramFunction):
+ """Description of a clipping plane and rendering.
+
+ Convention: Clipping is performed in camera/eye space.
+
+ :param point: Local coordinates of a point on the plane.
+ :type point: numpy.ndarray-like of 3 float32
+ :param normal: Local coordinates of the plane normal.
+ :type normal: numpy.ndarray-like of 3 float32
+ """
+
+ _fragDecl = """
+ /* Clipping plane */
+ /* as rx + gy + bz + a > 0, clipping all positive */
+ uniform vec4 planeEq;
+
+ /* Position is in camera/eye coordinates */
+
+ bool isClipped(vec4 position) {
+ vec4 tmp = planeEq * position;
+ float value = tmp.x + tmp.y + tmp.z + planeEq.a;
+ return (value < 0.0001);
+ }
+
+ void clipping(vec4 position) {
+ if (isClipped(position)) {
+ discard;
+ }
+ }
+ /* End of clipping */
+ """
+
+ _fragDeclNoop = """
+ bool isClipped(vec4 position)
+ {
+ return false;
+ }
+
+ void clipping(vec4 position) {}
+ """
+
+ def __init__(self, point=(0., 0., 0.), normal=(0., 0., 0.)):
+ self._plane = utils.Plane(point, normal)
+
+ @property
+ def plane(self):
+ """Plane parameters in camera space."""
+ return self._plane
+
+ # GL2
+
+ @property
+ def fragDecl(self):
+ return self._fragDecl if self.plane.isPlane else self._fragDeclNoop
+
+ @property
+ def fragCall(self):
+ return "clipping"
+
+ def setupProgram(self, context, program):
+ """Sets-up uniforms of a program using this shader function.
+
+ :param RenderContext context: The current rendering context
+ :param GLProgram program: The program to set-up.
+ It MUST be in use and using this function.
+ """
+ if self.plane.isPlane:
+ gl.glUniform4f(program.uniforms['planeEq'], *self.plane.parameters)
+
+
+class DirectionalLight(event.Notifier, ProgramFunction):
+ """Description of a directional Phong light.
+
+ :param direction: The direction of the light or None to disable light
+ :type direction: ndarray of 3 floats or None
+ :param ambient: RGB ambient light
+ :type ambient: ndarray of 3 floats in [0, 1], default: (1., 1., 1.)
+ :param diffuse: RGB diffuse light parameter
+ :type diffuse: ndarray of 3 floats in [0, 1], default: (0., 0., 0.)
+ :param specular: RGB specular light parameter
+ :type specular: ndarray of 3 floats in [0, 1], default: (1., 1., 1.)
+ :param int shininess: The shininess of the material for specular term,
+ default: 0 which disables specular component.
+ """
+
+ fragmentShaderFunction = """
+ /* Lighting */
+ struct DLight {
+ vec3 lightDir; // Direction of light in object space
+ vec3 ambient;
+ vec3 diffuse;
+ vec3 specular;
+ float shininess;
+ vec3 viewPos; // Camera position in object space
+ };
+
+ uniform DLight dLight;
+
+ vec4 lighting(vec4 color, vec3 position, vec3 normal)
+ {
+ normal = normalize(normal);
+ // 1-sided
+ float nDotL = max(0.0, dot(normal, - dLight.lightDir));
+
+ // 2-sided
+ //float nDotL = dot(normal, - dLight.lightDir);
+ //if (nDotL < 0.) {
+ // nDotL = - nDotL;
+ // normal = - normal;
+ //}
+
+ float specFactor = 0.;
+ if (dLight.shininess > 0. && nDotL > 0.) {
+ vec3 reflection = reflect(dLight.lightDir, normal);
+ vec3 viewDir = normalize(dLight.viewPos - position);
+ specFactor = max(0.0, dot(reflection, viewDir));
+ if (specFactor > 0.) {
+ specFactor = pow(specFactor, dLight.shininess);
+ }
+ }
+
+ vec3 enlightedColor = color.rgb * (dLight.ambient +
+ dLight.diffuse * nDotL) +
+ dLight.specular * specFactor;
+
+ return vec4(enlightedColor.rgb, color.a);
+ }
+ /* End of Lighting */
+ """
+
+ fragmentShaderFunctionNoop = """
+ vec4 lighting(vec4 color, vec3 position, vec3 normal)
+ {
+ return color;
+ }
+ """
+
+ def __init__(self, direction=None,
+ ambient=(1., 1., 1.), diffuse=(0., 0., 0.),
+ specular=(1., 1., 1.), shininess=0):
+ super(DirectionalLight, self).__init__()
+ self._direction = None
+ self.direction = direction # Set _direction
+ self._isOn = True
+ self._ambient = ambient
+ self._diffuse = diffuse
+ self._specular = specular
+ self._shininess = shininess
+
+ ambient = event.notifyProperty('_ambient')
+ diffuse = event.notifyProperty('_diffuse')
+ specular = event.notifyProperty('_specular')
+ shininess = event.notifyProperty('_shininess')
+
+ @property
+ def isOn(self):
+ """True if light is on, False otherwise."""
+ return self._isOn and self._direction is not None
+
+ @isOn.setter
+ def isOn(self, isOn):
+ self._isOn = bool(isOn)
+
+ @contextlib.contextmanager
+ def turnOff(self):
+ """Context manager to temporary turn off lighting during rendering.
+
+ >>> with light.turnOff():
+ ... # Do some rendering without lighting
+ """
+ wason = self._isOn
+ self._isOn = False
+ yield
+ self._isOn = wason
+
+ @property
+ def direction(self):
+ """The direction of the light, or None if light is not on."""
+ return self._direction
+
+ @direction.setter
+ def direction(self, direction):
+ if direction is None:
+ self._direction = None
+ else:
+ assert len(direction) == 3
+ direction = numpy.array(direction, dtype=numpy.float32, copy=True)
+ norm = numpy.linalg.norm(direction)
+ assert norm != 0
+ self._direction = direction / norm
+ self.notify()
+
+ # GL2
+
+ @property
+ def fragmentDef(self):
+ """Definition to add to fragment shader"""
+ if self.isOn:
+ return self.fragmentShaderFunction
+ else:
+ return self.fragmentShaderFunctionNoop
+
+ @property
+ def fragmentCall(self):
+ """Function name to call in fragment shader"""
+ return "lighting"
+
+ def setupProgram(self, context, program):
+ """Sets-up uniforms of a program using this shader function.
+
+ :param RenderContext context: The current rendering context
+ :param GLProgram program: The program to set-up.
+ It MUST be in use and using this function.
+ """
+ if self.isOn and self._direction is not None:
+ # Transform light direction from camera space to object coords
+ lightdir = context.objectToCamera.transformDir(
+ self._direction, direct=False)
+ lightdir /= numpy.linalg.norm(lightdir)
+
+ gl.glUniform3f(program.uniforms['dLight.lightDir'], *lightdir)
+
+ # Convert view position to object coords
+ viewpos = context.objectToCamera.transformPoint(
+ numpy.array((0., 0., 0., 1.), dtype=numpy.float32),
+ direct=False,
+ perspectiveDivide=True)[:3]
+ gl.glUniform3f(program.uniforms['dLight.viewPos'], *viewpos)
+
+ gl.glUniform3f(program.uniforms['dLight.ambient'], *self.ambient)
+ gl.glUniform3f(program.uniforms['dLight.diffuse'], *self.diffuse)
+ gl.glUniform3f(program.uniforms['dLight.specular'], *self.specular)
+ gl.glUniform1f(program.uniforms['dLight.shininess'],
+ self.shininess)
+
+
+class Colormap(event.Notifier, ProgramFunction):
+ # TODO use colors for out-of-bound values, for <=0 with log, for nan
+ # TODO texture-based colormap
+
+ decl = """
+ #define CMAP_GRAY 0
+ #define CMAP_R_GRAY 1
+ #define CMAP_RED 2
+ #define CMAP_GREEN 3
+ #define CMAP_BLUE 4
+ #define CMAP_TEMP 5
+
+ uniform struct {
+ int id;
+ bool isLog;
+ float min;
+ float oneOverRange;
+ } cmap;
+
+ const float oneOverLog10 = 0.43429448190325176;
+
+ vec4 colormap(float value) {
+ if (cmap.isLog) { /* Log10 mapping */
+ if (value > 0.0) {
+ value = clamp(cmap.oneOverRange *
+ (oneOverLog10 * log(value) - cmap.min),
+ 0.0, 1.0);
+ } else {
+ value = 0.0;
+ }
+ } else { /* Linear mapping */
+ value = clamp(cmap.oneOverRange * (value - cmap.min), 0.0, 1.0);
+ }
+
+ if (cmap.id == CMAP_GRAY) {
+ return vec4(value, value, value, 1.0);
+ }
+ else if (cmap.id == CMAP_R_GRAY) {
+ float invValue = 1.0 - value;
+ return vec4(invValue, invValue, invValue, 1.0);
+ }
+ else if (cmap.id == CMAP_RED) {
+ return vec4(value, 0.0, 0.0, 1.0);
+ }
+ else if (cmap.id == CMAP_GREEN) {
+ return vec4(0.0, value, 0.0, 1.0);
+ }
+ else if (cmap.id == CMAP_BLUE) {
+ return vec4(0.0, 0.0, value, 1.0);
+ }
+ else if (cmap.id == CMAP_TEMP) {
+ //red: 0.5->0.75: 0->1
+ //green: 0.->0.25: 0->1; 0.75->1.: 1->0
+ //blue: 0.25->0.5: 1->0
+ return vec4(
+ clamp(4.0 * value - 2.0, 0.0, 1.0),
+ 1.0 - clamp(4.0 * abs(value - 0.5) - 1.0, 0.0, 1.0),
+ 1.0 - clamp(4.0 * value - 1.0, 0.0, 1.0),
+ 1.0);
+ }
+ else {
+ /* Unknown colormap */
+ return vec4(0.0, 0.0, 0.0, 1.0);
+ }
+ }
+ """
+
+ call = "colormap"
+
+ _COLORMAPS = {
+ 'gray': 0,
+ 'reversed gray': 1,
+ 'red': 2,
+ 'green': 3,
+ 'blue': 4,
+ 'temperature': 5
+ }
+
+ COLORMAPS = tuple(_COLORMAPS.keys())
+ """Tuple of supported colormap names."""
+
+ NORMS = 'linear', 'log'
+ """Tuple of supported normalizations."""
+
+ def __init__(self, name='gray', norm='linear', range_=(1., 10.)):
+ """Shader function to apply a colormap to a value.
+
+ :param str name: Name of the colormap.
+ :param str norm: Normalization to apply: 'linear' (default) or 'log'.
+ :param range_: Range of value to map to the colormap.
+ :type range_: 2-tuple of float (begin, end).
+ """
+ super(Colormap, self).__init__()
+
+ # Init privates to default
+ self._name, self._norm, self._range = 'gray', 'linear', (1., 10.)
+
+ # Set to param values through properties to go through asserts
+ self.name = name
+ self.norm = norm
+ self.range_ = range_
+
+ @property
+ def name(self):
+ """Name of the colormap in use."""
+ return self._name
+
+ @name.setter
+ def name(self, name):
+ if name != self._name:
+ assert name in self.COLORMAPS
+ self._name = name
+ self.notify()
+
+ @property
+ def norm(self):
+ """Normalization to use for colormap mapping.
+
+ Either 'linear' (the default) or 'log' for log10 mapping.
+ With 'log' normalization, values <= 0. are set to 1. (i.e. log == 0)
+ """
+ return self._norm
+
+ @norm.setter
+ def norm(self, norm):
+ if norm != self._norm:
+ assert norm in self.NORMS
+ self._norm = norm
+ if norm == 'log':
+ self.range_ = self.range_ # To test for positive range_
+ self.notify()
+
+ @property
+ def range_(self):
+ """Range of values to map to the colormap.
+
+ 2-tuple of floats: (begin, end).
+ The begin value is mapped to the origin of the colormap and the
+ end value is mapped to the other end of the colormap.
+ The colormap is reversed if begin > end.
+ """
+ return self._range
+
+ @range_.setter
+ def range_(self, range_):
+ assert len(range_) == 2
+ range_ = float(range_[0]), float(range_[1])
+
+ if self.norm == 'log' and (range_[0] <= 0. or range_[1] <= 0.):
+ _logger.warn(
+ "Log normalization and negative range: updating range.")
+ minPos = numpy.finfo(numpy.float32).tiny
+ range_ = max(range_[0], minPos), max(range_[1], minPos)
+
+ if range_ != self._range:
+ self._range = range_
+ self.notify()
+
+ def setupProgram(self, context, program):
+ """Sets-up uniforms of a program using this shader function.
+
+ :param RenderContext context: The current rendering context
+ :param GLProgram program: The program to set-up.
+ It MUST be in use and using this function.
+ """
+ gl.glUniform1i(program.uniforms['cmap.id'], self._COLORMAPS[self.name])
+ gl.glUniform1i(program.uniforms['cmap.isLog'], self._norm == 'log')
+
+ min_, max_ = self.range_
+ if self._norm == 'log':
+ min_, max_ = numpy.log10(min_), numpy.log10(max_)
+
+ gl.glUniform1f(program.uniforms['cmap.min'], min_)
+ gl.glUniform1f(program.uniforms['cmap.oneOverRange'],
+ (1. / (max_ - min_)) if max_ != min_ else 0.)
diff --git a/silx/gui/plot3d/scene/interaction.py b/silx/gui/plot3d/scene/interaction.py
new file mode 100644
index 0000000..68bfc13
--- /dev/null
+++ b/silx/gui/plot3d/scene/interaction.py
@@ -0,0 +1,652 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides interaction to plug on the scene graph."""
+
+from __future__ import absolute_import
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+import logging
+import numpy
+
+from silx.gui.plot.Interaction import \
+ StateMachine, State, LEFT_BTN, RIGHT_BTN # , MIDDLE_BTN
+
+from . import transform
+
+
+_logger = logging.getLogger(__name__)
+
+
+# ClickOrDrag #################################################################
+
+# TODO merge with silx.gui.plot.Interaction.ClickOrDrag
+class ClickOrDrag(StateMachine):
+ """Click or drag interaction for a given button."""
+
+ DRAG_THRESHOLD_SQUARE_DIST = 5 ** 2
+
+ class Idle(State):
+ def onPress(self, x, y, btn):
+ if btn == self.machine.button:
+ self.goto('clickOrDrag', x, y)
+ return True
+
+ class ClickOrDrag(State):
+ def enterState(self, x, y):
+ self.initPos = x, y
+
+ enter = enterState # silx v.0.3 support, remove when 0.4 out
+
+ def onMove(self, x, y):
+ dx = (x - self.initPos[0]) ** 2
+ dy = (y - self.initPos[1]) ** 2
+ if (dx ** 2 + dy ** 2) >= self.machine.DRAG_THRESHOLD_SQUARE_DIST:
+ self.goto('drag', self.initPos, (x, y))
+
+ def onRelease(self, x, y, btn):
+ if btn == self.machine.button:
+ self.machine.click(x, y)
+ self.goto('idle')
+
+ class Drag(State):
+ def enterState(self, initPos, curPos):
+ self.initPos = initPos
+ self.machine.beginDrag(*initPos)
+ self.machine.drag(*curPos)
+
+ enter = enterState # silx v.0.3 support, remove when 0.4 out
+
+ def onMove(self, x, y):
+ self.machine.drag(x, y)
+
+ def onRelease(self, x, y, btn):
+ if btn == self.machine.button:
+ self.machine.endDrag(self.initPos, (x, y))
+ self.goto('idle')
+
+ def __init__(self, button=LEFT_BTN):
+ self.button = button
+ states = {
+ 'idle': ClickOrDrag.Idle,
+ 'clickOrDrag': ClickOrDrag.ClickOrDrag,
+ 'drag': ClickOrDrag.Drag
+ }
+ super(ClickOrDrag, self).__init__(states, 'idle')
+
+ def click(self, x, y):
+ """Called upon a left or right button click.
+ To override in a subclass.
+ """
+ pass
+
+ def beginDrag(self, x, y):
+ """Called at the beginning of a drag gesture with left button
+ pressed.
+ To override in a subclass.
+ """
+ pass
+
+ def drag(self, x, y):
+ """Called on mouse moved during a drag gesture.
+ To override in a subclass.
+ """
+ pass
+
+ def endDrag(self, x, y):
+ """Called at the end of a drag gesture when the left button is
+ released.
+ To override in a subclass.
+ """
+ pass
+
+
+# CameraRotate ################################################################
+
+class CameraRotate(ClickOrDrag):
+ """Camera rotation using an arcball-like interaction."""
+
+ def __init__(self, viewport, orbitAroundCenter=True, button=RIGHT_BTN):
+ self._viewport = viewport
+ self._orbitAroundCenter = orbitAroundCenter
+ self._reset()
+ super(CameraRotate, self).__init__(button)
+
+ def _reset(self):
+ self._origin, self._center = None, None
+ self._startExtrinsic = None
+
+ def click(self, x, y):
+ pass # No interaction yet
+
+ def beginDrag(self, x, y):
+ centerPos = None
+ if not self._orbitAroundCenter:
+ # Try to use picked object position as center of rotation
+ ndcZ = self._viewport._pickNdcZGL(x, y)
+ if ndcZ != 1.:
+ # Hit an object, use picked point as center
+ centerPos = self._viewport._getXZYGL(x, y) # Can return None
+
+ if centerPos is None:
+ # Not using picked position, use scene center
+ bounds = self._viewport.scene.bounds(transformed=True)
+ centerPos = 0.5 * (bounds[0] + bounds[1])
+
+ self._center = transform.Translate(*centerPos)
+ self._origin = x, y
+ self._startExtrinsic = self._viewport.camera.extrinsic.copy()
+
+ def drag(self, x, y):
+ if self._center is None:
+ return
+
+ dx, dy = self._origin[0] - x, self._origin[1] - y
+
+ if dx == 0 and dy == 0:
+ direction = self._startExtrinsic.direction
+ up = self._startExtrinsic.up
+ position = self._startExtrinsic.position
+ else:
+ minsize = min(self._viewport.size)
+ distance = numpy.sqrt(dx ** 2 + dy ** 2)
+ angle = distance / minsize * numpy.pi
+
+ # Take care of y inversion
+ direction = dx * self._startExtrinsic.side - \
+ dy * self._startExtrinsic.up
+ direction /= numpy.linalg.norm(direction)
+ axis = numpy.cross(direction, self._startExtrinsic.direction)
+ axis /= numpy.linalg.norm(axis)
+
+ # Orbit start camera with current angle and axis
+ # Rotate viewing direction
+ rotation = transform.Rotate(numpy.degrees(angle), *axis)
+ direction = rotation.transformDir(self._startExtrinsic.direction)
+ up = rotation.transformDir(self._startExtrinsic.up)
+
+ # Rotate position around center
+ trlist = transform.StaticTransformList((
+ self._center,
+ rotation,
+ self._center.inverse()))
+ position = trlist.transformPoint(self._startExtrinsic.position)
+
+ camerapos = self._viewport.camera.extrinsic
+ camerapos.setOrientation(direction, up)
+ camerapos.position = position
+
+ def endDrag(self, x, y):
+ self._reset()
+
+
+# CameraSelectPan #############################################################
+
+class CameraSelectPan(ClickOrDrag):
+ """Picking on click and pan camera on drag."""
+
+ def __init__(self, viewport, button=LEFT_BTN, selectCB=None):
+ self._viewport = viewport
+ self._selectCB = selectCB
+ self._lastPosNdc = None
+ super(CameraSelectPan, self).__init__(button)
+
+ def click(self, x, y):
+ if self._selectCB is not None:
+ ndcZ = self._viewport._pickNdcZGL(x, y)
+ position = self._viewport._getXZYGL(x, y)
+ # This assume no object lie on the far plane
+ # Alternative, change the depth range so that far is < 1
+ if ndcZ != 1. and position is not None:
+ self._selectCB((x, y, ndcZ), position)
+
+ def beginDrag(self, x, y):
+ ndc = self._viewport.windowToNdc(x, y)
+ ndcZ = self._viewport._pickNdcZGL(x, y)
+ # ndcZ is the panning plane
+ if ndc is not None and ndcZ is not None:
+ self._lastPosNdc = numpy.array((ndc[0], ndc[1], ndcZ, 1.),
+ dtype=numpy.float32)
+ else:
+ self._lastPosNdc = None
+
+ def drag(self, x, y):
+ if self._lastPosNdc is not None:
+ ndc = self._viewport.windowToNdc(x, y)
+ if ndc is not None:
+ ndcPos = numpy.array((ndc[0], ndc[1], self._lastPosNdc[2], 1.),
+ dtype=numpy.float32)
+
+ # Convert last and current NDC positions to scene coords
+ scenePos = self._viewport.camera.transformPoint(
+ ndcPos, direct=False, perspectiveDivide=True)
+ lastScenePos = self._viewport.camera.transformPoint(
+ self._lastPosNdc, direct=False, perspectiveDivide=True)
+
+ # Get translation in scene coords
+ translation = scenePos[:3] - lastScenePos[:3]
+ self._viewport.camera.extrinsic.position -= translation
+
+ # Store for next drag
+ self._lastPosNdc = ndcPos
+
+ def endDrag(self, x, y):
+ self._lastPosNdc = None
+
+
+# CameraWheel #################################################################
+
+class CameraWheel(object):
+ """StateMachine like class, just handling wheel events."""
+
+ # TODO choose scale of motion? Translation or Scale?
+ def __init__(self, viewport, mode='center', scaleTransform=None):
+ assert mode in ('center', 'position', 'scale')
+ self._viewport = viewport
+ if mode == 'center':
+ self._zoomTo = self._zoomToCenter
+ elif mode == 'position':
+ self._zoomTo = self._zoomToPosition
+ elif mode == 'scale':
+ self._zoomTo = self._zoomByScale
+ self._scale = scaleTransform
+ else:
+ raise ValueError('Unsupported mode: %s' % mode)
+
+ def handleEvent(self, eventName, *args, **kwargs):
+ if eventName == 'wheel':
+ return self._zoomTo(*args, **kwargs)
+
+ def _zoomToCenter(self, x, y, angleInDegrees):
+ """Zoom to center of display.
+
+ Only works with perspective camera.
+ """
+ direction = 'forward' if angleInDegrees > 0 else 'backward'
+ self._viewport.camera.move(direction)
+ return True
+
+ def _zoomToPositionAbsolute(self, x, y, angleInDegrees):
+ """Zoom while keeping pixel under mouse invariant.
+
+ Only works with perspective camera.
+ """
+ ndc = self._viewport.windowToNdc(x, y)
+ if ndc is not None:
+ near = numpy.array((ndc[0], ndc[1], -1., 1.), dtype=numpy.float32)
+
+ nearscene = self._viewport.camera.transformPoint(
+ near, direct=False, perspectiveDivide=True)
+
+ far = numpy.array((ndc[0], ndc[1], 1., 1.), dtype=numpy.float32)
+ farscene = self._viewport.camera.transformPoint(
+ far, direct=False, perspectiveDivide=True)
+
+ dirscene = farscene[:3] - nearscene[:3]
+ dirscene /= numpy.linalg.norm(dirscene)
+
+ if angleInDegrees < 0:
+ dirscene *= -1.
+
+ # TODO which scale
+ self._viewport.camera.extrinsic.position += dirscene
+ return True
+
+ def _zoomToPosition(self, x, y, angleInDegrees):
+ """Zoom while keeping pixel under mouse invariant."""
+ projection = self._viewport.camera.intrinsic
+ extrinsic = self._viewport.camera.extrinsic
+
+ if isinstance(projection, transform.Perspective):
+ # For perspective projection, move camera
+ ndc = self._viewport.windowToNdc(x, y)
+ if ndc is not None:
+ ndcz = self._viewport._pickNdcZGL(x, y)
+
+ position = numpy.array((ndc[0], ndc[1], ndcz),
+ dtype=numpy.float32)
+ positionscene = self._viewport.camera.transformPoint(
+ position, direct=False, perspectiveDivide=True)
+
+ camtopos = extrinsic.position - positionscene
+
+ step = 0.2 * (1. if angleInDegrees < 0 else -1.)
+ extrinsic.position += step * camtopos
+
+ elif isinstance(projection, transform.Orthographic):
+ # For orthographic projection, change projection borders
+ ndcx, ndcy = self._viewport.windowToNdc(x, y, checkInside=False)
+
+ step = 0.2 * (1. if angleInDegrees < 0 else -1.)
+
+ dx = (ndcx + 1) / 2.
+ stepwidth = step * (projection.right - projection.left)
+ left = projection.left - dx * stepwidth
+ right = projection.right + (1. - dx) * stepwidth
+
+ dy = (ndcy + 1) / 2.
+ stepheight = step * (projection.top - projection.bottom)
+ bottom = projection.bottom - dy * stepheight
+ top = projection.top + (1. - dy) * stepheight
+
+ projection.setClipping(left, right, bottom, top)
+
+ else:
+ raise RuntimeError('Unsupported camera', projection)
+ return True
+
+ def _zoomByScale(self, x, y, angleInDegrees):
+ """Zoom by scaling scene (do not keep pixel under mouse invariant)."""
+ scalefactor = 1.1
+ if angleInDegrees < 0.:
+ scalefactor = 1. / scalefactor
+ self._scale.scale = scalefactor * self._scale.scale
+
+ self._viewport.adjustCameraDepthExtent()
+ return True
+
+
+# FocusManager ################################################################
+
+class FocusManager(StateMachine):
+ """Manages focus across multiple event handlers
+
+ On press an event handler can acquire focus.
+ By default it looses focus when all buttons are released.
+ """
+ class Idle(State):
+ def onPress(self, x, y, btn):
+ for eventHandler in self.machine.eventHandlers:
+ requestfocus = eventHandler.handleEvent('press', x, y, btn)
+ if requestfocus:
+ self.goto('focus', eventHandler, btn)
+ break
+
+ def _processEvent(self, *args):
+ for eventHandler in self.machine.eventHandlers:
+ consumeevent = eventHandler.handleEvent(*args)
+ if consumeevent:
+ break
+
+ def onMove(self, x, y):
+ self._processEvent('move', x, y)
+
+ def onRelease(self, x, y, btn):
+ self._processEvent('release', x, y, btn)
+
+ def onWheel(self, x, y, angle):
+ self._processEvent('wheel', x, y, angle)
+
+ class Focus(State):
+ def enterState(self, eventHandler, btn):
+ self.eventHandler = eventHandler
+ self.focusBtns = {btn} # Set
+
+ enter = enterState # silx v.0.3 support, remove when 0.4 out
+
+ def onPress(self, x, y, btn):
+ self.focusBtns.add(btn)
+ self.eventHandler.handleEvent('press', x, y, btn)
+
+ def onMove(self, x, y):
+ self.eventHandler.handleEvent('move', x, y)
+
+ def onRelease(self, x, y, btn):
+ self.focusBtns.discard(btn)
+ requestfocus = self.eventHandler.handleEvent('release', x, y, btn)
+ if len(self.focusBtns) == 0 and not requestfocus:
+ self.goto('idle')
+
+ def onWheel(self, x, y, angleInDegrees):
+ self.eventHandler.handleEvent('wheel', x, y, angleInDegrees)
+
+ def __init__(self, eventHandlers=()):
+ self.eventHandlers = list(eventHandlers)
+
+ states = {
+ 'idle': FocusManager.Idle,
+ 'focus': FocusManager.Focus
+ }
+ super(FocusManager, self).__init__(states, 'idle')
+
+ def cancel(self):
+ for handler in self.eventHandlers:
+ handler.cancel()
+
+
+# CameraControl ###############################################################
+
+class CameraControl(FocusManager):
+ """Combine wheel, selectPan and rotate state machine."""
+ def __init__(self, viewport,
+ orbitAroundCenter=False,
+ mode='center', scaleTransform=None,
+ selectCB=None):
+ handlers = (CameraWheel(viewport, mode, scaleTransform),
+ CameraSelectPan(viewport, LEFT_BTN, selectCB),
+ CameraRotate(viewport, orbitAroundCenter, RIGHT_BTN))
+ super(CameraControl, self).__init__(handlers)
+
+
+# PlaneRotate #################################################################
+
+class PlaneRotate(ClickOrDrag):
+ """Plane rotation using arcball interaction.
+
+ Arcball ref.:
+ Ken Shoemake. ARCBALL: A user interface for specifying three-dimensional
+ orientation using a mouse. In Proc. GI '92. (1992). pp. 151-156.
+ """
+
+ def __init__(self, viewport, plane, button=RIGHT_BTN):
+ self._viewport = viewport
+ self._plane = plane
+ self._reset()
+ super(PlaneRotate, self).__init__(button)
+
+ def _reset(self):
+ self._beginNormal, self._beginCenter = None, None
+
+ def click(self, x, y):
+ pass # No interaction
+
+ @staticmethod
+ def _sphereUnitVector(radius, center, position):
+ """Returns the unit vector of the projection of position on a sphere.
+
+ It assumes an orthographic projection.
+ For perspective projection, it gives an approximation, but it
+ simplifies computations and results in consistent arcball control
+ in control space.
+
+ All parameters must be in screen coordinate system
+ (either pixels or normalized coordinates).
+
+ :param float radius: The radius of the sphere.
+ :param center: (x, y) coordinates of the center.
+ :param position: (x, y) coordinates of the cursor position.
+ :return: Unit vector.
+ :rtype: numpy.ndarray of 3 floats.
+ """
+ center, position = numpy.array(center), numpy.array(position)
+
+ # Normalize x and y on a unit circle
+ spherecoords = (position - center) / float(radius)
+ squarelength = numpy.sum(spherecoords ** 2)
+
+ # Project on the unit sphere and compute z coordinates
+ if squarelength > 1.0: # Outside sphere: project
+ spherecoords /= numpy.sqrt(squarelength)
+ zsphere = 0.0
+ else: # In sphere: compute z
+ zsphere = numpy.sqrt(1. - squarelength)
+
+ spherecoords = numpy.append(spherecoords, zsphere)
+ return spherecoords
+
+ def beginDrag(self, x, y):
+ # Makes sure the point defining the plane is at the center as
+ # it will be the center of rotation (as rotation is applied to normal)
+ self._plane.plane.point = self._plane.center
+
+ # Store the plane normal
+ self._beginNormal = self._plane.plane.normal
+
+ _logger.debug(
+ 'Begin arcball, plane center %s', str(self._plane.center))
+
+ # Do the arcball on the screen
+ radius = min(self._viewport.size)
+ if self._plane.center is None:
+ self._beginCenter = None
+
+ else:
+ center = self._plane.objectToNDCTransform.transformPoint(
+ self._plane.center, perspectiveDivide=True)
+ self._beginCenter = self._viewport.ndcToWindow(
+ center[0], center[1], checkInside=False)
+
+ self._startVector = self._sphereUnitVector(
+ radius, self._beginCenter, (x, y))
+
+ def drag(self, x, y):
+ if self._beginCenter is None:
+ return
+
+ # Compute rotation: this is twice the rotation of the arcball
+ radius = min(self._viewport.size)
+ currentvector = self._sphereUnitVector(
+ radius, self._beginCenter, (x, y))
+ crossprod = numpy.cross(self._startVector, currentvector)
+ dotprod = numpy.dot(self._startVector, currentvector)
+
+ quaternion = numpy.append(crossprod, dotprod)
+ # Rotation was computed with Y downward, but apply in NDC, invert Y
+ quaternion[1] *= -1.
+
+ rotation = transform.Rotate()
+ rotation.quaternion = quaternion
+
+ # Convert to NDC, rotate, convert back to object
+ normal = self._plane.objectToNDCTransform.transformNormal(
+ self._beginNormal)
+ normal = rotation.transformNormal(normal)
+ normal = self._plane.objectToNDCTransform.transformNormal(
+ normal, direct=False)
+ self._plane.plane.normal = normal
+
+ def endDrag(self, x, y):
+ self._reset()
+
+
+# PlanePan ###################################################################
+
+class PlanePan(ClickOrDrag):
+ """Pan a plane along its normal on drag."""
+
+ def __init__(self, viewport, plane, button=LEFT_BTN):
+ self._plane = plane
+ self._viewport = viewport
+ self._beginPlanePoint = None
+ self._beginPos = None
+ self._dragNdcZ = 0.
+ super(PlanePan, self).__init__(button)
+
+ def click(self, x, y):
+ pass
+
+ def beginDrag(self, x, y):
+ ndc = self._viewport.windowToNdc(x, y)
+ ndcZ = self._viewport._pickNdcZGL(x, y)
+ # ndcZ is the panning plane
+ if ndc is not None and ndcZ is not None:
+ ndcPos = numpy.array((ndc[0], ndc[1], ndcZ, 1.),
+ dtype=numpy.float32)
+ scenePos = self._viewport.camera.transformPoint(
+ ndcPos, direct=False, perspectiveDivide=True)
+ self._beginPos = self._plane.objectToSceneTransform.transformPoint(
+ scenePos, direct=False)
+ self._dragNdcZ = ndcZ
+ else:
+ self._beginPos = None
+ self._dragNdcZ = 0.
+
+ self._beginPlanePoint = self._plane.plane.point
+
+ def drag(self, x, y):
+ if self._beginPos is not None:
+ ndc = self._viewport.windowToNdc(x, y)
+ if ndc is not None:
+ ndcPos = numpy.array((ndc[0], ndc[1], self._dragNdcZ, 1.),
+ dtype=numpy.float32)
+
+ # Convert last and current NDC positions to scene coords
+ scenePos = self._viewport.camera.transformPoint(
+ ndcPos, direct=False, perspectiveDivide=True)
+ curPos = self._plane.objectToSceneTransform.transformPoint(
+ scenePos, direct=False)
+
+ # Get translation in scene coords
+ translation = curPos[:3] - self._beginPos[:3]
+
+ newPoint = self._beginPlanePoint + translation
+
+ # Keep plane point in bounds
+ bounds = self._plane.parent.bounds(dataBounds=True)
+ if bounds is not None:
+ newPoint = numpy.clip(
+ newPoint, a_min=bounds[0], a_max=bounds[1])
+
+ # Only update plane if it is in some bounds
+ self._plane.plane.point = newPoint
+
+ def endDrag(self, x, y):
+ self._beginPlanePoint = None
+
+
+# PlaneControl ################################################################
+
+class PlaneControl(FocusManager):
+ """Combine wheel, selectPan and rotate state machine for plane control."""
+ def __init__(self, viewport, plane,
+ mode='center', scaleTransform=None):
+ handlers = (CameraWheel(viewport, mode, scaleTransform),
+ PlanePan(viewport, plane, LEFT_BTN),
+ PlaneRotate(viewport, plane, RIGHT_BTN))
+ super(PlaneControl, self).__init__(handlers)
+
+
+class PanPlaneRotateCameraControl(FocusManager):
+ """Combine wheel, pan plane and camera rotate state machine."""
+ def __init__(self, viewport, plane,
+ mode='center', scaleTransform=None):
+ handlers = (CameraWheel(viewport, mode, scaleTransform),
+ PlanePan(viewport, plane, LEFT_BTN),
+ CameraRotate(viewport,
+ orbitAroundCenter=False,
+ button=RIGHT_BTN))
+ super(PanPlaneRotateCameraControl, self).__init__(handlers)
diff --git a/silx/gui/plot3d/scene/primitives.py b/silx/gui/plot3d/scene/primitives.py
new file mode 100644
index 0000000..ca2616a
--- /dev/null
+++ b/silx/gui/plot3d/scene/primitives.py
@@ -0,0 +1,1764 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import collections
+import ctypes
+from functools import reduce
+import logging
+import string
+
+import numpy
+
+from silx.gui.plot.Colors import rgba
+
+from ... import _glutils
+from ..._glutils import gl
+
+from . import event
+from . import core
+from . import transform
+from . import utils
+
+_logger = logging.getLogger(__name__)
+
+
+# Geometry ####################################################################
+
+class Geometry(core.Elem):
+ """Set of vertices with normals and colors.
+
+ :param str mode: OpenGL drawing mode:
+ lines, line_strip, loop, triangles, triangle_strip, fan
+ :param indices: Array of vertex indices or None
+ :param bool copy: True (default) to copy the data, False to use as is.
+ :param attributes: Provide list of attributes as extra parameters.
+ """
+
+ _ATTR_INFO = {
+ 'position': {'dims': (1, 2), 'lastDim': (2, 3, 4)},
+ 'normal': {'dims': (1, 2), 'lastDim': (3,)},
+ 'color': {'dims': (1, 2), 'lastDim': (3, 4)},
+ }
+
+ _MODE_CHECKS = { # Min, Modulo
+ 'lines': (2, 2), 'line_strip': (2, 0), 'loop': (2, 0),
+ 'points': (1, 0),
+ 'triangles': (3, 3), 'triangle_strip': (3, 0), 'fan': (3, 0)
+ }
+
+ _MODES = {
+ 'lines': gl.GL_LINES,
+ 'line_strip': gl.GL_LINE_STRIP,
+ 'loop': gl.GL_LINE_LOOP,
+
+ 'points': gl.GL_POINTS,
+
+ 'triangles': gl.GL_TRIANGLES,
+ 'triangle_strip': gl.GL_TRIANGLE_STRIP,
+ 'fan': gl.GL_TRIANGLE_FAN
+ }
+
+ _LINE_MODES = 'lines', 'line_strip', 'loop'
+
+ _TRIANGLE_MODES = 'triangles', 'triangle_strip', 'fan'
+
+ def __init__(self, mode, indices=None, copy=True, **attributes):
+ super(Geometry, self).__init__()
+
+ self._vbos = {} # Store current vbos
+ self._unsyncAttributes = [] # Store attributes to copy to vbos
+ self.__bounds = None # Cache object's bounds
+
+ assert mode in self._MODES
+ self._mode = mode
+
+ # Set attributes
+ self._attributes = {}
+ for name, data in attributes.items():
+ self.setAttribute(name, data, copy=copy)
+
+ # Set indices
+ self._indices = None
+ self.setIndices(indices, copy=copy)
+
+ # More consistency checks
+ mincheck, modulocheck = self._MODE_CHECKS[self._mode]
+ if self._indices is not None:
+ nbvertices = len(self._indices)
+ else:
+ nbvertices = self.nbVertices
+ assert nbvertices >= mincheck
+ if modulocheck != 0:
+ assert (nbvertices % modulocheck) == 0
+
+ @staticmethod
+ def _glReadyArray(array, copy=True):
+ """Making a contiguous array, checking float types.
+
+ :param iterable array: array-like data to prepare for attribute
+ :param bool copy: True to make a copy of the array, False to use as is
+ """
+ # Convert single value (int, float, numpy types) to tuple
+ if not isinstance(array, collections.Iterable):
+ array = (array, )
+
+ # Makes sure it is an array
+ array = numpy.array(array, copy=False)
+
+ # Cast all float to float32
+ dtype = None
+ if numpy.dtype(array.dtype).kind == 'f':
+ dtype = numpy.float32
+
+ return numpy.array(array, dtype=dtype, order='C', copy=copy)
+
+ @property
+ def nbVertices(self):
+ """Returns the number of vertices of current attributes.
+
+ It returns None if there is no attributes.
+ """
+ for array in self._attributes.values():
+ if len(array.shape) == 2:
+ return len(array)
+ return None
+
+ def setAttribute(self, name, array, copy=True):
+ """Set attribute with provided array.
+
+ :param str name: The name of the attribute
+ :param array: Array-like attribute data or None to remove attribute
+ :param bool copy: True (default) to copy the data, False to use as is
+ """
+ # This triggers associated GL resources to be garbage collected
+ self._vbos.pop(name, None)
+
+ if array is None:
+ self._attributes.pop(name, None)
+
+ else:
+ array = self._glReadyArray(array, copy=copy)
+
+ if name not in self._ATTR_INFO:
+ _logger.info('Not checking attibute %s dimensions', name)
+ else:
+ checks = self._ATTR_INFO[name]
+
+ if (len(array.shape) == 1 and checks['lastDim'] == (1,) and
+ len(array) > 1):
+ array = array.reshape((len(array), 1))
+
+ # Checks
+ assert len(array.shape) in checks['dims'], "Attr %s" % name
+ assert array.shape[-1] in checks['lastDim'], "Attr %s" % name
+
+ # Check length against another attribute array
+ # Causes problems when updating
+ # nbVertices = self.nbVertices
+ # if len(array.shape) == 2 and nbVertices is not None:
+ # assert len(array) == nbVertices
+
+ self._attributes[name] = array
+ if len(array.shape) == 2: # Store this in a VBO
+ self._unsyncAttributes.append(name)
+
+ if name == 'position': # Reset bounds
+ self.__bounds = None
+
+ self.notify()
+
+ def getAttribute(self, name, copy=True):
+ """Returns the numpy.ndarray corresponding to the name attribute.
+
+ :param str name: The name of the attribute to get.
+ :param bool copy: True to get a copy (default),
+ False to get internal array (DO NOT MODIFY)
+ :return: The corresponding array or None if no corresponding attribute.
+ :rtype: numpy.ndarray
+ """
+ attr = self._attributes.get(name, None)
+ return None if attr is None else numpy.array(attr, copy=copy)
+
+ def useAttribute(self, program, name=None):
+ """Enable and bind attribute(s) for a specific program.
+
+ This MUST be called with OpenGL context active and after prepareGL2
+ has been called.
+
+ :param GLProgram program: The program for which to set the attributes
+ :param str name: The attribute name to set or None to set then all
+ """
+ if name is None:
+ for name in program.attributes:
+ self.useAttribute(program, name)
+
+ else:
+ attribute = program.attributes.get(name)
+ if attribute is None:
+ return
+
+ vboattrib = self._vbos.get(name)
+ if vboattrib is not None:
+ gl.glEnableVertexAttribArray(attribute)
+ vboattrib.setVertexAttrib(attribute)
+
+ elif name not in self._attributes:
+ gl.glDisableVertexAttribArray(attribute)
+
+ else:
+ array = self._attributes[name]
+ assert array is not None
+
+ if len(array.shape) == 1:
+ assert len(array) in (1, 2, 3, 4)
+ gl.glDisableVertexAttribArray(attribute)
+ _glVertexAttribFunc = getattr(
+ _glutils.gl, 'glVertexAttrib{}f'.format(len(array)))
+ _glVertexAttribFunc(attribute, *array)
+ else:
+ # TODO As is this is a never event, remove?
+ gl.glEnableVertexAttribArray(attribute)
+ gl.glVertexAttribPointer(
+ attribute,
+ array.shape[-1],
+ _glutils.numpyToGLType(array.dtype),
+ gl.GL_FALSE,
+ 0,
+ array)
+
+ def setIndices(self, indices, copy=True):
+ """Set the primitive indices to use.
+
+ :param indices: Array-like of uint primitive indices or None to unset
+ :param bool copy: True (default) to copy the data, False to use as is
+ """
+ # Trigger garbage collection of previous indices VBO if any
+ self._vbos.pop('__indices__', None)
+
+ if indices is None:
+ self._indices = None
+ else:
+ indices = self._glReadyArray(indices, copy=copy).ravel()
+ assert indices.dtype.name in ('uint8', 'uint16', 'uint32')
+ if _logger.getEffectiveLevel() <= logging.DEBUG:
+ # This might be a costy check
+ assert indices.max() < self.nbVertices
+ self._indices = indices
+
+ def getIndices(self, copy=True):
+ """Returns the numpy.ndarray corresponding to the indices.
+
+ :param bool copy: True to get a copy (default),
+ False to get internal array (DO NOT MODIFY)
+ :return: The primitive indices array or None if not set.
+ :rtype: numpy.ndarray or None
+ """
+ if self._indices is None:
+ return None
+ else:
+ return numpy.array(self._indices, copy=copy)
+
+ def _bounds(self, dataBounds=False):
+ if self.__bounds is None:
+ self.__bounds = numpy.zeros((2, 3), dtype=numpy.float32)
+ # Support vertex with to 2 to 4 coordinates
+ positions = self._attributes['position']
+ self.__bounds[0, :positions.shape[1]] = positions.min(axis=0)[:3]
+ self.__bounds[1, :positions.shape[1]] = positions.max(axis=0)[:3]
+ return self.__bounds.copy()
+
+ def prepareGL2(self, ctx):
+ # TODO manage _vbo and multiple GL context + allow to share them !
+ # TODO make one or multiple VBO depending on len(vertices),
+ # TODO use a general common VBO for small amount of data
+ for name in self._unsyncAttributes:
+ array = self._attributes[name]
+ self._vbos[name] = ctx.glCtx.makeVboAttrib(array)
+ self._unsyncAttributes = []
+
+ if self._indices is not None and '__indices__' not in self._vbos:
+ vbo = ctx.glCtx.makeVbo(self._indices,
+ usage=gl.GL_STATIC_DRAW,
+ target=gl.GL_ELEMENT_ARRAY_BUFFER)
+ self._vbos['__indices__'] = vbo
+
+ def _draw(self, program=None, nbVertices=None):
+ """Perform OpenGL draw calls.
+
+ :param GLProgram program:
+ If not None, call :meth:`useAttribute` for this program.
+ :param int nbVertices:
+ The number of vertices to render or None to render all vertices.
+ """
+ if program is not None:
+ self.useAttribute(program)
+
+ if self._indices is None:
+ if nbVertices is None:
+ nbVertices = self.nbVertices
+ gl.glDrawArrays(self._MODES[self._mode], 0, nbVertices)
+ else:
+ if nbVertices is None:
+ nbVertices = self._indices.size
+ with self._vbos['__indices__']:
+ gl.glDrawElements(self._MODES[self._mode],
+ nbVertices,
+ _glutils.numpyToGLType(self._indices.dtype),
+ ctypes.c_void_p(0))
+
+
+# Lines #######################################################################
+
+class Lines(Geometry):
+ """A set of segments"""
+ _shaders = ("""
+ attribute vec3 position;
+ attribute vec3 normal;
+ attribute vec4 color;
+
+ uniform mat4 matrix;
+ uniform mat4 transformMat;
+
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec3 vNormal;
+ varying vec4 vColor;
+
+ void main(void)
+ {
+ gl_Position = matrix * vec4(position, 1.0);
+ vCameraPosition = transformMat * vec4(position, 1.0);
+ vPosition = position;
+ vNormal = normal;
+ vColor = color;
+ }
+ """,
+ string.Template("""
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec3 vNormal;
+ varying vec4 vColor;
+
+ $clippingDecl
+ $lightingFunction
+
+ void main(void)
+ {
+ $clippingCall(vCameraPosition);
+ gl_FragColor = $lightingCall(vColor, vPosition, vNormal);
+ }
+ """))
+
+ def __init__(self, positions, normals=None, colors=(1., 1., 1., 1.),
+ indices=None, mode='lines', width=1.):
+ if mode == 'strip':
+ mode = 'line_strip'
+ assert mode in self._LINE_MODES
+
+ self._width = width
+ self._smooth = True
+
+ super(Lines, self).__init__(mode, indices,
+ position=positions,
+ normal=normals,
+ color=colors)
+
+ width = event.notifyProperty('_width', converter=float,
+ doc="Width of the line in pixels.")
+
+ smooth = event.notifyProperty(
+ '_smooth',
+ converter=bool,
+ doc="Smooth line rendering enabled (bool, default: True)")
+
+ def renderGL2(self, ctx):
+ # Prepare program
+ isnormals = 'normal' in self._attributes
+ if isnormals:
+ fraglightfunction = ctx.viewport.light.fragmentDef
+ else:
+ fraglightfunction = ctx.viewport.light.fragmentShaderFunctionNoop
+
+ fragment = self._shaders[1].substitute(
+ clippingDecl=ctx.clipper.fragDecl,
+ clippingCall=ctx.clipper.fragCall,
+ lightingFunction=fraglightfunction,
+ lightingCall=ctx.viewport.light.fragmentCall)
+ prog = ctx.glCtx.prog(self._shaders[0], fragment)
+ prog.use()
+
+ if isnormals:
+ ctx.viewport.light.setupProgram(ctx, prog)
+
+ gl.glLineWidth(self.width)
+
+ prog.setUniformMatrix('matrix', ctx.objectToNDC.matrix)
+ prog.setUniformMatrix('transformMat',
+ ctx.objectToCamera.matrix,
+ safe=True)
+
+ ctx.clipper.setupProgram(ctx, prog)
+
+ with gl.enabled(gl.GL_LINE_SMOOTH, self._smooth):
+ self._draw(prog)
+
+
+class DashedLines(Lines):
+ """Set of dashed lines
+
+ This MUST be defined as a set of lines (no strip or loop).
+ """
+
+ _shaders = ("""
+ attribute vec3 position;
+ attribute vec3 origin;
+ attribute vec3 normal;
+ attribute vec4 color;
+
+ uniform mat4 matrix;
+ uniform mat4 transformMat;
+ uniform vec2 viewportSize; /* Width, height of the viewport */
+
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec3 vNormal;
+ varying vec4 vColor;
+ varying vec2 vOriginFragCoord;
+
+ void main(void)
+ {
+ gl_Position = matrix * vec4(position, 1.0);
+ vCameraPosition = transformMat * vec4(position, 1.0);
+ vPosition = position;
+ vNormal = normal;
+ vColor = color;
+
+ vec4 clipOrigin = matrix * vec4(origin, 1.0);
+ vec4 ndcOrigin = clipOrigin / clipOrigin.w; /* Perspective divide */
+ /* Convert to same frame as gl_FragCoord: lower-left, pixel center at 0.5, 0.5 */
+ vOriginFragCoord = (ndcOrigin.xy + vec2(1.0, 1.0)) * 0.5 * viewportSize + vec2(0.5, 0.5);
+ }
+ """, # noqa
+ string.Template("""
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec3 vNormal;
+ varying vec4 vColor;
+ varying vec2 vOriginFragCoord;
+
+ uniform vec2 dash;
+
+ $clippingDecl
+ $lightingFunction
+
+ void main(void)
+ {
+ /* Discard off dash fragments */
+ float lineDist = distance(vOriginFragCoord, gl_FragCoord.xy);
+ if (mod(lineDist, dash.x + dash.y) > dash.x) {
+ discard;
+ }
+ $clippingCall(vCameraPosition);
+ gl_FragColor = $lightingCall(vColor, vPosition, vNormal);
+ }
+ """))
+
+ def __init__(self, positions, colors=(1., 1., 1., 1.),
+ indices=None, width=1.):
+ self._dash = 1, 0
+ super(DashedLines, self).__init__(positions=positions,
+ colors=colors,
+ indices=indices,
+ mode='lines',
+ width=width)
+
+ @property
+ def dash(self):
+ """Dash of the line as a 2-tuple of lengths in pixels: (on, off)"""
+ return self._dash
+
+ @dash.setter
+ def dash(self, dash):
+ dash = float(dash[0]), float(dash[1])
+ if dash != self._dash:
+ self._dash = dash
+ self.notify()
+
+ def getPositions(self, copy=True):
+ """Get coordinates of lines.
+
+ :param bool copy: True to get a copy, False otherwise
+ :returns: Coordinates of lines
+ :rtype: numpy.ndarray of float32 of shape (N, 2, Ndim)
+ """
+ return self.getAttribute('position', copy=copy)
+
+ def setPositions(self, positions, copy=True):
+ """Set line coordinates.
+
+ :param positions: Array of line coordinates
+ :param bool copy: True to copy input array, False to use as is
+ """
+ self.setAttribute('position', positions, copy=copy)
+ # Update line origins from given positions
+ origins = numpy.array(positions, copy=True, order='C')
+ origins[1::2] = origins[::2]
+ self.setAttribute('origin', origins, copy=False)
+
+ def renderGL2(self, context):
+ # Prepare program
+ isnormals = 'normal' in self._attributes
+ if isnormals:
+ fraglightfunction = context.viewport.light.fragmentDef
+ else:
+ fraglightfunction = \
+ context.viewport.light.fragmentShaderFunctionNoop
+
+ fragment = self._shaders[1].substitute(
+ clippingDecl=context.clipper.fragDecl,
+ clippingCall=context.clipper.fragCall,
+ lightingFunction=fraglightfunction,
+ lightingCall=context.viewport.light.fragmentCall)
+ program = context.glCtx.prog(self._shaders[0], fragment)
+ program.use()
+
+ if isnormals:
+ context.viewport.light.setupProgram(context, program)
+
+ gl.glLineWidth(self.width)
+
+ program.setUniformMatrix('matrix', context.objectToNDC.matrix)
+ program.setUniformMatrix('transformMat',
+ context.objectToCamera.matrix,
+ safe=True)
+
+ gl.glUniform2f(
+ program.uniforms['viewportSize'], *context.viewport.size)
+ gl.glUniform2f(program.uniforms['dash'], *self.dash)
+
+ context.clipper.setupProgram(context, program)
+
+ self._draw(program)
+
+
+class Box(core.PrivateGroup):
+ """Rectangular box"""
+
+ _lineIndices = numpy.array((
+ (0, 1), (1, 2), (2, 3), (3, 0), # Lines with z=0
+ (0, 4), (1, 5), (2, 6), (3, 7), # Lines from z=0 to z=1
+ (4, 5), (5, 6), (6, 7), (7, 4)), # Lines with z=1
+ dtype=numpy.uint8)
+
+ _faceIndices = numpy.array(
+ (0, 3, 1, 2, 5, 6, 4, 7, 7, 6, 6, 2, 7, 3, 4, 0, 5, 1),
+ dtype=numpy.uint8)
+
+ _vertices = numpy.array((
+ # Corners with z=0
+ (0., 0., 0.), (1., 0., 0.), (1., 1., 0.), (0., 1., 0.),
+ # Corners with z=1
+ (0., 0., 1.), (1., 0., 1.), (1., 1., 1.), (0., 1., 1.)),
+ dtype=numpy.float32)
+
+ def __init__(self, size=(1., 1., 1.),
+ stroke=(1., 1., 1., 1.),
+ fill=(1., 1., 1., 0.)):
+ super(Box, self).__init__()
+
+ self._fill = Mesh3D(self._vertices,
+ colors=rgba(fill),
+ mode='triangle_strip',
+ indices=self._faceIndices)
+ self._fill.visible = self.fillColor[-1] != 0.
+
+ self._stroke = Lines(self._vertices,
+ indices=self._lineIndices,
+ colors=rgba(stroke),
+ mode='lines')
+ self._stroke.visible = self.strokeColor[-1] != 0.
+ self.strokeWidth = 1.
+
+ self._children = [self._stroke, self._fill]
+
+ self._size = None
+ self.size = size
+
+ @property
+ def size(self):
+ """Size of the box (sx, sy, sz)"""
+ return self._size
+
+ @size.setter
+ def size(self, size):
+ assert len(size) == 3
+ size = tuple(size)
+ if size != self.size:
+ self._size = size
+ self._fill.setAttribute(
+ 'position',
+ self._vertices * numpy.array(size, dtype=numpy.float32))
+ self._stroke.setAttribute(
+ 'position',
+ self._vertices * numpy.array(size, dtype=numpy.float32))
+ self.notify()
+
+ @property
+ def strokeSmooth(self):
+ """True to draw smooth stroke, False otherwise"""
+ return self._stroke.smooth
+
+ @strokeSmooth.setter
+ def strokeSmooth(self, smooth):
+ smooth = bool(smooth)
+ if smooth != self._stroke.smooth:
+ self._stroke.smooth = smooth
+ self.notify()
+
+ @property
+ def strokeWidth(self):
+ """Width of the stroke (float)"""
+ return self._stroke.width
+
+ @strokeWidth.setter
+ def strokeWidth(self, width):
+ width = float(width)
+ if width != self.strokeWidth:
+ self._stroke.width = width
+ self.notify()
+
+ @property
+ def strokeColor(self):
+ """RGBA color of the box lines (4-tuple of float in [0, 1])"""
+ return tuple(self._stroke.getAttribute('color', copy=False))
+
+ @strokeColor.setter
+ def strokeColor(self, color):
+ color = rgba(color)
+ if color != self.strokeColor:
+ self._stroke.setAttribute('color', color)
+ # Fully transparent = hidden
+ self._stroke.visible = color[-1] != 0.
+ self.notify()
+
+ @property
+ def fillColor(self):
+ """RGBA color of the box faces (4-tuple of float in [0, 1])"""
+ return tuple(self._fill.getAttribute('color', copy=False))
+
+ @fillColor.setter
+ def fillColor(self, color):
+ color = rgba(color)
+ if color != self.fillColor:
+ self._fill.setAttribute('color', color)
+ # Fully transparent = hidden
+ self._fill.visible = color[-1] != 0.
+ self.notify()
+
+ @property
+ def fillCulling(self):
+ return self._fill.culling
+
+ @fillCulling.setter
+ def fillCulling(self, culling):
+ self._fill.culling = culling
+
+
+class Axes(Lines):
+ """3D RGB orthogonal axes"""
+ _vertices = numpy.array(((0., 0., 0.), (1., 0., 0.),
+ (0., 0., 0.), (0., 1., 0.),
+ (0., 0., 0.), (0., 0., 1.)),
+ dtype=numpy.float32)
+
+ _colors = numpy.array(((255, 0, 0, 255), (255, 0, 0, 255),
+ (0, 255, 0, 255), (0, 255, 0, 255),
+ (0, 0, 255, 255), (0, 0, 255, 255)),
+ dtype=numpy.uint8)
+
+ def __init__(self):
+ super(Axes, self).__init__(self._vertices,
+ colors=self._colors,
+ width=3.)
+
+
+class BoxWithAxes(Lines):
+ """Rectangular box with RGB OX, OY, OZ axes
+
+ :param color: RGBA color of the box
+ """
+
+ _vertices = numpy.array((
+ # Axes corners
+ (0., 0., 0.), (1., 0., 0.),
+ (0., 0., 0.), (0., 1., 0.),
+ (0., 0., 0.), (0., 0., 1.),
+ # Box corners with z=0
+ (1., 0., 0.), (1., 1., 0.), (0., 1., 0.),
+ # Box corners with z=1
+ (0., 0., 1.), (1., 0., 1.), (1., 1., 1.), (0., 1., 1.)),
+ dtype=numpy.float32)
+
+ _axesColors = numpy.array(((1., 0., 0., 1.), (1., 0., 0., 1.),
+ (0., 1., 0., 1.), (0., 1., 0., 1.),
+ (0., 0., 1., 1.), (0., 0., 1., 1.)),
+ dtype=numpy.float32)
+
+ _lineIndices = numpy.array((
+ (0, 1), (2, 3), (4, 5), # Axes lines
+ (6, 7), (7, 8), # Box lines with z=0
+ (6, 10), (7, 11), (8, 12), # Box lines from z=0 to z=1
+ (9, 10), (10, 11), (11, 12), (12, 9)), # Box lines with z=1
+ dtype=numpy.uint8)
+
+ def __init__(self, color=(1., 1., 1., 1.)):
+ self._color = (1., 1., 1., 1.)
+ colors = numpy.ones((len(self._vertices), 4), dtype=numpy.float32)
+ colors[:len(self._axesColors), :] = self._axesColors
+
+ super(BoxWithAxes, self).__init__(self._vertices,
+ indices=self._lineIndices,
+ colors=colors,
+ width=2.)
+ self.color = color
+
+ @property
+ def color(self):
+ """The RGBA color to use for the box: 4 float in [0, 1]"""
+ return self._color
+
+ @color.setter
+ def color(self, color):
+ color = rgba(color)
+ if color != self._color:
+ self._color = color
+ colors = numpy.empty((len(self._vertices), 4), dtype=numpy.float32)
+ colors[:len(self._axesColors), :] = self._axesColors
+ colors[len(self._axesColors):, :] = self._color
+ self.setAttribute('color', colors) # Do the notification
+
+
+class PlaneInGroup(core.PrivateGroup):
+ """A plane using its parent bounds to display a contour.
+
+ If plane is outside the bounds of its parent, it is not visible.
+
+ Cannot set the transform attribute of this primitive.
+ This primitive never has any bounds.
+ """
+ # TODO inherit from Lines directly?, make sure the plane remains visible?
+
+ def __init__(self, point=(0., 0., 0.), normal=(0., 0., 1.)):
+ super(PlaneInGroup, self).__init__()
+ self._cache = None, None # Store bounds, vertices
+ self._outline = None
+
+ self._color = None
+ self.color = 1., 1., 1., 1. # Set _color
+ self._width = 2.
+
+ self._plane = utils.Plane(point, normal)
+ self._plane.addListener(self._planeChanged)
+
+ def moveToCenter(self):
+ """Place the plane at the center of the data, not changing orientation.
+ """
+ if self.parent is not None:
+ bounds = self.parent.bounds(dataBounds=True)
+ if bounds is not None:
+ center = (bounds[0] + bounds[1]) / 2.
+ _logger.debug('Moving plane to center: %s', str(center))
+ self.plane.point = center
+
+ @property
+ def color(self):
+ """Plane outline color (array of 4 float in [0, 1])."""
+ return self._color.copy()
+
+ @color.setter
+ def color(self, color):
+ self._color = numpy.array(color, copy=True, dtype=numpy.float32)
+ if self._outline is not None:
+ self._outline.setAttribute('color', self._color)
+ self.notify() # This is OK as Lines are rebuild for each rendering
+
+ @property
+ def width(self):
+ """Width of the plane stroke in pixels"""
+ return self._width
+
+ @width.setter
+ def width(self, width):
+ self._width = float(width)
+ if self._outline is not None:
+ self._outline.width = self._width # Sync width
+
+ # Plane access
+
+ @property
+ def plane(self):
+ """The plane parameters in the frame of the object."""
+ return self._plane
+
+ def _planeChanged(self, source):
+ """Listener of plane changes: clear cache and notify listeners."""
+ self._cache = None, None
+ self.notify()
+
+ # Disable some scene features
+
+ @property
+ def transforms(self):
+ # Ready-only transforms to prevent using it
+ return self._transforms
+
+ def _bounds(self, dataBounds=False):
+ # This is bound less as it uses the bounds of its parent.
+ return None
+
+ @property
+ def contourVertices(self):
+ """The vertices of the contour of the plane/bounds intersection."""
+ parent = self.parent
+ if parent is None:
+ return None # No parent: no vertices
+
+ bounds = parent.bounds(dataBounds=True)
+ if bounds is None:
+ return None # No bounds: no vertices
+
+ # Check if cache is valid and return it
+ cachebounds, cachevertices = self._cache
+ if numpy.all(numpy.equal(bounds, cachebounds)):
+ return cachevertices
+
+ # Cache is not OK, rebuild it
+ boxvertices = bounds[0] + Box._vertices.copy()*(bounds[1] - bounds[0])
+ lineindices = Box._lineIndices
+ vertices = utils.boxPlaneIntersect(
+ boxvertices, lineindices, self.plane.normal, self.plane.point)
+
+ self._cache = bounds, vertices if len(vertices) != 0 else None
+
+ return self._cache[1]
+
+ @property
+ def center(self):
+ """The center of the plane/bounds intersection points."""
+ if not self.isValid:
+ return None
+ else:
+ return numpy.mean(self.contourVertices, axis=0)
+
+ @property
+ def isValid(self):
+ """True if a contour is defined, False otherwise."""
+ return self.plane.isPlane and self.contourVertices is not None
+
+ def prepareGL2(self, ctx):
+ if self.isValid:
+ if self._outline is None: # Init outline
+ self._outline = Lines(self.contourVertices,
+ mode='loop',
+ colors=self.color)
+ self._outline.width = self._width
+ self._children.append(self._outline)
+
+ # Update vertices, TODO only when necessary
+ self._outline.setAttribute('position', self.contourVertices)
+
+ super(PlaneInGroup, self).prepareGL2(ctx)
+
+ def renderGL2(self, ctx):
+ if self.isValid:
+ super(PlaneInGroup, self).renderGL2(ctx)
+
+
+# Points ######################################################################
+
+_POINTS_ATTR_INFO = Geometry._ATTR_INFO.copy()
+_POINTS_ATTR_INFO.update(value={'dims': (1, 2), 'lastDim': (1,)},
+ size={'dims': (1, 2), 'lastDim': (1,)},
+ symbol={'dims': (1, 2), 'lastDim': (1,)})
+
+
+class Points(Geometry):
+ """A set of data points with an associated value and size."""
+ _shaders = ("""
+ #version 120
+
+ attribute vec3 position;
+ attribute float symbol;
+ attribute float value;
+ attribute float size;
+
+ uniform mat4 matrix;
+ uniform mat4 transformMat;
+
+ uniform vec2 valRange;
+
+ varying vec4 vCameraPosition;
+ varying float vSymbol;
+ varying float vNormValue;
+ varying float vSize;
+
+ void main(void)
+ {
+ vSymbol = symbol;
+
+ vNormValue = clamp((value - valRange.x) / (valRange.y - valRange.x),
+ 0.0, 1.0);
+
+ bool isValueInRange = value >= valRange.x && value <= valRange.y;
+ if (isValueInRange) {
+ gl_Position = matrix * vec4(position, 1.0);
+ } else {
+ gl_Position = vec4(2.0, 0.0, 0.0, 1.0); /* Get clipped */
+ }
+ vCameraPosition = transformMat * vec4(position, 1.0);
+
+ gl_PointSize = size;
+ vSize = size;
+ }
+ """,
+ string.Template("""
+ #version 120
+
+ varying vec4 vCameraPosition;
+ varying float vSize;
+ varying float vSymbol;
+ varying float vNormValue;
+
+ $clippinDecl
+
+ /* Circle */
+ #define SYMBOL_CIRCLE 1.0
+
+ float alphaCircle(vec2 coord, float size) {
+ float radius = 0.5;
+ float r = distance(coord, vec2(0.5, 0.5));
+ return clamp(size * (radius - r), 0.0, 1.0);
+ }
+
+ /* Half lines */
+ #define SYMBOL_H_LINE 2.0
+ #define LEFT 1.0
+ #define RIGHT 2.0
+ #define SYMBOL_V_LINE 3.0
+ #define UP 1.0
+ #define DOWN 2.0
+
+ float alphaLine(vec2 coord, float size, float direction)
+ {
+ vec2 delta = abs(size * (coord - 0.5));
+
+ if (direction == SYMBOL_H_LINE) {
+ return (delta.y < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_H_LINE + LEFT) {
+ return (coord.x <= 0.5 && delta.y < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_H_LINE + RIGHT) {
+ return (coord.x >= 0.5 && delta.y < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_V_LINE) {
+ return (delta.x < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_V_LINE + UP) {
+ return (coord.y <= 0.5 && delta.x < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_V_LINE + DOWN) {
+ return (coord.y >= 0.5 && delta.x < 0.5) ? 1.0 : 0.0;
+ }
+ return 1.0;
+ }
+
+ void main(void)
+ {
+ $clippingCall(vCameraPosition);
+
+ gl_FragColor = vec4(0.5 * vNormValue + 0.5, 0.0, 0.0, 1.0);
+
+ float alpha = 1.0;
+ float symbol = floor(vSymbol);
+ if (1 == 1) { //symbol == SYMBOL_CIRCLE) {
+ alpha = alphaCircle(gl_PointCoord, vSize);
+ }
+ else if (symbol >= SYMBOL_H_LINE &&
+ symbol <= (SYMBOL_V_LINE + DOWN)) {
+ alpha = alphaLine(gl_PointCoord, vSize, symbol);
+ }
+ if (alpha == 0.0) {
+ discard;
+ }
+ gl_FragColor.a *= alpha;
+ }
+ """))
+
+ _ATTR_INFO = _POINTS_ATTR_INFO
+
+ # TODO Add colormap, light?
+
+ def __init__(self, vertices, values=0., sizes=1., indices=None,
+ symbols=0.,
+ minValue=None, maxValue=None):
+ super(Points, self).__init__('points', indices,
+ position=vertices,
+ value=values,
+ size=sizes,
+ symbol=symbols)
+
+ values = self._attributes['value']
+ self._minValue = values.min() if minValue is None else minValue
+ self._maxValue = values.max() if maxValue is None else maxValue
+
+ minValue = event.notifyProperty('_minValue')
+ maxValue = event.notifyProperty('_maxValue')
+
+ def renderGL2(self, ctx):
+ fragment = self._shaders[1].substitute(
+ clippingDecl=ctx.clipper.fragDecl,
+ clippingCall=ctx.clipper.fragCall)
+ prog = ctx.glCtx.prog(self._shaders[0], fragment)
+ prog.use()
+
+ gl.glEnable(gl.GL_VERTEX_PROGRAM_POINT_SIZE) # OpenGL 2
+ gl.glEnable(gl.GL_POINT_SPRITE) # OpenGL 2
+ # gl.glEnable(gl.GL_PROGRAM_POINT_SIZE)
+
+ prog.setUniformMatrix('matrix', ctx.objectToNDC.matrix)
+ prog.setUniformMatrix('transformMat',
+ ctx.objectToCamera.matrix,
+ safe=True)
+
+ ctx.clipper.setupProgram(ctx, prog)
+
+ gl.glUniform2f(prog.uniforms['valRange'], self.minValue, self.maxValue)
+
+ self._draw(prog)
+
+
+class ColorPoints(Geometry):
+ """A set of points with an associated color and size."""
+
+ _shaders = ("""
+ #version 120
+
+ attribute vec3 position;
+ attribute float symbol;
+ attribute vec4 color;
+ attribute float size;
+
+ uniform mat4 matrix;
+ uniform mat4 transformMat;
+
+ varying vec4 vCameraPosition;
+ varying float vSymbol;
+ varying vec4 vColor;
+ varying float vSize;
+
+ void main(void)
+ {
+ vCameraPosition = transformMat * vec4(position, 1.0);
+ vSymbol = symbol;
+ vColor = color;
+ gl_Position = matrix * vec4(position, 1.0);
+ gl_PointSize = size;
+ vSize = size;
+ }
+ """,
+ string.Template("""
+ #version 120
+
+ varying vec4 vCameraPosition;
+ varying float vSize;
+ varying float vSymbol;
+ varying vec4 vColor;
+
+ $clippingDecl;
+
+ /* Circle */
+ #define SYMBOL_CIRCLE 1.0
+
+ float alphaCircle(vec2 coord, float size) {
+ float radius = 0.5;
+ float r = distance(coord, vec2(0.5, 0.5));
+ return clamp(size * (radius - r), 0.0, 1.0);
+ }
+
+ /* Half lines */
+ #define SYMBOL_H_LINE 2.0
+ #define LEFT 1.0
+ #define RIGHT 2.0
+ #define SYMBOL_V_LINE 3.0
+ #define UP 1.0
+ #define DOWN 2.0
+
+ float alphaLine(vec2 coord, float size, float direction)
+ {
+ vec2 delta = abs(size * (coord - 0.5));
+
+ if (direction == SYMBOL_H_LINE) {
+ return (delta.y < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_H_LINE + LEFT) {
+ return (coord.x <= 0.5 && delta.y < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_H_LINE + RIGHT) {
+ return (coord.x >= 0.5 && delta.y < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_V_LINE) {
+ return (delta.x < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_V_LINE + UP) {
+ return (coord.y <= 0.5 && delta.x < 0.5) ? 1.0 : 0.0;
+ }
+ else if (direction == SYMBOL_V_LINE + DOWN) {
+ return (coord.y >= 0.5 && delta.x < 0.5) ? 1.0 : 0.0;
+ }
+ return 1.0;
+ }
+
+ void main(void)
+ {
+ $clippingCall(vCameraPosition);
+
+ gl_FragColor = vColor;
+
+ float alpha = 1.0;
+ float symbol = floor(vSymbol);
+ if (1 == 1) { //symbol == SYMBOL_CIRCLE) {
+ alpha = alphaCircle(gl_PointCoord, vSize);
+ }
+ else if (symbol >= SYMBOL_H_LINE &&
+ symbol <= (SYMBOL_V_LINE + DOWN)) {
+ alpha = alphaLine(gl_PointCoord, vSize, symbol);
+ }
+ if (alpha == 0.0) {
+ discard;
+ }
+ gl_FragColor.a *= alpha;
+ }
+ """))
+
+ _ATTR_INFO = _POINTS_ATTR_INFO
+
+ def __init__(self, vertices, colors=(1., 1., 1., 1.), sizes=1.,
+ indices=None, symbols=0.,
+ minValue=None, maxValue=None):
+ super(ColorPoints, self).__init__('points', indices,
+ position=vertices,
+ color=colors,
+ size=sizes,
+ symbol=symbols)
+
+ def renderGL2(self, ctx):
+ fragment = self._shaders[1].substitute(
+ clippingDecl=ctx.clipper.fragDecl,
+ clippingCall=ctx.clipper.fragCall)
+ prog = ctx.glCtx.prog(self._shaders[0], fragment)
+ prog.use()
+
+ gl.glEnable(gl.GL_VERTEX_PROGRAM_POINT_SIZE) # OpenGL 2
+ gl.glEnable(gl.GL_POINT_SPRITE) # OpenGL 2
+ # gl.glEnable(gl.GL_PROGRAM_POINT_SIZE)
+
+ prog.setUniformMatrix('matrix', ctx.objectToNDC.matrix)
+ prog.setUniformMatrix('transformMat',
+ ctx.objectToCamera.matrix,
+ safe=True)
+
+ ctx.clipper.setupProgram(ctx, prog)
+
+ self._draw(prog)
+
+
+class GridPoints(Geometry):
+ # GLSL 1.30 !
+ """Data points on a regular grid with an associated value and size."""
+ _shaders = ("""
+ #version 130
+
+ in float value;
+ in float size;
+
+ uniform ivec3 gridDims;
+ uniform mat4 matrix;
+ uniform mat4 transformMat;
+ uniform vec2 valRange;
+
+ out vec4 vCameraPosition;
+ out float vNormValue;
+
+ //ivec3 coordsFromIndex(int index, ivec3 shape)
+ //{
+ /*Assumes that data is stored as z-major, then y, contiguous on x
+ */
+ // int yxPlaneSize = shape.y * shape.x; /* nb of elem in 2d yx plane */
+ // int z = index / yxPlaneSize;
+ // int yxIndex = index - z * yxPlaneSize; /* index in 2d yx plane */
+ // int y = yxIndex / shape.x;
+ // int x = yxIndex - y * shape.x;
+ // return ivec3(x, y, z);
+ // }
+
+ ivec3 coordsFromIndex(int index, ivec3 shape)
+ {
+ /*Assumes that data is stored as x-major, then y, contiguous on z
+ */
+ int yzPlaneSize = shape.y * shape.z; /* nb of elem in 2d yz plane */
+ int x = index / yzPlaneSize;
+ int yzIndex = index - x * yzPlaneSize; /* index in 2d yz plane */
+ int y = yzIndex / shape.z;
+ int z = yzIndex - y * shape.z;
+ return ivec3(x, y, z);
+ }
+
+ void main(void)
+ {
+ vNormValue = clamp((value - valRange.x) / (valRange.y - valRange.x),
+ 0.0, 1.0);
+
+ bool isValueInRange = value >= valRange.x && value <= valRange.y;
+ if (isValueInRange) {
+ /* Retrieve 3D position from gridIndex */
+ vec3 coords = vec3(coordsFromIndex(gl_VertexID, gridDims));
+ vec3 position = coords / max(vec3(gridDims) - 1.0, 1.0);
+ gl_Position = matrix * vec4(position, 1.0);
+ vCameraPosition = transformMat * vec4(position, 1.0);
+ } else {
+ gl_Position = vec4(2.0, 0.0, 0.0, 1.0); /* Get clipped */
+ vCameraPosition = vec4(0.0, 0.0, 0.0, 0.0);
+ }
+
+ gl_PointSize = size;
+ }
+ """,
+ string.Template("""
+ #version 130
+
+ in vec4 vCameraPosition;
+ in float vNormValue;
+ out vec4 fragColor;
+
+ $clippingDecl
+
+ void main(void)
+ {
+ $clippingCall(vCameraPosition);
+
+ fragColor = vec4(0.5 * vNormValue + 0.5, 0.0, 0.0, 1.0);
+ }
+ """))
+
+ _ATTR_INFO = {
+ 'value': {'dims': (1, 2), 'lastDim': (1,)},
+ 'size': {'dims': (1, 2), 'lastDim': (1,)}
+ }
+
+ # TODO Add colormap, shape?
+ # TODO could also use a texture to store values
+
+ def __init__(self, values=0., shape=None, sizes=1., indices=None,
+ minValue=None, maxValue=None):
+ if isinstance(values, collections.Iterable):
+ values = numpy.array(values, copy=False)
+
+ # Test if gl_VertexID will overflow
+ assert values.size < numpy.iinfo(numpy.int32).max
+
+ self._shape = values.shape
+ values = values.ravel() # 1D to add as a 1D vertex attribute
+
+ else:
+ assert shape is not None
+ self._shape = tuple(shape)
+
+ assert len(self._shape) in (1, 2, 3)
+
+ super(GridPoints, self).__init__('points', indices,
+ value=values,
+ size=sizes)
+
+ data = self.getAttribute('value', copy=False)
+ self._minValue = data.min() if minValue is None else minValue
+ self._maxValue = data.max() if maxValue is None else maxValue
+
+ minValue = event.notifyProperty('_minValue')
+ maxValue = event.notifyProperty('_maxValue')
+
+ def _bounds(self, dataBounds=False):
+ # Get bounds from values shape
+ bounds = numpy.zeros((2, 3), dtype=numpy.float32)
+ bounds[1, :] = self._shape
+ bounds[1, :] -= 1
+ return bounds
+
+ def renderGL2(self, ctx):
+ fragment = self._shaders[1].substitute(
+ clippingDecl=ctx.clipper.fragDecl,
+ clippingCall=ctx.clipper.fragCall)
+ prog = ctx.glCtx.prog(self._shaders[0], fragment)
+ prog.use()
+
+ gl.glEnable(gl.GL_VERTEX_PROGRAM_POINT_SIZE) # OpenGL 2
+ gl.glEnable(gl.GL_POINT_SPRITE) # OpenGL 2
+ # gl.glEnable(gl.GL_PROGRAM_POINT_SIZE)
+
+ prog.setUniformMatrix('matrix', ctx.objectToNDC.matrix)
+ prog.setUniformMatrix('transformMat',
+ ctx.objectToCamera.matrix,
+ safe=True)
+
+ ctx.clipper.setupProgram(ctx, prog)
+
+ gl.glUniform3i(prog.uniforms['gridDims'],
+ self._shape[2] if len(self._shape) == 3 else 1,
+ self._shape[1] if len(self._shape) >= 2 else 1,
+ self._shape[0])
+
+ gl.glUniform2f(prog.uniforms['valRange'], self.minValue, self.maxValue)
+
+ self._draw(prog, nbVertices=reduce(lambda a, b: a * b, self._shape))
+
+
+# Spheres #####################################################################
+
+class Spheres(Geometry):
+ """A set of spheres.
+
+ Spheres are rendered as circles using points.
+ This brings some limitations:
+ - Do not support non-uniform scaling.
+ - Assume the projection keeps ratio.
+ - Do not render distorion by perspective projection.
+ - If the sphere center is clipped, the whole sphere is not displayed.
+ """
+ # TODO check those links
+ # Accounting for perspective projection
+ # http://iquilezles.org/www/articles/sphereproj/sphereproj.htm
+
+ # Michael Mara and Morgan McGuire.
+ # 2D Polyhedral Bounds of a Clipped, Perspective-Projected 3D Sphere
+ # Journal of Computer Graphics Techniques, Vol. 2, No. 2, 2013.
+ # http://jcgt.org/published/0002/02/05/paper.pdf
+ # https://research.nvidia.com/publication/2d-polyhedral-bounds-clipped-perspective-projected-3d-sphere
+
+ # TODO some issues with small scaling and regular grid or due to sampling
+
+ _shaders = ("""
+ #version 120
+
+ attribute vec3 position;
+ attribute vec4 color;
+ attribute float radius;
+
+ uniform mat4 transformMat;
+ uniform mat4 projMat;
+ uniform vec2 screenSize;
+
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec4 vColor;
+ varying float vViewDepth;
+ varying float vViewRadius;
+
+ void main(void)
+ {
+ vCameraPosition = transformMat * vec4(position, 1.0);
+ gl_Position = projMat * vCameraPosition;
+
+ vPosition = gl_Position.xyz / gl_Position.w;
+
+ /* From object space radius to view space diameter.
+ * Do not support non-uniform scaling */
+ vec4 viewSizeVector = transformMat * vec4(2.0 * radius, 0.0, 0.0, 0.0);
+ float viewSize = length(viewSizeVector.xyz);
+
+ /* Convert to pixel size at the xy center of the view space */
+ vec4 projSize = projMat * vec4(0.5 * viewSize, 0.0,
+ vCameraPosition.z, vCameraPosition.w);
+ gl_PointSize = max(1.0, screenSize[0] * projSize.x / projSize.w);
+
+ vColor = color;
+ vViewRadius = 0.5 * viewSize;
+ vViewDepth = vCameraPosition.z;
+ }
+ """,
+ string.Template("""
+ # version 120
+
+ uniform mat4 projMat;
+
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec4 vColor;
+ varying float vViewDepth;
+ varying float vViewRadius;
+
+ $clippingDecl
+ $lightingFunction
+
+ void main(void)
+ {
+ $clippingCall(vCameraPosition);
+
+ /* Get normal from point coords */
+ vec3 normal;
+ normal.xy = 2.0 * gl_PointCoord - vec2(1.0);
+ normal.y *= -1.0; /*Invert y to match NDC orientation*/
+ float sqLength = dot(normal.xy, normal.xy);
+ if (sqLength > 1.0) { /* Length -> out of sphere */
+ discard;
+ }
+ normal.z = sqrt(1.0 - sqLength);
+
+ /*Lighting performed in NDC*/
+ /*TODO update this when lighting changed*/
+ //XXX vec3 position = vPosition + vViewRadius * normal;
+ gl_FragColor = $lightingCall(vColor, vPosition, normal);
+
+ /*Offset depth*/
+ float viewDepth = vViewDepth + vViewRadius * normal.z;
+ vec2 clipZW = viewDepth * projMat[2].zw + projMat[3].zw;
+ gl_FragDepth = 0.5 * (clipZW.x / clipZW.y) + 0.5;
+ }
+ """))
+
+ _ATTR_INFO = {
+ 'position': {'dims': (2, ), 'lastDim': (2, 3, 4)},
+ 'radius': {'dims': (1, 2), 'lastDim': (1, )},
+ 'color': {'dims': (1, 2), 'lastDim': (3, 4)},
+ }
+
+ def __init__(self, positions, radius=1., colors=(1., 1., 1., 1.)):
+ self.__bounds = None
+ super(Spheres, self).__init__('points', None,
+ position=positions,
+ radius=radius,
+ color=colors)
+
+ def renderGL2(self, ctx):
+ fragment = self._shaders[1].substitute(
+ clippingDecl=ctx.clipper.fragDecl,
+ clippingCall=ctx.clipper.fragCall,
+ lightingFunction=ctx.viewport.light.fragmentDef,
+ lightingCall=ctx.viewport.light.fragmentCall)
+ prog = ctx.glCtx.prog(self._shaders[0], fragment)
+ prog.use()
+
+ ctx.viewport.light.setupProgram(ctx, prog)
+
+ gl.glEnable(gl.GL_VERTEX_PROGRAM_POINT_SIZE) # OpenGL 2
+ gl.glEnable(gl.GL_POINT_SPRITE) # OpenGL 2
+ # gl.glEnable(gl.GL_PROGRAM_POINT_SIZE)
+
+ prog.setUniformMatrix('projMat', ctx.projection.matrix)
+ prog.setUniformMatrix('transformMat',
+ ctx.objectToCamera.matrix,
+ safe=True)
+
+ ctx.clipper.setupProgram(ctx, prog)
+
+ gl.glUniform2f(prog.uniforms['screenSize'], *ctx.viewport.size)
+
+ self._draw(prog)
+
+ def _bounds(self, dataBounds=False):
+ if self.__bounds is None:
+ self.__bounds = numpy.zeros((2, 3), dtype=numpy.float32)
+ # Support vertex with to 2 to 4 coordinates
+ positions = self._attributes['position']
+ radius = self._attributes['radius']
+ self.__bounds[0, :positions.shape[1]] = \
+ (positions - radius).min(axis=0)[:3]
+ self.__bounds[1, :positions.shape[1]] = \
+ (positions + radius).max(axis=0)[:3]
+ return self.__bounds.copy()
+
+
+# Meshes ######################################################################
+
+class Mesh3D(Geometry):
+ """A conventional 3D mesh"""
+
+ _shaders = ("""
+ attribute vec3 position;
+ attribute vec3 normal;
+ attribute vec4 color;
+
+ uniform mat4 matrix;
+ uniform mat4 transformMat;
+ //uniform mat3 matrixInvTranspose;
+
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec3 vNormal;
+ varying vec4 vColor;
+
+ void main(void)
+ {
+ vCameraPosition = transformMat * vec4(position, 1.0);
+ //vNormal = matrixInvTranspose * normalize(normal);
+ vPosition = position;
+ vNormal = normal;
+ vColor = color;
+ gl_Position = matrix * vec4(position, 1.0);
+ }
+ """,
+ string.Template("""
+ varying vec4 vCameraPosition;
+ varying vec3 vPosition;
+ varying vec3 vNormal;
+ varying vec4 vColor;
+
+ $clippingDecl
+ $lightingFunction
+
+ void main(void)
+ {
+ $clippingCall(vCameraPosition);
+
+ gl_FragColor = $lightingCall(vColor, vPosition, vNormal);
+ }
+ """))
+
+ def __init__(self,
+ positions,
+ colors,
+ normals=None,
+ mode='triangles',
+ indices=None):
+ assert mode in self._TRIANGLE_MODES
+ super(Mesh3D, self).__init__(mode, indices,
+ position=positions,
+ normal=normals,
+ color=colors)
+
+ self._culling = None
+
+ @property
+ def culling(self):
+ """Face culling (str)
+
+ One of 'back', 'front' or None.
+ """
+ return self._culling
+
+ @culling.setter
+ def culling(self, culling):
+ assert culling in ('back', 'front', None)
+ if culling != self._culling:
+ self._culling = culling
+ self.notify()
+
+ def renderGL2(self, ctx):
+ isnormals = 'normal' in self._attributes
+ if isnormals:
+ fragLightFunction = ctx.viewport.light.fragmentDef
+ else:
+ fragLightFunction = ctx.viewport.light.fragmentShaderFunctionNoop
+
+ fragment = self._shaders[1].substitute(
+ clippingDecl=ctx.clipper.fragDecl,
+ clippingCall=ctx.clipper.fragCall,
+ lightingFunction=fragLightFunction,
+ lightingCall=ctx.viewport.light.fragmentCall)
+ prog = ctx.glCtx.prog(self._shaders[0], fragment)
+ prog.use()
+
+ if isnormals:
+ ctx.viewport.light.setupProgram(ctx, prog)
+
+ if self.culling is not None:
+ cullFace = gl.GL_FRONT if self.culling == 'front' else gl.GL_BACK
+ gl.glCullFace(cullFace)
+ gl.glEnable(gl.GL_CULL_FACE)
+
+ prog.setUniformMatrix('matrix', ctx.objectToNDC.matrix)
+ prog.setUniformMatrix('transformMat',
+ ctx.objectToCamera.matrix,
+ safe=True)
+
+ ctx.clipper.setupProgram(ctx, prog)
+
+ self._draw(prog)
+
+ if self.culling is not None:
+ gl.glDisable(gl.GL_CULL_FACE)
+
+
+# Group ######################################################################
+
+# TODO lighting, clipping as groups?
+# group composition?
+
+class GroupDepthOffset(core.Group):
+ """A group using 2-pass rendering and glDepthRange to avoid Z-fighting"""
+
+ def __init__(self, children=(), epsilon=None):
+ super(GroupDepthOffset, self).__init__(children)
+ self._epsilon = epsilon
+ self.isDepthRangeOn = True
+
+ def prepareGL2(self, ctx):
+ if self._epsilon is None:
+ depthbits = gl.glGetInteger(gl.GL_DEPTH_BITS)
+ self._epsilon = 1. / (1 << (depthbits - 1))
+
+ def renderGL2(self, ctx):
+ if self.isDepthRangeOn:
+ self._renderGL2WithDepthRange(ctx)
+ else:
+ super(GroupDepthOffset, self).renderGL2(ctx)
+
+ def _renderGL2WithDepthRange(self, ctx):
+ # gl.glDepthFunc(gl.GL_LESS)
+ with gl.enabled(gl.GL_CULL_FACE):
+ gl.glCullFace(gl.GL_BACK)
+ for child in self.children:
+ gl.glColorMask(
+ gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE)
+ gl.glDepthMask(gl.GL_TRUE)
+ gl.glDepthRange(self._epsilon, 1.)
+
+ child.render(ctx)
+
+ gl.glColorMask(
+ gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE)
+ gl.glDepthMask(gl.GL_FALSE)
+ gl.glDepthRange(0., 1. - self._epsilon)
+
+ child.render(ctx)
+
+ gl.glCullFace(gl.GL_FRONT)
+ for child in reversed(self.children):
+ gl.glColorMask(
+ gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE, gl.GL_FALSE)
+ gl.glDepthMask(gl.GL_TRUE)
+ gl.glDepthRange(self._epsilon, 1.)
+
+ child.render(ctx)
+
+ gl.glColorMask(
+ gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE, gl.GL_TRUE)
+ gl.glDepthMask(gl.GL_FALSE)
+ gl.glDepthRange(0., 1. - self._epsilon)
+
+ child.render(ctx)
+
+ gl.glDepthMask(gl.GL_TRUE)
+ gl.glDepthRange(0., 1.)
+ # gl.glDepthFunc(gl.GL_LEQUAL)
+ # TODO use epsilon for all rendering?
+ # TODO issue with picking in depth buffer!
+
+
+class GroupBBox(core.PrivateGroup):
+ """A group displaying a bounding box around the children."""
+
+ def __init__(self, children=(), color=(1., 1., 1., 1.)):
+ super(GroupBBox, self).__init__()
+ self._group = core.Group(children)
+
+ self._boxTransforms = transform.TransformList(
+ (transform.Translate(), transform.Scale()))
+
+ self._boxWithAxes = BoxWithAxes(color)
+ self._boxWithAxes.smooth = False
+ self._boxWithAxes.transforms = self._boxTransforms
+
+ self._children = [self._boxWithAxes, self._group]
+
+ def _updateBoxAndAxes(self):
+ """Update bbox and axes position and size according to children."""
+ bounds = self._group.bounds(dataBounds=True)
+ if bounds is not None:
+ origin = bounds[0]
+ scale = [(d if d != 0. else 1.) for d in bounds[1] - bounds[0]]
+ else:
+ origin, scale = (0., 0., 0.), (1., 1., 1.)
+
+ self._boxTransforms[0].translation = origin
+ self._boxTransforms[1].scale = scale
+
+ def _bounds(self, dataBounds=False):
+ self._updateBoxAndAxes()
+ return super(GroupBBox, self)._bounds(dataBounds)
+
+ def prepareGL2(self, ctx):
+ self._updateBoxAndAxes()
+ super(GroupBBox, self).prepareGL2(ctx)
+
+ # Give access to _group children
+
+ @property
+ def children(self):
+ return self._group.children
+
+ @children.setter
+ def children(self, iterable):
+ self._group.children = iterable
+
+ # Give access to box color
+
+ @property
+ def color(self):
+ """The RGBA color to use for the box: 4 float in [0, 1]"""
+ return self._boxWithAxes.color
+
+ @color.setter
+ def color(self, color):
+ self._boxWithAxes.color = color
+
+
+# Clipping Plane ##############################################################
+
+class ClipPlane(PlaneInGroup):
+ """A clipping plane attached to a box"""
+
+ def renderGL2(self, ctx):
+ super(ClipPlane, self).renderGL2(ctx)
+
+ if self.visible:
+ # Set-up clipping plane for following brothers
+
+ # No need of perspective divide, no projection
+ point = ctx.objectToCamera.transformPoint(self.plane.point,
+ perspectiveDivide=False)
+ normal = ctx.objectToCamera.transformNormal(self.plane.normal)
+ ctx.setClipPlane(point, normal)
+
+ def postRender(self, ctx):
+ if self.visible:
+ # Disable clip planes
+ ctx.setClipPlane()
diff --git a/silx/gui/plot3d/scene/setup.py b/silx/gui/plot3d/scene/setup.py
new file mode 100644
index 0000000..ff4c0a6
--- /dev/null
+++ b/silx/gui/plot3d/scene/setup.py
@@ -0,0 +1,41 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('scene', parent_package, top_path)
+ config.add_subpackage('test')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/gui/plot3d/scene/test/__init__.py b/silx/gui/plot3d/scene/test/__init__.py
new file mode 100644
index 0000000..fc4621e
--- /dev/null
+++ b/silx/gui/plot3d/scene/test/__init__.py
@@ -0,0 +1,43 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import unittest
+
+from .test_transform import suite as test_transform_suite
+from .test_utils import suite as test_utils_suite
+
+
+def suite():
+ testsuite = unittest.TestSuite()
+ testsuite.addTest(test_transform_suite())
+ testsuite.addTest(test_utils_suite())
+ return testsuite
diff --git a/silx/gui/plot3d/scene/test/test_transform.py b/silx/gui/plot3d/scene/test/test_transform.py
new file mode 100644
index 0000000..9ea0af1
--- /dev/null
+++ b/silx/gui/plot3d/scene/test/test_transform.py
@@ -0,0 +1,91 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/01/2017"
+
+
+import numpy
+import unittest
+
+from silx.gui.plot3d.scene import transform
+
+
+class TestTransformList(unittest.TestCase):
+
+ def assertSameArrays(self, a, b):
+ return self.assertTrue(numpy.allclose(a, b, atol=1e-06))
+
+ def testTransformList(self):
+ """Minimalistic test of TransformList"""
+ transforms = transform.TransformList()
+ refmatrix = numpy.identity(4, dtype=numpy.float32)
+ self.assertSameArrays(refmatrix, transforms.matrix)
+
+ # Append translate
+ transforms.append(transform.Translate(1., 1., 1.))
+ refmatrix = numpy.array(((1., 0., 0., 1.),
+ (0., 1., 0., 1.),
+ (0., 0., 1., 1.),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+ self.assertSameArrays(refmatrix, transforms.matrix)
+
+ # Extend scale
+ transforms.extend([transform.Scale(0.1, 2., 1.)])
+ refmatrix = numpy.dot(refmatrix,
+ numpy.array(((0.1, 0., 0., 0.),
+ (0., 2., 0., 0.),
+ (0., 0., 1., 0.),
+ (0., 0., 0., 1.)),
+ dtype=numpy.float32))
+ self.assertSameArrays(refmatrix, transforms.matrix)
+
+ # Insert rotate
+ transforms.insert(0, transform.Rotate(360.))
+ self.assertSameArrays(refmatrix, transforms.matrix)
+
+ # Update translate and check for listener called
+ self._callCount = 0
+
+ def listener(source):
+ self._callCount += 1
+ transforms.addListener(listener)
+
+ transforms[1].tx += 1
+ self.assertEqual(self._callCount, 1)
+
+
+def suite():
+ testsuite = unittest.TestSuite()
+ testsuite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestTransformList))
+ return testsuite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot3d/scene/test/test_utils.py b/silx/gui/plot3d/scene/test/test_utils.py
new file mode 100644
index 0000000..65c2407
--- /dev/null
+++ b/silx/gui/plot3d/scene/test/test_utils.py
@@ -0,0 +1,275 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import unittest
+from silx.test.utils import ParametricTestCase
+
+import numpy
+
+from silx.gui.plot3d.scene import utils
+
+
+# angleBetweenVectors #########################################################
+
+class TestAngleBetweenVectors(ParametricTestCase):
+
+ TESTS = { # name: (refvector, vectors, norm, refangles)
+ 'single vector':
+ ((1., 0., 0.), (1., 0., 0.), (0., 0., 1.), 0.),
+ 'single vector, no norm':
+ ((1., 0., 0.), (1., 0., 0.), None, 0.),
+
+ 'with orthogonal norm':
+ ((1., 0., 0.),
+ ((1., 0., 0.), (0., 1., 0.), (-1., 0., 0.), (0., -1., 0.)),
+ (0., 0., 1.),
+ (0., 90., 180., 270.)),
+
+ 'with coplanar norm': # = similar to no norm
+ ((1., 0., 0.),
+ ((1., 0., 0.), (0., 1., 0.), (-1., 0., 0.), (0., -1., 0.)),
+ (1., 0., 0.),
+ (0., 90., 180., 90.)),
+
+ 'without norm':
+ ((1., 0., 0.),
+ ((1., 0., 0.), (0., 1., 0.), (-1., 0., 0.), (0., -1., 0.)),
+ None,
+ (0., 90., 180., 90.)),
+
+ 'not unit vectors':
+ ((2., 2., 0.), ((1., 1., 0.), (1., -1., 0.)), None, (0., 90.)),
+ }
+
+ def testAngleBetweenVectorsFunction(self):
+ for name, params in self.TESTS.items():
+ refvector, vectors, norm, refangles = params
+ with self.subTest(name):
+ refangles = numpy.radians(refangles)
+
+ refvector = numpy.array(refvector)
+ vectors = numpy.array(vectors)
+ if norm is not None:
+ norm = numpy.array(norm)
+
+ testangles = utils.angleBetweenVectors(
+ refvector, vectors, norm)
+
+ self.assertTrue(
+ numpy.allclose(testangles, refangles, atol=1e-5))
+
+
+# Plane #######################################################################
+
+class AssertNotificationContext(object):
+ """Context that checks if an event.Notifier is sending events."""
+
+ def __init__(self, notifier, count=1):
+ """Initializer.
+
+ :param event.Notifier notifier: The notifier to test.
+ :param int count: The expected number of calls.
+ """
+ self._notifier = notifier
+ self._callCount = None
+ self._count = count
+
+ def __enter__(self):
+ self._callCount = 0
+ self._notifier.addListener(self._callback)
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ # Do not return True so exceptions are propagated
+ self._notifier.removeListener(self._callback)
+ assert self._callCount == self._count
+ self._callCount = None
+
+ def _callback(self, *args, **kwargs):
+ self._callCount += 1
+
+
+class TestPlaneParameters(ParametricTestCase):
+ """Test Plane.parameters read/write and notifications."""
+
+ PARAMETERS = {
+ 'unit normal': (1., 0., 0., 1.),
+ 'not unit normal': (1., 1., 0., 1.),
+ 'd = 0': (1., 0., 0., 0.)
+ }
+
+ def testParameters(self):
+ """Check parameters read/write and notification."""
+ plane = utils.Plane()
+
+ for name, parameters in self.PARAMETERS.items():
+ with self.subTest(name, parameters=parameters):
+ with AssertNotificationContext(plane):
+ plane.parameters = parameters
+
+ # Plane parameters are converted to have a unit normal
+ normparams = parameters / numpy.linalg.norm(parameters[:3])
+ self.assertTrue(numpy.allclose(plane.parameters, normparams))
+
+ ZEROS_PARAMETERS = (
+ (0., 0., 0., 0.),
+ (0., 0., 0., 1.)
+ )
+
+ ZEROS = 0., 0., 0., 0.
+
+ def testParametersNoPlane(self):
+ """Test Plane.parameters with ||normal|| == 0 ."""
+ plane = utils.Plane()
+ plane.parameters = self.ZEROS
+
+ for parameters in self.ZEROS_PARAMETERS:
+ with self.subTest(parameters=parameters):
+ with AssertNotificationContext(plane, count=0):
+ plane.parameters = parameters
+ self.assertTrue(
+ numpy.allclose(plane.parameters, self.ZEROS, 0., 0.))
+
+
+# unindexArrays ###############################################################
+
+class TestUnindexArrays(ParametricTestCase):
+ """Test unindexArrays function."""
+
+ def testBasicModes(self):
+ """Test for modes: points, lines and triangles"""
+ indices = numpy.array((1, 2, 0))
+ arrays = (numpy.array((0., 1., 2.)),
+ numpy.array(((0, 0), (1, 1), (2, 2))))
+ refresults = (numpy.array((1., 2., 0.)),
+ numpy.array(((1, 1), (2, 2), (0, 0))))
+
+ for mode in ('points', 'lines', 'triangles'):
+ with self.subTest(mode=mode):
+ testresults = utils.unindexArrays(mode, indices, *arrays)
+ for ref, test in zip(refresults, testresults):
+ self.assertTrue(numpy.equal(ref, test).all())
+
+ def testPackedLines(self):
+ """Test for modes: line_strip, loop"""
+ indices = numpy.array((1, 2, 0))
+ arrays = (numpy.array((0., 1., 2.)),
+ numpy.array(((0, 0), (1, 1), (2, 2))))
+ results = {
+ 'line_strip': (
+ numpy.array((1., 2., 2., 0.)),
+ numpy.array(((1, 1), (2, 2), (2, 2), (0, 0)))),
+ 'loop': (
+ numpy.array((1., 2., 2., 0., 0., 1.)),
+ numpy.array(((1, 1), (2, 2), (2, 2), (0, 0), (0, 0), (1, 1)))),
+ }
+
+ for mode, refresults in results.items():
+ with self.subTest(mode=mode):
+ testresults = utils.unindexArrays(mode, indices, *arrays)
+ for ref, test in zip(refresults, testresults):
+ self.assertTrue(numpy.equal(ref, test).all())
+
+ def testPackedTriangles(self):
+ """Test for modes: triangle_strip, fan"""
+ indices = numpy.array((1, 2, 0, 3))
+ arrays = (numpy.array((0., 1., 2., 3.)),
+ numpy.array(((0, 0), (1, 1), (2, 2), (3, 3))))
+ results = {
+ 'triangle_strip': (
+ numpy.array((1., 2., 0., 2., 0., 3.)),
+ numpy.array(((1, 1), (2, 2), (0, 0), (2, 2), (0, 0), (3, 3)))),
+ 'fan': (
+ numpy.array((1., 2., 0., 1., 0., 3.)),
+ numpy.array(((1, 1), (2, 2), (0, 0), (1, 1), (0, 0), (3, 3)))),
+ }
+
+ for mode, refresults in results.items():
+ with self.subTest(mode=mode):
+ testresults = utils.unindexArrays(mode, indices, *arrays)
+ for ref, test in zip(refresults, testresults):
+ self.assertTrue(numpy.equal(ref, test).all())
+
+ def testBadIndices(self):
+ """Test with negative indices and indices higher than array length"""
+ arrays = numpy.array((0, 1)), numpy.array((0, 1, 2))
+
+ # negative indices
+ with self.assertRaises(AssertionError):
+ utils.unindexArrays('points', (-1, 0), *arrays)
+
+ # Too high indices
+ with self.assertRaises(AssertionError):
+ utils.unindexArrays('points', (0, 10), *arrays)
+
+
+# triangleNormals #############################################################
+
+class TestTriangleNormals(ParametricTestCase):
+ """Test triangleNormals function."""
+
+ def test(self):
+ """Test for modes: points, lines and triangles"""
+ positions = numpy.array(
+ ((0., 0., 0.), (1., 0., 0.), (0., 1., 0.), # normal = Z
+ (1., 1., 1.), (1., 2., 3.), (4., 5., 6.), # Random triangle
+ # Degenerated triangles:
+ (0., 0., 0.), (1., 0., 0.), (2., 0., 0.), # Colinear points
+ (1., 1., 1.), (1., 1., 1.), (1., 1., 1.), # All same point
+ ),
+ dtype='float32')
+
+ normals = numpy.array(
+ ((0., 0., 1.),
+ (-0.40824829, 0.81649658, -0.40824829),
+ (0., 0., 0.),
+ (0., 0., 0.)),
+ dtype='float32')
+
+ testnormals = utils.trianglesNormal(positions)
+ self.assertTrue(numpy.allclose(testnormals, normals))
+
+
+# suite #######################################################################
+
+def suite():
+ testsuite = unittest.TestSuite()
+ for test in (TestAngleBetweenVectors,
+ TestPlaneParameters,
+ TestUnindexArrays,
+ TestTriangleNormals):
+ testsuite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(test))
+ return testsuite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/plot3d/scene/text.py b/silx/gui/plot3d/scene/text.py
new file mode 100644
index 0000000..903fc21
--- /dev/null
+++ b/silx/gui/plot3d/scene/text.py
@@ -0,0 +1,534 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Primitive displaying a text field in the scene."""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "17/10/2016"
+
+
+import logging
+import numpy
+
+from silx.gui.plot.Colors import rgba
+
+from ... import _glutils
+from ..._glutils import gl
+
+from ..._glutils import font as _font
+from ...plot._utils import ticklayout
+
+from . import event, primitives, core, transform
+
+
+_logger = logging.getLogger(__name__)
+
+
+class Font(event.Notifier):
+ """Description of a font.
+
+ :param str name: Family of the font
+ :param int size: Size of the font in points
+ :param int weight: Font weight
+ :param bool italic: True for italic font, False (default) otherwise
+ """
+
+ def __init__(self, name=None, size=-1, weight=-1, italic=False):
+ self._name = name if name is not None else _font.getDefaultFontFamily()
+ self._size = size
+ self._weight = weight
+ self._italic = italic
+ super(Font, self).__init__()
+
+ name = event.notifyProperty(
+ '_name',
+ doc="""Name of the font (str)""",
+ converter=str)
+
+ size = event.notifyProperty(
+ '_size',
+ doc="""Font size in points (int)""",
+ converter=int)
+
+ weight = event.notifyProperty(
+ '_weight',
+ doc="""Font size in points (int)""",
+ converter=int)
+
+ italic = event.notifyProperty(
+ '_italic',
+ doc="""True for italic (bool)""",
+ converter=bool)
+
+
+class Text2D(primitives.Geometry):
+ """Text field as a 2D texture displayed with bill-boarding
+
+ :param str text: Text to display
+ :param Font font: The font to use
+ """
+
+ # Text anchor values
+ CENTER = 'center'
+
+ LEFT = 'left'
+ RIGHT = 'right'
+
+ TOP = 'top'
+ BASELINE = 'baseline'
+ BOTTOM = 'bottom'
+
+ _ALIGN = LEFT, CENTER, RIGHT
+ _VALIGN = TOP, BASELINE, CENTER, BOTTOM
+
+ _rasterTextCache = {}
+ """Internal cache storing already rasterized text"""
+ # TODO limit cache size and discard least recent used
+
+ def __init__(self, text='', font=None):
+ self._dirtyTexture = True
+ self._dirtyAlign = True
+ self._baselineOffset = 0
+ self._text = text
+ self._font = font if font is not None else Font()
+ self._foreground = 1., 1., 1., 1.
+ self._background = 0., 0., 0., 0.
+ self._overlay = False
+ self._align = 'left'
+ self._valign = 'baseline'
+ self._devicePixelRatio = 1.0 # Store it to check for changes
+
+ self._texture = None
+ self._textureDirty = True
+
+ super(Text2D, self).__init__(
+ 'triangle_strip',
+ copy=False,
+ # Keep an array for position as it is bound to attr 0 and MUST
+ # be active and an array at least on Mac OS X
+ position=numpy.zeros((4, 3), dtype=numpy.float32),
+ vertexID=numpy.arange(4., dtype=numpy.float32).reshape(4, 1),
+ offsetInViewportCoords=(0., 0.))
+
+ @property
+ def text(self):
+ """Text displayed by this primitive (str)"""
+ return self._text
+
+ @text.setter
+ def text(self, text):
+ text = str(text)
+ if text != self._text:
+ self._dirtyTexture = True
+ self._text = text
+ self.notify()
+
+ @property
+ def font(self):
+ """Font to use to raster text (Font)"""
+ return self._font
+
+ @font.setter
+ def font(self, font):
+ self._font.removeListener(self._fontChanged)
+ self._font = font
+ self._font.addListener(self._fontChanged)
+ self._fontChanged(self) # Which calls notify and primitive as dirty
+
+ def _fontChanged(self, source):
+ """Listen for font change"""
+ self._dirtyTexture = True
+ self.notify()
+
+ foreground = event.notifyProperty(
+ '_foreground', doc="""RGBA color of the text: 4 float in [0, 1]""",
+ converter=rgba)
+
+ background = event.notifyProperty(
+ '_background',
+ doc="RGBA background color of the text field: 4 float in [0, 1]",
+ converter=rgba)
+
+ overlay = event.notifyProperty(
+ '_overlay',
+ doc="True to always display text on top of the scene (default: False)",
+ converter=bool)
+
+ def _setAlign(self, align):
+ assert align in self._ALIGN
+ self._align = align
+ self._dirtyAlign = True
+ self.notify()
+
+ align = property(
+ lambda self: self._align,
+ _setAlign,
+ doc="""Horizontal anchor position of the text field (str).
+
+ Either 'left' (default), 'center' or 'right'.""")
+
+ def _setVAlign(self, valign):
+ assert valign in self._VALIGN
+ self._valign = valign
+ self._dirtyAlign = True
+ self.notify()
+
+ valign = property(
+ lambda self: self._valign,
+ _setVAlign,
+ doc="""Vertical anchor position of the text field (str).
+
+ Either 'top', 'baseline' (default), 'center' or 'bottom'""")
+
+ def _raster(self, devicePixelRatio):
+ """Raster current primitive to a bitmap
+
+ :param float devicePixelRatio:
+ The ratio between device and device-independent pixels
+ :return: Corresponding image in grayscale and baseline offset from top
+ :rtype: (HxW numpy.ndarray of uint8, int)
+ """
+ params = (self.text,
+ self.font.name,
+ self.font.size,
+ self.font.weight,
+ self.font.italic,
+ devicePixelRatio)
+
+ if params not in self._rasterTextCache: # Add to cache
+ self._rasterTextCache[params] = _font.rasterText(*params)
+
+ array, offset = self._rasterTextCache[params]
+ return array.copy(), offset
+
+ def _bounds(self, dataBounds=False):
+ return None
+
+ def prepareGL2(self, context):
+ # Check if devicePixelRatio has changed since last rendering
+ devicePixelRatio = context.glCtx.devicePixelRatio
+ if self._devicePixelRatio != devicePixelRatio:
+ self._devicePixelRatio = devicePixelRatio
+ self._dirtyTexture = True
+
+ if self._dirtyTexture:
+ self._dirtyTexture = False
+
+ if self._texture is not None:
+ self._texture.discard()
+ self._texture = None
+ self._baselineOffset = 0
+
+ if self.text:
+ image, self._baselineOffset = self._raster(
+ self._devicePixelRatio)
+ self._texture = _glutils.Texture(
+ gl.GL_R8, image, gl.GL_RED,
+ minFilter=gl.GL_NEAREST,
+ magFilter=gl.GL_NEAREST,
+ wrap=gl.GL_CLAMP_TO_EDGE)
+ self._dirtyAlign = True # To force update of offset
+
+ if self._dirtyAlign:
+ self._dirtyAlign = False
+
+ if self._texture is not None:
+ height, width = self._texture.shape
+
+ if self._align == 'left':
+ ox = 0.
+ elif self._align == 'center':
+ ox = - width // 2
+ elif self._align == 'right':
+ ox = - width
+ else:
+ _logger.error("Unsupported align: %s", self._align)
+ ox = 0.
+
+ if self._valign == 'top':
+ oy = 0.
+ elif self._valign == 'baseline':
+ oy = self._baselineOffset
+ elif self._valign == 'center':
+ oy = height // 2
+ elif self._valign == 'bottom':
+ oy = height
+ else:
+ _logger.error("Unsupported valign: %s", self._valign)
+ oy = 0.
+
+ offsets = (ox, oy) + numpy.array(
+ ((0., 0.), (width, 0.), (0., -height), (width, -height)),
+ dtype=numpy.float32)
+ self.setAttribute('offsetInViewportCoords', offsets)
+
+ super(Text2D, self).prepareGL2(context)
+
+ def renderGL2(self, context):
+ if not self.text:
+ return # Nothing to render
+
+ program = context.glCtx.prog(*self._shaders)
+ program.use()
+
+ program.setUniformMatrix('matrix', context.objectToNDC.matrix)
+ gl.glUniform2f(
+ program.uniforms['viewportSize'], *context.viewport.size)
+ gl.glUniform4f(program.uniforms['foreground'], *self.foreground)
+ gl.glUniform4f(program.uniforms['background'], *self.background)
+ gl.glUniform1i(program.uniforms['texture'], self._texture.texUnit)
+ gl.glUniform1i(program.uniforms['isOverlay'],
+ 1 if self._overlay else 0)
+
+ self._texture.bind()
+
+ if not self._overlay or not gl.glGetBoolean(gl.GL_DEPTH_TEST):
+ self._draw(program)
+ else: # overlay and depth test currently enabled
+ gl.glDisable(gl.GL_DEPTH_TEST)
+ self._draw(program)
+ gl.glEnable(gl.GL_DEPTH_TEST)
+
+ # TODO texture atlas + viewportSize as attribute to chain text rendering
+
+ _shaders = (
+ """
+ attribute vec3 position;
+ attribute vec2 offsetInViewportCoords; /* Offset in pixels (y upward) */
+ attribute float vertexID; /* Index of rectangle corner */
+
+ uniform mat4 matrix;
+ uniform vec2 viewportSize; /* Width, height of the viewport */
+ uniform int isOverlay;
+
+ varying vec2 texCoords;
+
+ void main(void)
+ {
+ vec4 clipPos = matrix * vec4(position, 1.0);
+ vec4 ndcPos = clipPos / clipPos.w; /* Perspective divide */
+
+ /* Align ndcPos with pixels in viewport-like coords (origin useless) */
+ vec2 viewportPos = floor((ndcPos.xy + vec2(1.0, 1.0)) * 0.5 * viewportSize);
+
+ /* Apply offset in viewport coords */
+ viewportPos += offsetInViewportCoords;
+
+ /* Convert back to NDC */
+ vec2 pointPos = 2.0 * viewportPos / viewportSize - vec2(1.0, 1.0);
+ float z = (isOverlay != 0) ? -1.0 : ndcPos.z;
+ gl_Position = vec4(pointPos, z, 1.0);
+
+ /* Index : texCoords:
+ * 0: (0., 0.)
+ * 1: (1., 0.)
+ * 2: (0., 1.)
+ * 3: (1., 1.)
+ */
+ texCoords = vec2(vertexID == 0.0 || vertexID == 2.0 ? 0.0 : 1.0,
+ vertexID < 1.5 ? 0.0 : 1.0);
+ }
+ """, # noqa
+
+ """
+ varying vec2 texCoords;
+
+ uniform vec4 foreground;
+ uniform vec4 background;
+ uniform sampler2D texture;
+
+ void main(void)
+ {
+ float value = texture2D(texture, texCoords).r;
+
+ if (background.a != 0.0) {
+ gl_FragColor = mix(background, foreground, value);
+ } else {
+ gl_FragColor = foreground;
+ gl_FragColor.a *= value;
+ if (gl_FragColor.a <= 0.01) {
+ discard;
+ }
+ }
+ }
+ """)
+
+
+class LabelledAxes(primitives.GroupBBox):
+ """A group displaying a bounding box with axes labels around its children.
+ """
+
+ def __init__(self):
+ super(LabelledAxes, self).__init__()
+ self._ticksForBounds = None
+
+ self._font = Font()
+
+ # TODO offset labels from anchor in pixels
+
+ self._xlabel = Text2D(font=self._font)
+ self._xlabel.align = 'center'
+ self._xlabel.transforms = [self._boxTransforms,
+ transform.Translate(tx=0.5)]
+ self._children.append(self._xlabel)
+
+ self._ylabel = Text2D(font=self._font)
+ self._ylabel.align = 'center'
+ self._ylabel.transforms = [self._boxTransforms,
+ transform.Translate(ty=0.5)]
+ self._children.append(self._ylabel)
+
+ self._zlabel = Text2D(font=self._font)
+ self._zlabel.align = 'center'
+ self._zlabel.transforms = [self._boxTransforms,
+ transform.Translate(tz=0.5)]
+ self._children.append(self._zlabel)
+
+ self._tickLines = primitives.Lines( # Init tick lines with dummy pos
+ positions=((0., 0., 0.), (0., 0., 0.)),
+ mode='lines')
+ self._tickLines.visible = False
+ self._children.append(self._tickLines)
+
+ self._tickLabels = core.Group()
+ self._children.append(self._tickLabels)
+
+ @property
+ def font(self):
+ """Font of axes text labels (Font)"""
+ return self._font
+
+ @font.setter
+ def font(self, font):
+ self._font = font
+ self._xlabel.font = font
+ self._ylabel.font = font
+ self._zlabel.font = font
+ for label in self._tickLabels.children:
+ label.font = font
+
+ @property
+ def xlabel(self):
+ """Text label of the X axis (str)"""
+ return self._xlabel.text
+
+ @xlabel.setter
+ def xlabel(self, text):
+ self._xlabel.text = text
+
+ @property
+ def ylabel(self):
+ """Text label of the Y axis (str)"""
+ return self._ylabel.text
+
+ @ylabel.setter
+ def ylabel(self, text):
+ self._ylabel.text = text
+
+ @property
+ def zlabel(self):
+ """Text label of the Z axis (str)"""
+ return self._zlabel.text
+
+ @zlabel.setter
+ def zlabel(self, text):
+ self._zlabel.text = text
+
+ def _updateTicks(self):
+ """Check if ticks need update and update them if needed."""
+ bounds = self._group.bounds(transformed=False, dataBounds=True)
+ if bounds is None: # No content
+ if self._ticksForBounds is not None:
+ self._ticksForBounds = None
+ self._tickLines.visible = False
+ self._tickLabels.children = [] # Reset previous labels
+
+ elif (self._ticksForBounds is None or
+ not numpy.all(numpy.equal(bounds, self._ticksForBounds))):
+ self._ticksForBounds = bounds
+
+ # Update ticks
+ # TODO make ticks having a constant length on the screen
+ ticklength = numpy.abs(bounds[1] - bounds[0]) / 20.
+
+ xticks, xlabels = ticklayout.ticks(*bounds[:, 0])
+ yticks, ylabels = ticklayout.ticks(*bounds[:, 1])
+ zticks, zlabels = ticklayout.ticks(*bounds[:, 2])
+
+ # Update tick lines
+ coords = numpy.empty(
+ ((len(xticks) + len(yticks) + len(zticks)), 4, 3),
+ dtype=numpy.float32)
+ coords[:, :, :] = bounds[0, :] # account for offset from origin
+
+ xcoords = coords[:len(xticks)]
+ xcoords[:, :, 0] = numpy.asarray(xticks)[:, numpy.newaxis]
+ xcoords[:, 1, 1] += ticklength[1] # X ticks on XY plane
+ xcoords[:, 3, 2] += ticklength[2] # X ticks on XZ plane
+
+ ycoords = coords[len(xticks):len(xticks) + len(yticks)]
+ ycoords[:, :, 1] = numpy.asarray(yticks)[:, numpy.newaxis]
+ ycoords[:, 1, 0] += ticklength[0] # Y ticks on XY plane
+ ycoords[:, 3, 2] += ticklength[2] # Y ticks on YZ plane
+
+ zcoords = coords[len(xticks) + len(yticks):]
+ zcoords[:, :, 2] = numpy.asarray(zticks)[:, numpy.newaxis]
+ zcoords[:, 1, 0] += ticklength[0] # Z ticks on XZ plane
+ zcoords[:, 3, 1] += ticklength[1] # Z ticks on YZ plane
+
+ self._tickLines.setAttribute('position', coords.reshape(-1, 3))
+ self._tickLines.visible = True
+
+ # Update labels
+ offsets = bounds[0] - ticklength
+ labels = []
+ for tick, label in zip(xticks, xlabels):
+ text = Text2D(text=label, font=self.font)
+ text.align = 'center'
+ text.transforms = [transform.Translate(
+ tx=tick, ty=offsets[1], tz=offsets[2])]
+ labels.append(text)
+
+ for tick, label in zip(yticks, ylabels):
+ text = Text2D(text=label, font=self.font)
+ text.align = 'center'
+ text.transforms = [transform.Translate(
+ tx=offsets[0], ty=tick, tz=offsets[2])]
+ labels.append(text)
+
+ for tick, label in zip(zticks, zlabels):
+ text = Text2D(text=label, font=self.font)
+ text.align = 'center'
+ text.transforms = [transform.Translate(
+ tx=offsets[0], ty=offsets[1], tz=tick)]
+ labels.append(text)
+
+ self._tickLabels.children = labels # Reset previous labels
+
+ def prepareGL2(self, context):
+ self._updateTicks()
+ super(LabelledAxes, self).prepareGL2(context)
diff --git a/silx/gui/plot3d/scene/transform.py b/silx/gui/plot3d/scene/transform.py
new file mode 100644
index 0000000..71a6b74
--- /dev/null
+++ b/silx/gui/plot3d/scene/transform.py
@@ -0,0 +1,968 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides 4x4 matrix operation and classes to handle them."""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import itertools
+import numpy
+
+from . import event
+
+
+# Functions ###################################################################
+
+# Projections
+
+def mat4LookAtDir(position, direction, up):
+ """Creates matrix to look in direction from position.
+
+ :param position: Array-like 3 coordinates of the point of view position.
+ :param direction: Array-like 3 coordinates of the sight direction vector.
+ :param up: Array-like 3 coordinates of the upward direction
+ in the image plane.
+ :returns: Corresponding matrix.
+ :rtype: numpy.ndarray of shape (4, 4)
+ """
+ assert len(position) == 3
+ assert len(direction) == 3
+ assert len(up) == 3
+
+ direction = numpy.array(direction, copy=True, dtype=numpy.float32)
+ dirnorm = numpy.linalg.norm(direction)
+ assert dirnorm != 0.
+ direction /= dirnorm
+
+ side = numpy.cross(direction,
+ numpy.array(up, copy=False, dtype=numpy.float32))
+ sidenorm = numpy.linalg.norm(side)
+ assert sidenorm != 0.
+ up = numpy.cross(side / sidenorm, direction)
+ upnorm = numpy.linalg.norm(up)
+ assert upnorm != 0.
+ up /= upnorm
+
+ matrix = numpy.identity(4, dtype=numpy.float32)
+ matrix[0, :3] = side
+ matrix[1, :3] = up
+ matrix[2, :3] = -direction
+ return numpy.dot(matrix,
+ mat4Translate(-position[0], -position[1], -position[2]))
+
+
+def mat4LookAt(position, center, up):
+ """Creates matrix to look at center from position.
+
+ See gluLookAt.
+
+ :param position: Array-like 3 coordinates of the point of view position.
+ :param center: Array-like 3 coordinates of the center of the scene.
+ :param up: Array-like 3 coordinates of the upward direction
+ in the image plane.
+ :returns: Corresponding matrix.
+ :rtype: numpy.ndarray of shape (4, 4)
+ """
+ position = numpy.array(position, copy=False, dtype=numpy.float32)
+ center = numpy.array(center, copy=False, dtype=numpy.float32)
+ direction = center - position
+ return mat4LookAtDir(position, direction, up)
+
+
+def mat4Frustum(left, right, bottom, top, near, far):
+ """Creates a frustum projection matrix.
+
+ See glFrustum.
+ """
+ return numpy.array((
+ (2.*near / (right-left), 0., (right+left) / (right-left), 0.),
+ (0., 2.*near / (top-bottom), (top+bottom) / (top-bottom), 0.),
+ (0., 0., -(far+near) / (far-near), -2.*far*near / (far-near)),
+ (0., 0., -1., 0.)), dtype=numpy.float32)
+
+
+def mat4Perspective(fovy, width, height, near, far):
+ """Creates a perspective projection matrix.
+
+ Similar to gluPerspective.
+
+ :param float fovy: Field of view angle in degrees in the y direction.
+ :param float width: Width of the viewport.
+ :param float height: Height of the viewport.
+ :param float near: Distance to the near plane (strictly positive).
+ :param float far: Distance to the far plane (strictly positive).
+ :return: Corresponding matrix.
+ :rtype: numpy.ndarray of shape (4, 4)
+ """
+ assert fovy != 0
+ assert height != 0
+ assert width != 0
+ assert near > 0.
+ assert far > near
+ aspectratio = width / height
+ f = 1. / numpy.tan(numpy.radians(fovy) / 2.)
+ return numpy.array((
+ (f / aspectratio, 0., 0., 0.),
+ (0., f, 0., 0.),
+ (0., 0., (far + near) / (near - far), 2. * far * near / (near - far)),
+ (0., 0., -1., 0.)), dtype=numpy.float32)
+
+
+def mat4Orthographic(left, right, bottom, top, near, far):
+ """Creates an orthographic (i.e., parallel) projection matrix.
+
+ See glOrtho.
+ """
+ return numpy.array((
+ (2. / (right - left), 0., 0., - (right + left) / (right - left)),
+ (0., 2. / (top - bottom), 0., - (top + bottom) / (top - bottom)),
+ (0., 0., -2. / (far - near), - (far + near) / (far - near)),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+
+# Affine
+
+def mat4Translate(tx, ty, tz):
+ """4x4 translation matrix."""
+ return numpy.array((
+ (1., 0., 0., tx),
+ (0., 1., 0., ty),
+ (0., 0., 1., tz),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+
+def mat4Scale(sx, sy, sz):
+ """4x4 scale matrix."""
+ return numpy.array((
+ (sx, 0., 0., 0.),
+ (0., sy, 0., 0.),
+ (0., 0., sz, 0.),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+
+def mat4RotateFromAngleAxis(angle, x=0., y=0., z=1.):
+ """4x4 rotation matrix from angle and axis.
+
+ :param float angle: The rotation angle in radians.
+ :param float x: The rotation vector x coordinate.
+ :param float y: The rotation vector y coordinate.
+ :param float z: The rotation vector z coordinate.
+ """
+ ca = numpy.cos(angle)
+ sa = numpy.sin(angle)
+ return numpy.array((
+ ((1.-ca) * x*x + ca, (1.-ca) * x*y - sa*z, (1.-ca) * x*z + sa*y, 0.),
+ ((1.-ca) * x*y + sa*z, (1.-ca) * y*y + ca, (1.-ca) * y*z - sa*x, 0.),
+ ((1.-ca) * x*z - sa*y, (1.-ca) * y*z + sa*x, (1.-ca) * z*z + ca, 0.),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+
+def mat4RotateFromQuaternion(quaternion):
+ """4x4 rotation matrix from quaternion.
+
+ :param quaternion: Array-like unit quaternion stored as (x, y, z, w)
+ """
+ quaternion = numpy.array(quaternion, copy=True)
+ quaternion /= numpy.linalg.norm(quaternion)
+
+ qx, qy, qz, qw = quaternion
+ return numpy.array((
+ (1. - 2.*(qy**2 + qz**2), 2.*(qx*qy - qw*qz), 2.*(qx*qz + qw*qy), 0.),
+ (2.*(qx*qy + qw*qz), 1. - 2.*(qx**2 + qz**2), 2.*(qy*qz - qw*qx), 0.),
+ (2.*(qx*qz - qw*qy), 2.*(qy*qz + qw*qx), 1. - 2.*(qx**2 + qy**2), 0.),
+ (0., 0., 0., 1.)), dtype=numpy.float32)
+
+
+def mat4Shear(axis, sx=0., sy=0., sz=0.):
+ """4x4 shear matrix: Skew two axes relative to a third fixed one.
+
+ shearFactor = tan(shearAngle)
+
+ :param str axis: The axis to keep constant and shear against.
+ In 'x', 'y', 'z'.
+ :param float sx: The shear factor for the X axis relative to axis.
+ :param float sy: The shear factor for the Y axis relative to axis.
+ :param float sz: The shear factor for the Z axis relative to axis.
+ """
+ assert axis in ('x', 'y', 'z')
+
+ matrix = numpy.identity(4, dtype=numpy.float32)
+
+ # Make the shear column
+ index = 'xyz'.find(axis)
+ shearcolumn = numpy.array((sx, sy, sz, 0.), dtype=numpy.float32)
+ shearcolumn[index] = 1.
+ matrix[:, index] = shearcolumn
+ return matrix
+
+
+# Transforms ##################################################################
+
+class Transform(event.Notifier):
+
+ def __init__(self, static=False):
+ """Base class for (row-major) 4x4 matrix transforms.
+
+ :param bool static: False (default) to reset cache when changed,
+ True for static matrices.
+ """
+ super(Transform, self).__init__()
+ self._matrix = None
+ self._inverse = None
+ if not static:
+ self.addListener(self._changed) # Listening self for changes
+
+ def __repr__(self):
+ return '%s(%s)' % (self.__class__.__init__,
+ repr(self.getMatrix(copy=False)))
+
+ def inverse(self):
+ """Return the Transform of the inverse.
+
+ The returned Transform is static, it is not updated when this
+ Transform is modified.
+
+ :return: A Transform which is the inverse of this Transform.
+ """
+ return Inverse(self)
+
+ # Matrix
+
+ def _makeMatrix(self):
+ """Override to build matrix"""
+ return numpy.identity(4, dtype=numpy.float32)
+
+ def _makeInverse(self):
+ """Override to build inverse matrix."""
+ return numpy.linalg.inv(self.getMatrix(copy=False))
+
+ def getMatrix(self, copy=True):
+ """The 4x4 matrix of this transform.
+
+ :param bool copy: True (the default) to get a copy of the matrix,
+ False to get the internal matrix, do not modify!
+ :return: 4x4 matrix of this transform.
+ """
+ if self._matrix is None:
+ self._matrix = self._makeMatrix()
+ if copy:
+ return self._matrix.copy()
+ else:
+ return self._matrix
+
+ matrix = property(getMatrix, doc="The 4x4 matrix of this transform.")
+
+ def getInverseMatrix(self, copy=False):
+ """The 4x4 matrix of the inverse of this transform.
+
+ :param bool copy: True (the default) to get a copy of the matrix,
+ False to get the internal matrix, do not modify!
+ :return: 4x4 matrix of the inverse of this transform.
+ """
+ if self._inverse is None:
+ self._inverse = self._makeInverse()
+ if copy:
+ return self._inverse.copy()
+ else:
+ return self._inverse
+
+ inverseMatrix = property(
+ getInverseMatrix,
+ doc="The 4x4 matrix of the inverse of this transform.")
+
+ # Listener
+
+ def _changed(self, source):
+ """Default self listener reseting matrix cache."""
+ self._matrix = None
+ self._inverse = None
+
+ # Multiplication with vectors
+
+ @staticmethod
+ def _prepareVector(vector, w):
+ """Add 4th coordinate (w) to vector if missing."""
+ assert len(vector) in (3, 4)
+ vector = numpy.array(vector, copy=False, dtype=numpy.float32)
+ if len(vector) == 3:
+ vector = numpy.append(vector, w)
+ return vector
+
+ def transformPoint(self, point, direct=True, perspectiveDivide=False):
+ """Apply the transform to a point.
+
+ If len(point) == 3, apply persective divide if possible.
+
+ :param point: Array-like vector of 3 or 4 coordinates.
+ :param bool direct: Whether to apply the direct (True, the default)
+ or inverse (False) transform.
+ :param bool perspectiveDivide: Whether to apply the perspective divide
+ (True) or not (False, the default).
+ :return: The transformed point.
+ :rtype: numpy.ndarray of same length as point.
+ """
+ if direct:
+ matrix = self.getMatrix(copy=False)
+ else:
+ matrix = self.getInverseMatrix(copy=False)
+ result = numpy.dot(matrix, self._prepareVector(point, 1.))
+
+ if perspectiveDivide and result[3] != 0.:
+ result /= result[3]
+
+ if len(point) == 3:
+ return result[:3]
+ else:
+ return result
+
+ def transformDir(self, direction, direct=True):
+ """Apply the transform to a direction.
+
+ :param direction: Array-like vector of 3 coordinates.
+ :param bool direct: Whether to apply the direct (True, the default)
+ or inverse (False) transform.
+ :return: The transformed direction.
+ :rtype: numpy.ndarray of length 3.
+ """
+ if direct:
+ matrix = self.getMatrix(copy=False)
+ else:
+ matrix = self.getInverseMatrix(copy=False)
+ return numpy.dot(matrix[:3, :3], direction[:3])
+
+ def transformNormal(self, normal, direct=True):
+ """Apply the transform to a normal: R = (M-1)t * V.
+
+ :param normal: Array-like vector of 3 coordinates.
+ :param bool direct: Whether to apply the direct (True, the default)
+ or inverse (False) transform.
+ :return: The transformed normal.
+ :rtype: numpy.ndarray of length 3.
+ """
+ if direct:
+ matrix = self.getInverseMatrix(copy=False).T
+ else:
+ matrix = self.getMatrix(copy=False).T
+ return numpy.dot(matrix[:3, :3], normal[:3])
+
+ _CUBE_CORNERS = numpy.array(list(itertools.product((0., 1.), repeat=3)),
+ dtype=numpy.float32)
+ """Unit cube corners used by :meth:`transformRectangularBox`"""
+
+ def transformBounds(self, bounds, direct=True):
+ """Apply the transform to an axes-aligned rectangular box.
+
+ :param bounds: Min and max coords of the box for each axes.
+ :type bounds: 2x3 numpy.ndarray
+ :param bool direct: Whether to apply the direct (True, the default)
+ or inverse (False) transform.
+ :return: Axes-aligned rectangular box including the transformed box.
+ :rtype: 2x3 numpy.ndarray of float32
+ """
+ corners = numpy.ones((8, 4), dtype=numpy.float32)
+ corners[:, :3] = bounds[0] + \
+ self._CUBE_CORNERS * (bounds[1] - bounds[0])
+
+ if direct:
+ matrix = self.getMatrix(copy=False)
+ else:
+ matrix = self.getInverseMatrix(copy=False)
+
+ # Transform corners
+ cornerstransposed = numpy.dot(matrix, corners.T)
+ cornerstransposed = cornerstransposed / cornerstransposed[3]
+
+ # Get min/max for each axis
+ transformedbounds = numpy.empty((2, 3), dtype=numpy.float32)
+ transformedbounds[0] = cornerstransposed.T[:, :3].min(axis=0)
+ transformedbounds[1] = cornerstransposed.T[:, :3].max(axis=0)
+
+ return transformedbounds
+
+
+class Inverse(Transform):
+ """Transform which is the inverse of another one.
+
+ Static: It never gets updated.
+ """
+
+ def __init__(self, transform):
+ """Initializer.
+
+ :param Transform transform: The transform to invert.
+ """
+
+ super(Inverse, self).__init__(static=True)
+ self._matrix = transform.getInverseMatrix(copy=True)
+ self._inverse = transform.getMatrix(copy=True)
+
+
+class TransformList(Transform, event.HookList):
+ """List of transforms."""
+
+ def __init__(self, iterable=()):
+ Transform.__init__(self)
+ event.HookList.__init__(self, iterable)
+
+ def _listWillChangeHook(self, methodName, *args, **kwargs):
+ for item in self:
+ item.removeListener(self._transformChanged)
+
+ def _listWasChangedHook(self, methodName, *args, **kwargs):
+ for item in self:
+ item.addListener(self._transformChanged)
+ self.notify()
+
+ def _transformChanged(self, source):
+ """Listen to transform changes of the list and its items."""
+ if source is not self: # Avoid infinite recursion
+ self.notify()
+
+ def _makeMatrix(self):
+ matrix = numpy.identity(4, dtype=numpy.float32)
+ for transform in self:
+ matrix = numpy.dot(matrix, transform.getMatrix(copy=False))
+ return matrix
+
+
+class StaticTransformList(Transform):
+ """Transform that is a snapshot of a list of Transforms
+
+ It does not keep reference to the list of Transforms.
+
+ :param iterable: Iterable of Transform used for initialization
+ """
+
+ def __init__(self, iterable=()):
+ super(StaticTransformList, self).__init__(static=True)
+ matrix = numpy.identity(4, dtype=numpy.float32)
+ for transform in iterable:
+ matrix = numpy.dot(matrix, transform.getMatrix(copy=False))
+ self._matrix = matrix # Init matrix once
+
+
+# Affine ######################################################################
+
+class Matrix(Transform):
+
+ def __init__(self, matrix=None):
+ """4x4 Matrix.
+
+ :param matrix: 4x4 array-like matrix or None for identity matrix.
+ """
+ super(Matrix, self).__init__(static=True)
+ self.setMatrix(matrix)
+
+ def setMatrix(self, matrix=None):
+ """Update the 4x4 Matrix.
+
+ :param matrix: 4x4 array-like matrix or None for identity matrix.
+ """
+ if matrix is None:
+ self._matrix = numpy.identity(4, dtype=numpy.float32)
+ else:
+ matrix = numpy.array(matrix, copy=True, dtype=numpy.float32)
+ assert matrix.shape == (4, 4)
+ self._matrix = matrix
+ # Reset cached inverse as Transform is declared static
+ self._inverse = None
+ self.notify()
+
+ # Redefined here to add a setter
+ matrix = property(Transform.getMatrix, setMatrix,
+ doc="The 4x4 matrix of this transform.")
+
+
+class Translate(Transform):
+ """4x4 translation matrix."""
+
+ def __init__(self, tx=0., ty=0., tz=0.):
+ super(Translate, self).__init__()
+ self._tx, self._ty, self._tz = 0., 0., 0.
+ self.setTranslate(tx, ty, tz)
+
+ def _makeMatrix(self):
+ return mat4Translate(self.tx, self.ty, self.tz)
+
+ def _makeInverse(self):
+ return mat4Translate(-self.tx, -self.ty, -self.tz)
+
+ @property
+ def tx(self):
+ return self._tx
+
+ @tx.setter
+ def tx(self, tx):
+ self.setTranslate(tx=tx)
+
+ @property
+ def ty(self):
+ return self._ty
+
+ @ty.setter
+ def ty(self, ty):
+ self.setTranslate(ty=ty)
+
+ @property
+ def tz(self):
+ return self._tz
+
+ @tz.setter
+ def tz(self, tz):
+ self.setTranslate(tz=tz)
+
+ @property
+ def translation(self):
+ return numpy.array((self.tx, self.ty, self.tz), dtype=numpy.float32)
+
+ @translation.setter
+ def translation(self, translations):
+ tx, ty, tz = translations
+ self.setTranslate(tx, ty, tz)
+
+ def setTranslate(self, tx=None, ty=None, tz=None):
+ if tx is not None:
+ self._tx = tx
+ if ty is not None:
+ self._ty = ty
+ if tz is not None:
+ self._tz = tz
+ self.notify()
+
+
+class Scale(Transform):
+ """4x4 scale matrix."""
+
+ def __init__(self, sx=1., sy=1., sz=1.):
+ super(Scale, self).__init__()
+ self._sx, self._sy, self._sz = 0., 0., 0.
+ self.setScale(sx, sy, sz)
+
+ def _makeMatrix(self):
+ return mat4Scale(self.sx, self.sy, self.sz)
+
+ def _makeInverse(self):
+ return mat4Scale(1. / self.sx, 1. / self.sy, 1. / self.sz)
+
+ @property
+ def sx(self):
+ return self._sx
+
+ @sx.setter
+ def sx(self, sx):
+ self.setScale(sx=sx)
+
+ @property
+ def sy(self):
+ return self._sy
+
+ @sy.setter
+ def sy(self, sy):
+ self.setScale(sy=sy)
+
+ @property
+ def sz(self):
+ return self._sz
+
+ @sz.setter
+ def sz(self, sz):
+ self.setScale(sz=sz)
+
+ @property
+ def scale(self):
+ return numpy.array((self._sx, self._sy, self._sz), dtype=numpy.float32)
+
+ @scale.setter
+ def scale(self, scales):
+ sx, sy, sz = scales
+ self.setScale(sx, sy, sz)
+
+ def setScale(self, sx=None, sy=None, sz=None):
+ if sx is not None:
+ assert sx != 0.
+ self._sx = sx
+ if sy is not None:
+ assert sy != 0.
+ self._sy = sy
+ if sz is not None:
+ assert sz != 0.
+ self._sz = sz
+ self.notify()
+
+
+class Rotate(Transform):
+
+ def __init__(self, angle=0., ax=0., ay=0., az=1.):
+ """4x4 rotation matrix.
+
+ :param float angle: The rotation angle in degrees.
+ :param float ax: The x coordinate of the rotation axis.
+ :param float ay: The y coordinate of the rotation axis.
+ :param float az: The z coordinate of the rotation axis.
+ """
+ super(Rotate, self).__init__()
+ self._angle = 0.
+ self._axis = None
+ self.setAngleAxis(angle, (ax, ay, az))
+
+ @property
+ def angle(self):
+ """The rotation angle in degrees."""
+ return self._angle
+
+ @angle.setter
+ def angle(self, angle):
+ self.setAngleAxis(angle=angle)
+
+ @property
+ def axis(self):
+ """The normalized rotation axis as a numpy.ndarray."""
+ return self._axis.copy()
+
+ @axis.setter
+ def axis(self, axis):
+ self.setAngleAxis(axis=axis)
+
+ def setAngleAxis(self, angle=None, axis=None):
+ """Update the angle and/or axis of the rotation.
+
+ :param float angle: The rotation angle in degrees.
+ :param axis: Array-like axis vector (3 coordinates).
+ """
+ if angle is not None:
+ self._angle = angle
+ if axis is not None:
+ assert len(axis) == 3
+ axis = numpy.array(axis, copy=True, dtype=numpy.float32)
+ assert axis.size == 3
+ norm = numpy.linalg.norm(axis)
+ if norm == 0.: # No axis, set rotation angle to 0.
+ self._angle = 0.
+ self._axis = numpy.array((0., 0., 1.), dtype=numpy.float32)
+ else:
+ self._axis = axis / norm
+
+ if angle is not None or axis is not None:
+ self.notify()
+
+ @property
+ def quaternion(self):
+ """Rotation unit quaternion as (x, y, z, w).
+
+ Where: ||(x, y, z)|| = sin(angle/2), w = cos(angle/2).
+ """
+ if numpy.linalg.norm(self._axis) == 0.:
+ return numpy.array((0., 0., 0., 1.), dtype=numpy.float32)
+
+ else:
+ quaternion = numpy.empty((4,), dtype=numpy.float32)
+ halfangle = 0.5 * numpy.radians(self.angle)
+ quaternion[0:3] = numpy.sin(halfangle) * self._axis
+ quaternion[3] = numpy.cos(halfangle)
+ return quaternion
+
+ @quaternion.setter
+ def quaternion(self, quaternion):
+ assert len(quaternion) == 4
+
+ # Normalize quaternion
+ quaternion = numpy.array(quaternion, copy=True)
+ quaternion /= numpy.linalg.norm(quaternion)
+
+ # Get angle
+ sinhalfangle = numpy.linalg.norm(quaternion[0:3])
+ coshalfangle = quaternion[3]
+ angle = 2. * numpy.arctan2(sinhalfangle, coshalfangle)
+
+ # Axis will be normalized in setAngleAxis
+ self.setAngleAxis(numpy.degrees(angle), quaternion[0:3])
+
+ def _makeMatrix(self):
+ angle = numpy.radians(self.angle, dtype=numpy.float32)
+ return mat4RotateFromAngleAxis(angle, *self.axis)
+
+ def _makeInverse(self):
+ return numpy.array(self.getMatrix(copy=False).transpose(),
+ copy=True, order='C',
+ dtype=numpy.float32)
+
+
+class Shear(Transform):
+
+ def __init__(self, axis, sx=0., sy=0., sz=0.):
+ """4x4 shear/skew matrix of 2 axes relative to the third one.
+
+ :param str axis: The axis to keep fixed, in 'x', 'y', 'z'
+ :param float sx: The shear factor for the x axis.
+ :param float sy: The shear factor for the y axis.
+ :param float sz: The shear factor for the z axis.
+ """
+ assert axis in ('x', 'y', 'z')
+ super(Shear, self).__init__()
+ self._axis = axis
+ self._factors = sx, sy, sz
+
+ @property
+ def axis(self):
+ """The axis against which other axes are skewed."""
+ return self._axis
+
+ @property
+ def factors(self):
+ """The shear factors: shearFactor = tan(shearAngle)"""
+ return self._factors
+
+ def _makeMatrix(self):
+ return mat4Shear(self.axis, *self.factors)
+
+ def _makeInverse(self):
+ sx, sy, sz = self.factors
+ return mat4Shear(self.axis, -sx, -sy, -sz)
+
+
+# Projection ##################################################################
+
+class _Projection(Transform):
+ """Base class for projection matrix.
+
+ Handles near and far clipping plane values.
+ Subclasses must implement :meth:`_makeMatrix`.
+
+ :param float near: Distance to the near plane.
+ :param float far: Distance to the far plane.
+ :param bool checkDepthExtent: Toggle checks near > 0 and far > near.
+ :param size: Viewport's size used to compute the aspect ratio.
+ :type size: 2-tuple of float (width, height).
+ """
+
+ def __init__(self, near, far, checkDepthExtent=False, size=(1., 1.)):
+ super(_Projection, self).__init__()
+ self._checkDepthExtent = checkDepthExtent
+ self._depthExtent = 1, 10
+ self.setDepthExtent(near, far) # set _depthExtent
+ self._size = 1., 1.
+ self.size = size # set _size
+
+ def setDepthExtent(self, near=None, far=None):
+ """Set the extent of the visible area along the viewing direction.
+
+ :param float near: The near clipping plane Z coord.
+ :param float far: The far clipping plane Z coord.
+ """
+ near = float(near) if near is not None else self._depthExtent[0]
+ far = float(far) if far is not None else self._depthExtent[1]
+
+ if self._checkDepthExtent:
+ assert near > 0.
+ assert far > near
+
+ self._depthExtent = near, far
+ self.notify()
+
+ @property
+ def near(self):
+ """Distance to the near plane."""
+ return self._depthExtent[0]
+
+ @near.setter
+ def near(self, near):
+ if near != self.near:
+ self.setDepthExtent(near=near)
+
+ @property
+ def far(self):
+ """Distance to the far plane."""
+ return self._depthExtent[1]
+
+ @far.setter
+ def far(self, far):
+ if far != self.far:
+ self.setDepthExtent(far=far)
+
+ @property
+ def size(self):
+ """Viewport size as a 2-tuple of float (width, height)."""
+ return self._size
+
+ @size.setter
+ def size(self, size):
+ assert len(size) == 2
+ self._size = tuple(size)
+ self.notify()
+
+
+class Orthographic(_Projection):
+ """Orthographic (i.e., parallel) projection which keeps aspect ratio.
+
+ Clipping planes are adjusted to match the aspect ratio of
+ the :attr:`size` attribute.
+
+ The left, right, bottom and top parameters defines the area which must
+ always remain visible.
+ Effective clipping planes are adjusted to keep the aspect ratio.
+
+ :param float left: Coord of the left clipping plane.
+ :param float right: Coord of the right clipping plane.
+ :param float bottom: Coord of the bottom clipping plane.
+ :param float top: Coord of the top clipping plane.
+ :param float near: Distance to the near plane.
+ :param float far: Distance to the far plane.
+ :param size: Viewport's size used to compute the aspect ratio.
+ :type size: 2-tuple of float (width, height).
+ """
+
+ def __init__(self, left=0., right=1., bottom=1., top=0., near=-1., far=1.,
+ size=(1., 1.)):
+ self._left, self._right = left, right
+ self._bottom, self._top = bottom, top
+ super(Orthographic, self).__init__(near, far, checkDepthExtent=False,
+ size=size)
+ # _update called when setting size
+
+ def _makeMatrix(self):
+ return mat4Orthographic(
+ self.left, self.right, self.bottom, self.top, self.near, self.far)
+
+ def _update(self, left, right, bottom, top):
+ width, height = self.size
+ aspect = width / height
+
+ orthoaspect = abs(left - right) / abs(bottom - top)
+
+ if orthoaspect >= aspect: # Keep width, enlarge height
+ newheight = \
+ numpy.sign(top - bottom) * abs(left - right) / aspect
+ bottom = 0.5 * (bottom + top) - 0.5 * newheight
+ top = bottom + newheight
+
+ else: # Keep height, enlarge width
+ newwidth = \
+ numpy.sign(right - left) * abs(bottom - top) * aspect
+ left = 0.5 * (left + right) - 0.5 * newwidth
+ right = left + newwidth
+
+ # Store values
+ self._left, self._right = left, right
+ self._bottom, self._top = bottom, top
+
+ def setClipping(self, left=None, right=None, bottom=None, top=None):
+ """Set the clipping planes of the projection.
+
+ Parameters are adjusted to keep aspect ratio.
+ If a clipping plane coord is not provided, it uses its current value
+
+ :param float left: Coord of the left clipping plane.
+ :param float right: Coord of the right clipping plane.
+ :param float bottom: Coord of the bottom clipping plane.
+ :param float top: Coord of the top clipping plane.
+ """
+ left = float(left) if left is not None else self.left
+ right = float(right) if right is not None else self.right
+ bottom = float(bottom) if bottom is not None else self.bottom
+ top = float(top) if top is not None else self.top
+
+ self._update(left, right, bottom, top)
+ self.notify()
+
+ left = property(lambda self: self._left,
+ doc="Coord of the left clipping plane.")
+
+ right = property(lambda self: self._right,
+ doc="Coord of the right clipping plane.")
+
+ bottom = property(lambda self: self._bottom,
+ doc="Coord of the bottom clipping plane.")
+
+ top = property(lambda self: self._top,
+ doc="Coord of the top clipping plane.")
+
+ @property
+ def size(self):
+ """Viewport size as a 2-tuple of float (width, height) or None."""
+ return self._size
+
+ @size.setter
+ def size(self, size):
+ assert len(size) == 2
+ self._size = float(size[0]), float(size[1])
+ self._update(self.left, self.right, self.bottom, self.top)
+ self.notify()
+
+
+class Ortho2DWidget(_Projection):
+ """Orthographic projection with pixel as unit.
+
+ Provides same coordinates as widgets:
+ origin: top left, X axis goes left, Y axis goes down.
+
+ :param float near: Z coordinate of the near clipping plane.
+ :param float far: Z coordinante of the far clipping plane.
+ :param size: Viewport's size used to compute the aspect ratio.
+ :type size: 2-tuple of float (width, height).
+ """
+
+ def __init__(self, near=-1., far=1., size=(1., 1.)):
+
+ super(Ortho2DWidget, self).__init__(near, far, size)
+
+ def _makeMatrix(self):
+ width, height = self.size
+ return mat4Orthographic(0., width, height, 0., self.near, self.far)
+
+
+class Perspective(_Projection):
+ """Perspective projection matrix defined by FOV and aspect ratio.
+
+ :param float fovy: Vertical field-of-view in degrees.
+ :param float near: The near clipping plane Z coord (stricly positive).
+ :param float far: The far clipping plane Z coord (> near).
+ :param size: Viewport's size used to compute the aspect ratio.
+ :type size: 2-tuple of float (width, height).
+ """
+
+ def __init__(self, fovy=90., near=0.1, far=1., size=(1., 1.)):
+
+ super(Perspective, self).__init__(near, far, checkDepthExtent=True)
+ self._fovy = 90.
+ self.fovy = fovy # Set _fovy
+ self.size = size # Set _ size
+
+ def _makeMatrix(self):
+ width, height = self.size
+ return mat4Perspective(self.fovy, width, height, self.near, self.far)
+
+ @property
+ def fovy(self):
+ """Vertical field-of-view in degrees."""
+ return self._fovy
+
+ @fovy.setter
+ def fovy(self, fovy):
+ self._fovy = float(fovy)
+ self.notify()
diff --git a/silx/gui/plot3d/scene/utils.py b/silx/gui/plot3d/scene/utils.py
new file mode 100644
index 0000000..930a087
--- /dev/null
+++ b/silx/gui/plot3d/scene/utils.py
@@ -0,0 +1,516 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""
+This module provides functions to generate indices, to check intersection
+and to handle planes.
+"""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import logging
+import numpy
+
+from . import event
+
+
+_logger = logging.getLogger(__name__)
+
+
+# numpy #######################################################################
+
+def _uniqueAlongLastAxis(a):
+ """Numpy unique on the last axis of a 2D array
+
+ Implemented here as not in numpy as of writing.
+
+ See adding axis parameter to numpy.unique:
+ https://github.com/numpy/numpy/pull/3584/files#r6225452
+
+ :param array_like a: Input array.
+ :return: Unique elements along the last axis.
+ :rtype: numpy.ndarray
+ """
+ assert len(a.shape) == 2
+
+ # Construct a type over last array dimension to run unique on a 1D array
+ if a.dtype.char in numpy.typecodes['AllInteger']:
+ # Bit-wise comparison of the 2 indices of a line at once
+ # Expect a C contiguous array of shape N, 2
+ uniquedt = numpy.dtype((numpy.void, a.itemsize * a.shape[-1]))
+ elif a.dtype.char in numpy.typecodes['Float']:
+ uniquedt = [('f{i}'.format(i=i), a.dtype) for i in range(a.shape[-1])]
+ else:
+ raise TypeError("Unsupported type {dtype}".format(dtype=a.dtype))
+
+ uniquearray = numpy.unique(numpy.ascontiguousarray(a).view(uniquedt))
+ return uniquearray.view(a.dtype).reshape((-1, a.shape[-1]))
+
+
+# conversions #################################################################
+
+def triangleToLineIndices(triangleIndices, unicity=False):
+ """Generates lines indices from triangle indices.
+
+ This is generating lines indices for the edges of the triangles.
+
+ :param triangleIndices: The indices to draw a set of vertices as triangles.
+ :type triangleIndices: numpy.ndarray
+ :param bool unicity: If True remove duplicated lines,
+ else (the default) returns all lines.
+ :return: The indices to draw the edges of the triangles as lines.
+ :rtype: 1D numpy.ndarray of uint16 or uint32.
+ """
+ # Makes sure indices ar packed by triangle
+ triangleIndices = triangleIndices.reshape(-1, 3)
+
+ # Pack line indices by triangle and by edge
+ lineindices = numpy.empty((len(triangleIndices), 3, 2),
+ dtype=triangleIndices.dtype)
+ lineindices[:, 0] = triangleIndices[:, :2] # edge = t0, t1
+ lineindices[:, 1] = triangleIndices[:, 1:] # edge =t1, t2
+ lineindices[:, 2] = triangleIndices[:, ::2] # edge = t0, t2
+
+ if unicity:
+ lineindices = _uniqueAlongLastAxis(lineindices.reshape(-1, 2))
+
+ # Make sure it is 1D
+ lineindices.shape = -1
+
+ return lineindices
+
+
+def verticesNormalsToLines(vertices, normals, scale=1.):
+ """Return vertices of lines representing normals at given positions.
+
+ :param vertices: Positions of the points.
+ :type vertices: numpy.ndarray with shape: (nbPoints, 3)
+ :param normals: Corresponding normals at the points.
+ :type normals: numpy.ndarray with shape: (nbPoints, 3)
+ :param float scale: The scale factor to apply to normals.
+ :returns: Array of vertices to draw corresponding lines.
+ :rtype: numpy.ndarray with shape: (nbPoints * 2, 3)
+ """
+ linevertices = numpy.empty((len(vertices) * 2, 3), dtype=vertices.dtype)
+ linevertices[0::2] = vertices
+ linevertices[1::2] = vertices + scale * normals
+ return linevertices
+
+
+def unindexArrays(mode, indices, *arrays):
+ """Convert indexed GL primitives to unindexed ones.
+
+ Given indices in arrays and the OpenGL primitive they represent,
+ return the unindexed equivalent.
+
+ :param str mode:
+ Kind of primitive represented by indices.
+ In: points, lines, line_strip, loop, triangles, triangle_strip, fan.
+ :param indices: Indices in other arrays
+ :type indices: numpy.ndarray of dimension 1.
+ :param arrays: Remaining arguments are arrays to convert
+ :return: Converted arrays
+ :rtype: tuple of numpy.ndarray
+ """
+ indices = numpy.array(indices, copy=False)
+
+ assert mode in ('points',
+ 'lines', 'line_strip', 'loop',
+ 'triangles', 'triangle_strip', 'fan')
+
+ if mode in ('lines', 'line_strip', 'loop'):
+ assert len(indices) >= 2
+ elif mode in ('triangles', 'triangle_strip', 'fan'):
+ assert len(indices) >= 3
+
+ assert indices.min() >= 0
+ max_index = indices.max()
+ for data in arrays:
+ assert len(data) >= max_index
+
+ if mode == 'line_strip':
+ unpacked = numpy.empty((2 * (len(indices) - 1),), dtype=indices.dtype)
+ unpacked[0::2] = indices[:-1]
+ unpacked[1::2] = indices[1:]
+ indices = unpacked
+
+ elif mode == 'loop':
+ unpacked = numpy.empty((2 * len(indices),), dtype=indices.dtype)
+ unpacked[0::2] = indices
+ unpacked[1:-1:2] = indices[1:]
+ unpacked[-1] = indices[0]
+ indices = unpacked
+
+ elif mode == 'triangle_strip':
+ unpacked = numpy.empty((3 * (len(indices) - 2),), dtype=indices.dtype)
+ unpacked[0::3] = indices[:-2]
+ unpacked[1::3] = indices[1:-1]
+ unpacked[2::3] = indices[2:]
+ indices = unpacked
+
+ elif mode == 'fan':
+ unpacked = numpy.empty((3 * (len(indices) - 2),), dtype=indices.dtype)
+ unpacked[0::3] = indices[0]
+ unpacked[1::3] = indices[1:-1]
+ unpacked[2::3] = indices[2:]
+ indices = unpacked
+
+ return tuple(numpy.ascontiguousarray(data[indices]) for data in arrays)
+
+
+def trianglesNormal(positions):
+ """Return normal for each triangle.
+
+ :param positions: Serie of triangle's corners
+ :type positions: numpy.ndarray of shape (NbTriangles*3, 3)
+ :return: Normals corresponding to each position.
+ :rtype: numpy.ndarray of shape (NbTriangles, 3)
+ """
+ assert positions.ndim == 2
+ assert positions.shape[1] == 3
+
+ positions = numpy.array(positions, copy=False).reshape(-1, 3, 3)
+
+ normals = numpy.cross(positions[:, 1] - positions[:, 0],
+ positions[:, 2] - positions[:, 0])
+
+ # Normalize normals
+ if numpy.version.version < '1.8.0':
+ # Debian 7 support: numpy.linalg.norm has no axis argument
+ norms = numpy.array(tuple(numpy.linalg.norm(vec) for vec in normals),
+ dtype=normals.dtype)
+ else:
+ norms = numpy.linalg.norm(normals, axis=1)
+ norms[norms == 0] = 1
+
+ return normals / norms.reshape(-1, 1)
+
+
+# grid ########################################################################
+
+def gridVertices(dim0Array, dim1Array, dtype):
+ """Generate an array of 2D positions from 2 arrays of 1D coordinates.
+
+ :param dim0Array: 1D array-like of coordinates along the first dimension.
+ :param dim1Array: 1D array-like of coordinates along the second dimension.
+ :param numpy.dtype dtype: Data type of the output array.
+ :return: Array of grid coordinates.
+ :rtype: numpy.ndarray with shape: (len(dim0Array), len(dim1Array), 2)
+ """
+ grid = numpy.empty((len(dim0Array), len(dim1Array), 2), dtype=dtype)
+ grid.T[0, :, :] = dim0Array
+ grid.T[1, :, :] = numpy.array(dim1Array, copy=False)[:, None]
+ return grid
+
+
+def triangleStripGridIndices(dim0, dim1):
+ """Generate indices to draw a grid of vertices as a triangle strip.
+
+ Vertices are expected to be stored as row-major (i.e., C contiguous).
+
+ :param int dim0: The number of rows of vertices.
+ :param int dim1: The number of columns of vertices.
+ :return: The vertex indices
+ :rtype: 1D numpy.ndarray of uint32
+ """
+ assert dim0 >= 2
+ assert dim1 >= 2
+
+ # Filling a row of squares +
+ # an index before and one after for degenerated triangles
+ indices = numpy.empty((dim0 - 1, 2 * (dim1 + 1)), dtype=numpy.uint32)
+
+ # Init indices with minimum indices for each row of squares
+ indices[:] = (dim1 * numpy.arange(dim0 - 1, dtype=numpy.uint32))[:, None]
+
+ # Update indices with offset per row of squares
+ offset = numpy.arange(dim1, dtype=numpy.uint32)
+ indices[:, 1:-1:2] += offset
+ offset += dim1
+ indices[:, 2::2] += offset
+ indices[:, -1] += offset[-1]
+
+ # Remove extra indices for degenerated triangles before returning
+ return indices.ravel()[1:-1]
+
+ # Alternative:
+ # indices = numpy.zeros(2 * dim1 * (dim0 - 1) + 2 * (dim0 - 2),
+ # dtype=numpy.uint32)
+ #
+ # offset = numpy.arange(dim1, dtype=numpy.uint32)
+ # for d0Index in range(dim0 - 1):
+ # start = 2 * d0Index * (dim1 + 1)
+ # end = start + 2 * dim1
+ # if d0Index != 0:
+ # indices[start - 2] = offset[-1]
+ # indices[start - 1] = offset[0]
+ # indices[start:end:2] = offset
+ # offset += dim1
+ # indices[start + 1:end:2] = offset
+ # return indices
+
+
+def linesGridIndices(dim0, dim1):
+ """Generate indices to draw a grid of vertices as lines.
+
+ Vertices are expected to be stored as row-major (i.e., C contiguous).
+
+ :param int dim0: The number of rows of vertices.
+ :param int dim1: The number of columns of vertices.
+ :return: The vertex indices.
+ :rtype: 1D numpy.ndarray of uint32
+ """
+ # Horizontal and vertical lines
+ nbsegmentalongdim1 = 2 * (dim1 - 1)
+ nbsegmentalongdim0 = 2 * (dim0 - 1)
+
+ indices = numpy.empty(nbsegmentalongdim1 * dim0 +
+ nbsegmentalongdim0 * dim1,
+ dtype=numpy.uint32)
+
+ # Line indices over dim0
+ onedim1line = (numpy.arange(nbsegmentalongdim1,
+ dtype=numpy.uint32) + 1) // 2
+ indices[:dim0 * nbsegmentalongdim1] = \
+ (dim1 * numpy.arange(dim0, dtype=numpy.uint32)[:, None] +
+ onedim1line[None, :]).ravel()
+
+ # Line indices over dim1
+ onedim0line = (numpy.arange(nbsegmentalongdim0,
+ dtype=numpy.uint32) + 1) // 2
+ indices[dim0 * nbsegmentalongdim1:] = \
+ (numpy.arange(dim1, dtype=numpy.uint32)[:, None] +
+ dim1 * onedim0line[None, :]).ravel()
+
+ return indices
+
+
+# intersection ################################################################
+
+def angleBetweenVectors(refVector, vectors, norm=None):
+ """Return the angle between 2 vectors.
+
+ :param refVector: Coordinates of the reference vector.
+ :type refVector: numpy.ndarray of shape: (NCoords,)
+ :param vectors: Coordinates of the vector(s) to get angle from reference.
+ :type vectors: numpy.ndarray of shape: (NCoords,) or (NbVector, NCoords)
+ :param norm: A direction vector giving an orientation to the angles
+ or None.
+ :returns: The angles in radians in [0, pi] if norm is None
+ else in [0, 2pi].
+ :rtype: float or numpy.ndarray of shape (NbVectors,)
+ """
+ singlevector = len(vectors.shape) == 1
+ if singlevector: # Make it a 2D array for the computation
+ vectors = vectors.reshape(1, -1)
+
+ assert len(refVector.shape) == 1
+ assert len(vectors.shape) == 2
+ assert len(refVector) == vectors.shape[1]
+
+ # Normalize vectors
+ refVector /= numpy.linalg.norm(refVector)
+ vectors = numpy.array([v / numpy.linalg.norm(v) for v in vectors])
+
+ dots = numpy.sum(refVector * vectors, axis=-1)
+ angles = numpy.arccos(numpy.clip(dots, -1., 1.))
+ if norm is not None:
+ signs = numpy.sum(norm * numpy.cross(refVector, vectors), axis=-1) < 0.
+ angles[signs] = numpy.pi * 2. - angles[signs]
+
+ return angles[0] if singlevector else angles
+
+
+def segmentPlaneIntersect(s0, s1, planeNorm, planePt):
+ """Compute the intersection of a segment with a plane.
+
+ :param s0: First end of the segment
+ :type s0: 1D numpy.ndarray-like of length 3
+ :param s1: Second end of the segment
+ :type s1: 1D numpy.ndarray-like of length 3
+ :param planeNorm: Normal vector of the plane.
+ :type planeNorm: numpy.ndarray of shape: (3,)
+ :param planePt: A point of the plane.
+ :type planePt: numpy.ndarray of shape: (3,)
+ :return: The intersection points. The number of points goes
+ from 0 (no intersection) to 2 (segment in the plane)
+ :rtype: list of numpy.ndarray
+ """
+ s0, s1 = numpy.asarray(s0), numpy.asarray(s1)
+
+ segdir = s1 - s0
+ dotnormseg = numpy.dot(planeNorm, segdir)
+ if dotnormseg == 0:
+ # line and plane are parallels
+ if numpy.dot(planeNorm, planePt - s0) == 0: # segment is in plane
+ return [s0, s1]
+ else: # No intersection
+ return []
+
+ alpha = - numpy.dot(planeNorm, s0 - planePt) / dotnormseg
+ if 0. <= alpha <= 1.: # Intersection with segment
+ return [s0 + alpha * segdir]
+ else: # intersection outside segment
+ return []
+
+
+def boxPlaneIntersect(boxVertices, boxLineIndices, planeNorm, planePt):
+ """Return intersection points between a box and a plane.
+
+ :param boxVertices: Position of the corners of the box.
+ :type boxVertices: numpy.ndarray with shape: (8, 3)
+ :param boxLineIndices: Indices of the box edges.
+ :type boxLineIndices: numpy.ndarray-like with shape: (12, 2)
+ :param planeNorm: Normal vector of the plane.
+ :type planeNorm: numpy.ndarray of shape: (3,)
+ :param planePt: A point of the plane.
+ :type planePt: numpy.ndarray of shape: (3,)
+ :return: The found intersection points
+ :rtype: numpy.ndarray with 2 dimensions
+ """
+ segments = numpy.take(boxVertices, boxLineIndices, axis=0)
+
+ points = set() # Gather unique intersection points
+ for seg in segments:
+ for point in segmentPlaneIntersect(seg[0], seg[1], planeNorm, planePt):
+ points.add(tuple(point))
+ points = numpy.array(list(points))
+
+ if len(points) <= 2:
+ return numpy.array(())
+ elif len(points) == 3:
+ return points
+ else: # len(points) > 3
+ # Order point to have a polyline lying on the unit cube's faces
+ vectors = points - numpy.mean(points, axis=0)
+ angles = angleBetweenVectors(vectors[0], vectors, planeNorm)
+ points = numpy.take(points, numpy.argsort(angles), axis=0)
+ return points
+
+
+# Plane #######################################################################
+
+class Plane(event.Notifier):
+ """Object handling a plane and notifying plane changes.
+
+ :param point: A point on the plane.
+ :type point: 3-tuple of float.
+ :param normal: Normal of the plane.
+ :type normal: 3-tuple of float.
+ """
+
+ def __init__(self, point=(0., 0., 0.), normal=(0., 0., 1.)):
+ super(Plane, self).__init__()
+
+ assert len(point) == 3
+ self._point = numpy.array(point, copy=True, dtype=numpy.float32)
+ assert len(normal) == 3
+ self._normal = numpy.array(normal, copy=True, dtype=numpy.float32)
+ self.notify()
+
+ def setPlane(self, point=None, normal=None):
+ """Set plane point and normal and notify.
+
+ :param point: A point on the plane.
+ :type point: 3-tuple of float or None.
+ :param normal: Normal of the plane.
+ :type normal: 3-tuple of float or None.
+ """
+ planechanged = False
+
+ if point is not None:
+ assert len(point) == 3
+ point = numpy.array(point, copy=True, dtype=numpy.float32)
+ if not numpy.all(numpy.equal(self._point, point)):
+ self._point = point
+ planechanged = True
+
+ if normal is not None:
+ assert len(normal) == 3
+ normal = numpy.array(normal, copy=True, dtype=numpy.float32)
+
+ norm = numpy.linalg.norm(normal)
+ if norm != 0.:
+ normal /= norm
+
+ if not numpy.all(numpy.equal(self._normal, normal)):
+ self._normal = normal
+ planechanged = True
+
+ if planechanged:
+ _logger.debug('Plane updated:\n\tpoint: %s\n\tnormal: %s',
+ str(self._point), str(self._normal))
+ self.notify()
+
+ @property
+ def point(self):
+ """A point on the plane."""
+ return self._point.copy()
+
+ @point.setter
+ def point(self, point):
+ self.setPlane(point=point)
+
+ @property
+ def normal(self):
+ """The (normalized) normal of the plane."""
+ return self._normal.copy()
+
+ @normal.setter
+ def normal(self, normal):
+ self.setPlane(normal=normal)
+
+ @property
+ def parameters(self):
+ """Plane equation parameters: a*x + b*y + c*z + d = 0."""
+ return numpy.append(self._normal,
+ - numpy.dot(self._point, self._normal))
+
+ @parameters.setter
+ def parameters(self, parameters):
+ assert len(parameters) == 4
+ parameters = numpy.array(parameters, dtype=numpy.float32)
+
+ # Normalize normal
+ norm = numpy.linalg.norm(parameters[:3])
+ if norm != 0:
+ parameters /= norm
+
+ normal = parameters[:3]
+ point = - parameters[3] * normal
+ self.setPlane(point, normal)
+
+ @property
+ def isPlane(self):
+ """True if a plane is defined (i.e., ||normal|| != 0)."""
+ return numpy.any(self.normal != 0.)
+
+ def move(self, step):
+ """Move the plane of step along the normal."""
+ self.point += step * self.normal
diff --git a/silx/gui/plot3d/scene/viewport.py b/silx/gui/plot3d/scene/viewport.py
new file mode 100644
index 0000000..83cda43
--- /dev/null
+++ b/silx/gui/plot3d/scene/viewport.py
@@ -0,0 +1,492 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a class to control a viewport on the rendering window.
+
+The :class:`Viewport` describes a Viewport rendering a scene.
+The attribute :attr:`scene` is the root group of the scene tree.
+:class:`RenderContext` handles the current state during rendering.
+"""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+import numpy
+
+from silx.gui.plot.Colors import rgba
+
+from ..._glutils import gl
+
+from . import camera
+from . import event
+from . import transform
+from .function import DirectionalLight, ClippingPlane
+
+
+class RenderContext(object):
+ """Handle a current rendering context.
+
+ An instance of this class is passed to rendering method through
+ the scene during render.
+
+ User should NEVER use an instance of this class beyond the method
+ it is passed to as an argument (i.e., do not keep a reference to it).
+
+ :param Viewport viewport: The viewport doing the rendering.
+ :param Context glContext: The operating system OpenGL context in use.
+ """
+
+ def __init__(self, viewport, glContext):
+ self._viewport = viewport
+ self._glContext = glContext
+ self._transformStack = [viewport.camera.extrinsic]
+ self._clipPlane = ClippingPlane(normal=(0., 0., 0.))
+
+ @property
+ def viewport(self):
+ """Viewport doing the current rendering"""
+ return self._viewport
+
+ @property
+ def glCtx(self):
+ """The OpenGL context in use"""
+ return self._glContext
+
+ @property
+ def objectToCamera(self):
+ """The current transform from object to camera coords.
+
+ Do not modify.
+ """
+ return self._transformStack[-1]
+
+ @property
+ def projection(self):
+ """Projection transform.
+
+ Do not modify.
+ """
+ return self.viewport.camera.intrinsic
+
+ @property
+ def objectToNDC(self):
+ """The transform from object to NDC (this includes projection).
+
+ Do not modify.
+ """
+ return transform.StaticTransformList(
+ (self.projection, self.objectToCamera))
+
+ def pushTransform(self, transform_, multiply=True):
+ """Push a :class:`Transform` on the transform stack.
+
+ :param Transform transform_: The transform to add to the stack.
+ :param bool multiply:
+ True (the default) to multiply with the top of the stack,
+ False to push the transform as is without multiplication.
+ """
+ if multiply:
+ assert len(self._transformStack) >= 1
+ transform_ = transform.StaticTransformList(
+ (self._transformStack[-1], transform_))
+
+ self._transformStack.append(transform_)
+
+ def popTransform(self):
+ """Pop the transform on top of the stack.
+
+ :return: The Transform that is popped from the stack.
+ """
+ assert len(self._transformStack) > 1
+ return self._transformStack.pop()
+
+ @property
+ def clipper(self):
+ """The current clipping plane
+ """
+ return self._clipPlane
+
+ def setClipPlane(self, point=(0., 0., 0.), normal=(0., 0., 0.)):
+ """Set the clipping plane to use
+
+ For now only handles a single clipping plane.
+
+ :param point: A point of the plane
+ :type point: 3-tuple of float
+ :param normal: Normal vector of the plane or (0, 0, 0) for no clipping
+ :type normal: 3-tuple of float
+ """
+ self._clipPlane = ClippingPlane(point, normal)
+
+
+class Viewport(event.Notifier):
+ """Rendering a single scene through a camera in part of a framebuffer.
+
+ :param int framebuffer: The framebuffer ID this viewport is rendering into
+ """
+
+ def __init__(self, framebuffer=0):
+ from . import Group # Here to avoid cyclic import
+ super(Viewport, self).__init__()
+ self._dirty = True
+ self._origin = 0, 0
+ self._size = 1, 1
+ self._framebuffer = int(framebuffer)
+ self.scene = Group() # The stuff to render, add overlaid scenes?
+ self.scene._setParent(self)
+ self.scene.addListener(self._changed)
+ self._background = 0., 0., 0., 1.
+ self._camera = camera.Camera(fovy=30., near=1., far=100.,
+ position=(0., 0., 12.))
+ self._camera.addListener(self._changed)
+ self._transforms = transform.TransformList([self._camera])
+
+ self._light = DirectionalLight(direction=(0., 0., -1.),
+ ambient=(0.3, 0.3, 0.3),
+ diffuse=(0.7, 0.7, 0.7))
+ self._light.addListener(self._changed)
+
+ @property
+ def transforms(self):
+ """Proxy of camera transforms.
+
+ Do not modify the list.
+ """
+ return self._transforms
+
+ def _changed(self, *args, **kwargs):
+ """Callback handling scene updates"""
+ self._dirty = True
+ self.notify()
+
+ @property
+ def dirty(self):
+ """True if scene is dirty and needs redisplay."""
+ return self._dirty
+
+ def resetDirty(self):
+ """Mark the scene as not being dirty.
+
+ To call after rendering.
+ """
+ self._dirty = False
+
+ @property
+ def background(self):
+ """Background color of the viewport (4-tuple of float in [0, 1]"""
+ return self._background
+
+ @background.setter
+ def background(self, color):
+ color = rgba(color)
+ if self._background != color:
+ self._background = color
+ self._changed()
+
+ @property
+ def camera(self):
+ """The camera used to render the scene."""
+ return self._camera
+
+ @property
+ def light(self):
+ """The light used to render the scene."""
+ return self._light
+
+ @property
+ def origin(self):
+ """Origin (ox, oy) of the viewport in pixels"""
+ return self._origin
+
+ @origin.setter
+ def origin(self, origin):
+ ox, oy = origin
+ origin = int(ox), int(oy)
+ if origin != self._origin:
+ self._origin = origin
+ self._changed()
+
+ @property
+ def size(self):
+ """Size (width, height) of the viewport in pixels"""
+ return self._size
+
+ @size.setter
+ def size(self, size):
+ w, h = size
+ size = int(w), int(h)
+ if size != self._size:
+ self._size = size
+
+ self.camera.intrinsic.size = size
+ self._changed()
+
+ @property
+ def shape(self):
+ """Shape (height, width) of the viewport in pixels.
+
+ This is a convenient wrapper to the inverse of size.
+ """
+ return self._size[1], self._size[0]
+
+ @shape.setter
+ def shape(self, shape):
+ self.size = shape[1], shape[0]
+
+ @property
+ def framebuffer(self):
+ """The framebuffer ID this viewport is rendering into (int)"""
+ return self._framebuffer
+
+ @framebuffer.setter
+ def framebuffer(self, framebuffer):
+ self._framebuffer = int(framebuffer)
+
+ def render(self, glContext):
+ """Perform the rendering of the viewport
+
+ :param Context glContext: The context used for rendering"""
+ # Get a chance to run deferred delete
+ glContext.cleanGLGarbage()
+
+ # OpenGL set-up: really need to be done once
+ ox, oy = self.origin
+ w, h = self.size
+ gl.glViewport(ox, oy, w, h)
+
+ gl.glEnable(gl.GL_SCISSOR_TEST)
+ gl.glScissor(ox, oy, w, h)
+
+ gl.glEnable(gl.GL_BLEND)
+ gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
+
+ gl.glEnable(gl.GL_DEPTH_TEST)
+ gl.glDepthFunc(gl.GL_LEQUAL)
+ gl.glDepthRange(0., 1.)
+
+ # gl.glEnable(gl.GL_POLYGON_OFFSET_FILL)
+ # gl.glPolygonOffset(1., 1.)
+
+ gl.glHint(gl.GL_LINE_SMOOTH_HINT, gl.GL_NICEST)
+ gl.glEnable(gl.GL_LINE_SMOOTH)
+
+ gl.glClearColor(*self.background)
+
+ # Prepare OpenGL
+ gl.glClear(gl.GL_COLOR_BUFFER_BIT |
+ gl.GL_STENCIL_BUFFER_BIT |
+ gl.GL_DEPTH_BUFFER_BIT)
+
+ ctx = RenderContext(self, glContext)
+ self.scene.render(ctx)
+ self.scene.postRender(ctx)
+
+ def adjustCameraDepthExtent(self):
+ """Update camera depth extent to fit the scene bounds.
+
+ Only near and far planes are updated.
+ The scene might still not be fully visible
+ (e.g., if spanning behind the viewpoint with perspective projection).
+ """
+ bounds = self.scene.bounds(transformed=True)
+ bounds = self.camera.extrinsic.transformBounds(bounds)
+
+ if isinstance(self.camera.intrinsic, transform.Perspective):
+ # This needs to be reworked
+ zbounds = - bounds[:, 2]
+ zextent = max(numpy.fabs(zbounds[0] - zbounds[1]), 0.0001)
+ near = max(zextent / 1000., 0.95 * zbounds[1])
+ far = max(near + 0.1, 1.05 * zbounds[0])
+
+ self.camera.intrinsic.setDepthExtent(near, far)
+ elif isinstance(self.camera.intrinsic, transform.Orthographic):
+ # Makes sure z bounds are included
+ border = max(abs(bounds[:, 2]))
+ self.camera.intrinsic.setDepthExtent(-border, border)
+ else:
+ raise RuntimeError('Unsupported camera', self.camera.intrinsic)
+
+ def resetCamera(self):
+ """Change camera to have the whole scene in the viewing frustum.
+
+ It updates the camera position and depth extent.
+ Camera sight direction and up are not affected.
+ """
+ self.camera.resetCamera(self.scene.bounds(transformed=True))
+
+ def orbitCamera(self, direction, angle=1.):
+ """Rotate the camera around center of the scene.
+
+ :param str direction: Direction of movement relative to image plane.
+ In: 'up', 'down', 'left', 'right'.
+ :param float angle: he angle in degrees of the rotation.
+ """
+ bounds = self.scene.bounds(transformed=True)
+ center = 0.5 * (bounds[0] + bounds[1])
+ self.camera.orbit(direction, center, angle)
+
+ def moveCamera(self, direction, step=0.1):
+ """Move the camera relative to the image plane.
+
+ :param str direction: Direction relative to image plane.
+ One of: 'up', 'down', 'left', 'right',
+ 'forward', 'backward'.
+ :param float step: The ratio of data to step for each pan.
+ """
+ bounds = self.scene.bounds(transformed=True)
+ bounds = self.camera.extrinsic.transformBounds(bounds)
+ center = 0.5 * (bounds[0] + bounds[1])
+ ndcCenter = self.camera.intrinsic.transformPoint(
+ center, perspectiveDivide=True)
+
+ step *= 2. # NDC has size 2
+
+ if direction == 'up':
+ ndcCenter[1] -= step
+ elif direction == 'down':
+ ndcCenter[1] += step
+
+ elif direction == 'right':
+ ndcCenter[0] -= step
+ elif direction == 'left':
+ ndcCenter[0] += step
+
+ elif direction == 'forward':
+ ndcCenter[2] += step
+ elif direction == 'backward':
+ ndcCenter[2] -= step
+
+ else:
+ raise ValueError('Unsupported direction: %s' % direction)
+
+ newCenter = self.camera.intrinsic.transformPoint(
+ ndcCenter, direct=False, perspectiveDivide=True)
+
+ self.camera.move(direction, numpy.linalg.norm(newCenter - center))
+
+ def windowToNdc(self, winX, winY, checkInside=True):
+ """Convert position from window to normalized device coordinates.
+
+ If window coordinates are int, they are moved half a pixel
+ to be positioned at the center of pixel.
+
+ :param winX: X window coord, origin left.
+ :param winY: Y window coord, origin top.
+ :param bool checkInside: If True, returns None if position is
+ outside viewport.
+ :return: (x, y) Normalize device coordinates in [-1, 1] or None.
+ Origin center, x to the right, y goes upward.
+ """
+ ox, oy = self._origin
+ width, height = self.size
+
+ # If int, move it to the center of pixel
+ if isinstance(winX, int):
+ winX += 0.5
+ if isinstance(winY, int):
+ winY += 0.5
+
+ x, y = winX - ox, winY - oy
+
+ if checkInside and (x < 0. or x > width or y < 0. or y > height):
+ return None # Out of viewport
+
+ ndcx = 2. * x / float(width) - 1.
+ ndcy = 1. - 2. * y / float(height)
+ return ndcx, ndcy
+
+ def ndcToWindow(self, ndcX, ndcY, checkInside=True):
+ """Convert position from normalized device coordinates (NDC) to window.
+
+ :param float ndcX: X NDC coord.
+ :param float ndcY: Y NDC coord.
+ :param bool checkInside: If True, returns None if position is
+ outside viewport.
+ :return: (x, y) window coordinates or None.
+ Origin top-left, x to the right, y goes downward.
+ """
+ if (checkInside and
+ (ndcX < -1. or ndcX > 1. or ndcY < -1. or ndcY > 1.)):
+ return None # Outside viewport
+
+ ox, oy = self._origin
+ width, height = self.size
+
+ winx = ox + width * 0.5 * (ndcX + 1.)
+ winy = oy + height * 0.5 * (1. - ndcY)
+ return winx, winy
+
+ def _pickNdcZGL(self, x, y):
+ """Retrieve depth from depth buffer and return corresponding NDC Z.
+
+ :param int x: In pixels in window coordinates, origin left.
+ :param int y: In pixels in window coordinates, origin top.
+ :return: Normalize device Z coordinate of depth in [-1, 1]
+ or None if outside viewport.
+ :rtype: float or None
+ """
+ ox, oy = self._origin
+ width, height = self.size
+
+ x = int(x)
+ y = height - int(y) # Invert y coord
+
+ if x < ox or x > ox + width or y < oy or y > oy + height:
+ # Outside viewport
+ return None
+
+ # Get depth from depth buffer in [0., 1.]
+ # Bind used framebuffer to get depth
+ gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebuffer)
+ depth = gl.glReadPixels(
+ x, y, 1, 1, gl.GL_DEPTH_COMPONENT, gl.GL_FLOAT)[0]
+ gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
+ # This is not GL|ES friendly
+
+ # Z in NDC in [-1., 1.]
+ return float(depth) * 2. - 1.
+
+ def _getXZYGL(self, x, y):
+ ndc = self.windowToNdc(x, y)
+ if ndc is None:
+ return None # Outside viewport
+ ndcz = self._pickNdcZGL(x, y)
+ ndcpos = numpy.array((ndc[0], ndc[1], ndcz, 1.), dtype=numpy.float32)
+
+ camerapos = self.camera.intrinsic.transformPoint(
+ ndcpos, direct=False, perspectiveDivide=True)
+
+ scenepos = self.camera.extrinsic.transformPoint(camerapos,
+ direct=False)
+ return scenepos[:3]
+
+ def pick(self, x, y):
+ pass
+ # ndcX, ndcY = self.windowToNdc(x, y)
+ # ndcNearPt = ndcX, ndcY, -1.
+ # ndcFarPT = ndcX, ndcY, 1.
diff --git a/silx/gui/plot3d/scene/window.py b/silx/gui/plot3d/scene/window.py
new file mode 100644
index 0000000..ad7e6e5
--- /dev/null
+++ b/silx/gui/plot3d/scene/window.py
@@ -0,0 +1,420 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides a class for Viewports rendering on the screen.
+
+The :class:`Window` renders a list of Viewports in the current framebuffer.
+The rendering can be performed in an off-screen framebuffer that is only
+updated when the scene has changed and not each time Qt is requiring a repaint.
+
+The :class:`Context` and :class:`ContextGL2` represent the operating system
+OpenGL context and handle OpenGL resources.
+"""
+
+from __future__ import absolute_import, division, unicode_literals
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "10/01/2017"
+
+
+import weakref
+import numpy
+
+from ..._glutils import gl
+from ... import _glutils
+
+from . import event
+
+
+class Context(object):
+ """Correspond to an operating system OpenGL context.
+
+ User should NEVER use an instance of this class beyond the method
+ it is passed to as an argument (i.e., do not keep a reference to it).
+
+ :param glContextHandle: System specific OpenGL context handle.
+ """
+
+ def __init__(self, glContextHandle):
+ self._context = glContextHandle
+ self._isCurrent = False
+ self._devicePixelRatio = 1.0
+
+ @property
+ def isCurrent(self):
+ """Whether this OpenGL context is the current one or not."""
+ return self._isCurrent
+
+ def setCurrent(self, isCurrent=True):
+ """Set the state of the OpenGL context to reflect OpenGL state.
+
+ This should not be called from the scene graph, only in the
+ wrapper that handle the OpenGL context to reflect its state.
+
+ :param bool isCurrent: The state of the system OpenGL context.
+ """
+ self._isCurrent = bool(isCurrent)
+
+ @property
+ def devicePixelRatio(self):
+ """Ratio between device and device independent pixels (float)
+
+ This is useful for font rendering.
+ """
+ return self._devicePixelRatio
+
+ @devicePixelRatio.setter
+ def devicePixelRatio(self, ratio):
+ assert ratio > 0
+ self._devicePixelRatio = float(ratio)
+
+ def __enter__(self):
+ self.setCurrent(True)
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.setCurrent(False)
+
+ @property
+ def glContext(self):
+ """The handle to the OpenGL context provided by the system."""
+ return self._context
+
+ def cleanGLGarbage(self):
+ """This is releasing OpenGL resource that are no longer used."""
+ pass
+
+
+class ContextGL2(Context):
+ """Handle a system GL2 context.
+
+ User should NEVER use an instance of this class beyond the method
+ it is passed to as an argument (i.e., do not keep a reference to it).
+
+ :param glContextHandle: System specific OpenGL context handle.
+ """
+ def __init__(self, glContextHandle):
+ super(ContextGL2, self).__init__(glContextHandle)
+
+ self._programs = {} # GL programs already compiled
+ self._vbos = {} # GL Vbos already set
+ self._vboGarbage = [] # Vbos waiting to be discarded
+
+ # programs
+
+ def prog(self, vertexShaderSrc, fragmentShaderSrc):
+ """Cache program within context.
+
+ WARNING: No clean-up.
+ """
+ assert self.isCurrent
+ key = vertexShaderSrc, fragmentShaderSrc
+ prog = self._programs.get(key, None)
+ if prog is None:
+ prog = _glutils.Program(vertexShaderSrc, fragmentShaderSrc)
+ self._programs[key] = prog
+ return prog
+
+ # VBOs
+
+ def makeVbo(self, data=None, sizeInBytes=None,
+ usage=None, target=None):
+ """Create a VBO in this context with the data.
+
+ Current limitations:
+
+ - One array per VBO
+ - Do not support sharing VertexBuffer across VboAttrib
+
+ Automatically discards the VBO when the returned
+ :class:`VertexBuffer` istance is deleted.
+
+ :param numpy.ndarray data: 2D array of data to store in VBO or None.
+ :param int sizeInBytes: Size of the VBO or None.
+ It should be <= data.nbytes if both are given.
+ :param usage: OpenGL usage define in VertexBuffer._USAGES.
+ :param target: OpenGL target in VertexBuffer._TARGETS.
+ :return: The VertexBuffer created in this context.
+ """
+ assert self.isCurrent
+ vbo = _glutils.VertexBuffer(data, sizeInBytes, usage, target)
+ vboref = weakref.ref(vbo, self._deadVbo)
+ # weakref is hashable as far as target is
+ self._vbos[vboref] = vbo.name
+ return vbo
+
+ def makeVboAttrib(self, data, usage=None, target=None):
+ """Create a VBO from data and returns the associated VBOAttrib.
+
+ Automatically discards the VBO when the returned
+ :class:`VBOAttrib` istance is deleted.
+
+ :param numpy.ndarray data: 2D array of data to store in VBO or None.
+ :param usage: OpenGL usage define in VertexBuffer._USAGES.
+ :param target: OpenGL target in VertexBuffer._TARGETS.
+ :returns: A VBOAttrib instance created in this context.
+ """
+ assert self.isCurrent
+ vbo = self.makeVbo(data, usage=usage, target=target)
+
+ assert len(data.shape) <= 2
+ dimension = 1 if len(data.shape) == 1 else data.shape[1]
+
+ return _glutils.VertexBufferAttrib(
+ vbo,
+ type_=_glutils.numpyToGLType(data.dtype),
+ size=data.shape[0],
+ dimension=dimension,
+ offset=0,
+ stride=0)
+
+ def _deadVbo(self, vboRef):
+ """Callback handling dead VBOAttribs."""
+ vboid = self._vbos.pop(vboRef)
+ if self.isCurrent:
+ # Direct delete if context is active
+ gl.glDeleteBuffers(vboid)
+ else:
+ # Deferred VBO delete if context is not active
+ self._vboGarbage.append(vboid)
+
+ def cleanGLGarbage(self):
+ """Delete OpenGL resources that are pending for destruction.
+
+ This requires the associated OpenGL context to be active.
+ This is meant to be called before rendering.
+ """
+ assert self.isCurrent
+ if self._vboGarbage:
+ vboids = self._vboGarbage
+ gl.glDeleteBuffers(vboids)
+ self._vboGarbage = []
+
+
+class Window(event.Notifier):
+ """OpenGL Framebuffer where to render viewports
+
+ :param str mode: Rendering mode to use:
+
+ - 'direct' to render everything for each render call
+ - 'framebuffer' to cache viewport rendering in a texture and
+ update the texture only when needed.
+ """
+
+ _position = numpy.array(((-1., -1., 0., 0.),
+ (1., -1., 1., 0.),
+ (-1., 1., 0., 1.),
+ (1., 1., 1., 1.)),
+ dtype=numpy.float32)
+
+ _shaders = ("""
+ attribute vec4 position;
+ varying vec2 textureCoord;
+
+ void main(void) {
+ gl_Position = vec4(position.x, position.y, 0., 1.);
+ textureCoord = position.zw;
+ }
+ """,
+ """
+ uniform sampler2D texture;
+ varying vec2 textureCoord;
+
+ void main(void) {
+ gl_FragColor = texture2D(texture, textureCoord);
+ }
+ """)
+
+ def __init__(self, mode='framebuffer'):
+ super(Window, self).__init__()
+ self._dirty = True
+ self._size = 0, 0
+ self._contexts = {} # To map system GL context id to Context objects
+ self._viewports = event.NotifierList()
+ self._viewports.addListener(self._updated)
+ self._framebufferid = 0
+ self._framebuffers = {} # Cache of framebuffers
+
+ assert mode in ('direct', 'framebuffer')
+ self._isframebuffer = mode == 'framebuffer'
+
+ @property
+ def dirty(self):
+ """True if this object or any attached viewports is dirty."""
+ for viewport in self._viewports:
+ if viewport.dirty:
+ return True
+ return self._dirty
+
+ @property
+ def size(self):
+ """Size (width, height) of the window in pixels"""
+ return self._size
+
+ @size.setter
+ def size(self, size):
+ w, h = size
+ size = int(w), int(h)
+ if size != self._size:
+ self._size = size
+ self._dirty = True
+ self.notify()
+
+ @property
+ def shape(self):
+ """Shape (height, width) of the window in pixels.
+
+ This is a convenient wrapper to the reverse of size.
+ """
+ return self._size[1], self._size[0]
+
+ @shape.setter
+ def shape(self, shape):
+ self.size = shape[1], shape[0]
+
+ @property
+ def viewports(self):
+ """List of viewports to render in the corresponding framebuffer"""
+ return self._viewports
+
+ @viewports.setter
+ def viewports(self, iterable):
+ self._viewports.removeListener(self._updated)
+ self._viewports = event.NotifierList(iterable)
+ self._viewports.addListener(self._updated)
+ self._dirty = True
+
+ def _updated(self, source, *args, **kwargs):
+ if source is not self:
+ self._dirty = True
+ self.notify(*args, **kwargs)
+
+ framebufferid = property(lambda self: self._framebufferid,
+ doc="Framebuffer ID used to perform rendering")
+
+ def grab(self, glcontext):
+ """Returns the raster of the scene as an RGB numpy array
+
+ :returns: OpenGL scene RGB bitmap
+ :rtype: numpy.ndarray of uint8 of dimension (height, width, 3)
+ """
+ height, width = self.shape
+ image = numpy.empty((height, width, 3), dtype=numpy.uint8)
+
+ gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebufferid)
+ gl.glPixelStorei(gl.GL_PACK_ALIGNMENT, 1)
+ gl.glReadPixels(
+ 0, 0, width, height, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, image)
+ gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
+
+ # glReadPixels gives bottom to top,
+ # while images are stored as top to bottom
+ image = numpy.flipud(image)
+
+ return numpy.array(image, copy=False, order='C')
+
+ def render(self, glcontext, devicePixelRatio):
+ """Perform the rendering of attached viewports
+
+ :param glcontext: System identifier of the OpenGL context
+ :param float devicePixelRatio:
+ Ratio between device and device-independent pixels
+ """
+ if glcontext not in self._contexts:
+ self._contexts[glcontext] = ContextGL2(glcontext) # New context
+
+ with self._contexts[glcontext] as context:
+ context.devicePixelRatio = devicePixelRatio
+ if self._isframebuffer:
+ self._renderWithOffscreenFramebuffer(context)
+ else:
+ self._renderDirect(context)
+
+ self._dirty = False
+
+ def _renderDirect(self, context):
+ """Perform the direct rendering of attached viewports
+
+ :param Context context: Object wrapping OpenGL context
+ """
+ for viewport in self._viewports:
+ viewport.framebuffer = self.framebufferid
+ viewport.render(context)
+ viewport.resetDirty()
+
+ def _renderWithOffscreenFramebuffer(self, context):
+ """Renders viewports in a texture and render this texture on screen.
+
+ The texture is updated only if viewport or size has changed.
+
+ :param ContextGL2 context: Object wrappign OpenGL context
+ """
+ if self.dirty or context not in self._framebuffers:
+ # Need to redraw framebuffer content
+
+ if (context not in self._framebuffers or
+ self._framebuffers[context].shape != self.shape):
+ # Need to rebuild framebuffer
+
+ if context in self._framebuffers:
+ self._framebuffers[context].discard()
+
+ fbo = _glutils.FramebufferTexture(gl.GL_RGBA,
+ shape=self.shape,
+ minFilter=gl.GL_NEAREST,
+ magFilter=gl.GL_NEAREST,
+ wrap=gl.GL_CLAMP_TO_EDGE)
+ self._framebuffers[context] = fbo
+ self._framebufferid = fbo.name
+
+ # Render in framebuffer
+ with self._framebuffers[context]:
+ self._renderDirect(context)
+
+ # Render framebuffer texture to screen
+ fbo = self._framebuffers[context]
+ height, width = fbo.shape
+
+ program = context.prog(*self._shaders)
+ program.use()
+
+ gl.glViewport(0, 0, width, height)
+ gl.glDisable(gl.GL_BLEND)
+ gl.glDisable(gl.GL_DEPTH_TEST)
+ gl.glDisable(gl.GL_SCISSOR_TEST)
+ # gl.glScissor(0, 0, width, height)
+ gl.glClearColor(0., 0., 0., 0.)
+ gl.glClear(gl.GL_COLOR_BUFFER_BIT)
+ gl.glUniform1i(program.uniforms['texture'], fbo.texture.texUnit)
+ gl.glEnableVertexAttribArray(program.attributes['position'])
+ gl.glVertexAttribPointer(program.attributes['position'],
+ 4,
+ gl.GL_FLOAT,
+ gl.GL_FALSE,
+ 0,
+ self._position)
+ fbo.texture.bind()
+ gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, len(self._position))
+ gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
diff --git a/silx/gui/plot3d/setup.py b/silx/gui/plot3d/setup.py
new file mode 100644
index 0000000..b9d626f
--- /dev/null
+++ b/silx/gui/plot3d/setup.py
@@ -0,0 +1,44 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "25/07/2016"
+
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('plot3d', parent_package, top_path)
+ config.add_subpackage('scene')
+ config.add_subpackage('test')
+ config.add_subpackage('utils')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/gui/plot3d/test/__init__.py b/silx/gui/plot3d/test/__init__.py
new file mode 100644
index 0000000..66a2f62
--- /dev/null
+++ b/silx/gui/plot3d/test/__init__.py
@@ -0,0 +1,62 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""plot3d test suite."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/01/2017"
+
+
+import logging
+import os
+import unittest
+
+
+_logger = logging.getLogger(__name__)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+
+ if os.environ.get('WITH_GL_TEST', 'True') == 'False':
+ # Explicitly disabled tests
+ _logger.warning(
+ "silx.gui.plot3d tests disabled (WITH_GL_TEST=False)")
+
+ class SkipPlot3DTest(unittest.TestCase):
+ def runTest(self):
+ self.skipTest(
+ "silx.gui.plot3d tests disabled (WITH_GL_TEST=False)")
+
+ test_suite.addTest(SkipPlot3DTest())
+ return test_suite
+
+ # Import here to avoid loading modules if tests are disabled
+
+ from ..scene import test as test_scene
+
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(test_scene.suite())
+ return test_suite
diff --git a/silx/gui/plot3d/utils/__init__.py b/silx/gui/plot3d/utils/__init__.py
new file mode 100644
index 0000000..99d3e08
--- /dev/null
+++ b/silx/gui/plot3d/utils/__init__.py
@@ -0,0 +1,28 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "18/10/2016"
diff --git a/silx/gui/plot3d/utils/mng.py b/silx/gui/plot3d/utils/mng.py
new file mode 100644
index 0000000..fe79a52
--- /dev/null
+++ b/silx/gui/plot3d/utils/mng.py
@@ -0,0 +1,121 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module provides basic writing Mulitple-image Network Graphics files.
+
+It only supports RGB888 images of the same shape stored as
+MNG-VLC (very low complexity) format.
+"""
+
+from __future__ import absolute_import
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "15/12/2016"
+
+
+import logging
+import struct
+import zlib
+
+import numpy
+
+_logger = logging.getLogger(__name__)
+
+
+def _png_chunk(name, data):
+ """Return a PNG chunk
+
+ :param str name: Chunk type
+ :param byte data: Chunk payload
+ """
+ length = struct.pack('>I', len(data))
+ name = [char.encode('ascii') for char in name]
+ chunk = struct.pack('cccc', *name) + data
+ crc = struct.pack('>I', zlib.crc32(chunk) & 0xffffffff)
+ return length + chunk + crc
+
+
+def convert(images, nb_images=0, fps=25):
+ """Convert RGB images to MNG-VLC format.
+
+ See http://www.libpng.org/pub/mng/spec/
+ See http://www.libpng.org/pub/png/book/
+ See http://www.libpng.org/pub/png/spec/1.2/
+
+ :param images: iterator of RGB888 images
+ :type images: iterator of numpy.ndarray of dimension 3
+ :param int nb_images: The number of images indicated in the MNG header
+ :param int fps: The frame rate indicated in the MNG header
+ :return: An iterator of MNG chunks as bytes
+ """
+ first_image = True
+
+ for image in images:
+ if first_image:
+ first_image = False
+
+ height, width = image.shape[:2]
+
+ # MNG signature
+ yield b'\x8aMNG\r\n\x1a\n'
+
+ # MHDR chunk: File header
+ yield _png_chunk('MHDR', struct.pack(
+ ">IIIIIII",
+ width,
+ height,
+ fps, # ticks
+ nb_images + 1, # layer count
+ nb_images, # frame count
+ nb_images, # play time
+ 1)) # profile: MNG-VLC no alpha: only least significant bit 1
+
+ assert image.shape == (height, width, 3)
+ assert image.dtype == numpy.dtype('uint8')
+
+ # IHDR chunk: Image header
+ depth = 8 # 8 bit per channel
+ color_type = 2 # 'truecolor' = RGB
+ interlace = 0 # No
+ yield _png_chunk('IHDR', struct.pack(">IIBBBBB",
+ width,
+ height,
+ depth,
+ color_type,
+ 0, 0, interlace))
+
+ # Add filter 'None' before each scanline
+ prepared_data = b'\x00' + b'\x00'.join(
+ line.tostring() for line in image) # TODO optimize that
+ compressed_data = zlib.compress(prepared_data, 8)
+
+ # IDAT chunk: Payload
+ yield _png_chunk('IDAT', compressed_data)
+
+ # IEND chunk: Image footer
+ yield _png_chunk('IEND', b'')
+
+ # MEND chunk: footer
+ yield _png_chunk('MEND', b'')
diff --git a/silx/gui/qt/__init__.py b/silx/gui/qt/__init__.py
new file mode 100644
index 0000000..44daa94
--- /dev/null
+++ b/silx/gui/qt/__init__.py
@@ -0,0 +1,61 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Common wrapper over Python Qt bindings:
+
+- `PyQt5 <http://pyqt.sourceforge.net/Docs/PyQt5/>`_,
+- `PyQt4 <http://pyqt.sourceforge.net/Docs/PyQt4/>`_ or
+- `PySide <http://www.pyside.org>`_.
+
+If a Qt binding is already loaded, it will use it, otherwise the different
+Qt bindings are tried in this order: PyQt4, PySide, PyQt5.
+
+The name of the loaded Qt binding is stored in the BINDING variable.
+
+This module provides a flat namespace over Qt bindings by importing
+all symbols from **QtCore** and **QtGui** packages and if available
+from **QtOpenGL** and **QtSvg** packages.
+For **PyQt5**, it also imports all symbols from **QtWidgets** and
+**QtPrintSupport** packages.
+
+Example of using :mod:`silx.gui.qt` module:
+
+>>> from silx.gui import qt
+>>> app = qt.QApplication([])
+>>> widget = qt.QWidget()
+
+For an alternative solution providing a structured namespace,
+see `qtpy <https://pypi.python.org/pypi/QtPy/>`_ which
+provides the namespace of PyQt5 over PyQt4 and PySide.
+"""
+
+import sys
+from ._qt import * # noqa
+from ._utils import * # noqa
+
+
+if sys.platform == "darwin":
+ if BINDING in ["PySide", "PyQt4"]:
+ from . import _macosx
+ _macosx.patch_QUrl_toLocalFile()
diff --git a/silx/gui/qt/_macosx.py b/silx/gui/qt/_macosx.py
new file mode 100644
index 0000000..07f3143
--- /dev/null
+++ b/silx/gui/qt/_macosx.py
@@ -0,0 +1,68 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+# ###########################################################################*/
+"""
+Patches for Mac OS X
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "30/11/2016"
+
+
+def patch_QUrl_toLocalFile():
+ """Apply a monkey-patch on qt.QUrl to allow to reach filename when the URL
+ come from a MIME data from a file drop. Without, `QUrl.toLocalName` with
+ some version of Mac OS X returns a path which looks like
+ `/.file/id=180.112`.
+
+ Qt5 is or will be patch, but Qt4 and PySide are not.
+
+ This fix uses the file URL and use an subprocess with an
+ AppleScript. The script convert the URI into a posix path.
+ The interpreter (osascript) is available on default OS X installs.
+
+ See https://bugreports.qt.io/browse/QTBUG-40449
+ """
+ from ._qt import QUrl
+ import subprocess
+
+ def QUrl_toLocalFile(self):
+ path = QUrl._oldToLocalFile(self)
+ if not path.startswith("/.file/id="):
+ return path
+
+ url = self.toString()
+ script = 'get posix path of my posix file \"%s\" -- kthxbai' % url
+ try:
+ p = subprocess.Popen(["osascript", "-e", script], stdout=subprocess.PIPE)
+ out, _err = p.communicate()
+ if p.returncode == 0:
+ return out.strip()
+ except OSError:
+ pass
+ return path
+
+ QUrl._oldToLocalFile = QUrl.toLocalFile
+ QUrl.toLocalFile = QUrl_toLocalFile
diff --git a/silx/gui/qt/_pyside_dynamic.py b/silx/gui/qt/_pyside_dynamic.py
new file mode 100644
index 0000000..a9246b9
--- /dev/null
+++ b/silx/gui/qt/_pyside_dynamic.py
@@ -0,0 +1,158 @@
+# -*- coding: utf-8 -*-
+
+# Taken from: https://gist.github.com/cpbotha/1b42a20c8f3eb9bb7cb8
+
+# Copyright (c) 2011 Sebastian Wiesner <lunaryorn@gmail.com>
+# Modifications by Charl Botha <cpbotha@vxlabs.com>
+# * customWidgets support (registerCustomWidget() causes segfault in
+# pyside 1.1.2 on Ubuntu 12.04 x86_64)
+# * workingDirectory support in loadUi
+
+# found this here:
+# https://github.com/lunaryorn/snippets/blob/master/qt4/designer/pyside_dynamic.py
+
+# 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.
+
+"""
+ How to load a user interface dynamically with PySide.
+
+ .. moduleauthor:: Sebastian Wiesner <lunaryorn@gmail.com>
+"""
+
+from __future__ import (print_function, division, unicode_literals,
+ absolute_import)
+
+import logging
+
+from PySide.QtCore import QMetaObject
+from PySide.QtUiTools import QUiLoader
+from PySide.QtGui import QMainWindow
+
+
+_logger = logging.getLogger(__name__)
+
+
+class UiLoader(QUiLoader):
+ """
+ Subclass :class:`~PySide.QtUiTools.QUiLoader` to create the user interface
+ in a base instance.
+
+ Unlike :class:`~PySide.QtUiTools.QUiLoader` itself this class does not
+ create a new instance of the top-level widget, but creates the user
+ interface in an existing instance of the top-level class.
+
+ This mimics the behaviour of :func:`PyQt4.uic.loadUi`.
+ """
+
+ def __init__(self, baseinstance, customWidgets=None):
+ """
+ Create a loader for the given ``baseinstance``.
+
+ The user interface is created in ``baseinstance``, which must be an
+ instance of the top-level class in the user interface to load, or a
+ subclass thereof.
+
+ ``customWidgets`` is a dictionary mapping from class name to class
+ object for widgets that you've promoted in the Qt Designer
+ interface. Usually, this should be done by calling
+ registerCustomWidget on the QUiLoader, but
+ with PySide 1.1.2 on Ubuntu 12.04 x86_64 this causes a segfault.
+
+ ``parent`` is the parent object of this loader.
+ """
+
+ QUiLoader.__init__(self, baseinstance)
+ self.baseinstance = baseinstance
+ self.customWidgets = customWidgets
+
+ def createWidget(self, class_name, parent=None, name=''):
+ """
+ Function that is called for each widget defined in ui file,
+ overridden here to populate baseinstance instead.
+ """
+
+ if parent is None and self.baseinstance:
+ # supposed to create the top-level widget, return the base instance
+ # instead
+ return self.baseinstance
+
+ else:
+ if class_name in self.availableWidgets():
+ # create a new widget for child widgets
+ widget = QUiLoader.createWidget(self, class_name, parent, name)
+
+ else:
+ # if not in the list of availableWidgets,
+ # must be a custom widget
+ # this will raise KeyError if the user has not supplied the
+ # relevant class_name in the dictionary, or TypeError, if
+ # customWidgets is None
+ try:
+ widget = self.customWidgets[class_name](parent)
+
+ except (TypeError, KeyError):
+ raise Exception('No custom widget ' + class_name +
+ ' found in customWidgets param of' +
+ 'UiLoader __init__.')
+
+ if self.baseinstance:
+ # set an attribute for the new child widget on the base
+ # instance, just like PyQt4.uic.loadUi does.
+ setattr(self.baseinstance, name, widget)
+
+ # this outputs the various widget names, e.g.
+ # sampleGraphicsView, dockWidget, samplesTableView etc.
+ # print(name)
+
+ return widget
+
+
+def loadUi(uifile, baseinstance=None, package=None, resource_suffix=None):
+ """
+ Dynamically load a user interface from the given ``uifile``.
+
+ ``uifile`` is a string containing a file name of the UI file to load.
+
+ If ``baseinstance`` is ``None``, the a new instance of the top-level widget
+ will be created. Otherwise, the user interface is created within the given
+ ``baseinstance``. In this case ``baseinstance`` must be an instance of the
+ top-level widget class in the UI file to load, or a subclass thereof. In
+ other words, if you've created a ``QMainWindow`` interface in the designer,
+ ``baseinstance`` must be a ``QMainWindow`` or a subclass thereof, too. You
+ cannot load a ``QMainWindow`` UI file with a plain
+ :class:`~PySide.QtGui.QWidget` as ``baseinstance``.
+
+ :method:`~PySide.QtCore.QMetaObject.connectSlotsByName()` is called on the
+ created user interface, so you can implemented your slots according to its
+ conventions in your widget class.
+
+ Return ``baseinstance``, if ``baseinstance`` is not ``None``. Otherwise
+ return the newly created instance of the user interface.
+ """
+ if package is not None:
+ _logger.warning(
+ "loadUi package parameter not implemented with PySide")
+ if resource_suffix is not None:
+ _logger.warning(
+ "loadUi resource_suffix parameter not implemented with PySide")
+
+ loader = UiLoader(baseinstance)
+ widget = loader.load(uifile)
+ QMetaObject.connectSlotsByName(widget)
+ return widget
diff --git a/silx/gui/qt/_pyside_missing.py b/silx/gui/qt/_pyside_missing.py
new file mode 100644
index 0000000..a7e2781
--- /dev/null
+++ b/silx/gui/qt/_pyside_missing.py
@@ -0,0 +1,274 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""
+Python implementation of classes which are not provided by default by PySide.
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "17/01/2017"
+
+
+from PySide.QtGui import QAbstractProxyModel
+from PySide.QtCore import QModelIndex
+from PySide.QtCore import Qt
+from PySide.QtGui import QItemSelection
+from PySide.QtGui import QItemSelectionRange
+
+
+class QIdentityProxyModel(QAbstractProxyModel):
+ """Python translation of the source code of Qt c++ file"""
+
+ def __init__(self, parent=None):
+ super(QIdentityProxyModel, self).__init__(parent)
+ self.__ignoreNextLayoutAboutToBeChanged = False
+ self.__ignoreNextLayoutChanged = False
+ self.__persistentIndexes = []
+
+ def columnCount(self, parent):
+ parent = self.mapToSource(parent)
+ return self.sourceModel().columnCount(parent)
+
+ def dropMimeData(self, data, action, row, column, parent):
+ parent = self.mapToSource(parent)
+ return self.sourceModel().dropMimeData(data, action, row, column, parent)
+
+ def index(self, row, column, parent=QModelIndex()):
+ parent = self.mapToSource(parent)
+ i = self.sourceModel().index(row, column, parent)
+ return self.mapFromSource(i)
+
+ def insertColumns(self, column, count, parent=QModelIndex()):
+ parent = self.mapToSource(parent)
+ return self.sourceModel().insertColumns(column, count, parent)
+
+ def insertRows(self, row, count, parent=QModelIndex()):
+ parent = self.mapToSource(parent)
+ return self.sourceModel().insertRows(row, count, parent)
+
+ def mapFromSource(self, sourceIndex):
+ if self.sourceModel() is None or not sourceIndex.isValid():
+ return QModelIndex()
+ index = self.createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer())
+ return index
+
+ def mapSelectionFromSource(self, sourceSelection):
+ proxySelection = QItemSelection()
+ if self.sourceModel() is None:
+ return proxySelection
+
+ cursor = sourceSelection.constBegin()
+ end = sourceSelection.constEnd()
+ while cursor != end:
+ topLeft = self.mapFromSource(cursor.topLeft())
+ bottomRight = self.mapFromSource(cursor.bottomRight())
+ proxyRange = QItemSelectionRange(topLeft, bottomRight)
+ proxySelection.append(proxyRange)
+ cursor += 1
+ return proxySelection
+
+ def mapSelectionToSource(self, proxySelection):
+ sourceSelection = QItemSelection()
+ if self.sourceModel() is None:
+ return sourceSelection
+
+ cursor = proxySelection.constBegin()
+ end = proxySelection.constEnd()
+ while cursor != end:
+ topLeft = self.mapToSource(cursor.topLeft())
+ bottomRight = self.mapToSource(cursor.bottomRight())
+ sourceRange = QItemSelectionRange(topLeft, bottomRight)
+ sourceSelection.append(sourceRange)
+ cursor += 1
+ return sourceSelection
+
+ def mapToSource(self, proxyIndex):
+ if self.sourceModel() is None or not proxyIndex.isValid():
+ return QModelIndex()
+ return self.sourceModel().createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer())
+
+ def match(self, start, role, value, hits=1, flags=Qt.MatchFlags(Qt.MatchStartsWith | Qt.MatchWrap)):
+ if self.sourceModel() is None:
+ return []
+
+ start = self.mapToSource(start)
+ sourceList = self.sourceModel().match(start, role, value, hits, flags)
+ proxyList = []
+ for cursor in sourceList:
+ proxyList.append(self.mapFromSource(cursor))
+ return proxyList
+
+ def parent(self, child):
+ sourceIndex = self.mapToSource(child)
+ sourceParent = sourceIndex.parent()
+ index = self.mapFromSource(sourceParent)
+ return index
+
+ def removeColumns(self, column, count, parent=QModelIndex()):
+ parent = self.mapToSource(parent)
+ return self.sourceModel().removeColumns(column, count, parent)
+
+ def removeRows(self, row, count, parent=QModelIndex()):
+ parent = self.mapToSource(parent)
+ return self.sourceModel().removeRows(row, count, parent)
+
+ def rowCount(self, parent=QModelIndex()):
+ parent = self.mapToSource(parent)
+ return self.sourceModel().rowCount(parent)
+
+ def setSourceModel(self, newSourceModel):
+ """Bind and unbind the source model events"""
+ self.beginResetModel()
+
+ sourceModel = self.sourceModel()
+ if sourceModel is not None:
+ sourceModel.rowsAboutToBeInserted.disconnect(self.__rowsAboutToBeInserted)
+ sourceModel.rowsInserted.disconnect(self.__rowsInserted)
+ sourceModel.rowsAboutToBeRemoved.disconnect(self.__rowsAboutToBeRemoved)
+ sourceModel.rowsRemoved.disconnect(self.__rowsRemoved)
+ sourceModel.rowsAboutToBeMoved.disconnect(self.__rowsAboutToBeMoved)
+ sourceModel.rowsMoved.disconnect(self.__rowsMoved)
+ sourceModel.columnsAboutToBeInserted.disconnect(self.__columnsAboutToBeInserted)
+ sourceModel.columnsInserted.disconnect(self.__columnsInserted)
+ sourceModel.columnsAboutToBeRemoved.disconnect(self.__columnsAboutToBeRemoved)
+ sourceModel.columnsRemoved.disconnect(self.__columnsRemoved)
+ sourceModel.columnsAboutToBeMoved.disconnect(self.__columnsAboutToBeMoved)
+ sourceModel.columnsMoved.disconnect(self.__columnsMoved)
+ sourceModel.modelAboutToBeReset.disconnect(self.__modelAboutToBeReset)
+ sourceModel.modelReset.disconnect(self.__modelReset)
+ sourceModel.dataChanged.disconnect(self.__dataChanged)
+ sourceModel.headerDataChanged.disconnect(self.__headerDataChanged)
+ sourceModel.layoutAboutToBeChanged.disconnect(self.__layoutAboutToBeChanged)
+ sourceModel.layoutChanged.disconnect(self.__layoutChanged)
+
+ super(QIdentityProxyModel, self).setSourceModel(newSourceModel)
+
+ sourceModel = self.sourceModel()
+ if sourceModel is not None:
+ sourceModel.rowsAboutToBeInserted.connect(self.__rowsAboutToBeInserted)
+ sourceModel.rowsInserted.connect(self.__rowsInserted)
+ sourceModel.rowsAboutToBeRemoved.connect(self.__rowsAboutToBeRemoved)
+ sourceModel.rowsRemoved.connect(self.__rowsRemoved)
+ sourceModel.rowsAboutToBeMoved.connect(self.__rowsAboutToBeMoved)
+ sourceModel.rowsMoved.connect(self.__rowsMoved)
+ sourceModel.columnsAboutToBeInserted.connect(self.__columnsAboutToBeInserted)
+ sourceModel.columnsInserted.connect(self.__columnsInserted)
+ sourceModel.columnsAboutToBeRemoved.connect(self.__columnsAboutToBeRemoved)
+ sourceModel.columnsRemoved.connect(self.__columnsRemoved)
+ sourceModel.columnsAboutToBeMoved.connect(self.__columnsAboutToBeMoved)
+ sourceModel.columnsMoved.connect(self.__columnsMoved)
+ sourceModel.modelAboutToBeReset.connect(self.__modelAboutToBeReset)
+ sourceModel.modelReset.connect(self.__modelReset)
+ sourceModel.dataChanged.connect(self.__dataChanged)
+ sourceModel.headerDataChanged.connect(self.__headerDataChanged)
+ sourceModel.layoutAboutToBeChanged.connect(self.__layoutAboutToBeChanged)
+ sourceModel.layoutChanged.connect(self.__layoutChanged)
+
+ self.endResetModel()
+
+ def __columnsAboutToBeInserted(self, parent, start, end):
+ parent = self.mapFromSource(parent)
+ self.beginInsertColumns(parent, start, end)
+
+ def __columnsAboutToBeMoved(self, sourceParent, sourceStart, sourceEnd, destParent, dest):
+ sourceParent = self.mapFromSource(sourceParent)
+ destParent = self.mapFromSource(destParent)
+ self.beginMoveColumns(sourceParent, sourceStart, sourceEnd, destParent, dest)
+
+ def __columnsAboutToBeRemoved(self, parent, start, end):
+ parent = self.mapFromSource(parent)
+ self.beginRemoveColumns(parent, start, end)
+
+ def __columnsInserted(self, parent, start, end):
+ self.endInsertColumns()
+
+ def __columnsMoved(self, sourceParent, sourceStart, sourceEnd, destParent, dest):
+ self.endMoveColumns()
+
+ def __columnsRemoved(self, parent, start, end):
+ self.endRemoveColumns()
+
+ def __dataChanged(self, topLeft, bottomRight):
+ topLeft = self.mapFromSource(topLeft)
+ bottomRight = self.mapFromSource(bottomRight)
+ self.dataChanged(topLeft, bottomRight)
+
+ def __headerDataChanged(self, orientation, first, last):
+ self.headerDataChanged(orientation, first, last)
+
+ def __layoutAboutToBeChanged(self):
+ """Store persistent indexes"""
+ if self.__ignoreNextLayoutAboutToBeChanged:
+ return
+
+ for proxyPersistentIndex in self.persistentIndexList():
+ self.__proxyIndexes.append()
+ sourcePersistentIndex = self.mapToSource(proxyPersistentIndex)
+ mapping = proxyPersistentIndex, sourcePersistentIndex
+ self.__persistentIndexes.append(mapping)
+
+ self.layoutAboutToBeChanged()
+
+ def __layoutChanged(self):
+ """Restore persistent indexes"""
+ if self.__ignoreNextLayoutChanged:
+ return
+
+ for mapping in self.__persistentIndexes:
+ proxyIndex, sourcePersistentIndex = mapping
+ sourcePersistentIndex = self.mapFromSource(sourcePersistentIndex)
+ self.changePersistentIndex(proxyIndex, sourcePersistentIndex)
+
+ self.__persistentIndexes = []
+
+ self.layoutChanged()
+
+ def __modelAboutToBeReset(self):
+ self.beginResetModel()
+
+ def __modelReset(self):
+ self.endResetModel()
+
+ def __rowsAboutToBeInserted(self, parent, start, end):
+ parent = self.mapFromSource(parent)
+ self.beginInsertRows(parent, start, end)
+
+ def __rowsAboutToBeMoved(self, sourceParent, sourceStart, sourceEnd, destParent, dest):
+ sourceParent = self.mapFromSource(sourceParent)
+ destParent = self.mapFromSource(destParent)
+ self.beginMoveRows(sourceParent, sourceStart, sourceEnd, destParent, dest)
+
+ def __rowsAboutToBeRemoved(self, parent, start, end):
+ parent = self.mapFromSource(parent)
+ self.beginRemoveRows(parent, start, end)
+
+ def __rowsInserted(self, parent, start, end):
+ self.endInsertRows()
+
+ def __rowsMoved(self, sourceParent, sourceStart, sourceEnd, destParent, dest):
+ self.endMoveRows()
+
+ def __rowsRemoved(self, parent, start, end):
+ self.endRemoveRows()
diff --git a/silx/gui/qt/_qt.py b/silx/gui/qt/_qt.py
new file mode 100644
index 0000000..0962c21
--- /dev/null
+++ b/silx/gui/qt/_qt.py
@@ -0,0 +1,229 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Common wrapper over Python Qt bindings:
+
+- `PyQt5 <http://pyqt.sourceforge.net/Docs/PyQt5/>`_,
+- `PyQt4 <http://pyqt.sourceforge.net/Docs/PyQt4/>`_ or
+- `PySide <http://www.pyside.org>`_.
+
+If a Qt binding is already loaded, it will use it, otherwise the different
+Qt bindings are tried in this order: PyQt4, PySide, PyQt5.
+
+The name of the loaded Qt binding is stored in the BINDING variable.
+
+For an alternative solution providing a structured namespace,
+see `qtpy <https://pypi.python.org/pypi/QtPy/>`_ which
+provides the namespace of PyQt5 over PyQt4 and PySide.
+"""
+
+__authors__ = ["V.A. Sole - ESRF Data Analysis"]
+__license__ = "MIT"
+__date__ = "17/01/2017"
+
+
+import logging
+import sys
+import traceback
+
+
+_logger = logging.getLogger(__name__)
+
+
+BINDING = None
+"""The name of the Qt binding in use: 'PyQt5', 'PyQt4' or 'PySide'."""
+
+QtBinding = None # noqa
+"""The Qt binding module in use: PyQt5, PyQt4 or PySide."""
+
+HAS_SVG = False
+"""True if Qt provides support for Scalable Vector Graphics (QtSVG)."""
+
+HAS_OPENGL = False
+"""True if Qt provides support for OpenGL (QtOpenGL)."""
+
+# First check for an already loaded wrapper
+if 'PySide.QtCore' in sys.modules:
+ BINDING = 'PySide'
+
+elif 'PyQt5.QtCore' in sys.modules:
+ BINDING = 'PyQt5'
+
+elif 'PyQt4.QtCore' in sys.modules:
+ BINDING = 'PyQt4'
+
+else: # Then try Qt bindings
+ try:
+ import PyQt4 # noqa
+ except ImportError:
+ try:
+ import PySide # noqa
+ except ImportError:
+ try:
+ import PyQt5 # noqa
+ except ImportError:
+ raise ImportError(
+ 'No Qt wrapper found. Install PyQt4, PyQt5 or PySide.')
+ else:
+ BINDING = 'PyQt5'
+ else:
+ BINDING = 'PySide'
+ else:
+ BINDING = 'PyQt4'
+
+
+if BINDING == 'PyQt4':
+ _logger.debug('Using PyQt4 bindings')
+
+ if sys.version < "3.0.0":
+ try:
+ import sip
+
+ sip.setapi("QString", 2)
+ sip.setapi("QVariant", 2)
+ except:
+ _logger.warning("Cannot set sip API")
+
+ import PyQt4 as QtBinding # noqa
+
+ from PyQt4.QtCore import * # noqa
+ from PyQt4.QtGui import * # noqa
+
+ try:
+ from PyQt4.QtOpenGL import * # noqa
+ except ImportError:
+ _logger.info("PyQt4.QtOpenGL not available")
+ HAS_OPENGL = False
+ else:
+ HAS_OPENGL = True
+
+ try:
+ from PyQt4.QtSvg import * # noqa
+ except ImportError:
+ _logger.info("PyQt4.QtSvg not available")
+ HAS_SVG = False
+ else:
+ HAS_SVG = True
+
+ from PyQt4.uic import loadUi # noqa
+
+ Signal = pyqtSignal
+
+ Property = pyqtProperty
+
+ Slot = pyqtSlot
+
+elif BINDING == 'PySide':
+ _logger.debug('Using PySide bindings')
+
+ import PySide as QtBinding # noqa
+
+ from PySide.QtCore import * # noqa
+ from PySide.QtGui import * # noqa
+
+ try:
+ from PySide.QtOpenGL import * # noqa
+ except ImportError:
+ _logger.info("PySide.QtOpenGL not available")
+ HAS_OPENGL = False
+ else:
+ HAS_OPENGL = True
+
+ try:
+ from PySide.QtSvg import * # noqa
+ except ImportError:
+ _logger.info("PySide.QtSvg not available")
+ HAS_SVG = False
+ else:
+ HAS_SVG = True
+
+ pyqtSignal = Signal
+
+ # Import loadUi wrapper for PySide
+ from ._pyside_dynamic import loadUi # noqa
+
+ # Import missing classes
+ if not hasattr(locals(), "QIdentityProxyModel"):
+ from ._pyside_missing import QIdentityProxyModel # noqa
+
+elif BINDING == 'PyQt5':
+ _logger.debug('Using PyQt5 bindings')
+
+ import PyQt5 as QtBinding # noqa
+
+ from PyQt5.QtCore import * # noqa
+ from PyQt5.QtGui import * # noqa
+ from PyQt5.QtWidgets import * # noqa
+ from PyQt5.QtPrintSupport import * # noqa
+
+ try:
+ from PyQt5.QtOpenGL import * # noqa
+ except ImportError:
+ _logger.info("PySide.QtOpenGL not available")
+ HAS_OPENGL = False
+ else:
+ HAS_OPENGL = True
+
+ try:
+ from PyQt5.QtSvg import * # noqa
+ except ImportError:
+ _logger.info("PyQt5.QtSvg not available")
+ HAS_SVG = False
+ else:
+ HAS_SVG = True
+
+ from PyQt5.uic import loadUi # noqa
+
+ Signal = pyqtSignal
+
+ Property = pyqtProperty
+
+ Slot = pyqtSlot
+
+else:
+ raise ImportError('No Qt wrapper found. Install PyQt4, PyQt5 or PySide')
+
+# provide a exception handler but not implement it by default
+def exceptionHandler(type_, value, trace):
+ """
+ This exception handler prevents quitting to the command line when there is
+ an unhandled exception while processing a Qt signal.
+
+ The script/application willing to use it should implement code similar to:
+
+ .. code-block:: python
+
+ if __name__ == "__main__":
+ sys.excepthook = qt.exceptionHandler
+
+ """
+ _logger.error("%s %s %s", type_, value, ''.join(traceback.format_tb(trace)))
+ msg = QMessageBox()
+ msg.setWindowTitle("Unhandled exception")
+ msg.setIcon(QMessageBox.Critical)
+ msg.setInformativeText("%s %s\nPlease report details" % (type_, value))
+ msg.setDetailedText(("%s " % value) + ''.join(traceback.format_tb(trace)))
+ msg.raise_()
+ msg.exec_()
+
diff --git a/silx/gui/qt/_utils.py b/silx/gui/qt/_utils.py
new file mode 100644
index 0000000..0aa3ef1
--- /dev/null
+++ b/silx/gui/qt/_utils.py
@@ -0,0 +1,44 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""This module provides convenient functions related to Qt.
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "30/11/2016"
+
+import sys
+from ._qt import BINDING, QImageReader
+
+
+def supportedImageFormats():
+ """Return a set of string of file format extensions supported by the
+ Qt runtime."""
+ if sys.version_info[0] < 3 or BINDING == 'PySide':
+ convert = str
+ else:
+ convert = lambda data: str(data, 'ascii')
+ formats = QImageReader.supportedImageFormats()
+ return set([convert(data) for data in formats])
diff --git a/silx/gui/setup.py b/silx/gui/setup.py
new file mode 100644
index 0000000..fbe9058
--- /dev/null
+++ b/silx/gui/setup.py
@@ -0,0 +1,51 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('gui', parent_package, top_path)
+ config.add_subpackage('_glutils')
+ config.add_subpackage('qt')
+ config.add_subpackage('plot')
+ config.add_subpackage('fit')
+ config.add_subpackage('hdf5')
+ config.add_subpackage('widgets')
+ config.add_subpackage('test')
+ config.add_subpackage('plot3d')
+ config.add_subpackage('data')
+
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/gui/test/__init__.py b/silx/gui/test/__init__.py
new file mode 100644
index 0000000..7449860
--- /dev/null
+++ b/silx/gui/test/__init__.py
@@ -0,0 +1,108 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/01/2017"
+
+
+import logging
+import os
+import sys
+import unittest
+
+
+_logger = logging.getLogger(__name__)
+
+
+def suite():
+
+ test_suite = unittest.TestSuite()
+
+ if sys.platform.startswith('linux') and not os.environ.get('DISPLAY', ''):
+ # On Linux and no DISPLAY available (e.g., ssh without -X)
+ _logger.warning('silx.gui tests disabled (DISPLAY env. variable not set)')
+
+ class SkipGUITest(unittest.TestCase):
+ def runTest(self):
+ self.skipTest(
+ 'silx.gui tests disabled (DISPLAY env. variable not set)')
+
+ test_suite.addTest(SkipGUITest())
+ return test_suite
+
+ elif os.environ.get('WITH_QT_TEST', 'True') == 'False':
+ # Explicitly disabled tests
+ _logger.warning(
+ "silx.gui tests disabled (env. variable WITH_QT_TEST=False)")
+
+ class SkipGUITest(unittest.TestCase):
+ def runTest(self):
+ self.skipTest(
+ "silx.gui tests disabled (env. variable WITH_QT_TEST=False)")
+
+ test_suite.addTest(SkipGUITest())
+ return test_suite
+
+ # Import here to avoid loading QT if tests are disabled
+
+ from ..plot import test as test_plot
+ from ..fit import test as test_fit
+ from ..hdf5 import test as test_hdf5
+ from ..widgets import test as test_widgets
+ from ..data import test as test_data
+ from . import test_qt
+ # Console tests disabled due to corruption of python environment
+ # (see issue #538 on github)
+ # from . import test_console
+ from . import test_icons
+ from . import test_utils
+
+ try:
+ from ..plot3d.test import suite as test_plot3d_suite
+
+ except ImportError:
+ _logger.warning(
+ 'silx.gui.plot3d tests disabled '
+ '(PyOpenGL or QtOpenGL not installed)')
+
+ class SkipPlot3DTest(unittest.TestCase):
+ def runTest(self):
+ self.skipTest('silx.gui.plot3d tests disabled '
+ '(PyOpenGL or QtOpenGL not installed)')
+
+ test_plot3d_suite = SkipPlot3DTest
+
+
+ test_suite.addTest(test_qt.suite())
+ test_suite.addTest(test_plot.suite())
+ test_suite.addTest(test_fit.suite())
+ test_suite.addTest(test_hdf5.suite())
+ test_suite.addTest(test_widgets.suite())
+ # test_suite.addTest(test_console.suite()) # see issue #538 on github
+ test_suite.addTest(test_icons.suite())
+ test_suite.addTest(test_data.suite())
+ test_suite.addTest(test_utils.suite())
+ test_suite.addTest(test_plot3d_suite())
+ return test_suite
diff --git a/silx/gui/test/test_console.py b/silx/gui/test/test_console.py
new file mode 100644
index 0000000..7c25372
--- /dev/null
+++ b/silx/gui/test/test_console.py
@@ -0,0 +1,91 @@
+# 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.
+#
+# ###########################################################################*/
+"""Basic tests for IPython console widget"""
+
+from __future__ import print_function
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import unittest
+
+from silx.gui.test.utils import TestCaseQt
+
+from silx.gui import qt
+try:
+ from silx.gui.console import IPythonDockWidget
+except ImportError:
+ console_missing = True
+else:
+ console_missing = False
+
+
+# dummy objects to test pushing variables to the interactive namespace
+_a = 1
+
+
+def _f():
+ print("Hello World!")
+
+
+@unittest.skipIf(console_missing, "Could not import Ipython and/or qtconsole")
+class TestConsole(TestCaseQt):
+ """Basic test for ``module.IPythonDockWidget``"""
+
+ def setUp(self):
+ super(TestConsole, self).setUp()
+ self.console = IPythonDockWidget(
+ available_vars={"a": _a, "f": _f},
+ custom_banner="Welcome!\n")
+ self.console.show()
+ self.qWaitForWindowExposed(self.console)
+
+ def tearDown(self):
+ self.console.setAttribute(qt.Qt.WA_DeleteOnClose)
+ self.console.close()
+ del self.console
+ super(TestConsole, self).tearDown()
+
+ def testShow(self):
+ pass
+
+ def testInteract(self):
+ self.mouseClick(self.console, qt.Qt.LeftButton)
+ self.keyClicks(self.console, 'import silx')
+ self.keyClick(self.console, qt.Qt.Key_Enter)
+ self.qapp.processEvents()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestConsole))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/test/test_icons.py b/silx/gui/test/test_icons.py
new file mode 100644
index 0000000..f363c43
--- /dev/null
+++ b/silx/gui/test/test_icons.py
@@ -0,0 +1,116 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Basic test of Qt icons module."""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+
+import gc
+import unittest
+import weakref
+
+from silx.gui import qt
+from silx.gui.test.utils import TestCaseQt
+from silx.gui import icons
+
+
+class TestIcons(TestCaseQt):
+ """Test to check that icons module."""
+
+ def testSvgIcon(self):
+ if "svg" not in qt.supportedImageFormats():
+ self.skipTest("SVG not supported")
+ icon = icons.getQIcon("test-svg")
+ self.assertIsNotNone(icon)
+
+ def testPngIcon(self):
+ icon = icons.getQIcon("test-png")
+ self.assertIsNotNone(icon)
+
+ def testUnexistingIcon(self):
+ self.assertRaises(ValueError, icons.getQIcon, "not-exists")
+
+ def testExistingQPixmap(self):
+ icon = icons.getQPixmap("crop")
+ self.assertIsNotNone(icon)
+
+ def testUnexistingQPixmap(self):
+ self.assertRaises(ValueError, icons.getQPixmap, "not-exists")
+
+ def testCache(self):
+ icon1 = icons.getQIcon("crop")
+ icon2 = icons.getQIcon("crop")
+ self.assertIs(icon1, icon2)
+
+ def testCacheReleased(self):
+ icon = icons.getQIcon("crop")
+ icon_ref = weakref.ref(icon)
+ del icon
+ gc.collect()
+ self.assertIsNone(icon_ref())
+
+
+class TestAnimatedIcons(TestCaseQt):
+ """Test to check that icons module."""
+
+ def testProcessWorking(self):
+ icon = icons.getWaitIcon()
+ self.assertIsNotNone(icon)
+
+ def testProcessWorkingCache(self):
+ icon1 = icons.getWaitIcon()
+ icon2 = icons.getWaitIcon()
+ self.assertIs(icon1, icon2)
+
+ def testMovieIconExists(self):
+ if "mng" not in qt.supportedImageFormats():
+ self.skipTest("MNG not supported")
+ icon = icons.MovieAnimatedIcon("process-working")
+ self.assertIsNotNone(icon)
+
+ def testMovieIconNotExists(self):
+ self.assertRaises(ValueError, icons.MovieAnimatedIcon, "not-exists")
+
+ def testMultiImageIconExists(self):
+ icon = icons.MultiImageAnimatedIcon("process-working")
+ self.assertIsNotNone(icon)
+
+ def testMultiImageIconNotExists(self):
+ self.assertRaises(ValueError, icons.MultiImageAnimatedIcon, "not-exists")
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestIcons))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestAnimatedIcons))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/test/test_qt.py b/silx/gui/test/test_qt.py
new file mode 100644
index 0000000..3a89a33
--- /dev/null
+++ b/silx/gui/test/test_qt.py
@@ -0,0 +1,144 @@
+# 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.
+#
+# ###########################################################################*/
+"""Basic test of Qt bindings wrapper."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import os.path
+import unittest
+
+from silx.test.utils import temp_dir
+from silx.gui.test.utils import TestCaseQt
+
+from silx.gui import qt
+
+
+class TestQtWrapper(unittest.TestCase):
+ """Minimalistic test to check that Qt has been loaded."""
+
+ def testQObject(self):
+ """Test that QObject is there."""
+ obj = qt.QObject()
+ self.assertTrue(obj is not None)
+
+
+class TestLoadUi(TestCaseQt):
+ """Test loadUi function"""
+
+ TEST_UI = """<?xml version="1.0" encoding="UTF-8"?>
+ <ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>293</width>
+ <height>296</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Test loadUi</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>89</width>
+ <height>27</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Button 1</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" name="pushButton_2">
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>50</y>
+ <width>89</width>
+ <height>27</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Button 2</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QMenuBar" name="menubar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>293</width>
+ <height>25</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+ </ui>
+ """
+
+ def testLoadUi(self):
+ """Create a QMainWindow from an ui file"""
+ with temp_dir() as tmp:
+ uifile = os.path.join(tmp, "test.ui")
+
+ # write file
+ with open(uifile, mode='w') as f:
+ f.write(self.TEST_UI)
+
+ class TestMainWindow(qt.QMainWindow):
+ def __init__(self, parent=None):
+ super(TestMainWindow, self).__init__(parent)
+ qt.loadUi(uifile, self)
+
+ testMainWindow = TestMainWindow()
+ testMainWindow.show()
+ self.qWaitForWindowExposed(testMainWindow)
+
+ testMainWindow.setAttribute(qt.Qt.WA_DeleteOnClose)
+ testMainWindow.close()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for TestCaseCls in (TestQtWrapper, TestLoadUi):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestCaseCls))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/test/test_utils.py b/silx/gui/test/test_utils.py
new file mode 100644
index 0000000..4625969
--- /dev/null
+++ b/silx/gui/test/test_utils.py
@@ -0,0 +1,77 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""Test of utils module."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+
+import unittest
+
+import numpy
+
+from silx.gui import qt
+from silx.gui.test.utils import TestCaseQt
+
+from silx.gui import _utils
+
+
+class TestQImageConversion(TestCaseQt):
+ """Tests conversion of QImage to/from numpy array."""
+
+ def testConvertArrayToQImage(self):
+ """Test conversion of numpy array to QImage"""
+ image = numpy.ones((3, 3, 3), dtype=numpy.uint8)
+ qimage = _utils.convertArrayToQImage(image)
+
+ self.assertEqual(qimage.height(), image.shape[0])
+ self.assertEqual(qimage.width(), image.shape[1])
+ self.assertEqual(qimage.format(), qt.QImage.Format_RGB888)
+
+ color = qt.QColor(1, 1, 1).rgb()
+ self.assertEqual(qimage.pixel(1, 1), color)
+
+ def testConvertQImageToArray(self):
+ """Test conversion of QImage to numpy array"""
+ qimage = qt.QImage(3, 3, qt.QImage.Format_RGB888)
+ qimage.fill(0x010101)
+ image = _utils.convertQImageToArray(qimage)
+
+ self.assertEqual(qimage.height(), image.shape[0])
+ self.assertEqual(qimage.width(), image.shape[1])
+ self.assertEqual(image.shape[2], 3)
+ self.assertTrue(numpy.all(numpy.equal(image, 1)))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(
+ TestQImageConversion))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/test/utils.py b/silx/gui/test/utils.py
new file mode 100644
index 0000000..50cf7bf
--- /dev/null
+++ b/silx/gui/test/utils.py
@@ -0,0 +1,428 @@
+# 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.
+#
+# ###########################################################################*/
+"""Helper class to write Qt widget unittests."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "11/04/2017"
+
+
+import gc
+import logging
+import unittest
+import time
+import functools
+import sys
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+from silx.gui import qt
+
+if qt.BINDING == 'PySide':
+ from PySide.QtTest import QTest
+elif qt.BINDING == 'PyQt5':
+ from PyQt5.QtTest import QTest
+elif qt.BINDING == 'PyQt4':
+ from PyQt4.QtTest import QTest
+else:
+ raise ImportError('Unsupported Qt bindings')
+
+# Qt4/Qt5 compatibility wrapper
+if qt.BINDING in ('PySide', 'PyQt4'):
+ _logger.info("QTest.qWaitForWindowExposed not available," +
+ "using QTest.qWaitForWindowShown instead.")
+
+ def qWaitForWindowExposed(window, timeout=None):
+ """Mimic QTest.qWaitForWindowExposed for Qt4."""
+ QTest.qWaitForWindowShown(window)
+ return True
+else:
+ qWaitForWindowExposed = QTest.qWaitForWindowExposed
+
+
+def qWaitForWindowExposedAndActivate(window, timeout=None):
+ """Waits until the window is shown in the screen.
+
+ It also activates the window and raises it.
+
+ See QTest.qWaitForWindowExposed for details.
+ """
+ if timeout is None:
+ result = qWaitForWindowExposed(window)
+ else:
+ result = qWaitForWindowExposed(window, timeout)
+
+ if result:
+ # Makes sure window is active and on top
+ window.activateWindow()
+ window.raise_()
+
+ return result
+
+
+# Placeholder for QApplication
+_qapp = None
+
+
+class TestCaseQt(unittest.TestCase):
+ """Base class to write test for Qt stuff.
+
+ It creates a QApplication before running the tests.
+ WARNING: The QApplication is shared by all tests, which might have side
+ effects.
+
+ After each test, this class is checking for widgets remaining alive.
+ To allow some widgets to remain alive at the end of a test, set the
+ allowedLeakingWidgets attribute to the number of widgets that can remain
+ alive at the end of the test.
+ With PySide, this test is not run for now as it seems PySide
+ is leaking widgets internally.
+
+ All keyboard and mouse event simulation methods call qWait(20) after
+ simulating the event (as QTest does on Mac OSX).
+ This was introduced to fix issues with continuous integration tests
+ running with Xvfb on Linux.
+ """
+
+ DEFAULT_TIMEOUT_WAIT = 100
+ """Default timeout for qWait"""
+
+ TIMEOUT_WAIT = 0
+ """Extra timeout in millisecond to add to qSleep, qWait and
+ qWaitForWindowExposed.
+
+ Intended purpose is for debugging, to add extra time to waits in order to
+ allow to view the tested widgets.
+ """
+
+ @classmethod
+ def exceptionHandler(cls, exceptionClass, exception, stack):
+ import traceback
+ message = (''.join(traceback.format_tb(stack)))
+ template = 'Traceback (most recent call last):\n{2}{0}: {1}'
+ message = template.format(exceptionClass.__name__, exception, message)
+ cls._exceptions.append(message)
+
+ @classmethod
+ def setUpClass(cls):
+ """Makes sure Qt is inited"""
+ cls._oldExceptionHook = sys.excepthook
+ sys.excepthook = cls.exceptionHandler
+
+ global _qapp
+ if _qapp is None:
+ # Makes sure a QApplication exists and do it once for all
+ _qapp = qt.QApplication.instance() or qt.QApplication([])
+
+ # Create/delate a QWidget to make sure init of QDesktopWidget
+ _dummyWidget = qt.QWidget()
+ _dummyWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
+ _dummyWidget.show()
+ _dummyWidget.close()
+ _qapp.processEvents()
+
+ @classmethod
+ def tearDownClass(cls):
+ sys.excepthook = cls._oldExceptionHook
+
+ def setUp(self):
+ """Get the list of existing widgets."""
+ self.allowedLeakingWidgets = 0
+ self.__previousWidgets = self.qapp.allWidgets()
+ self.__class__._exceptions = []
+
+ def _currentTestSucceeded(self):
+ if hasattr(self, '_outcome'):
+ # For Python >= 3.4
+ result = self.defaultTestResult() # these 2 methods have no side effects
+ self._feedErrorsToResult(result, self._outcome.errors)
+ else:
+ # For Python < 3.4
+ result = getattr(self, '_outcomeForDoCleanups', self._resultForDoCleanups)
+
+ error = self.id() in [case.id() for case, _ in result.errors]
+ failure = self.id() in [case.id() for case, _ in result.failures]
+ return not error and not failure
+
+ def _checkForUnreleasedWidgets(self):
+ """Test fixture checking that no more widgets exists."""
+ gc.collect()
+
+ widgets = [widget for widget in self.qapp.allWidgets()
+ if widget not in self.__previousWidgets]
+ del self.__previousWidgets
+
+ if qt.BINDING == 'PySide':
+ return # Do not test for leaking widgets with PySide
+
+ allowedLeakingWidgets = self.allowedLeakingWidgets
+ self.allowedLeakingWidgets = 0
+
+ if widgets and len(widgets) <= allowedLeakingWidgets:
+ _logger.info(
+ '%s: %d remaining widgets after test' % (self.id(),
+ len(widgets)))
+
+ if len(widgets) > allowedLeakingWidgets:
+ raise RuntimeError(
+ "Test ended with widgets alive: %s" % str(widgets))
+
+ def tearDown(self):
+ if len(self.__class__._exceptions) > 0:
+ messages = "\n".join(self.__class__._exceptions)
+ raise AssertionError("Exception occured in Qt thread:\n" + messages)
+
+ if self._currentTestSucceeded():
+ self._checkForUnreleasedWidgets()
+
+ @property
+ def qapp(self):
+ """The QApplication currently running."""
+ return qt.QApplication.instance()
+
+ # Proxy to QTest
+
+ Press = QTest.Press
+ """Key press action code"""
+
+ Release = QTest.Release
+ """Key release action code"""
+
+ Click = QTest.Click
+ """Key click action code"""
+
+ QTest = property(lambda self: QTest,
+ doc="""The Qt QTest class from the used Qt binding.""")
+
+ def keyClick(self, widget, key, modifier=qt.Qt.NoModifier, delay=-1):
+ """Simulate clicking a key.
+
+ See QTest.keyClick for details.
+ """
+ QTest.keyClick(widget, key, modifier, delay)
+ self.qWait(20)
+
+ def keyClicks(self, widget, sequence, modifier=qt.Qt.NoModifier, delay=-1):
+ """Simulate clicking a sequence of keys.
+
+ See QTest.keyClick for details.
+ """
+ QTest.keyClicks(widget, sequence, modifier, delay)
+ self.qWait(20)
+
+ def keyEvent(self, action, widget, key,
+ modifier=qt.Qt.NoModifier, delay=-1):
+ """Sends a Qt key event.
+
+ See QTest.keyEvent for details.
+ """
+ QTest.keyEvent(action, widget, key, modifier, delay)
+ self.qWait(20)
+
+ def keyPress(self, widget, key, modifier=qt.Qt.NoModifier, delay=-1):
+ """Sends a Qt key press event.
+
+ See QTest.keyPress for details.
+ """
+ QTest.keyPress(widget, key, modifier, delay)
+ self.qWait(20)
+
+ def keyRelease(self, widget, key, modifier=qt.Qt.NoModifier, delay=-1):
+ """Sends a Qt key release event.
+
+ See QTest.keyRelease for details.
+ """
+ QTest.keyRelease(widget, key, modifier, delay)
+ self.qWait(20)
+
+ def mouseClick(self, widget, button, modifier=None, pos=None, delay=-1):
+ """Simulate clicking a mouse button.
+
+ See QTest.mouseClick for details.
+ """
+ if modifier is None:
+ modifier = qt.Qt.KeyboardModifiers()
+ pos = qt.QPoint(pos[0], pos[1]) if pos is not None else qt.QPoint()
+ QTest.mouseClick(widget, button, modifier, pos, delay)
+ self.qWait(20)
+
+ def mouseDClick(self, widget, button, modifier=None, pos=None, delay=-1):
+ """Simulate double clicking a mouse button.
+
+ See QTest.mouseDClick for details.
+ """
+ if modifier is None:
+ modifier = qt.Qt.KeyboardModifiers()
+ pos = qt.QPoint(pos[0], pos[1]) if pos is not None else qt.QPoint()
+ QTest.mouseDClick(widget, button, modifier, pos, delay)
+ self.qWait(20)
+
+ def mouseMove(self, widget, pos=None, delay=-1):
+ """Simulate moving the mouse.
+
+ See QTest.mouseMove for details.
+ """
+ pos = qt.QPoint(pos[0], pos[1]) if pos is not None else qt.QPoint()
+ QTest.mouseMove(widget, pos, delay)
+ self.qWait(20)
+
+ def mousePress(self, widget, button, modifier=None, pos=None, delay=-1):
+ """Simulate pressing a mouse button.
+
+ See QTest.mousePress for details.
+ """
+ if modifier is None:
+ modifier = qt.Qt.KeyboardModifiers()
+ pos = qt.QPoint(pos[0], pos[1]) if pos is not None else qt.QPoint()
+ QTest.mousePress(widget, button, modifier, pos, delay)
+ self.qWait(20)
+
+ def mouseRelease(self, widget, button, modifier=None, pos=None, delay=-1):
+ """Simulate releasing a mouse button.
+
+ See QTest.mouseRelease for details.
+ """
+ if modifier is None:
+ modifier = qt.Qt.KeyboardModifiers()
+ pos = qt.QPoint(pos[0], pos[1]) if pos is not None else qt.QPoint()
+ QTest.mouseRelease(widget, button, modifier, pos, delay)
+ self.qWait(20)
+
+ def qSleep(self, ms):
+ """Sleep for ms milliseconds, blocking the execution of the test.
+
+ See QTest.qSleep for details.
+ """
+ QTest.qSleep(ms + self.TIMEOUT_WAIT)
+
+ def qWait(self, ms=None):
+ """Waits for ms milliseconds, events will be processed.
+
+ See QTest.qWait for details.
+ """
+ if ms is None:
+ ms = self.DEFAULT_TIMEOUT_WAIT
+
+ if qt.BINDING == 'PySide':
+ # PySide has no qWait, provide a replacement
+ timeout = int(ms)
+ endTimeMS = int(time.time() * 1000) + timeout
+ while timeout > 0:
+ self.qapp.processEvents(qt.QEventLoop.AllEvents,
+ maxtime=timeout)
+ timeout = endTimeMS - int(time.time() * 1000)
+ else:
+ QTest.qWait(ms + self.TIMEOUT_WAIT)
+
+ def qWaitForWindowExposed(self, window, timeout=None):
+ """Waits until the window is shown in the screen.
+
+ See QTest.qWaitForWindowExposed for details.
+ """
+ result = qWaitForWindowExposedAndActivate(window, timeout)
+
+ if self.TIMEOUT_WAIT:
+ QTest.qWait(self.TIMEOUT_WAIT)
+
+ return result
+
+
+class SignalListener():
+ """Util to listen a Qt event and store parameters
+ """
+
+ def __init__(self):
+ self.__calls = []
+
+ def __call__(self, *args, **kargs):
+ self.__calls.append((args, kargs))
+
+ def clear(self):
+ """Clear stored data"""
+ self.__calls = []
+
+ def callCount(self):
+ """
+ Returns how many times the listener was called.
+
+ :rtype: int
+ """
+ return len(self.__calls)
+
+ def arguments(self, callIndex=None, argumentIndex=None):
+ """Returns positional arguments optionally filtered by call count id
+ or argument index.
+
+ :param int callIndex: Index of the called data
+ :param int argumentIndex: Index of the positional argument.
+ """
+ if callIndex is not None:
+ result = self.__calls[callIndex][0]
+ if argumentIndex is not None:
+ result = result[argumentIndex]
+ else:
+ result = [x[0] for x in self.__calls]
+ if argumentIndex is not None:
+ result = [x[argumentIndex] for x in result]
+ return result
+
+ def karguments(self, callIndex=None, argumentName=None):
+ """Returns positional arguments optionally filtered by call count id
+ or name of the keyword argument.
+
+ :param int callIndex: Index of the called data
+ :param int argumentName: Name of the keyword argument.
+ """
+ if callIndex is not None:
+ result = self.__calls[callIndex][1]
+ if argumentName is not None:
+ result = result[argumentName]
+ else:
+ result = [x[1] for x in self.__calls]
+ if argumentName is not None:
+ result = [x[argumentName] for x in result]
+ return result
+
+ def partial(self, *args, **kargs):
+ """Returns a new partial object which when called will behave like this
+ listener called with the positional arguments args and keyword
+ arguments keywords. If more arguments are supplied to the call, they
+ are appended to args. If additional keyword arguments are supplied,
+ they extend and override keywords.
+ """
+ return functools.partial(self, *args, **kargs)
+
+
+def getQToolButtonFromAction(action):
+ """Return a QToolButton corresponding to a QAction.
+
+ :param QAction action: The QAction from which to get QToolButton.
+ :return: A QToolButton associated to action or None.
+ """
+ for widget in action.associatedWidgets():
+ if isinstance(widget, qt.QToolButton):
+ return widget
+ return None
diff --git a/silx/gui/widgets/FrameBrowser.py b/silx/gui/widgets/FrameBrowser.py
new file mode 100644
index 0000000..783a70a
--- /dev/null
+++ b/silx/gui/widgets/FrameBrowser.py
@@ -0,0 +1,307 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module defines two main classes:
+
+ - :class:`FrameBrowser`: a widget with 4 buttons (first, previous, next,
+ last) to browse between frames and a text entry to access a specific frame
+ by typing it's number)
+ - :class:`HorizontalSliderWithBrowser`: a FrameBrowser with an additional
+ slider. This class inherits :class:`qt.QAbstractSlider`.
+
+"""
+from silx.gui import qt
+from silx.gui import icons
+
+__authors__ = ["V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+
+class FrameBrowser(qt.QWidget):
+ """Frame browser widget, with 4 buttons/icons and a line edit to provide
+ a way of selecting a frame index in a stack of images.
+
+ It can be used in more generic case to select an integer within a range.
+
+ :param QWidget parent: Parent widget
+ :param int n: Number of frames. This will set the range
+ of frame indices to 0--n-1.
+ If None, the range is initialized to the default QSlider range (0--99)."""
+ sigIndexChanged = qt.pyqtSignal(object)
+
+ def __init__(self, parent=None, n=None):
+ qt.QWidget.__init__(self, parent)
+
+ # Use the font size as the icon size to avoid to create bigger buttons
+ fontMetric = self.fontMetrics()
+ iconSize = qt.QSize(fontMetric.height(), fontMetric.height())
+
+ self.mainLayout = qt.QHBoxLayout(self)
+ self.mainLayout.setContentsMargins(0, 0, 0, 0)
+ self.mainLayout.setSpacing(0)
+ self.firstButton = qt.QPushButton(self)
+ self.firstButton.setIcon(icons.getQIcon("first"))
+ self.firstButton.setIconSize(iconSize)
+ self.previousButton = qt.QPushButton(self)
+ self.previousButton.setIcon(icons.getQIcon("previous"))
+ self.previousButton.setIconSize(iconSize)
+ self._lineEdit = qt.QLineEdit(self)
+
+ self._label = qt.QLabel(self)
+ self.nextButton = qt.QPushButton(self)
+ self.nextButton.setIcon(icons.getQIcon("next"))
+ self.nextButton.setIconSize(iconSize)
+ self.lastButton = qt.QPushButton(self)
+ self.lastButton.setIcon(icons.getQIcon("last"))
+ self.lastButton.setIconSize(iconSize)
+
+ self.mainLayout.addWidget(self.firstButton)
+ self.mainLayout.addWidget(self.previousButton)
+ self.mainLayout.addWidget(self._lineEdit)
+ self.mainLayout.addWidget(self._label)
+ self.mainLayout.addWidget(self.nextButton)
+ self.mainLayout.addWidget(self.lastButton)
+
+ if n is None:
+ first = qt.QSlider().minimum()
+ last = qt.QSlider().maximum()
+ else:
+ first, last = 0, n
+
+ self._lineEdit.setFixedWidth(self._lineEdit.fontMetrics().width('%05d' % last))
+ validator = qt.QIntValidator(first, last, self._lineEdit)
+ self._lineEdit.setValidator(validator)
+ self._lineEdit.setText("%d" % first)
+ self._label.setText("of %d" % last)
+
+ self._index = first
+ """0-based index"""
+
+ self.firstButton.clicked.connect(self._firstClicked)
+ self.previousButton.clicked.connect(self._previousClicked)
+ self.nextButton.clicked.connect(self._nextClicked)
+ self.lastButton.clicked.connect(self._lastClicked)
+ self._lineEdit.editingFinished.connect(self._textChangedSlot)
+
+ def lineEdit(self):
+ """Returns the line edit provided by this widget.
+
+ :rtype: qt.QLineEdit
+ """
+ return self._lineEdit
+
+ def limitWidget(self):
+ """Returns the widget displaying axes limits.
+
+ :rtype: qt.QLabel
+ """
+ return self._label
+
+ def _firstClicked(self):
+ """Select first/lowest frame number"""
+ self._lineEdit.setText("%d" % self._lineEdit.validator().bottom())
+ self._textChangedSlot()
+
+ def _previousClicked(self):
+ """Select previous frame number"""
+ if self._index > self._lineEdit.validator().bottom():
+ self._lineEdit.setText("%d" % (self._index - 1))
+ self._textChangedSlot()
+
+ def _nextClicked(self):
+ """Select next frame number"""
+ if self._index < (self._lineEdit.validator().top()):
+ self._lineEdit.setText("%d" % (self._index + 1))
+ self._textChangedSlot()
+
+ def _lastClicked(self):
+ """Select last/highest frame number"""
+ self._lineEdit.setText("%d" % self._lineEdit.validator().top())
+ self._textChangedSlot()
+
+ def _textChangedSlot(self):
+ """Select frame number typed in the line edit widget"""
+ txt = self._lineEdit.text()
+ if not len(txt):
+ self._lineEdit.setText("%d" % self._index)
+ return
+ new_value = int(txt)
+ if new_value == self._index:
+ return
+ ddict = {
+ "event": "indexChanged",
+ "old": self._index,
+ "new": new_value,
+ "id": id(self)
+ }
+ self._index = new_value
+ self.sigIndexChanged.emit(ddict)
+
+ def setRange(self, first, last):
+ """Set minimum and maximum frame indices
+ Initialize the frame index to *first*.
+ Update the label text to *" limits: first, last"*
+
+ :param int first: Minimum frame index
+ :param int last: Maximum frame index"""
+ return self.setLimits(first, last)
+
+ def setLimits(self, first, last):
+ """Set minimum and maximum frame indices.
+ Initialize the frame index to *first*.
+ Update the label text to *" limits: first, last"*
+
+ :param int first: Minimum frame index
+ :param int last: Maximum frame index"""
+ bottom = min(first, last)
+ top = max(first, last)
+ self._lineEdit.validator().setTop(top)
+ self._lineEdit.validator().setBottom(bottom)
+ self._index = bottom
+ self._lineEdit.setText("%d" % self._index)
+ self._label.setText(" limits: %d, %d " % (bottom, top))
+
+ def setNFrames(self, nframes):
+ """Set minimum=0 and maximum=nframes-1 frame numbers.
+ Initialize the frame index to 0.
+ Update the label text to *"1 of nframes"*
+
+ :param int nframes: Number of frames"""
+ bottom = 0
+ top = nframes - 1
+ self._lineEdit.validator().setTop(top)
+ self._lineEdit.validator().setBottom(bottom)
+ self._index = bottom
+ self._lineEdit.setText("%d" % self._index)
+ # display 1-based index in label
+ self._label.setText(" %d of %d " % (self._index + 1, top + 1))
+
+ def getCurrentIndex(self):
+ """Get 0-based frame index
+ """
+ return self._index
+
+ def setValue(self, value):
+ """Set 0-based frame index
+
+ :param int value: Frame number"""
+ self._lineEdit.setText("%d" % value)
+ self._textChangedSlot()
+
+
+class HorizontalSliderWithBrowser(qt.QAbstractSlider):
+ """
+ Slider widget combining a :class:`QSlider` and a :class:`FrameBrowser`.
+
+ The data model is an integer within a range.
+
+ The default value is the default :class:`QSlider` value (0),
+ and the default range is the default QSlider range (0 -- 99)
+
+ The signal emitted when the value is changed is the usual QAbstractSlider
+ signal :attr:`valueChanged`. The signal carries the value (as an integer).
+
+ :param QWidget parent: Optional parent widget
+ """
+ sigIndexChanged = qt.pyqtSignal(object)
+
+ def __init__(self, parent=None):
+ qt.QAbstractSlider.__init__(self, parent)
+ self.setOrientation(qt.Qt.Horizontal)
+
+ self.mainLayout = qt.QHBoxLayout(self)
+ self.mainLayout.setContentsMargins(0, 0, 0, 0)
+ self.mainLayout.setSpacing(2)
+
+ self._slider = qt.QSlider(self)
+ self._slider.setOrientation(qt.Qt.Horizontal)
+
+ self._browser = FrameBrowser(self)
+
+ self.mainLayout.addWidget(self._slider, 1)
+ self.mainLayout.addWidget(self._browser)
+
+ self._slider.valueChanged[int].connect(self._sliderSlot)
+ self._browser.sigIndexChanged.connect(self._browserSlot)
+
+ def lineEdit(self):
+ """Returns the line edit provided by this widget.
+
+ :rtype: qt.QLineEdit
+ """
+ return self._browser.lineEdit()
+
+ def limitWidget(self):
+ """Returns the widget displaying axes limits.
+
+ :rtype: qt.QLabel
+ """
+ return self._browser.limitWidget()
+
+ def setMinimum(self, value):
+ """Set minimum value
+
+ :param int value: Minimum value"""
+ self._slider.setMinimum(value)
+ maximum = self._slider.maximum()
+ self._browser.setRange(value, maximum)
+
+ def setMaximum(self, value):
+ """Set maximum value
+
+ :param int value: Maximum value
+ """
+ self._slider.setMaximum(value)
+ minimum = self._slider.minimum()
+ self._browser.setRange(minimum, value)
+
+ def setRange(self, first, last):
+ """Set minimum/maximum values
+
+ :param int first: Minimum value
+ :param int last: Maximum value"""
+ self._slider.setRange(first, last)
+ self._browser.setRange(first, last)
+
+ def _sliderSlot(self, value):
+ """Emit selected value when slider is activated
+ """
+ self._browser.setValue(value)
+ self.valueChanged.emit(value)
+
+ def _browserSlot(self, ddict):
+ """Emit selected value when browser state is changed"""
+ self._slider.setValue(ddict['new'])
+
+ def setValue(self, value):
+ """Set value
+
+ :param int value: value"""
+ self._slider.setValue(value)
+ self._browser.setValue(value)
+
+ def value(self):
+ """Get selected value"""
+ return self._slider.value()
diff --git a/silx/gui/widgets/HierarchicalTableView.py b/silx/gui/widgets/HierarchicalTableView.py
new file mode 100644
index 0000000..3ccf4c7
--- /dev/null
+++ b/silx/gui/widgets/HierarchicalTableView.py
@@ -0,0 +1,172 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""
+This module define a hierarchical table view and model.
+
+It allows to define many headers in the middle of a table.
+
+The implementation hide the default header and allows to custom each cells
+to became a header.
+
+Row and column span is a concept of the view in a QTableView.
+This implementation also provide a span property as part of the model of the
+cell. A role is define to custom this information.
+The view is updated everytime the model is reset to take care of the
+changes of this information.
+
+A default item delegate is used to redefine the paint of the cells.
+"""
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "07/04/2017"
+
+from silx.gui import qt
+
+
+class HierarchicalTableModel(qt.QAbstractTableModel):
+ """
+ Abstract table model to provide more custom on row and column span and
+ headers.
+
+ Default headers are ignored and each cells can define IsHeaderRole and
+ SpanRole using the `data` function.
+ """
+
+ SpanRole = qt.Qt.UserRole + 0
+ """Role returning a tuple for number of row span then column span.
+
+ None and (1, 1) are neutral for the rendering.
+ """
+
+ IsHeaderRole = qt.Qt.UserRole + 1
+ """Role returning True is the identified cell is a header."""
+
+ UserRole = qt.Qt.UserRole + 2
+ """First index of user defined roles"""
+
+ def headerData(self, section, orientation, role=qt.Qt.DisplayRole):
+ """Returns the 0-based row or column index, for display in the
+ horizontal and vertical headers
+
+ In this case the headers are just ignored. Header information is part
+ of each cells.
+ """
+ return None
+
+
+class HierarchicalItemDelegate(qt.QStyledItemDelegate):
+ """
+ Delegate item to take care of the rendering of the default table cells and
+ also the header cells.
+ """
+
+ def __init__(self, parent=None):
+ """
+ Constructor
+
+ :param qt.QObject parent: Parent of the widget
+ """
+ qt.QStyledItemDelegate.__init__(self, parent)
+
+ def paint(self, painter, option, index):
+ """Override the paint function to inject the style of the header.
+
+ :param qt.QPainter painter: Painter context used to displayed the cell
+ :param qt.QStyleOptionViewItem option: Control how the editor is shown
+ :param qt.QIndex index: Index of the data to display
+ """
+ isHeader = index.data(role=HierarchicalTableModel.IsHeaderRole)
+ if isHeader:
+ span = index.data(role=HierarchicalTableModel.SpanRole)
+ span = 1 if span is None else span[1]
+ columnCount = index.model().columnCount()
+ if span == columnCount:
+ mainTitle = True
+ position = qt.QStyleOptionHeader.OnlyOneSection
+ else:
+ mainTitle = False
+ col = index.column()
+ if col == 0:
+ position = qt.QStyleOptionHeader.Beginning
+ elif col < columnCount - 1:
+ position = qt.QStyleOptionHeader.Middle
+ else:
+ position = qt.QStyleOptionHeader.End
+ opt = qt.QStyleOptionHeader()
+ opt.direction = option.direction
+ opt.text = index.data()
+ opt.textAlignment = qt.Qt.AlignCenter if mainTitle else qt.Qt.AlignVCenter
+ opt.direction = option.direction
+ opt.fontMetrics = option.fontMetrics
+ opt.palette = option.palette
+ opt.rect = option.rect
+ opt.state = option.state
+ opt.position = position
+ margin = -1
+ style = qt.QApplication.instance().style()
+ opt.rect = opt.rect.adjusted(margin, margin, -margin, -margin)
+ style.drawControl(qt.QStyle.CE_HeaderSection, opt, painter, None)
+ margin = 3
+ opt.rect = opt.rect.adjusted(margin, margin, -margin, -margin)
+ style.drawControl(qt.QStyle.CE_HeaderLabel, opt, painter, None)
+ else:
+ qt.QStyledItemDelegate.paint(self, painter, option, index)
+
+
+class HierarchicalTableView(qt.QTableView):
+ """A TableView which allow to display a `HierarchicalTableModel`."""
+
+ def __init__(self, parent=None):
+ """
+ Constructor
+
+ :param qt.QWidget parent: Parent of the widget
+ """
+ super(HierarchicalTableView, self).__init__(parent)
+ self.setItemDelegate(HierarchicalItemDelegate(self))
+ self.verticalHeader().setVisible(False)
+ self.horizontalHeader().setVisible(False)
+
+ def setModel(self, model):
+ """Override the default function to connect the model to update
+ function"""
+ if self.model() is not None:
+ model.modelReset.disconnect(self.__modelReset)
+ super(HierarchicalTableView, self).setModel(model)
+ if self.model() is not None:
+ model.modelReset.connect(self.__modelReset)
+ self.__modelReset()
+
+ def __modelReset(self):
+ """Update the model to take care of the changes of the span
+ information"""
+ self.clearSpans()
+ model = self.model()
+ for row in range(model.rowCount()):
+ for column in range(model.columnCount()):
+ index = model.index(row, column, qt.QModelIndex())
+ span = model.data(index, HierarchicalTableModel.SpanRole)
+ if span is not None and span != (1, 1):
+ self.setSpan(row, column, span[0], span[1])
diff --git a/silx/gui/widgets/MedianFilterDialog.py b/silx/gui/widgets/MedianFilterDialog.py
new file mode 100644
index 0000000..3eddff3
--- /dev/null
+++ b/silx/gui/widgets/MedianFilterDialog.py
@@ -0,0 +1,74 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+""" MedianFilterDialog
+Classes
+-------
+
+Widgets:
+
+ - :class:`MedianFilterDialog`
+"""
+
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "14/02/2017"
+
+from silx.gui import qt
+
+class MedianFilterDialog(qt.QDialog):
+ """QDialog window featuring a :class:`BackgroundWidget`"""
+ sigFilterOptChanged = qt.Signal(int, bool)
+
+ def __init__(self, parent=None):
+ qt.QDialog.__init__(self, parent)
+
+ self.setWindowTitle("Median filter options")
+ self.mainLayout = qt.QHBoxLayout(self)
+ self.setLayout(self.mainLayout)
+
+ # filter width GUI
+ self.mainLayout.addWidget(qt.QLabel('filter width:', parent = self))
+ self._filterWidth = qt.QSpinBox(parent=self)
+ self._filterWidth.setMinimum(1)
+ self._filterWidth.setValue(1)
+ self._filterWidth.setSingleStep(2);
+ widthTooltip = """radius width of the pixel including in the filter
+ for each pixel"""
+ self._filterWidth.setToolTip(widthTooltip)
+ self._filterWidth.valueChanged.connect(self._filterOptionChanged)
+ self.mainLayout.addWidget(self._filterWidth)
+
+ # filter option GUI
+ self._filterOption = qt.QCheckBox('conditional', parent=self)
+ conditionalTooltip = """if check, implement a conditional filter"""
+ self._filterOption.stateChanged.connect(self._filterOptionChanged)
+ self.mainLayout.addWidget(self._filterOption)
+
+ def _filterOptionChanged(self):
+ """Call back used when the filter values are changed"""
+ if self._filterWidth.value()%2 == 0:
+ logging.warning('median filter only accept odd values')
+ else:
+ self.sigFilterOptChanged.emit(self._filterWidth.value(), self._filterOption.isChecked()) \ No newline at end of file
diff --git a/silx/gui/widgets/PeriodicTable.py b/silx/gui/widgets/PeriodicTable.py
new file mode 100644
index 0000000..2f1ca78
--- /dev/null
+++ b/silx/gui/widgets/PeriodicTable.py
@@ -0,0 +1,825 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""Periodic table widgets
+
+Classes
+-------
+
+Widgets:
+
+ - :class:`PeriodicTable`
+ - :class:`PeriodicList`
+ - :class:`PeriodicCombo`
+
+Data model:
+
+ - :class:`PeriodicTableItem`
+ - :class:`ColoredPeriodicTableItem`
+
+
+Example of usage
+----------------
+
+This example uses the widgets with the standard builtin elements list.
+
+.. code-block:: python
+
+ from silx.gui import qt
+ from silx.gui.widgets.PeriodicTable import PeriodicTable, \
+ PeriodicCombo, PeriodicList
+
+ a = qt.QApplication([])
+
+ w = qt.QTabWidget()
+
+ ptable = PeriodicTable(w, selectable=True)
+ pcombo = PeriodicCombo(w)
+ plist = PeriodicList(w)
+
+ w.addTab(ptable, "PeriodicTable")
+ w.addTab(plist, "PeriodicList")
+ w.addTab(pcombo, "PeriodicCombo")
+
+ ptable.setSelection(['H', 'Fe', 'Si'])
+ plist.setSelectedElements(['H', 'Be', 'F'])
+ pcombo.setSelection("Li")
+
+ def change_list(items):
+ print("New list selection:", [item.symbol for item in items])
+
+ def change_combo(item):
+ print("New combo selection:", item.symbol)
+
+ def click_table(item):
+ print("New table click:", item.symbol)
+
+ def change_table(items):
+ print("New table selection:", [item.symbol for item in items])
+
+ ptable.sigElementClicked.connect(click_table)
+ ptable.sigSelectionChanged.connect(change_table)
+ plist.sigSelectionChanged.connect(change_list)
+ pcombo.sigSelectionChanged.connect(change_combo)
+
+ w.show()
+ a.exec_()
+
+
+The second example explains how to define custom elements.
+
+.. code-block:: python
+
+ from silx.gui import qt
+ from silx.gui.widgets.PeriodicTable import PeriodicTable, \
+ PeriodicCombo, PeriodicList
+ from silx.gui.widgets.PeriodicTable import PeriodicTableItem
+
+ # subclass PeriodicTableItem
+ class MyPeriodicTableItem(PeriodicTableItem):
+ "New item with added mass number and number of protons"
+ def __init__(self, symbol, Z, A, col, row, name, mass,
+ subcategory=""):
+ PeriodicTableItem.__init__(
+ self, symbol, Z, col, row, name, mass,
+ subcategory)
+
+ self.A = A
+ "Mass number (neutrons + protons)"
+
+ self.num_neutrons = A - Z
+ "Number of neutrons"
+
+ # build your list of elements
+ my_elements = [MyPeriodicTableItem("H", 1, 1, 1, 1, "hydrogen",
+ 1.00800, "diatomic nonmetal"),
+ MyPeriodicTableItem("He", 2, 4, 18, 1, "helium",
+ 4.0030, "noble gas"),
+ # etc ...
+ ]
+
+ app = qt.QApplication([])
+
+ ptable = PeriodicTable(elements=my_elements, selectable=True)
+ ptable.show()
+
+ def click_table(item):
+ "Callback function printing the mass number of clicked element"
+ print("New table click, mass number:", item.A)
+
+ ptable.sigElementClicked.connect(click_table)
+ app.exec_()
+
+"""
+
+__authors__ = ["E. Papillon", "V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "26/01/2017"
+
+from collections import OrderedDict
+import logging
+from silx.gui import qt
+
+_logger = logging.getLogger(__name__)
+
+# Symbol Atomic Number col row name mass subcategory
+_elements = [("H", 1, 1, 1, "hydrogen", 1.00800, "diatomic nonmetal"),
+ ("He", 2, 18, 1, "helium", 4.0030, "noble gas"),
+ ("Li", 3, 1, 2, "lithium", 6.94000, "alkali metal"),
+ ("Be", 4, 2, 2, "beryllium", 9.01200, "alkaline earth metal"),
+ ("B", 5, 13, 2, "boron", 10.8110, "metalloid"),
+ ("C", 6, 14, 2, "carbon", 12.0100, "polyatomic nonmetal"),
+ ("N", 7, 15, 2, "nitrogen", 14.0080, "diatomic nonmetal"),
+ ("O", 8, 16, 2, "oxygen", 16.0000, "diatomic nonmetal"),
+ ("F", 9, 17, 2, "fluorine", 19.0000, "diatomic nonmetal"),
+ ("Ne", 10, 18, 2, "neon", 20.1830, "noble gas"),
+ ("Na", 11, 1, 3, "sodium", 22.9970, "alkali metal"),
+ ("Mg", 12, 2, 3, "magnesium", 24.3200, "alkaline earth metal"),
+ ("Al", 13, 13, 3, "aluminium", 26.9700, "post transition metal"),
+ ("Si", 14, 14, 3, "silicon", 28.0860, "metalloid"),
+ ("P", 15, 15, 3, "phosphorus", 30.9750, "polyatomic nonmetal"),
+ ("S", 16, 16, 3, "sulphur", 32.0660, "polyatomic nonmetal"),
+ ("Cl", 17, 17, 3, "chlorine", 35.4570, "diatomic nonmetal"),
+ ("Ar", 18, 18, 3, "argon", 39.9440, "noble gas"),
+ ("K", 19, 1, 4, "potassium", 39.1020, "alkali metal"),
+ ("Ca", 20, 2, 4, "calcium", 40.0800, "alkaline earth metal"),
+ ("Sc", 21, 3, 4, "scandium", 44.9600, "transition metal"),
+ ("Ti", 22, 4, 4, "titanium", 47.9000, "transition metal"),
+ ("V", 23, 5, 4, "vanadium", 50.9420, "transition metal"),
+ ("Cr", 24, 6, 4, "chromium", 51.9960, "transition metal"),
+ ("Mn", 25, 7, 4, "manganese", 54.9400, "transition metal"),
+ ("Fe", 26, 8, 4, "iron", 55.8500, "transition metal"),
+ ("Co", 27, 9, 4, "cobalt", 58.9330, "transition metal"),
+ ("Ni", 28, 10, 4, "nickel", 58.6900, "transition metal"),
+ ("Cu", 29, 11, 4, "copper", 63.5400, "transition metal"),
+ ("Zn", 30, 12, 4, "zinc", 65.3800, "transition metal"),
+ ("Ga", 31, 13, 4, "gallium", 69.7200, "post transition metal"),
+ ("Ge", 32, 14, 4, "germanium", 72.5900, "metalloid"),
+ ("As", 33, 15, 4, "arsenic", 74.9200, "metalloid"),
+ ("Se", 34, 16, 4, "selenium", 78.9600, "polyatomic nonmetal"),
+ ("Br", 35, 17, 4, "bromine", 79.9200, "diatomic nonmetal"),
+ ("Kr", 36, 18, 4, "krypton", 83.8000, "noble gas"),
+ ("Rb", 37, 1, 5, "rubidium", 85.4800, "alkali metal"),
+ ("Sr", 38, 2, 5, "strontium", 87.6200, "alkaline earth metal"),
+ ("Y", 39, 3, 5, "yttrium", 88.9050, "transition metal"),
+ ("Zr", 40, 4, 5, "zirconium", 91.2200, "transition metal"),
+ ("Nb", 41, 5, 5, "niobium", 92.9060, "transition metal"),
+ ("Mo", 42, 6, 5, "molybdenum", 95.9500, "transition metal"),
+ ("Tc", 43, 7, 5, "technetium", 99.0000, "transition metal"),
+ ("Ru", 44, 8, 5, "ruthenium", 101.0700, "transition metal"),
+ ("Rh", 45, 9, 5, "rhodium", 102.9100, "transition metal"),
+ ("Pd", 46, 10, 5, "palladium", 106.400, "transition metal"),
+ ("Ag", 47, 11, 5, "silver", 107.880, "transition metal"),
+ ("Cd", 48, 12, 5, "cadmium", 112.410, "transition metal"),
+ ("In", 49, 13, 5, "indium", 114.820, "post transition metal"),
+ ("Sn", 50, 14, 5, "tin", 118.690, "post transition metal"),
+ ("Sb", 51, 15, 5, "antimony", 121.760, "metalloid"),
+ ("Te", 52, 16, 5, "tellurium", 127.600, "metalloid"),
+ ("I", 53, 17, 5, "iodine", 126.910, "diatomic nonmetal"),
+ ("Xe", 54, 18, 5, "xenon", 131.300, "noble gas"),
+ ("Cs", 55, 1, 6, "caesium", 132.910, "alkali metal"),
+ ("Ba", 56, 2, 6, "barium", 137.360, "alkaline earth metal"),
+ ("La", 57, 3, 6, "lanthanum", 138.920, "lanthanide"),
+ ("Ce", 58, 4, 9, "cerium", 140.130, "lanthanide"),
+ ("Pr", 59, 5, 9, "praseodymium", 140.920, "lanthanide"),
+ ("Nd", 60, 6, 9, "neodymium", 144.270, "lanthanide"),
+ ("Pm", 61, 7, 9, "promethium", 147.000, "lanthanide"),
+ ("Sm", 62, 8, 9, "samarium", 150.350, "lanthanide"),
+ ("Eu", 63, 9, 9, "europium", 152.000, "lanthanide"),
+ ("Gd", 64, 10, 9, "gadolinium", 157.260, "lanthanide"),
+ ("Tb", 65, 11, 9, "terbium", 158.930, "lanthanide"),
+ ("Dy", 66, 12, 9, "dysprosium", 162.510, "lanthanide"),
+ ("Ho", 67, 13, 9, "holmium", 164.940, "lanthanide"),
+ ("Er", 68, 14, 9, "erbium", 167.270, "lanthanide"),
+ ("Tm", 69, 15, 9, "thulium", 168.940, "lanthanide"),
+ ("Yb", 70, 16, 9, "ytterbium", 173.040, "lanthanide"),
+ ("Lu", 71, 17, 9, "lutetium", 174.990, "lanthanide"),
+ ("Hf", 72, 4, 6, "hafnium", 178.500, "transition metal"),
+ ("Ta", 73, 5, 6, "tantalum", 180.950, "transition metal"),
+ ("W", 74, 6, 6, "tungsten", 183.920, "transition metal"),
+ ("Re", 75, 7, 6, "rhenium", 186.200, "transition metal"),
+ ("Os", 76, 8, 6, "osmium", 190.200, "transition metal"),
+ ("Ir", 77, 9, 6, "iridium", 192.200, "transition metal"),
+ ("Pt", 78, 10, 6, "platinum", 195.090, "transition metal"),
+ ("Au", 79, 11, 6, "gold", 197.200, "transition metal"),
+ ("Hg", 80, 12, 6, "mercury", 200.610, "transition metal"),
+ ("Tl", 81, 13, 6, "thallium", 204.390, "post transition metal"),
+ ("Pb", 82, 14, 6, "lead", 207.210, "post transition metal"),
+ ("Bi", 83, 15, 6, "bismuth", 209.000, "post transition metal"),
+ ("Po", 84, 16, 6, "polonium", 209.000, "post transition metal"),
+ ("At", 85, 17, 6, "astatine", 210.000, "metalloid"),
+ ("Rn", 86, 18, 6, "radon", 222.000, "noble gas"),
+ ("Fr", 87, 1, 7, "francium", 223.000, "alkali metal"),
+ ("Ra", 88, 2, 7, "radium", 226.000, "alkaline earth metal"),
+ ("Ac", 89, 3, 7, "actinium", 227.000, "actinide"),
+ ("Th", 90, 4, 10, "thorium", 232.000, "actinide"),
+ ("Pa", 91, 5, 10, "proactinium", 231.03588, "actinide"),
+ ("U", 92, 6, 10, "uranium", 238.070, "actinide"),
+ ("Np", 93, 7, 10, "neptunium", 237.000, "actinide"),
+ ("Pu", 94, 8, 10, "plutonium", 239.100, "actinide"),
+ ("Am", 95, 9, 10, "americium", 243, "actinide"),
+ ("Cm", 96, 10, 10, "curium", 247, "actinide"),
+ ("Bk", 97, 11, 10, "berkelium", 247, "actinide"),
+ ("Cf", 98, 12, 10, "californium", 251, "actinide"),
+ ("Es", 99, 13, 10, "einsteinium", 252, "actinide"),
+ ("Fm", 100, 14, 10, "fermium", 257, "actinide"),
+ ("Md", 101, 15, 10, "mendelevium", 258, "actinide"),
+ ("No", 102, 16, 10, "nobelium", 259, "actinide"),
+ ("Lr", 103, 17, 10, "lawrencium", 262, "actinide"),
+ ("Rf", 104, 4, 7, "rutherfordium", 261, "transition metal"),
+ ("Db", 105, 5, 7, "dubnium", 262, "transition metal"),
+ ("Sg", 106, 6, 7, "seaborgium", 266, "transition metal"),
+ ("Bh", 107, 7, 7, "bohrium", 264, "transition metal"),
+ ("Hs", 108, 8, 7, "hassium", 269, "transition metal"),
+ ("Mt", 109, 9, 7, "meitnerium", 268)]
+
+
+class PeriodicTableItem(object):
+ """Periodic table item, used as generic item in :class:`PeriodicTable`,
+ :class:`PeriodicCombo` and :class:`PeriodicList`.
+
+ This implementation stores the minimal amount of information needed by the
+ widgets:
+
+ - atomic symbol
+ - atomic number
+ - element name
+ - atomic mass
+ - column of element in periodic table
+ - row of element in periodic table
+
+ You can subclass this class to add additional information.
+
+ :param str symbol: Atomic symbol (e.g. H, He, Li...)
+ :param int Z: Proton number
+ :param int col: 1-based column index of element in periodic table
+ :param int row: 1-based row index of element in periodic table
+ :param str name: PeriodicTableItem name ("hydrogen", ...)
+ :param float mass: Atomic mass (gram per mol)
+ :param str subcategory: Subcategory, based on physical properties
+ (e.g. "alkali metal", "noble gas"...)
+ """
+ def __init__(self, symbol, Z, col, row, name, mass,
+ subcategory=""):
+ self.symbol = symbol
+ """Atomic symbol (e.g. H, He, Li...)"""
+ self.Z = Z
+ """Atomic number (Proton number)"""
+ self.col = col
+ """1-based column index of element in periodic table"""
+ self.row = row
+ """1-based row index of element in periodic table"""
+ self.name = name
+ """PeriodicTableItem name ("hydrogen", ...)"""
+ self.mass = mass
+ """Atomic mass (gram per mol)"""
+ self.subcategory = subcategory
+ """Subcategory, based on physical properties
+ (e.g. "alkali metal", "noble gas"...)"""
+
+ # pymca compatibility (elements used to be stored as a list of lists)
+ def __getitem__(self, idx):
+ if idx == 6:
+ _logger.warning("density not implemented in silx, returning 0.")
+
+ ret = [self.symbol, self.Z,
+ self.col, self.row,
+ self.name, self.mass,
+ 0.]
+ return ret[idx]
+
+ def __len__(self):
+ return 6
+
+
+class ColoredPeriodicTableItem(PeriodicTableItem):
+ """:class:`PeriodicTableItem` with an added :attr:`bgcolor`.
+ The background color can be passed as a parameter to the constructor.
+ If it is not specified, it will be defined based on
+ :attr:`subcategory`.
+
+ :param str bgcolor: Custom background color for element in
+ periodic table, as a RGB string *#RRGGBB*"""
+ COLORS = {
+ "diatomic nonmetal": "#7FFF00", # chartreuse
+ "noble gas": "#00FFFF", # cyan
+ "alkali metal": "#FFE4B5", # Moccasin
+ "alkaline earth metal": "#FFA500", # orange
+ "polyatomic nonmetal": "#7FFFD4", # aquamarine
+ "transition metal": "#FFA07A", # light salmon
+ "metalloid": "#8FBC8F", # Dark Sea Green
+ "post transition metal": "#D3D3D3", # light gray
+ "lanthanide": "#FFB6C1", # light pink
+ "actinide": "#F08080", # Light Coral
+ "": "#FFFFFF" # white
+ }
+ """Dictionary defining RGB colors for each subcategory."""
+
+ def __init__(self, symbol, Z, col, row, name, mass,
+ subcategory="", bgcolor=None):
+ PeriodicTableItem.__init__(self, symbol, Z, col, row, name, mass,
+ subcategory)
+
+ self.bgcolor = self.COLORS.get(subcategory, "#FFFFFF")
+ """Background color of element in the periodic table,
+ based on its subcategory. This should be a string of a hexadecimal
+ RGB code, with the format *#RRGGBB*.
+ If the subcategory is unknown, use white (*#FFFFFF*)
+ """
+
+ # possible custom color
+ if bgcolor is not None:
+ self.bgcolor = bgcolor
+
+
+_defaultTableItems = [ColoredPeriodicTableItem(*info) for info in _elements]
+
+
+class _ElementButton(qt.QPushButton):
+ """Atomic element button, used as a cell in the periodic table
+ """
+ sigElementEnter = qt.pyqtSignal(object)
+ """Signal emitted as the cursor enters the widget"""
+ sigElementLeave = qt.pyqtSignal(object)
+ """Signal emitted as the cursor leaves the widget"""
+ sigElementClicked = qt.pyqtSignal(object)
+ """Signal emitted when the widget is clicked"""
+
+ def __init__(self, item, parent=None):
+ """
+
+ :param parent: Parent widget
+ :param PeriodicTableItem item: :class:`PeriodicTableItem` object
+ """
+ qt.QPushButton.__init__(self, parent)
+
+ self.item = item
+ """:class:`PeriodicTableItem` object represented by this button"""
+
+ self.setText(item.symbol)
+ self.setFlat(1)
+ self.setCheckable(0)
+
+ self.setSizePolicy(qt.QSizePolicy(qt.QSizePolicy.Expanding,
+ qt.QSizePolicy.Expanding))
+
+ self.selected = False
+ self.current = False
+
+ # selection colors
+ self.selected_color = qt.QColor(qt.Qt.yellow)
+ self.current_color = qt.QColor(qt.Qt.gray)
+ self.selected_current_color = qt.QColor(qt.Qt.darkYellow)
+
+ # element colors
+
+ if hasattr(item, "bgcolor"):
+ self.bgcolor = qt.QColor(item.bgcolor)
+ else:
+ self.bgcolor = qt.QColor("#FFFFFF")
+
+ self.brush = qt.QBrush()
+ self.__setBrush()
+
+ self.clicked.connect(self.clickedSlot)
+
+ def sizeHint(self):
+ return qt.QSize(40, 40)
+
+ def setCurrent(self, b):
+ """Set this element button as current.
+ Multiple buttons can be selected.
+
+ :param b: boolean
+ """
+ self.current = b
+ self.__setBrush()
+
+ def isCurrent(self):
+ """
+ :return: True if element button is current
+ """
+ return self.current
+
+ def isSelected(self):
+ """
+ :return: True if element button is selected
+ """
+ return self.selected
+
+ def setSelected(self, b):
+ """Set this element button as selected.
+ Only a single button can be selected.
+
+ :param b: boolean
+ """
+ self.selected = b
+ self.__setBrush()
+
+ def __setBrush(self):
+ """Selected cells are yellow when not current.
+ The current cell is dark yellow when selected or grey when not
+ selected.
+ Other cells have no bg color by default, unless specified at
+ instantiation (:attr:`bgcolor`)"""
+ palette = self.palette()
+ # if self.current and self.selected:
+ # self.brush = qt.QBrush(self.selected_current_color)
+ # el
+ if self.selected:
+ self.brush = qt.QBrush(self.selected_color)
+ # elif self.current:
+ # self.brush = qt.QBrush(self.current_color)
+ elif self.bgcolor is not None:
+ self.brush = qt.QBrush(self.bgcolor)
+ else:
+ self.brush = qt.QBrush()
+ palette.setBrush(self.backgroundRole(),
+ self.brush)
+ self.setPalette(palette)
+ self.update()
+
+ def paintEvent(self, pEvent):
+ # get button geometry
+ widgGeom = self.rect()
+ paintGeom = qt.QRect(widgGeom.left() + 1,
+ widgGeom.top() + 1,
+ widgGeom.width() - 2,
+ widgGeom.height() - 2)
+
+ # paint background color
+ painter = qt.QPainter(self)
+ if self.brush is not None:
+ painter.fillRect(paintGeom, self.brush)
+ # paint frame
+ pen = qt.QPen(qt.Qt.black)
+ pen.setWidth(1 if not self.isCurrent() else 5)
+ painter.setPen(pen)
+ painter.drawRect(paintGeom)
+ painter.end()
+ qt.QPushButton.paintEvent(self, pEvent)
+
+ def enterEvent(self, e):
+ """Emit a :attr:`sigElementEnter` signal and send a
+ :class:`PeriodicTableItem` object"""
+ self.sigElementEnter.emit(self.item)
+
+ def leaveEvent(self, e):
+ """Emit a :attr:`sigElementLeave` signal and send a
+ :class:`PeriodicTableItem` object"""
+ self.sigElementLeave.emit(self.item)
+
+ def clickedSlot(self):
+ """Emit a :attr:`sigElementClicked` signal and send a
+ :class:`PeriodicTableItem` object"""
+ self.sigElementClicked.emit(self.item)
+
+
+class PeriodicTable(qt.QWidget):
+ """Periodic Table widget
+
+ The following example shows how to connect clicking to selection::
+
+ from silx.gui import qt
+ from silx.gui.widgets.PeriodicTable import PeriodicTable
+ app = qt.QApplication([])
+ pt = PeriodicTable()
+ pt.sigElementClicked.connect(pt.elementToggle)
+ pt.show()
+ app.exec_()
+
+ To print all selected elements each time a new element is selected::
+
+ def my_slot(item):
+ pt.elementToggle(item)
+ selected_elements = pt.getSelection()
+ for e in selected_elements:
+ print(e.symbol)
+
+ pt.sigElementClicked.connect(my_slot)
+
+ """
+ sigElementClicked = qt.pyqtSignal(object)
+ """When any element is clicked in the table, the widget emits
+ this signal and sends a :class:`PeriodicTableItem` object.
+ """
+
+ sigSelectionChanged = qt.pyqtSignal(object)
+ """When any element is selected/unselected in the table, the widget emits
+ this signal and sends a list of :class:`PeriodicTableItem` objects.
+
+ .. note::
+
+ To enable selection of elements, you must set *selectable=True*
+ when you instantiate the widget. Alternatively, you can also connect
+ :attr:`sigElementClicked` to :meth:`elementToggle` manually::
+
+ pt = PeriodicTable()
+ pt.sigElementClicked.connect(pt.elementToggle)
+
+
+ :param parent: parent QWidget
+ :param str name: Widget window title
+ :param elements: List of items (:class:`PeriodicTableItem` objects) to
+ be represented in the table. By default, take elements from
+ a predefined list with minimal information (symbol, atomic number,
+ name, mass).
+ :param bool selectable: If *True*, multiple elements can be
+ selected by clicking with the mouse. If *False* (default),
+ selection is only possible with method :meth:`setSelection`.
+ """
+
+ def __init__(self, parent=None, name="PeriodicTable", elements=None,
+ selectable=False):
+ self.selectable = selectable
+ qt.QWidget.__init__(self, parent)
+ self.setWindowTitle(name)
+ self.gridLayout = qt.QGridLayout(self)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.addItem(qt.QSpacerItem(0, 5), 7, 0)
+
+ for idx in range(10):
+ self.gridLayout.setRowStretch(idx, 3)
+ # row 8 (above lanthanoids is empty)
+ self.gridLayout.setRowStretch(7, 2)
+
+ # Element information displayed when cursor enters a cell
+ self.eltLabel = qt.QLabel(self)
+ f = self.eltLabel.font()
+ f.setBold(1)
+ self.eltLabel.setFont(f)
+ self.eltLabel.setAlignment(qt.Qt.AlignHCenter)
+ self.gridLayout.addWidget(self.eltLabel, 1, 1, 3, 10)
+
+ self._eltCurrent = None
+ """Current :class:`_ElementButton` (last clicked)"""
+
+ self._eltButtons = OrderedDict()
+ """Dictionary of all :class:`_ElementButton`. Keys are the symbols
+ ("H", "He", "Li"...)"""
+
+ if elements is None:
+ elements = _defaultTableItems
+ # fill cells with elements
+ for elmt in elements:
+ self.__addElement(elmt)
+
+ def __addElement(self, elmt):
+ """Add one :class:`_ElementButton` widget into the grid,
+ connect its signals to interact with the cursor"""
+ b = _ElementButton(elmt, self)
+ b.setAutoDefault(False)
+
+ self._eltButtons[elmt.symbol] = b
+ self.gridLayout.addWidget(b, elmt.row, elmt.col)
+
+ b.sigElementEnter.connect(self.elementEnter)
+ b.sigElementLeave.connect(self._elementLeave)
+ b.sigElementClicked.connect(self._elementClicked)
+
+ def elementEnter(self, item):
+ """Update label with element info (e.g. "Nb(41) - niobium")
+ when mouse cursor hovers an element.
+
+ :param PeriodicTableItem item: Element entered by cursor
+ """
+ self.eltLabel.setText("%s(%d) - %s" % (item.symbol, item.Z, item.name))
+
+ def _elementLeave(self, item):
+ """Clear label when the cursor leaves the cell
+
+ :param PeriodicTableItem item: Element left
+ """
+ self.eltLabel.setText("")
+
+ def _elementClicked(self, item):
+ """Emit :attr:`sigElementClicked`,
+ toggle selected state of element
+
+ :param PeriodicTableItem item: Element clicked
+ """
+ if self._eltCurrent is not None:
+ self._eltCurrent.setCurrent(False)
+ self._eltButtons[item.symbol].setCurrent(True)
+ self._eltCurrent = self._eltButtons[item.symbol]
+ if self.selectable:
+ self.elementToggle(item)
+ self.sigElementClicked.emit(item)
+
+ def getSelection(self):
+ """Return a list of selected elements, as a list of :class:`PeriodicTableItem`
+ objects.
+
+ :return: Selected items
+ :rtype: list(PeriodicTableItem)
+ """
+ return [b.item for b in self._eltButtons.values() if b.isSelected()]
+
+ def setSelection(self, symbols):
+ """Set selected elements.
+
+ This causes the sigSelectionChanged signal
+ to be emitted, even if the selection didn't actually change.
+
+ :param list(str) symbols: List of symbols of elements to be selected
+ (e.g. *["Fe", "Hg", "Li"]*)
+ """
+ # accept list of PeriodicTableItems as input, because getSelection
+ # returns these objects and it makes sense to have getter and setter
+ # use same type of data
+ if isinstance(symbols[0], PeriodicTableItem):
+ symbols = [elmt.symbol for elmt in symbols]
+
+ for (e, b) in self._eltButtons.items():
+ b.setSelected(e in symbols)
+ self.sigSelectionChanged.emit(self.getSelection())
+
+ def setElementSelected(self, symbol, state):
+ """Modify *selected* status of a single element (select or unselect)
+
+ :param str symbol: PeriodicTableItem symbol to be selected
+ :param bool state: *True* to select, *False* to unselect
+ """
+ self._eltButtons[symbol].setSelected(state)
+ self.sigSelectionChanged.emit(self.getSelection())
+
+ def isElementSelected(self, symbol):
+ """Return *True* if element is selected, else *False*
+
+ :param str symbol: PeriodicTableItem symbol
+ :return: *True* if element is selected, else *False*
+ """
+ return self._eltButtons[symbol].isSelected()
+
+ def elementToggle(self, item):
+ """Toggle selected/unselected state for element
+
+ :param item: PeriodicTableItem object
+ """
+ b = self._eltButtons[item.symbol]
+ b.setSelected(not b.isSelected())
+ self.sigSelectionChanged.emit(self.getSelection())
+
+
+class PeriodicCombo(qt.QComboBox):
+ """
+ Combo list with all atomic elements of the periodic table
+
+ :param bool detailed: True (default) display element symbol, Z and name.
+ False display only element symbol and Z.
+ :param elements: List of items (:class:`PeriodicTableItem` objects) to
+ be represented in the table. By default, take elements from
+ a predefined list with minimal information (symbol, atomic number,
+ name, mass).
+ """
+ sigSelectionChanged = qt.pyqtSignal(object)
+ """Signal emitted when the selection changes. Send
+ :class:`PeriodicTableItem` object representing selected
+ element
+ """
+
+ def __init__(self, parent=None, detailed=True, elements=None):
+ qt.QComboBox.__init__(self, parent)
+
+ # add all elements from global list
+ if elements is None:
+ elements = _defaultTableItems
+ for i, elmt in enumerate(elements):
+ if detailed:
+ txt = "%2s (%d) - %s" % (elmt.symbol, elmt.Z, elmt.name)
+ else:
+ txt = "%2s (%d)" % (elmt.symbol, elmt.Z)
+ self.insertItem(i, txt)
+
+ self.currentIndexChanged[int].connect(self.__selectionChanged)
+
+ def __selectionChanged(self, idx):
+ """Emit :attr:`sigSelectionChanged`"""
+ self.sigSelectionChanged.emit(_defaultTableItems[idx])
+
+ def getSelection(self):
+ """Get selected element
+
+ :return: Selected element
+ :rtype: PeriodicTableItem
+ """
+ return _defaultTableItems[self.currentIndex()]
+
+ def setSelection(self, symbol):
+ """Set selected item in combobox by giving the atomic symbol
+
+ :param symbol: Symbol of element to be selected
+ """
+ # accept PeriodicTableItem for getter/setter consistency
+ if isinstance(symbol, PeriodicTableItem):
+ symbol = symbol.symbol
+ symblist = [elmt.symbol for elmt in _defaultTableItems]
+ self.setCurrentIndex(symblist.index(symbol))
+
+
+class PeriodicList(qt.QTreeWidget):
+ """List of atomic elements in a :class:`QTreeView`
+
+ :param QWidget parent: Parent widget
+ :param bool detailed: True (default) display element symbol, Z and name.
+ False display only element symbol and Z.
+ :param single: *True* for single element selection with mouse click,
+ *False* for multiple element selection mode.
+ """
+ sigSelectionChanged = qt.pyqtSignal(object)
+ """When any element is selected/unselected in the widget, it emits
+ this signal and sends a list of currently selected
+ :class:`PeriodicTableItem` objects.
+ """
+
+ def __init__(self, parent=None, detailed=True, single=False, elements=None):
+ qt.QTreeWidget.__init__(self, parent)
+
+ self.detailed = detailed
+
+ headers = ["Z", "Symbol"]
+ if detailed:
+ headers.append("Name")
+ self.setColumnCount(3)
+ else:
+ self.setColumnCount(2)
+ self.setHeaderLabels(headers)
+ self.header().setStretchLastSection(False)
+
+ self.setRootIsDecorated(0)
+ self.itemClicked.connect(self.__selectionChanged)
+ self.setSelectionMode(qt.QAbstractItemView.SingleSelection if single
+ else qt.QAbstractItemView.ExtendedSelection)
+ self.__fill_widget(elements)
+ self.resizeColumnToContents(0)
+ self.resizeColumnToContents(1)
+ if detailed:
+ self.resizeColumnToContents(2)
+
+ def __fill_widget(self, elements):
+ """Fill tree widget with elements """
+ if elements is None:
+ elements = _defaultTableItems
+
+ self.tree_items = []
+
+ previous_item = None
+ for elmt in elements:
+ if previous_item is None:
+ item = qt.QTreeWidgetItem(self)
+ else:
+ item = qt.QTreeWidgetItem(self, previous_item)
+ item.setText(0, str(elmt.Z))
+ item.setText(1, elmt.symbol)
+ if self.detailed:
+ item.setText(2, elmt.name)
+ self.tree_items.append(item)
+ previous_item = item
+
+ def __selectionChanged(self, treeItem, column):
+ """Emit a :attr:`sigSelectionChanged` and send a list of
+ :class:`PeriodicTableItem` objects."""
+ self.sigSelectionChanged.emit(self.getSelection())
+
+ def getSelection(self):
+ """Get a list of selected elements, as a list of :class:`PeriodicTableItem`
+ objects.
+
+ :return: Selected elements
+ :rtype: list(PeriodicTableItem)"""
+ return [_defaultTableItems[idx] for idx in range(len(self.tree_items))
+ if self.tree_items[idx].isSelected()]
+
+ # setSelection is a bad name (name of a QTreeWidget method)
+ def setSelectedElements(self, symbolList):
+ """
+
+ :param symbolList: List of atomic symbols ["H", "He", "Li"...]
+ to be selected in the widget
+ """
+ # accept PeriodicTableItem for getter/setter consistency
+ if isinstance(symbolList[0], PeriodicTableItem):
+ symbolList = [elmt.symbol for elmt in symbolList]
+ for idx in range(len(self.tree_items)):
+ self.tree_items[idx].setSelected(_defaultTableItems[idx].symbol in symbolList)
diff --git a/silx/gui/widgets/TableWidget.py b/silx/gui/widgets/TableWidget.py
new file mode 100644
index 0000000..fad80ee
--- /dev/null
+++ b/silx/gui/widgets/TableWidget.py
@@ -0,0 +1,488 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+# ###########################################################################*/
+"""This module provides table widgets handling cut, copy and paste for
+multiple cell selections. These actions can be triggered using keyboard
+shortcuts or through a context menu (right-click).
+
+:class:`TableView` is a subclass of :class:`QTableView`. The added features
+are made available to users after a model is added to the widget, using
+:meth:`TableView.setModel`.
+
+:class:`TableWidget` is a subclass of :class:`qt.QTableWidget`, a table view
+with a built-in standard data model. The added features are available as soon as
+the widget is initialized.
+
+The cut, copy and paste actions are implemented as QActions:
+
+ - :class:`CopySelectedCellsAction` (*Ctrl+C*)
+ - :class:`CopyAllCellsAction`
+ - :class:`CutSelectedCellsAction` (*Ctrl+X*)
+ - :class:`CutAllCellsAction`
+ - :class:`PasteCellsAction` (*Ctrl+V*)
+
+The copy actions are enabled by default. The cut and paste actions must be
+explicitly enabled, by passing parameters ``cut=True, paste=True`` when
+creating the widgets, or later by calling their :meth:`enableCut` and
+:meth:`enablePaste` methods.
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "26/01/2017"
+
+
+import sys
+from .. import qt
+
+
+if sys.platform.startswith("win"):
+ row_separator = "\r\n"
+else:
+ row_separator = "\n"
+
+col_separator = "\t"
+
+
+class CopySelectedCellsAction(qt.QAction):
+ """QAction to copy text from selected cells in a :class:`QTableWidget`
+ into the clipboard.
+
+ If multiple cells are selected, the copied text will be a concatenation
+ of the texts in all selected cells, tabulated with tabulation and
+ newline characters.
+
+ If the cells are sparsely selected, the structure is preserved by
+ representing the unselected cells as empty strings in between two
+ tabulation characters.
+ Beware of pasting this data in another table widget, because depending
+ on how the paste is implemented, the empty cells may cause data in the
+ target table to be deleted, even though you didn't necessarily select the
+ corresponding cell in the origin table.
+
+ :param table: :class:`QTableView` to which this action belongs.
+ """
+ def __init__(self, table):
+ if not isinstance(table, qt.QTableView):
+ raise ValueError('CopySelectedCellsAction must be initialised ' +
+ 'with a QTableWidget.')
+ super(CopySelectedCellsAction, self).__init__(table)
+ self.setText("Copy selection")
+ self.setToolTip("Copy selected cells into the clipboard.")
+ self.setShortcut(qt.QKeySequence.Copy)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+ self.triggered.connect(self.copyCellsToClipboard)
+ self.table = table
+ self.cut = False
+ """:attr:`cut` can be set to True by classes inheriting this action,
+ to do a cut action."""
+
+ def copyCellsToClipboard(self):
+ """Concatenate the text content of all selected cells into a string
+ using tabulations and newlines to keep the table structure.
+ Put this text into the clipboard.
+ """
+ selected_idx = self.table.selectedIndexes()
+ selected_idx_tuples = [(idx.row(), idx.column()) for idx in selected_idx]
+
+ selected_rows = [idx[0] for idx in selected_idx_tuples]
+ selected_columns = [idx[1] for idx in selected_idx_tuples]
+
+ data_model = self.table.model()
+
+ copied_text = ""
+ for row in range(min(selected_rows), max(selected_rows) + 1):
+ for col in range(min(selected_columns), max(selected_columns) + 1):
+ index = data_model.index(row, col)
+ cell_text = data_model.data(index)
+ flags = data_model.flags(index)
+
+ if (row, col) in selected_idx_tuples and cell_text is not None:
+ copied_text += cell_text
+ if self.cut and (flags & qt.Qt.ItemIsEditable):
+ data_model.setData(index, "")
+ copied_text += col_separator
+ # remove the right-most tabulation
+ copied_text = copied_text[:-len(col_separator)]
+ # add a newline
+ copied_text += row_separator
+ # remove final newline
+ copied_text = copied_text[:-len(row_separator)]
+
+ # put this text into clipboard
+ qapp = qt.QApplication.instance()
+ qapp.clipboard().setText(copied_text)
+
+
+class CopyAllCellsAction(qt.QAction):
+ """QAction to copy text from all cells in a :class:`QTableWidget`
+ into the clipboard.
+
+ The copied text will be a concatenation
+ of the texts in all cells, tabulated with tabulation and
+ newline characters.
+
+ :param table: :class:`QTableView` to which this action belongs.
+ """
+ def __init__(self, table):
+ if not isinstance(table, qt.QTableView):
+ raise ValueError('CopyAllCellsAction must be initialised ' +
+ 'with a QTableWidget.')
+ super(CopyAllCellsAction, self).__init__(table)
+ self.setText("Copy all")
+ self.setToolTip("Copy all cells into the clipboard.")
+ self.triggered.connect(self.copyCellsToClipboard)
+ self.table = table
+ self.cut = False
+
+ def copyCellsToClipboard(self):
+ """Concatenate the text content of all cells into a string
+ using tabulations and newlines to keep the table structure.
+ Put this text into the clipboard.
+ """
+ data_model = self.table.model()
+ copied_text = ""
+ for row in range(data_model.rowCount()):
+ for col in range(data_model.columnCount()):
+ index = data_model.index(row, col)
+ cell_text = data_model.data(index)
+ flags = data_model.flags(index)
+ if cell_text is not None:
+ copied_text += cell_text
+ if self.cut and (flags & qt.Qt.ItemIsEditable):
+ data_model.setData(index, "")
+ copied_text += col_separator
+ # remove the right-most tabulation
+ copied_text = copied_text[:-len(col_separator)]
+ # add a newline
+ copied_text += row_separator
+ # remove final newline
+ copied_text = copied_text[:-len(row_separator)]
+
+ # put this text into clipboard
+ qapp = qt.QApplication.instance()
+ qapp.clipboard().setText(copied_text)
+
+
+class CutSelectedCellsAction(CopySelectedCellsAction):
+ """QAction to cut text from selected cells in a :class:`QTableWidget`
+ into the clipboard.
+
+ The text is deleted from the original table widget
+ (use :class:`CopySelectedCellsAction` to preserve the original data).
+
+ If multiple cells are selected, the cut text will be a concatenation
+ of the texts in all selected cells, tabulated with tabulation and
+ newline characters.
+
+ If the cells are sparsely selected, the structure is preserved by
+ representing the unselected cells as empty strings in between two
+ tabulation characters.
+ Beware of pasting this data in another table widget, because depending
+ on how the paste is implemented, the empty cells may cause data in the
+ target table to be deleted, even though you didn't necessarily select the
+ corresponding cell in the origin table.
+
+ :param table: :class:`QTableView` to which this action belongs."""
+ def __init__(self, table):
+ super(CutSelectedCellsAction, self).__init__(table)
+ self.setText("Cut selection")
+ self.setShortcut(qt.QKeySequence.Cut)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+ # cutting is already implemented in CopySelectedCellsAction (but
+ # it is disabled), we just need to enable it
+ self.cut = True
+
+
+class CutAllCellsAction(CopyAllCellsAction):
+ """QAction to cut text from all cells in a :class:`QTableWidget`
+ into the clipboard.
+
+ The text is deleted from the original table widget
+ (use :class:`CopyAllCellsAction` to preserve the original data).
+
+ The cut text will be a concatenation
+ of the texts in all cells, tabulated with tabulation and
+ newline characters.
+
+ :param table: :class:`QTableView` to which this action belongs."""
+ def __init__(self, table):
+ super(CutAllCellsAction, self).__init__(table)
+ self.setText("Cut all")
+ self.setToolTip("Cut all cells into the clipboard.")
+ self.cut = True
+
+
+def _parseTextAsTable(text, row_separator=row_separator, col_separator=col_separator):
+ """Parse text into list of lists (2D sequence).
+
+ The input text must be tabulated using tabulation characters and
+ newlines to separate columns and rows.
+
+ :param text: text to be parsed
+ :param record_separator: String, or single character, to be interpreted
+ as a record/row separator.
+ :param field_separator: String, or single character, to be interpreted
+ as a field/column separator.
+ :return: 2D sequence of strings
+ """
+ rows = text.split(row_separator)
+ table_data = [row.split(col_separator) for row in rows]
+ return table_data
+
+
+class PasteCellsAction(qt.QAction):
+ """QAction to paste text from the clipboard into the table.
+
+ If the text contains tabulations and
+ newlines, they are interpreted as column and row separators.
+ In such a case, the text is split into multiple texts to be pasted
+ into multiple cells.
+
+ If a cell content is an empty string in the original text, it is
+ ignored: the destination cell's text will not be deleted.
+
+ :param table: :class:`QTableView` to which this action belongs.
+ """
+ def __init__(self, table):
+ if not isinstance(table, qt.QTableView):
+ raise ValueError('PasteCellsAction must be initialised ' +
+ 'with a QTableWidget.')
+ super(PasteCellsAction, self).__init__(table)
+ self.table = table
+ self.setText("Paste")
+ self.setShortcut(qt.QKeySequence.Paste)
+ self.setShortcutContext(qt.Qt.WidgetShortcut)
+ self.setToolTip("Paste data. The selected cell is the top-left" +
+ "corner of the paste area.")
+ self.triggered.connect(self.pasteCellFromClipboard)
+
+ def pasteCellFromClipboard(self):
+ """Paste text from clipboard into the table.
+
+ :return: *True* in case of success, *False* if pasting data failed.
+ """
+ selected_idx = self.table.selectedIndexes()
+ if len(selected_idx) != 1:
+ msgBox = qt.QMessageBox(parent=self.table)
+ msgBox.setText("A single cell must be selected to paste data")
+ msgBox.exec_()
+ return False
+
+ data_model = self.table.model()
+
+ selected_row = selected_idx[0].row()
+ selected_col = selected_idx[0].column()
+
+ qapp = qt.QApplication.instance()
+ clipboard_text = qapp.clipboard().text()
+ table_data = _parseTextAsTable(clipboard_text)
+
+ protected_cells = 0
+ out_of_range_cells = 0
+
+ # paste table data into cells, using selected cell as origin
+ for row_offset in range(len(table_data)):
+ for col_offset in range(len(table_data[row_offset])):
+ target_row = selected_row + row_offset
+ target_col = selected_col + col_offset
+
+ if target_row >= data_model.rowCount() or\
+ target_col >= data_model.columnCount():
+ out_of_range_cells += 1
+ continue
+
+ index = data_model.index(target_row, target_col)
+ flags = data_model.flags(index)
+
+ # ignore empty strings
+ if table_data[row_offset][col_offset] != "":
+ if not flags & qt.Qt.ItemIsEditable:
+ protected_cells += 1
+ continue
+ data_model.setData(index, table_data[row_offset][col_offset])
+ # item.setText(table_data[row_offset][col_offset])
+
+ if protected_cells or out_of_range_cells:
+ msgBox = qt.QMessageBox(parent=self.table)
+ msg = "Some data could not be inserted, "
+ msg += "due to out-of-range or write-protected cells."
+ msgBox.setText(msg)
+ msgBox.exec_()
+ return False
+ return True
+
+
+class TableWidget(qt.QTableWidget):
+ """:class:`QTableWidget` with a context menu displaying up to 5 actions:
+
+ - :class:`CopySelectedCellsAction`
+ - :class:`CopyAllCellsAction`
+ - :class:`CutSelectedCellsAction`
+ - :class:`CutAllCellsAction`
+ - :class:`PasteCellsAction`
+
+ These actions interact with the clipboard and can be used to copy data
+ to or from an external application, or another widget.
+
+ The cut and paste actions are disabled by default, due to the risk of
+ overwriting data (no *Undo* action is available). Use :meth:`enablePaste`
+ and :meth:`enableCut` to activate them.
+
+ :param parent: Parent QWidget
+ :param bool cut: Enable cut action
+ :param bool paste: Enable paste action
+ """
+ def __init__(self, parent=None, cut=False, paste=False):
+ super(TableWidget, self).__init__(parent)
+ self.addAction(CopySelectedCellsAction(self))
+ self.addAction(CopyAllCellsAction(self))
+ if cut:
+ self.enableCut()
+ if paste:
+ self.enablePaste()
+
+ self.setContextMenuPolicy(qt.Qt.ActionsContextMenu)
+
+ def enablePaste(self):
+ """Enable paste action, to paste data from the clipboard into the
+ table.
+
+ .. warning::
+
+ This action can cause data to be overwritten.
+ There is currently no *Undo* action to retrieve lost data.
+ """
+ self.addAction(PasteCellsAction(self))
+
+ def enableCut(self):
+ """Enable cut action.
+
+ .. warning::
+
+ This action can cause data to be deleted.
+ There is currently no *Undo* action to retrieve lost data."""
+ self.addAction(CutSelectedCellsAction(self))
+ self.addAction(CutAllCellsAction(self))
+
+
+class TableView(qt.QTableView):
+ """:class:`QTableView` with a context menu displaying up to 5 actions:
+
+ - :class:`CopySelectedCellsAction`
+ - :class:`CopyAllCellsAction`
+ - :class:`CutSelectedCellsAction`
+ - :class:`CutAllCellsAction`
+ - :class:`PasteCellsAction`
+
+ These actions interact with the clipboard and can be used to copy data
+ to or from an external application, or another widget.
+
+ The cut and paste actions are disabled by default, due to the risk of
+ overwriting data (no *Undo* action is available). Use :meth:`enablePaste`
+ and :meth:`enableCut` to activate them.
+
+ .. note::
+
+ These actions will be available only after a model is associated
+ with this view, using :meth:`setModel`.
+
+ :param parent: Parent QWidget
+ :param bool cut: Enable cut action
+ :param bool paste: Enable paste action
+ """
+ def __init__(self, parent=None, cut=False, paste=False):
+ super(TableView, self).__init__(parent)
+ self.cut = cut
+ self.paste = paste
+
+ def setModel(self, model):
+ """Set the data model for the table view, activate the actions
+ and the context menu.
+
+ :param model: :class:`qt.QAbstractItemModel` object
+ """
+ super(TableView, self).setModel(model)
+
+ self.addAction(CopySelectedCellsAction(self))
+ self.addAction(CopyAllCellsAction(self))
+ if self.cut:
+ self.enableCut()
+ if self.paste:
+ self.enablePaste()
+
+ self.setContextMenuPolicy(qt.Qt.ActionsContextMenu)
+
+ def enablePaste(self):
+ """Enable paste action, to paste data from the clipboard into the
+ table.
+
+ .. warning::
+
+ This action can cause data to be overwritten.
+ There is currently no *Undo* action to retrieve lost data.
+ """
+ self.addAction(PasteCellsAction(self))
+
+ def enableCut(self):
+ """Enable cut action.
+
+ .. warning::
+
+ This action can cause data to be deleted.
+ There is currently no *Undo* action to retrieve lost data.
+ """
+ self.addAction(CutSelectedCellsAction(self))
+ self.addAction(CutAllCellsAction(self))
+
+ def addAction(self, action):
+ # ensure the actions are not added multiple times:
+ # compare action type and parent widget with those of existing actions
+ for existing_action in self.actions():
+ if type(action) == type(existing_action):
+ if hasattr(action, "table") and\
+ action.table is existing_action.table:
+ return None
+ super(TableView, self).addAction(action)
+
+if __name__ == "__main__":
+ app = qt.QApplication([])
+
+ tablewidget = TableWidget()
+ tablewidget.setWindowTitle("TableWidget")
+ tablewidget.setColumnCount(10)
+ tablewidget.setRowCount(7)
+ tablewidget.enableCut()
+ tablewidget.enablePaste()
+ tablewidget.show()
+
+ tableview = TableView(cut=True, paste=True)
+ tableview.setWindowTitle("TableView")
+ model = qt.QStandardItemModel()
+ model.setColumnCount(10)
+ model.setRowCount(7)
+ tableview.setModel(model)
+ tableview.show()
+
+ app.exec_()
diff --git a/silx/gui/widgets/ThreadPoolPushButton.py b/silx/gui/widgets/ThreadPoolPushButton.py
new file mode 100644
index 0000000..29e831d
--- /dev/null
+++ b/silx/gui/widgets/ThreadPoolPushButton.py
@@ -0,0 +1,233 @@
+# 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.
+#
+# ###########################################################################*/
+"""ThreadPoolPushButton module
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "13/10/2016"
+
+import logging
+from .. import qt
+from .WaitingPushButton import WaitingPushButton
+
+
+_logger = logging.getLogger(__name__)
+
+
+class _Wrapper(qt.QRunnable):
+ """Wrapper to allow to call a function into a `QThreadPool` and
+ sending signals during the life cycle of the object"""
+
+ def __init__(self, signalHolder, function, args, kwargs):
+ """Constructor"""
+ super(_Wrapper, self).__init__()
+ self.__signalHolder = signalHolder
+ self.__callable = function
+ self.__args = args
+ self.__kwargs = kwargs
+
+ def run(self):
+ holder = self.__signalHolder
+ holder.started.emit()
+ try:
+ result = self.__callable(*self.__args, **self.__kwargs)
+ holder.succeeded.emit(result)
+ except Exception as e:
+ module = self.__callable.__module__
+ name = self.__callable.__name__
+ _logger.error("Error while executing callable %s.%s.", module, name, exc_info=True)
+ holder.failed.emit(e)
+ finally:
+ holder.finished.emit()
+ holder._sigReleaseRunner.emit(self)
+
+ def autoDelete(self):
+ """Returns true to ask the QThreadPool to manage the life cycle of
+ this QRunner."""
+ return True
+
+
+class ThreadPoolPushButton(WaitingPushButton):
+ """
+ ThreadPoolPushButton provides a simple push button to execute
+ a threaded task with user feedback when the task is running.
+
+ The task can be defined with the method `setCallable`. It takes a python
+ function and arguments as parameters.
+
+ WARNING: This task is run in a separate thread.
+
+ Everytime the button is pushed a new runner is created to execute the
+ function with defined arguments. An animated waiting icon is displayed
+ to show the activity. By default the button is disabled when an execution
+ is requested. This behaviour can be disabled by using
+ `setDisabledWhenWaiting`.
+
+ When the button is clicked a `beforeExecuting` signal is sent from the
+ Qt main thread. Then the task is started in a thread pool and the following
+ signals are emitted from the thread pool. Right before calling the
+ registered callable, the widget emits a `started` signal.
+ When the task ends, its result is emitted by the `succeeded` signal, but
+ if it fails the signal `failed` is emitted with the resulting exception.
+ At the end, the `finished` signal is emitted.
+
+ The task can be programatically executed by using `executeCallable`.
+
+ >>> # Compute a value
+ >>> import math
+ >>> button = ThreadPoolPushButton(text="Compute 2^16")
+ >>> button.setCallable(math.pow, 2, 16)
+ >>> button.succeeded.connect(print) # python3
+
+ >>> # Compute a wrong value
+ >>> import math
+ >>> button = ThreadPoolPushButton(text="Compute sqrt(-1)")
+ >>> button.setCallable(math.sqrt, -1)
+ >>> button.failed.connect(print) # python3
+ """
+
+ def __init__(self, parent=None, text=None, icon=None):
+ """Constructor
+
+ :param str text: Text displayed on the button
+ :param qt.QIcon icon: Icon displayed on the button
+ :param qt.QWidget parent: Parent of the widget
+ """
+ WaitingPushButton.__init__(self, parent=parent, text=text, icon=icon)
+ self.__callable = None
+ self.__args = None
+ self.__kwargs = None
+ self.__runnerCount = 0
+ self.__runnerSet = set([])
+ self.clicked.connect(self.executeCallable)
+ self.finished.connect(self.__runnerFinished)
+ self._sigReleaseRunner.connect(self.__releaseRunner)
+
+ beforeExecuting = qt.Signal()
+ """Signal emitted just before execution of the callable by the main Qt
+ thread. In synchronous mode (direct mode), it can be used to define
+ dynamically `setCallable`, or to execute something in the Qt thread before
+ the execution, or both."""
+
+ started = qt.Signal()
+ """Signal emitted from the thread pool when the defined callable is
+ started.
+
+ WARNING: This signal is emitted from the thread performing the task, and
+ might be received after the registered callable has been called. If you
+ want to perform some initialisation or set the callable to run, use the
+ `beforeExecuting` signal instead.
+ """
+
+ finished = qt.Signal()
+ """Signal emitted from the thread pool when the defined callable is
+ finished"""
+
+ succeeded = qt.Signal(object)
+ """Signal emitted from the thread pool when the callable exit with a
+ success.
+
+ The parameter of the signal is the result returned by the callable.
+ """
+
+ failed = qt.Signal(object)
+ """Signal emitted emitted from the thread pool when the callable raises an
+ exception.
+
+ The parameter of the signal is the raised exception.
+ """
+
+ _sigReleaseRunner = qt.Signal(object)
+ """Callback to release runners"""
+
+ def __runnerStarted(self):
+ """Called when a runner is started.
+
+ Count the number of executed tasks to change the state of the widget.
+ """
+ self.__runnerCount += 1
+ if self.__runnerCount > 0:
+ self.wait()
+
+ def __runnerFinished(self):
+ """Called when a runner is finished.
+
+ Count the number of executed tasks to change the state of the widget.
+ """
+ self.__runnerCount -= 1
+ if self.__runnerCount <= 0:
+ self.stopWaiting()
+
+ @qt.Slot()
+ def executeCallable(self):
+ """Execute the defined callable in QThreadPool.
+
+ First emit a `beforeExecuting` signal.
+ If callable is not defined, nothing append.
+ If a callable is defined, it will be started
+ as a new thread using the `QThreadPool` system. At start of the thread
+ the `started` will be emitted. When the callable returns a result it
+ is emitted by the `succeeded` signal. If the callable fail, the signal
+ `failed` is emitted with the resulting exception. Then the `finished`
+ signal is emitted.
+ """
+ self.beforeExecuting.emit()
+ if self.__callable is None:
+ return
+ self.__runnerStarted()
+ runner = self._createRunner(self.__callable, self.__args, self.__kwargs)
+ qt.QThreadPool.globalInstance().start(runner)
+ self.__runnerSet.add(runner)
+
+ def __releaseRunner(self, runner):
+ self.__runnerSet.remove(runner)
+
+ def _createRunner(self, function, args, kwargs):
+ """Create a QRunnable from a callable object.
+
+ :param callable function: A callable Python object.
+ :param list args: List of arguments to call the function.
+ :param dict kwargs: Dictionary of arguments used to call the function.
+ :rtpye: qt.QRunnable
+ """
+ runnable = _Wrapper(self, function, args, kwargs)
+ return runnable
+
+ def setCallable(self, function, *args, **kwargs):
+ """Define a callable which will be executed on QThreadPool everytime
+ the button is clicked.
+
+ To retrieve the results, connect to the `succeeded` signal.
+
+ WARNING: The callable will be called in a separate thread.
+
+ :param callable function: A callable Python object
+ :param list args: List of arguments to call the function.
+ :param dict kwargs: Dictionary of arguments used to call the function.
+ """
+ self.__callable = function
+ self.__args = args
+ self.__kwargs = kwargs
diff --git a/silx/gui/widgets/WaitingPushButton.py b/silx/gui/widgets/WaitingPushButton.py
new file mode 100644
index 0000000..49ab9b9
--- /dev/null
+++ b/silx/gui/widgets/WaitingPushButton.py
@@ -0,0 +1,243 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ###########################################################################*/
+"""WaitingPushButton module
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+from .. import qt
+from .. import icons
+
+
+class WaitingPushButton(qt.QPushButton):
+ """Button which allows to display a waiting status when, for example,
+ something is still computing.
+
+ The component is graphically disabled when it is in waiting. Then we
+ overwrite the enabled method to dissociate the 2 concepts:
+ graphically enabled/disabled, and enabled/disabled
+ """
+
+ def __init__(self, parent=None, text=None, icon=None):
+ """Constructor
+
+ :param str text: Text displayed on the button
+ :param qt.QIcon icon: Icon displayed on the button
+ :param qt.QWidget parent: Parent of the widget
+ """
+ if icon is not None:
+ qt.QPushButton.__init__(self, icon, text, parent)
+ elif text is not None:
+ qt.QPushButton.__init__(self, text, parent)
+ else:
+ qt.QPushButton.__init__(self, parent)
+
+ self.__waiting = False
+ self.__enabled = True
+ self.__icon = icon
+ self.__disabled_when_waiting = True
+ self.__waitingIcon = icons.getWaitIcon()
+
+ def sizeHint(self):
+ """Returns the recommended size for the widget.
+
+ This implementation of the recommended size always consider there is an
+ icon. In this way it avoid to update the layout when the waiting icon
+ is displayed.
+ """
+ self.ensurePolished()
+
+ w = 0
+ h = 0
+
+ opt = qt.QStyleOptionButton()
+ self.initStyleOption(opt)
+
+ # Content with icon
+ # no condition, assume that there is an icon to avoid blinking
+ # when the widget switch to waiting state
+ ih = opt.iconSize.height()
+ iw = opt.iconSize.width() + 4
+ w += iw
+ h = max(h, ih)
+
+ # Content with text
+ text = self.text()
+ isEmpty = text == ""
+ if isEmpty:
+ text = "XXXX"
+ fm = self.fontMetrics()
+ textSize = fm.size(qt.Qt.TextShowMnemonic, text)
+ if not isEmpty or w == 0:
+ w += textSize.width()
+ if not isEmpty or h == 0:
+ h = max(h, textSize.height())
+
+ # Content with menu indicator
+ opt.rect.setSize(qt.QSize(w, h)) # PM_MenuButtonIndicator depends on the height
+ if self.menu() is not None:
+ w += self.style().pixelMetric(qt.QStyle.PM_MenuButtonIndicator, opt, self)
+
+ contentSize = qt.QSize(w, h)
+ if qt.qVersion().startswith("4.8."):
+ # On PyQt4/PySide the method QCommonStyle sizeFromContents returns
+ # different size when the widget provides an icon or not.
+ # In Qt5 there is not this problem.
+ opt.icon = qt.QIcon()
+ sizeHint = self.style().sizeFromContents(qt.QStyle.CT_PushButton, opt, contentSize, self)
+ sizeHint = sizeHint.expandedTo(qt.QApplication.globalStrut())
+ return sizeHint
+
+ def setDisabledWhenWaiting(self, isDisabled):
+ """Enable or disable the auto disable behaviour when the button is waiting.
+
+ :param bool isDisabled: Enable the auto-disable behaviour
+ """
+ if self.__disabled_when_waiting == isDisabled:
+ return
+ self.__disabled_when_waiting = isDisabled
+ self.__updateVisibleEnabled()
+
+ def isDisabledWhenWaiting(self):
+ """Returns true if the button is auto disabled when it is waiting.
+
+ :rtype: bool
+ """
+ return self.__disabled_when_waiting
+
+ disabledWhenWaiting = qt.Property(bool, isDisabledWhenWaiting, setDisabledWhenWaiting)
+ """Property to enable/disable the auto disabled state when the button is waiting."""
+
+ def __setWaitingIcon(self, icon):
+ """Called when the waiting icon is updated. It is called every frames
+ of the animation.
+
+ :param qt.QIcon icon: The new waiting icon
+ """
+ qt.QPushButton.setIcon(self, icon)
+
+ def setIcon(self, icon):
+ """Set the button icon. If the button is waiting, the icon is not
+ visible directly, but will be visible when the waiting state will be
+ removed.
+
+ :param qt.QIcon icon: An icon
+ """
+ self.__icon = icon
+ self.__updateVisibleIcon()
+
+ def getIcon(self):
+ """Returns the icon set to the button. If the widget is waiting
+ it is not returning the visible icon, but the one requested by
+ the application (the one displayed when the widget is not in
+ waiting state).
+
+ :rtype: qt.QIcon
+ """
+ return self.__icon
+
+ icon = qt.Property(qt.QIcon, getIcon, setIcon)
+ """Property providing access to the icon."""
+
+ def __updateVisibleIcon(self):
+ """Update the visible icon according to the state of the widget."""
+ if not self.isWaiting():
+ icon = self.__icon
+ else:
+ icon = self.__waitingIcon.currentIcon()
+ if icon is None:
+ icon = qt.QIcon()
+ qt.QPushButton.setIcon(self, icon)
+
+ def setEnabled(self, enabled):
+ """Set the enabled state of the widget.
+
+ :param bool enabled: The enabled state
+ """
+ if self.__enabled == enabled:
+ return
+ self.__enabled = enabled
+ self.__updateVisibleEnabled()
+
+ def isEnabled(self):
+ """Returns the enabled state of the widget.
+
+ :rtype: bool
+ """
+ return self.__enabled
+
+ enabled = qt.Property(bool, isEnabled, setEnabled)
+ """Property providing access to the enabled state of the widget"""
+
+ def __updateVisibleEnabled(self):
+ """Update the visible enabled state according to the state of the
+ widget."""
+ if self.__disabled_when_waiting:
+ enabled = not self.isWaiting() and self.__enabled
+ else:
+ enabled = self.__enabled
+ qt.QPushButton.setEnabled(self, enabled)
+
+ def setWaiting(self, waiting):
+ """Set the waiting state of the widget.
+
+ :param bool waiting: Requested state"""
+ if self.__waiting == waiting:
+ return
+ self.__waiting = waiting
+
+ if self.__waiting:
+ self.__waitingIcon.register(self)
+ self.__waitingIcon.iconChanged.connect(self.__setWaitingIcon)
+ else:
+ # unregister only if the object is registred
+ self.__waitingIcon.unregister(self)
+ self.__waitingIcon.iconChanged.disconnect(self.__setWaitingIcon)
+
+ self.__updateVisibleEnabled()
+ self.__updateVisibleIcon()
+
+ def isWaiting(self):
+ """Returns true if the widget is in waiting state.
+
+ :rtype: bool"""
+ return self.__waiting
+
+ @qt.Slot()
+ def wait(self):
+ """Enable the waiting state."""
+ self.setWaiting(True)
+
+ @qt.Slot()
+ def stopWaiting(self):
+ """Disable the waiting state."""
+ self.setWaiting(False)
+
+ @qt.Slot()
+ def swapWaiting(self):
+ """Swap the waiting state."""
+ self.setWaiting(not self.isWaiting())
diff --git a/silx/gui/widgets/__init__.py b/silx/gui/widgets/__init__.py
new file mode 100644
index 0000000..034f4d3
--- /dev/null
+++ b/silx/gui/widgets/__init__.py
@@ -0,0 +1,27 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This package provides a few simple Qt widgets that rely only on a Qt wrapper
+for Python (PyQt5, PyQt4 or PySide). No other optional dependencies of *silx*
+should be required."""
diff --git a/silx/gui/widgets/setup.py b/silx/gui/widgets/setup.py
new file mode 100644
index 0000000..e96ac8d
--- /dev/null
+++ b/silx/gui/widgets/setup.py
@@ -0,0 +1,41 @@
+# 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.
+#
+# ###########################################################################*/
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "11/10/2016"
+
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('widgets', parent_package, top_path)
+ config.add_subpackage('test')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
diff --git a/silx/gui/widgets/test/__init__.py b/silx/gui/widgets/test/__init__.py
new file mode 100644
index 0000000..afa0f78
--- /dev/null
+++ b/silx/gui/widgets/test/__init__.py
@@ -0,0 +1,45 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+import unittest
+
+from . import test_periodictable
+from . import test_tablewidget
+from . import test_threadpoolpushbutton
+from . import test_hierarchicaltableview
+
+__authors__ = ["V. Valls", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "07/04/2017"
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTests(
+ [test_threadpoolpushbutton.suite(),
+ test_tablewidget.suite(),
+ test_periodictable.suite(),
+ test_hierarchicaltableview.suite(),
+ ])
+ return test_suite
diff --git a/silx/gui/widgets/test/test_hierarchicaltableview.py b/silx/gui/widgets/test/test_hierarchicaltableview.py
new file mode 100644
index 0000000..b3d37ed
--- /dev/null
+++ b/silx/gui/widgets/test/test_hierarchicaltableview.py
@@ -0,0 +1,117 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "07/04/2017"
+
+import unittest
+
+from .. import HierarchicalTableView
+from ...test.utils import TestCaseQt
+from silx.gui import qt
+
+
+class TableModel(HierarchicalTableView.HierarchicalTableModel):
+
+ def __init__(self, parent):
+ HierarchicalTableView.HierarchicalTableModel.__init__(self, parent)
+ self.__content = {}
+
+ def rowCount(self, parent=qt.QModelIndex()):
+ return 3
+
+ def columnCount(self, parent=qt.QModelIndex()):
+ return 3
+
+ def setData1(self):
+ if qt.qVersion() > "4.6":
+ self.beginResetModel()
+ else:
+ self.reset()
+
+ content = {}
+ content[0, 0] = ("title", True, (1, 3))
+ content[0, 1] = ("a", True, (2, 1))
+ content[1, 1] = ("b", False, (1, 2))
+ content[1, 2] = ("c", False, (1, 1))
+ content[2, 2] = ("d", False, (1, 1))
+ self.__content = content
+ if qt.qVersion() > "4.6":
+ self.endResetModel()
+
+ def data(self, index, role=qt.Qt.DisplayRole):
+ if not index.isValid():
+ return None
+ cell = self.__content.get((index.column(), index.row()), None)
+ if cell is None:
+ return None
+
+ if role == self.SpanRole:
+ return cell[2]
+ elif role == self.IsHeaderRole:
+ return cell[1]
+ elif role == qt.Qt.DisplayRole:
+ return cell[0]
+ return None
+
+
+class TestHierarchicalTableView(TestCaseQt):
+ """Test for HierarchicalTableView"""
+
+ def testEmpty(self):
+ widget = HierarchicalTableView.HierarchicalTableView()
+ widget.show()
+ self.qWaitForWindowExposed(widget)
+
+ def testModel(self):
+ widget = HierarchicalTableView.HierarchicalTableView()
+ model = TableModel(widget)
+ # set the data before using the model into the widget
+ model.setData1()
+ widget.setModel(model)
+ span = widget.rowSpan(0, 0), widget.columnSpan(0, 0)
+ self.assertEqual(span, (1, 3))
+ widget.show()
+ self.qWaitForWindowExposed(widget)
+
+ def testModelUpdate(self):
+ widget = HierarchicalTableView.HierarchicalTableView()
+ model = TableModel(widget)
+ widget.setModel(model)
+ # set the data after using the model into the widget
+ model.setData1()
+ span = widget.rowSpan(0, 0), widget.columnSpan(0, 0)
+ self.assertEqual(span, (1, 3))
+
+
+def suite():
+ loader = unittest.defaultTestLoader.loadTestsFromTestCase
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(loader(TestHierarchicalTableView))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/widgets/test/test_periodictable.py b/silx/gui/widgets/test/test_periodictable.py
new file mode 100644
index 0000000..c6bed81
--- /dev/null
+++ b/silx/gui/widgets/test/test_periodictable.py
@@ -0,0 +1,163 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+import unittest
+
+from .. import PeriodicTable
+from ...test.utils import TestCaseQt
+from silx.gui import qt
+
+
+class TestPeriodicTable(TestCaseQt):
+ """Basic test for ArrayTableWidget with a numpy array"""
+
+ def testShow(self):
+ """basic test (instantiation done in setUp)"""
+ pt = PeriodicTable.PeriodicTable()
+ pt.show()
+ self.qWaitForWindowExposed(pt)
+
+ def testSelectable(self):
+ """basic test (instantiation done in setUp)"""
+ pt = PeriodicTable.PeriodicTable(selectable=True)
+ self.assertTrue(pt.selectable)
+
+ def testCustomElements(self):
+ PTI = PeriodicTable.ColoredPeriodicTableItem
+ my_items = [
+ PTI("Xx", 42, 43, 44, "xaxatorium", 1002.2,
+ bgcolor="#FF0000"),
+ PTI("Yy", 25, 22, 44, "yoyotrium", 8.8)
+ ]
+
+ pt = PeriodicTable.PeriodicTable(elements=my_items)
+
+ pt.setSelection(["He", "Xx"])
+ selection = pt.getSelection()
+ self.assertEqual(len(selection), 1) # "He" not found
+ self.assertEqual(selection[0].symbol, "Xx")
+ self.assertEqual(selection[0].Z, 42)
+ self.assertEqual(selection[0].col, 43)
+ self.assertAlmostEqual(selection[0].mass, 1002.2)
+ self.assertEqual(qt.QColor(selection[0].bgcolor),
+ qt.QColor(qt.Qt.red))
+
+ self.assertTrue(pt.isElementSelected("Xx"))
+ self.assertFalse(pt.isElementSelected("Yy"))
+ self.assertRaises(KeyError, pt.isElementSelected, "Yx")
+
+ def testVeryCustomElements(self):
+ class MyPTI(PeriodicTable.PeriodicTableItem):
+ def __init__(self, *args):
+ PeriodicTable.PeriodicTableItem.__init__(self, *args[:6])
+ self.my_feature = args[6]
+
+ my_items = [
+ MyPTI("Xx", 42, 43, 44, "xaxatorium", 1002.2, "spam"),
+ MyPTI("Yy", 25, 22, 44, "yoyotrium", 8.8, "eggs")
+ ]
+
+ pt = PeriodicTable.PeriodicTable(elements=my_items)
+
+ pt.setSelection(["Xx", "Yy"])
+ selection = pt.getSelection()
+ self.assertEqual(len(selection), 2)
+ self.assertEqual(selection[1].symbol, "Yy")
+ self.assertEqual(selection[1].Z, 25)
+ self.assertEqual(selection[1].col, 22)
+ self.assertEqual(selection[1].row, 44)
+ self.assertAlmostEqual(selection[0].mass, 1002.2)
+ self.assertAlmostEqual(selection[0].my_feature, "spam")
+
+
+class TestPeriodicCombo(TestCaseQt):
+ """Basic test for ArrayTableWidget with a numpy array"""
+ def setUp(self):
+ super(TestPeriodicCombo, self).setUp()
+ self.pc = PeriodicTable.PeriodicCombo()
+
+ def tearDown(self):
+ del self.pc
+ super(TestPeriodicCombo, self).tearDown()
+
+ def testShow(self):
+ """basic test (instantiation done in setUp)"""
+ self.pc.show()
+ self.qWaitForWindowExposed(self.pc)
+
+ def testSelect(self):
+ self.pc.setSelection("Sb")
+ selection = self.pc.getSelection()
+ self.assertIsInstance(selection,
+ PeriodicTable.PeriodicTableItem)
+ self.assertEqual(selection.symbol, "Sb")
+ self.assertEqual(selection.Z, 51)
+ self.assertEqual(selection.name, "antimony")
+
+
+class TestPeriodicList(TestCaseQt):
+ """Basic test for ArrayTableWidget with a numpy array"""
+ def setUp(self):
+ super(TestPeriodicList, self).setUp()
+ self.pl = PeriodicTable.PeriodicList()
+
+ def tearDown(self):
+ del self.pl
+ super(TestPeriodicList, self).tearDown()
+
+ def testShow(self):
+ """basic test (instantiation done in setUp)"""
+ self.pl.show()
+ self.qWaitForWindowExposed(self.pl)
+
+ def testSelect(self):
+ self.pl.setSelectedElements(["Li", "He", "Au"])
+ sel_elmts = self.pl.getSelection()
+
+ self.assertEqual(len(sel_elmts), 3,
+ "Wrong number of elements selected")
+ for e in sel_elmts:
+ self.assertIsInstance(e, PeriodicTable.PeriodicTableItem)
+ self.assertIn(e.symbol, ["Li", "He", "Au"])
+ self.assertIn(e.Z, [2, 3, 79])
+ self.assertIn(e.name, ["lithium", "helium", "gold"])
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPeriodicTable))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPeriodicList))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestPeriodicCombo))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/widgets/test/test_tablewidget.py b/silx/gui/widgets/test/test_tablewidget.py
new file mode 100644
index 0000000..5ad0a06
--- /dev/null
+++ b/silx/gui/widgets/test/test_tablewidget.py
@@ -0,0 +1,61 @@
+# 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.
+#
+# ###########################################################################*/
+"""Test TableWidget"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import unittest
+from silx.gui.test.utils import TestCaseQt
+from silx.gui.widgets.TableWidget import TableWidget
+
+
+class TestTableWidget(TestCaseQt):
+ def setUp(self):
+ super(TestTableWidget, self).setUp()
+ self._result = []
+
+ def testShow(self):
+ table = TableWidget()
+ table.setColumnCount(10)
+ table.setRowCount(7)
+ table.enableCut()
+ table.enablePaste()
+ table.show()
+ table.hide()
+ self.qapp.processEvents()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestTableWidget))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/gui/widgets/test/test_threadpoolpushbutton.py b/silx/gui/widgets/test/test_threadpoolpushbutton.py
new file mode 100644
index 0000000..126f8f3
--- /dev/null
+++ b/silx/gui/widgets/test/test_threadpoolpushbutton.py
@@ -0,0 +1,129 @@
+# 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.
+#
+# ###########################################################################*/
+"""Test for silx.gui.hdf5 module"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "15/12/2016"
+
+
+import unittest
+import time
+from silx.gui import qt
+from silx.gui.test.utils import TestCaseQt
+from silx.gui.test.utils import SignalListener
+from silx.gui.widgets.ThreadPoolPushButton import ThreadPoolPushButton
+from silx.test.utils import TestLogging
+
+
+class TestThreadPoolPushButton(TestCaseQt):
+
+ def setUp(self):
+ super(TestThreadPoolPushButton, self).setUp()
+ self._result = []
+
+ def _trace(self, name, delay=0):
+ self._result.append(name)
+ if delay != 0:
+ time.sleep(delay / 1000.0)
+
+ def _compute(self):
+ return "result"
+
+ def _computeFail(self):
+ raise Exception("exception")
+
+ def testExecute(self):
+ button = ThreadPoolPushButton()
+ button.setCallable(self._trace, "a", 0)
+ button.executeCallable()
+ time.sleep(0.1)
+ self.assertListEqual(self._result, ["a"])
+ self.qapp.processEvents()
+
+ def testMultiExecution(self):
+ button = ThreadPoolPushButton()
+ button.setCallable(self._trace, "a", 0)
+ number = qt.QThreadPool.globalInstance().maxThreadCount() * 2
+ for _ in range(number):
+ button.executeCallable()
+ time.sleep(number * 0.01 + 0.1)
+ self.assertListEqual(self._result, ["a"] * number)
+ self.qapp.processEvents()
+
+ def testSaturateThreadPool(self):
+ button = ThreadPoolPushButton()
+ button.setCallable(self._trace, "a", 100)
+ number = qt.QThreadPool.globalInstance().maxThreadCount() * 2
+ for _ in range(number):
+ button.executeCallable()
+ time.sleep(number * 0.1 + 0.1)
+ self.assertListEqual(self._result, ["a"] * number)
+ self.qapp.processEvents()
+
+ def testSuccess(self):
+ listener = SignalListener()
+ button = ThreadPoolPushButton()
+ button.setCallable(self._compute)
+ button.beforeExecuting.connect(listener.partial(test="be"))
+ button.started.connect(listener.partial(test="s"))
+ button.succeeded.connect(listener.partial(test="result"))
+ button.failed.connect(listener.partial(test="Unexpected exception"))
+ button.finished.connect(listener.partial(test="f"))
+ button.executeCallable()
+ self.qapp.processEvents()
+ time.sleep(0.1)
+ self.qapp.processEvents()
+ result = listener.karguments(argumentName="test")
+ self.assertListEqual(result, ["be", "s", "result", "f"])
+
+ def testFail(self):
+ listener = SignalListener()
+ button = ThreadPoolPushButton()
+ button.setCallable(self._computeFail)
+ button.beforeExecuting.connect(listener.partial(test="be"))
+ button.started.connect(listener.partial(test="s"))
+ button.succeeded.connect(listener.partial(test="Unexpected success"))
+ button.failed.connect(listener.partial(test="exception"))
+ button.finished.connect(listener.partial(test="f"))
+ with TestLogging('silx.gui.widgets.ThreadPoolPushButton', error=1):
+ button.executeCallable()
+ self.qapp.processEvents()
+ time.sleep(0.1)
+ self.qapp.processEvents()
+ result = listener.karguments(argumentName="test")
+ self.assertListEqual(result, ["be", "s", "exception", "f"])
+ listener.clear()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestThreadPoolPushButton))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/image/__init__.py b/silx/image/__init__.py
new file mode 100644
index 0000000..8e67a1d
--- /dev/null
+++ b/silx/image/__init__.py
@@ -0,0 +1,27 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2017 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.
+#
+# ############################################################################*/
+
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "14/02/2017"
diff --git a/silx/image/bilinear.c b/silx/image/bilinear.c
new file mode 100644
index 0000000..6185331
--- /dev/null
+++ b/silx/image/bilinear.c
@@ -0,0 +1,20006 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__silx__image__bilinear
+#define __PYX_HAVE_API__silx__image__bilinear
+#include "math.h"
+#include "pythread.h"
+#include "string.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+ "silx/image/bilinear.pyx",
+ "stringsource",
+};
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_4silx_5image_8bilinear_BilinearImage;
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+
+/* "silx/image/bilinear.pyx":39
+ *
+ *
+ * cdef class BilinearImage: # <<<<<<<<<<<<<<
+ * """Bilinear interpolator for images ... or any data on a regular grid
+ * """
+ */
+struct __pyx_obj_4silx_5image_8bilinear_BilinearImage {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage *__pyx_vtab;
+ __Pyx_memviewslice data;
+ float maxi;
+ float mini;
+ size_t width;
+ size_t height;
+};
+
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "silx/image/bilinear.pyx":39
+ *
+ *
+ * cdef class BilinearImage: # <<<<<<<<<<<<<<
+ * """Bilinear interpolator for images ... or any data on a regular grid
+ * """
+ */
+
+struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage {
+ size_t (*coarse_local_maxi)(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *, size_t, int __pyx_skip_dispatch);
+ size_t (*c_local_maxi)(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *, size_t);
+ float (*c_funct)(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *, float, float);
+};
+static struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage *__pyx_vtabptr_4silx_5image_8bilinear_BilinearImage;
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static PyObject *__pyx_memview_get_float(const char *itemp);
+static int __pyx_memview_set_float(const char *itemp, PyObject *obj);
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_float(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_float(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_float(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static float __pyx_f_4silx_5image_8bilinear_13BilinearImage_c_funct(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, float __pyx_v_x, float __pyx_v_y); /* proto*/
+static size_t __pyx_f_4silx_5image_8bilinear_13BilinearImage_coarse_local_maxi(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, size_t __pyx_v_x, int __pyx_skip_dispatch); /* proto*/
+static size_t __pyx_f_4silx_5image_8bilinear_13BilinearImage_c_local_maxi(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, size_t __pyx_v_idx); /* proto*/
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'libc.math' */
+
+/* Module declarations from 'silx.image.bilinear' */
+static PyTypeObject *__pyx_ptype_4silx_5image_8bilinear_BilinearImage = 0;
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_float = { "float", NULL, sizeof(float), { 0 }, 0, 'R', 0, 0 };
+#define __Pyx_MODULE_NAME "silx.image.bilinear"
+int __pyx_module_is_main_silx__image__bilinear = 0;
+
+/* Implementation of 'silx.image.bilinear' */
+static PyObject *__pyx_builtin_round;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_builtin_IndexError;
+static int __pyx_pf_4silx_5image_8bilinear_13BilinearImage___cinit__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_data); /* proto */
+static void __pyx_pf_4silx_5image_8bilinear_13BilinearImage_2__dealloc__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_4__call__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_coord); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_6opp_f(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_coord); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_8local_maxi(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_coord); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_10coarse_local_maxi(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, size_t __pyx_v_x); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_12map_coordinates(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_coordinates); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_14profile_line(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_src, PyObject *__pyx_v_dst, int __pyx_v_linewidth); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_4data___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_4maxi___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_4mini___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_5width___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_6height___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_4silx_5image_8bilinear_BilinearImage(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_O[] = "O";
+static char __pyx_k_c[] = "c";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k_doc[] = "__doc__";
+static char __pyx_k_dst[] = "dst";
+static char __pyx_k_max[] = "max";
+static char __pyx_k_min[] = "min";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_src[] = "src";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_data[] = "data";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_coord[] = "coord";
+static char __pyx_k_debug[] = "debug";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_empty[] = "empty";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_ravel[] = "ravel";
+static char __pyx_k_round[] = "round";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_zeros[] = "zeros";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_logger[] = "logger";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_asarray[] = "asarray";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_float32[] = "float32";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_logging[] = "logging";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_warning[] = "warning";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_J_Kieffer[] = "J. Kieffer";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_getLogger[] = "getLogger";
+static char __pyx_k_linewidth[] = "linewidth";
+static char __pyx_k_15_09_2016[] = "15/09/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_ascontiguousarray[] = "ascontiguousarray";
+static char __pyx_k_coarse_local_maxi[] = "coarse_local_maxi";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_silx_image_bilinear[] = "silx.image.bilinear";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_Bilinear_interpolator_peak_finde[] = "Bilinear interpolator, peak finder, line-profile for images";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Failed_to_find_root_using_second[] = "Failed to find root using second order expansion";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_Singular_determinant_Hessian_und[] = "Singular determinant, Hessian undefined";
+static char __pyx_k_Source_and_destination_points_ar[] = "Source and destination points are the same";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static PyObject *__pyx_kp_s_15_09_2016;
+static PyObject *__pyx_kp_s_Bilinear_interpolator_peak_finde;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_kp_s_Failed_to_find_root_using_second;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_kp_s_J_Kieffer;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_kp_s_Singular_determinant_Hessian_und;
+static PyObject *__pyx_kp_s_Source_and_destination_points_ar;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_asarray;
+static PyObject *__pyx_n_s_ascontiguousarray;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_n_s_coarse_local_maxi;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_coord;
+static PyObject *__pyx_n_s_data;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_debug;
+static PyObject *__pyx_n_s_doc;
+static PyObject *__pyx_n_s_dst;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_empty;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float32;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_n_s_getLogger;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_linewidth;
+static PyObject *__pyx_n_s_logger;
+static PyObject *__pyx_n_s_logging;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_max;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_n_s_min;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_ravel;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_round;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_kp_s_silx_image_bilinear;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_src;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_n_s_warning;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_n_s_zeros;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__11;
+static PyObject *__pyx_slice__12;
+static PyObject *__pyx_slice__13;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+
+/* "silx/image/bilinear.pyx":51
+ * cdef float c_funct(self, float, float) nogil
+ *
+ * def __cinit__(self, data not None): # <<<<<<<<<<<<<<
+ * """Constructor
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_pw_4silx_5image_8bilinear_13BilinearImage_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_4silx_5image_8bilinear_13BilinearImage_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_data = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(((PyObject *)__pyx_v_data) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "data"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage___cinit__(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self), __pyx_v_data);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_4silx_5image_8bilinear_13BilinearImage___cinit__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_data) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ size_t __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ float __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "silx/image/bilinear.pyx":56
+ * :param data: image as a 2D array
+ * """
+ * assert data.ndim == 2 # <<<<<<<<<<<<<<
+ * self.height = data.shape[0]
+ * self.width = data.shape[1]
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_int_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (unlikely(!__pyx_t_3)) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "silx/image/bilinear.pyx":57
+ * """
+ * assert data.ndim == 2
+ * self.height = data.shape[0] # <<<<<<<<<<<<<<
+ * self.width = data.shape[1]
+ * self.maxi = data.max()
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = __Pyx_PyInt_As_size_t(__pyx_t_1); if (unlikely((__pyx_t_4 == (size_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_self->height = __pyx_t_4;
+
+ /* "silx/image/bilinear.pyx":58
+ * assert data.ndim == 2
+ * self.height = data.shape[0]
+ * self.width = data.shape[1] # <<<<<<<<<<<<<<
+ * self.maxi = data.max()
+ * self.mini = data.min()
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_4 == (size_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_self->width = __pyx_t_4;
+
+ /* "silx/image/bilinear.pyx":59
+ * self.height = data.shape[0]
+ * self.width = data.shape[1]
+ * self.maxi = data.max() # <<<<<<<<<<<<<<
+ * self.mini = data.min()
+ * self.data = numpy.ascontiguousarray(data, dtype=numpy.float32)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_max); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_6 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_self->maxi = __pyx_t_6;
+
+ /* "silx/image/bilinear.pyx":60
+ * self.width = data.shape[1]
+ * self.maxi = data.max()
+ * self.mini = data.min() # <<<<<<<<<<<<<<
+ * self.data = numpy.ascontiguousarray(data, dtype=numpy.float32)
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_min); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_6 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_self->mini = __pyx_t_6;
+
+ /* "silx/image/bilinear.pyx":61
+ * self.maxi = data.max()
+ * self.mini = data.min()
+ * self.data = numpy.ascontiguousarray(data, dtype=numpy.float32) # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(self):
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_float32); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_float(__pyx_t_8);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_self->data, 0);
+ __pyx_v_self->data = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "silx/image/bilinear.pyx":51
+ * cdef float c_funct(self, float, float) nogil
+ *
+ * def __cinit__(self, data not None): # <<<<<<<<<<<<<<
+ * """Constructor
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":63
+ * self.data = numpy.ascontiguousarray(data, dtype=numpy.float32)
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * self.data = None
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_pw_4silx_5image_8bilinear_13BilinearImage_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_4silx_5image_8bilinear_13BilinearImage_3__dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_pf_4silx_5image_8bilinear_13BilinearImage_2__dealloc__(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_4silx_5image_8bilinear_13BilinearImage_2__dealloc__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "silx/image/bilinear.pyx":64
+ *
+ * def __dealloc__(self):
+ * self.data = None # <<<<<<<<<<<<<<
+ *
+ * def __call__(self, coord):
+ */
+ __pyx_t_1 = __Pyx_PyObject_to_MemoryviewSlice_d_dc_float(Py_None);
+ if (unlikely(!__pyx_t_1.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __PYX_XDEC_MEMVIEW(&__pyx_v_self->data, 0);
+ __pyx_v_self->data = __pyx_t_1;
+ __pyx_t_1.memview = NULL;
+ __pyx_t_1.data = NULL;
+
+ /* "silx/image/bilinear.pyx":63
+ * self.data = numpy.ascontiguousarray(data, dtype=numpy.float32)
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * self.data = None
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __PYX_XDEC_MEMVIEW(&__pyx_t_1, 1);
+ __Pyx_WriteUnraisable("silx.image.bilinear.BilinearImage.__dealloc__", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "silx/image/bilinear.pyx":66
+ * self.data = None
+ *
+ * def __call__(self, coord): # <<<<<<<<<<<<<<
+ * """Function f((y, x)) where f is a continuous function
+ * made from the image and (y,x)=(row, column) is the pixel coordinates
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_5__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_5image_8bilinear_13BilinearImage_4__call__[] = "Function f((y, x)) where f is a continuous function\n made from the image and (y,x)=(row, column) is the pixel coordinates\n in natural C-order\n\n :param x: 2-tuple of float (row, column)\n :return: Interpolated signal from the image\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_4silx_5image_8bilinear_13BilinearImage_4__call__;
+#endif
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_5__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_coord = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__call__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_coord,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_coord)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_coord = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__call__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.__call__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_4__call__(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self), __pyx_v_coord);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_4__call__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_coord) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ float __pyx_t_2;
+ float __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__call__", 0);
+
+ /* "silx/image/bilinear.pyx":74
+ * :return: Interpolated signal from the image
+ * """
+ * return self.c_funct(coord[1], coord[0]) # <<<<<<<<<<<<<<
+ *
+ * @cython.boundscheck(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_coord, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_2 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_coord, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_3 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyFloat_FromDouble(((struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self->__pyx_vtab)->c_funct(__pyx_v_self, __pyx_t_2, __pyx_t_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "silx/image/bilinear.pyx":66
+ * self.data = None
+ *
+ * def __call__(self, coord): # <<<<<<<<<<<<<<
+ * """Function f((y, x)) where f is a continuous function
+ * made from the image and (y,x)=(row, column) is the pixel coordinates
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.__call__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":78
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * cdef float c_funct(self, float x, float y) nogil: # <<<<<<<<<<<<<<
+ * """Function f(x, y) where f is a continuous function
+ * made from the image.
+ */
+
+static float __pyx_f_4silx_5image_8bilinear_13BilinearImage_c_funct(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, float __pyx_v_x, float __pyx_v_y) {
+ float __pyx_v_d0;
+ float __pyx_v_d1;
+ int __pyx_v_i0;
+ int __pyx_v_i1;
+ int __pyx_v_j0;
+ int __pyx_v_j1;
+ float __pyx_v_x0;
+ float __pyx_v_x1;
+ float __pyx_v_y0;
+ float __pyx_v_y1;
+ float __pyx_v_res;
+ float __pyx_r;
+ double __pyx_t_1;
+ double __pyx_t_2;
+ float __pyx_t_3;
+ double __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_t_13;
+ int __pyx_t_14;
+ int __pyx_t_15;
+ int __pyx_t_16;
+ int __pyx_t_17;
+ int __pyx_t_18;
+ int __pyx_t_19;
+ int __pyx_t_20;
+ int __pyx_t_21;
+ int __pyx_t_22;
+ int __pyx_t_23;
+ int __pyx_t_24;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "silx/image/bilinear.pyx":89
+ * """
+ * cdef:
+ * float d0 = min(max(y, 0.0), (self.height - 1.0)) # <<<<<<<<<<<<<<
+ * float d1 = min(max(x, 0.0), (self.width - 1.0))
+ * int i0, i1, j0, j1
+ */
+ __pyx_t_1 = (__pyx_v_self->height - 1.0);
+ __pyx_t_2 = 0.0;
+ __pyx_t_3 = __pyx_v_y;
+ if (((__pyx_t_2 > __pyx_t_3) != 0)) {
+ __pyx_t_4 = __pyx_t_2;
+ } else {
+ __pyx_t_4 = __pyx_t_3;
+ }
+ __pyx_t_2 = __pyx_t_4;
+ if (((__pyx_t_1 < __pyx_t_2) != 0)) {
+ __pyx_t_4 = __pyx_t_1;
+ } else {
+ __pyx_t_4 = __pyx_t_2;
+ }
+ __pyx_v_d0 = __pyx_t_4;
+
+ /* "silx/image/bilinear.pyx":90
+ * cdef:
+ * float d0 = min(max(y, 0.0), (self.height - 1.0))
+ * float d1 = min(max(x, 0.0), (self.width - 1.0)) # <<<<<<<<<<<<<<
+ * int i0, i1, j0, j1
+ * float x0, x1, y0, y1, res
+ */
+ __pyx_t_4 = (__pyx_v_self->width - 1.0);
+ __pyx_t_1 = 0.0;
+ __pyx_t_3 = __pyx_v_x;
+ if (((__pyx_t_1 > __pyx_t_3) != 0)) {
+ __pyx_t_2 = __pyx_t_1;
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ }
+ __pyx_t_1 = __pyx_t_2;
+ if (((__pyx_t_4 < __pyx_t_1) != 0)) {
+ __pyx_t_2 = __pyx_t_4;
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ }
+ __pyx_v_d1 = __pyx_t_2;
+
+ /* "silx/image/bilinear.pyx":94
+ * float x0, x1, y0, y1, res
+ *
+ * x0 = floor(d0) # <<<<<<<<<<<<<<
+ * x1 = ceil(d0)
+ * y0 = floor(d1)
+ */
+ __pyx_v_x0 = floor(__pyx_v_d0);
+
+ /* "silx/image/bilinear.pyx":95
+ *
+ * x0 = floor(d0)
+ * x1 = ceil(d0) # <<<<<<<<<<<<<<
+ * y0 = floor(d1)
+ * y1 = ceil(d1)
+ */
+ __pyx_v_x1 = ceil(__pyx_v_d0);
+
+ /* "silx/image/bilinear.pyx":96
+ * x0 = floor(d0)
+ * x1 = ceil(d0)
+ * y0 = floor(d1) # <<<<<<<<<<<<<<
+ * y1 = ceil(d1)
+ * i0 = < int > x0
+ */
+ __pyx_v_y0 = floor(__pyx_v_d1);
+
+ /* "silx/image/bilinear.pyx":97
+ * x1 = ceil(d0)
+ * y0 = floor(d1)
+ * y1 = ceil(d1) # <<<<<<<<<<<<<<
+ * i0 = < int > x0
+ * i1 = < int > x1
+ */
+ __pyx_v_y1 = ceil(__pyx_v_d1);
+
+ /* "silx/image/bilinear.pyx":98
+ * y0 = floor(d1)
+ * y1 = ceil(d1)
+ * i0 = < int > x0 # <<<<<<<<<<<<<<
+ * i1 = < int > x1
+ * j0 = < int > y0
+ */
+ __pyx_v_i0 = ((int)__pyx_v_x0);
+
+ /* "silx/image/bilinear.pyx":99
+ * y1 = ceil(d1)
+ * i0 = < int > x0
+ * i1 = < int > x1 # <<<<<<<<<<<<<<
+ * j0 = < int > y0
+ * j1 = < int > y1
+ */
+ __pyx_v_i1 = ((int)__pyx_v_x1);
+
+ /* "silx/image/bilinear.pyx":100
+ * i0 = < int > x0
+ * i1 = < int > x1
+ * j0 = < int > y0 # <<<<<<<<<<<<<<
+ * j1 = < int > y1
+ * if (i0 == i1) and (j0 == j1):
+ */
+ __pyx_v_j0 = ((int)__pyx_v_y0);
+
+ /* "silx/image/bilinear.pyx":101
+ * i1 = < int > x1
+ * j0 = < int > y0
+ * j1 = < int > y1 # <<<<<<<<<<<<<<
+ * if (i0 == i1) and (j0 == j1):
+ * res = self.data[i0, j0]
+ */
+ __pyx_v_j1 = ((int)__pyx_v_y1);
+
+ /* "silx/image/bilinear.pyx":102
+ * j0 = < int > y0
+ * j1 = < int > y1
+ * if (i0 == i1) and (j0 == j1): # <<<<<<<<<<<<<<
+ * res = self.data[i0, j0]
+ * elif i0 == i1:
+ */
+ __pyx_t_6 = ((__pyx_v_i0 == __pyx_v_i1) != 0);
+ if (__pyx_t_6) {
+ } else {
+ __pyx_t_5 = __pyx_t_6;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_6 = ((__pyx_v_j0 == __pyx_v_j1) != 0);
+ __pyx_t_5 = __pyx_t_6;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "silx/image/bilinear.pyx":103
+ * j1 = < int > y1
+ * if (i0 == i1) and (j0 == j1):
+ * res = self.data[i0, j0] # <<<<<<<<<<<<<<
+ * elif i0 == i1:
+ * res = (self.data[i0, j0] * (y1 - d1)) + (self.data[i0, j1] * (d1 - y0))
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_7 = __pyx_v_i0;
+ __pyx_t_8 = __pyx_v_j0;
+ __pyx_v_res = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_7 * __pyx_v_self->data.strides[0]) )) + __pyx_t_8)) )));
+ goto __pyx_L3;
+ }
+
+ /* "silx/image/bilinear.pyx":104
+ * if (i0 == i1) and (j0 == j1):
+ * res = self.data[i0, j0]
+ * elif i0 == i1: # <<<<<<<<<<<<<<
+ * res = (self.data[i0, j0] * (y1 - d1)) + (self.data[i0, j1] * (d1 - y0))
+ * elif j0 == j1:
+ */
+ __pyx_t_5 = ((__pyx_v_i0 == __pyx_v_i1) != 0);
+ if (__pyx_t_5) {
+
+ /* "silx/image/bilinear.pyx":105
+ * res = self.data[i0, j0]
+ * elif i0 == i1:
+ * res = (self.data[i0, j0] * (y1 - d1)) + (self.data[i0, j1] * (d1 - y0)) # <<<<<<<<<<<<<<
+ * elif j0 == j1:
+ * res = (self.data[i0, j0] * (x1 - d0)) + (self.data[i1, j0] * (d0 - x0))
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_9 = __pyx_v_i0;
+ __pyx_t_10 = __pyx_v_j0;
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_11 = __pyx_v_i0;
+ __pyx_t_12 = __pyx_v_j1;
+ __pyx_v_res = (((*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_9 * __pyx_v_self->data.strides[0]) )) + __pyx_t_10)) ))) * (__pyx_v_y1 - __pyx_v_d1)) + ((*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_11 * __pyx_v_self->data.strides[0]) )) + __pyx_t_12)) ))) * (__pyx_v_d1 - __pyx_v_y0)));
+ goto __pyx_L3;
+ }
+
+ /* "silx/image/bilinear.pyx":106
+ * elif i0 == i1:
+ * res = (self.data[i0, j0] * (y1 - d1)) + (self.data[i0, j1] * (d1 - y0))
+ * elif j0 == j1: # <<<<<<<<<<<<<<
+ * res = (self.data[i0, j0] * (x1 - d0)) + (self.data[i1, j0] * (d0 - x0))
+ * else:
+ */
+ __pyx_t_5 = ((__pyx_v_j0 == __pyx_v_j1) != 0);
+ if (__pyx_t_5) {
+
+ /* "silx/image/bilinear.pyx":107
+ * res = (self.data[i0, j0] * (y1 - d1)) + (self.data[i0, j1] * (d1 - y0))
+ * elif j0 == j1:
+ * res = (self.data[i0, j0] * (x1 - d0)) + (self.data[i1, j0] * (d0 - x0)) # <<<<<<<<<<<<<<
+ * else:
+ * res = (self.data[i0, j0] * (x1 - d0) * (y1 - d1)) \
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_13 = __pyx_v_i0;
+ __pyx_t_14 = __pyx_v_j0;
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_15 = __pyx_v_i1;
+ __pyx_t_16 = __pyx_v_j0;
+ __pyx_v_res = (((*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_13 * __pyx_v_self->data.strides[0]) )) + __pyx_t_14)) ))) * (__pyx_v_x1 - __pyx_v_d0)) + ((*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_15 * __pyx_v_self->data.strides[0]) )) + __pyx_t_16)) ))) * (__pyx_v_d0 - __pyx_v_x0)));
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "silx/image/bilinear.pyx":109
+ * res = (self.data[i0, j0] * (x1 - d0)) + (self.data[i1, j0] * (d0 - x0))
+ * else:
+ * res = (self.data[i0, j0] * (x1 - d0) * (y1 - d1)) \ # <<<<<<<<<<<<<<
+ * + (self.data[i1, j0] * (d0 - x0) * (y1 - d1)) \
+ * + (self.data[i0, j1] * (x1 - d0) * (d1 - y0)) \
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_17 = __pyx_v_i0;
+ __pyx_t_18 = __pyx_v_j0;
+
+ /* "silx/image/bilinear.pyx":110
+ * else:
+ * res = (self.data[i0, j0] * (x1 - d0) * (y1 - d1)) \
+ * + (self.data[i1, j0] * (d0 - x0) * (y1 - d1)) \ # <<<<<<<<<<<<<<
+ * + (self.data[i0, j1] * (x1 - d0) * (d1 - y0)) \
+ * + (self.data[i1, j1] * (d0 - x0) * (d1 - y0))
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_19 = __pyx_v_i1;
+ __pyx_t_20 = __pyx_v_j0;
+
+ /* "silx/image/bilinear.pyx":111
+ * res = (self.data[i0, j0] * (x1 - d0) * (y1 - d1)) \
+ * + (self.data[i1, j0] * (d0 - x0) * (y1 - d1)) \
+ * + (self.data[i0, j1] * (x1 - d0) * (d1 - y0)) \ # <<<<<<<<<<<<<<
+ * + (self.data[i1, j1] * (d0 - x0) * (d1 - y0))
+ * return res
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_21 = __pyx_v_i0;
+ __pyx_t_22 = __pyx_v_j1;
+
+ /* "silx/image/bilinear.pyx":112
+ * + (self.data[i1, j0] * (d0 - x0) * (y1 - d1)) \
+ * + (self.data[i0, j1] * (x1 - d0) * (d1 - y0)) \
+ * + (self.data[i1, j1] * (d0 - x0) * (d1 - y0)) # <<<<<<<<<<<<<<
+ * return res
+ *
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_23 = __pyx_v_i1;
+ __pyx_t_24 = __pyx_v_j1;
+ __pyx_v_res = ((((((*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_17 * __pyx_v_self->data.strides[0]) )) + __pyx_t_18)) ))) * (__pyx_v_x1 - __pyx_v_d0)) * (__pyx_v_y1 - __pyx_v_d1)) + (((*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_19 * __pyx_v_self->data.strides[0]) )) + __pyx_t_20)) ))) * (__pyx_v_d0 - __pyx_v_x0)) * (__pyx_v_y1 - __pyx_v_d1))) + (((*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_21 * __pyx_v_self->data.strides[0]) )) + __pyx_t_22)) ))) * (__pyx_v_x1 - __pyx_v_d0)) * (__pyx_v_d1 - __pyx_v_y0))) + (((*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_23 * __pyx_v_self->data.strides[0]) )) + __pyx_t_24)) ))) * (__pyx_v_d0 - __pyx_v_x0)) * (__pyx_v_d1 - __pyx_v_y0)));
+ }
+ __pyx_L3:;
+
+ /* "silx/image/bilinear.pyx":113
+ * + (self.data[i0, j1] * (x1 - d0) * (d1 - y0)) \
+ * + (self.data[i1, j1] * (d0 - x0) * (d1 - y0))
+ * return res # <<<<<<<<<<<<<<
+ *
+ * @cython.boundscheck(False)
+ */
+ __pyx_r = __pyx_v_res;
+ goto __pyx_L0;
+
+ /* "silx/image/bilinear.pyx":78
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * cdef float c_funct(self, float x, float y) nogil: # <<<<<<<<<<<<<<
+ * """Function f(x, y) where f is a continuous function
+ * made from the image.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_WriteUnraisable("silx.image.bilinear.BilinearImage.c_funct", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":117
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def opp_f(self, coord): # <<<<<<<<<<<<<<
+ * """Function -f((y,x)) for peak finding via minimizer.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_7opp_f(PyObject *__pyx_v_self, PyObject *__pyx_v_coord); /*proto*/
+static char __pyx_doc_4silx_5image_8bilinear_13BilinearImage_6opp_f[] = "BilinearImage.opp_f(self, coord)\nFunction -f((y,x)) for peak finding via minimizer.\n\n Gives large number outside the boundaries to return into the image\n\n :param x: 2-tuple of float in natural C order, i.e (row, column)\n :return: Negative interpolated signal from the image\n ";
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_7opp_f(PyObject *__pyx_v_self, PyObject *__pyx_v_coord) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("opp_f (wrapper)", 0);
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_6opp_f(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self), ((PyObject *)__pyx_v_coord));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_6opp_f(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_coord) {
+ float __pyx_v_d0;
+ float __pyx_v_d1;
+ float __pyx_v_res;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ float __pyx_t_5;
+ float __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("opp_f", 0);
+
+ /* "silx/image/bilinear.pyx":127
+ * cdef:
+ * float d0, d1, res
+ * d0, d1 = coord # <<<<<<<<<<<<<<
+ * if d0 < 0:
+ * res = self.mini + d0
+ */
+ if ((likely(PyTuple_CheckExact(__pyx_v_coord))) || (PyList_CheckExact(__pyx_v_coord))) {
+ PyObject* sequence = __pyx_v_coord;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1);
+ } else {
+ __pyx_t_1 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_2 = PyList_GET_ITEM(sequence, 1);
+ }
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_2);
+ #else
+ __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ #endif
+ } else {
+ Py_ssize_t index = -1;
+ __pyx_t_3 = PyObject_GetIter(__pyx_v_coord); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = Py_TYPE(__pyx_t_3)->tp_iternext;
+ index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_1);
+ index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_2);
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = NULL;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4_unpacking_done;
+ __pyx_L3_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_L4_unpacking_done:;
+ }
+ __pyx_t_5 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_5 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_6 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_d0 = __pyx_t_5;
+ __pyx_v_d1 = __pyx_t_6;
+
+ /* "silx/image/bilinear.pyx":128
+ * float d0, d1, res
+ * d0, d1 = coord
+ * if d0 < 0: # <<<<<<<<<<<<<<
+ * res = self.mini + d0
+ * elif d1 < 0:
+ */
+ __pyx_t_7 = ((__pyx_v_d0 < 0.0) != 0);
+ if (__pyx_t_7) {
+
+ /* "silx/image/bilinear.pyx":129
+ * d0, d1 = coord
+ * if d0 < 0:
+ * res = self.mini + d0 # <<<<<<<<<<<<<<
+ * elif d1 < 0:
+ * res = self.mini + d1
+ */
+ __pyx_v_res = (__pyx_v_self->mini + __pyx_v_d0);
+ goto __pyx_L5;
+ }
+
+ /* "silx/image/bilinear.pyx":130
+ * if d0 < 0:
+ * res = self.mini + d0
+ * elif d1 < 0: # <<<<<<<<<<<<<<
+ * res = self.mini + d1
+ * elif d0 > (self.height - 1):
+ */
+ __pyx_t_7 = ((__pyx_v_d1 < 0.0) != 0);
+ if (__pyx_t_7) {
+
+ /* "silx/image/bilinear.pyx":131
+ * res = self.mini + d0
+ * elif d1 < 0:
+ * res = self.mini + d1 # <<<<<<<<<<<<<<
+ * elif d0 > (self.height - 1):
+ * res = self.mini - d0 + self.height - 1
+ */
+ __pyx_v_res = (__pyx_v_self->mini + __pyx_v_d1);
+ goto __pyx_L5;
+ }
+
+ /* "silx/image/bilinear.pyx":132
+ * elif d1 < 0:
+ * res = self.mini + d1
+ * elif d0 > (self.height - 1): # <<<<<<<<<<<<<<
+ * res = self.mini - d0 + self.height - 1
+ * elif d1 > self.width - 1:
+ */
+ __pyx_t_7 = ((__pyx_v_d0 > (__pyx_v_self->height - 1)) != 0);
+ if (__pyx_t_7) {
+
+ /* "silx/image/bilinear.pyx":133
+ * res = self.mini + d1
+ * elif d0 > (self.height - 1):
+ * res = self.mini - d0 + self.height - 1 # <<<<<<<<<<<<<<
+ * elif d1 > self.width - 1:
+ * res = self.mini - d1 + self.width - 1
+ */
+ __pyx_v_res = (((__pyx_v_self->mini - __pyx_v_d0) + __pyx_v_self->height) - 1.0);
+ goto __pyx_L5;
+ }
+
+ /* "silx/image/bilinear.pyx":134
+ * elif d0 > (self.height - 1):
+ * res = self.mini - d0 + self.height - 1
+ * elif d1 > self.width - 1: # <<<<<<<<<<<<<<
+ * res = self.mini - d1 + self.width - 1
+ * else:
+ */
+ __pyx_t_7 = ((__pyx_v_d1 > (__pyx_v_self->width - 1)) != 0);
+ if (__pyx_t_7) {
+
+ /* "silx/image/bilinear.pyx":135
+ * res = self.mini - d0 + self.height - 1
+ * elif d1 > self.width - 1:
+ * res = self.mini - d1 + self.width - 1 # <<<<<<<<<<<<<<
+ * else:
+ * res = self.c_funct(d1, d0)
+ */
+ __pyx_v_res = (((__pyx_v_self->mini - __pyx_v_d1) + __pyx_v_self->width) - 1.0);
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "silx/image/bilinear.pyx":137
+ * res = self.mini - d1 + self.width - 1
+ * else:
+ * res = self.c_funct(d1, d0) # <<<<<<<<<<<<<<
+ * return - res
+ *
+ */
+ __pyx_v_res = ((struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self->__pyx_vtab)->c_funct(__pyx_v_self, __pyx_v_d1, __pyx_v_d0);
+ }
+ __pyx_L5:;
+
+ /* "silx/image/bilinear.pyx":138
+ * else:
+ * res = self.c_funct(d1, d0)
+ * return - res # <<<<<<<<<<<<<<
+ *
+ * @cython.boundscheck(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyFloat_FromDouble((-__pyx_v_res)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "silx/image/bilinear.pyx":117
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def opp_f(self, coord): # <<<<<<<<<<<<<<
+ * """Function -f((y,x)) for peak finding via minimizer.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.opp_f", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":143
+ * @cython.wraparound(False)
+ * @cython.cdivision(True)
+ * def local_maxi(self, coord): # <<<<<<<<<<<<<<
+ * """Return the nearest local maximum ... with sub-pixel refinement
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_9local_maxi(PyObject *__pyx_v_self, PyObject *__pyx_v_coord); /*proto*/
+static char __pyx_doc_4silx_5image_8bilinear_13BilinearImage_8local_maxi[] = "BilinearImage.local_maxi(self, coord)\nReturn the nearest local maximum ... with sub-pixel refinement\n\n Nearest maximum search:\n steepest ascent\n\n Sub-pixel refinement:\n Second order Taylor expansion of the function;\n At the maximum, the first derivative is null\n delta = x-i = -Inverse[Hessian].gradient\n if Hessian is singular or \\|delta\\|>1: use a center of mass.\n\n :param coord: 2-tuple of scalar (row, column)\n :return: 2-tuple of float with the nearest local maximum\n ";
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_9local_maxi(PyObject *__pyx_v_self, PyObject *__pyx_v_coord) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("local_maxi (wrapper)", 0);
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_8local_maxi(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self), ((PyObject *)__pyx_v_coord));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_8local_maxi(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_coord) {
+ int __pyx_v_res;
+ int __pyx_v_current0;
+ int __pyx_v_current1;
+ int __pyx_v_i0;
+ int __pyx_v_i1;
+ float __pyx_v_tmp;
+ float __pyx_v_sum0;
+ float __pyx_v_sum1;
+ float __pyx_v_sum;
+ float __pyx_v_a00;
+ float __pyx_v_a01;
+ float __pyx_v_a02;
+ float __pyx_v_a10;
+ float __pyx_v_a11;
+ float __pyx_v_a12;
+ float __pyx_v_a20;
+ float __pyx_v_a21;
+ float __pyx_v_a22;
+ float __pyx_v_d00;
+ float __pyx_v_d11;
+ float __pyx_v_d01;
+ float __pyx_v_denom;
+ float __pyx_v_delta0;
+ float __pyx_v_delta1;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ size_t __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ long __pyx_t_7;
+ long __pyx_t_8;
+ long __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ int __pyx_t_13;
+ long __pyx_t_14;
+ int __pyx_t_15;
+ int __pyx_t_16;
+ int __pyx_t_17;
+ long __pyx_t_18;
+ long __pyx_t_19;
+ long __pyx_t_20;
+ long __pyx_t_21;
+ int __pyx_t_22;
+ long __pyx_t_23;
+ long __pyx_t_24;
+ long __pyx_t_25;
+ int __pyx_t_26;
+ long __pyx_t_27;
+ int __pyx_t_28;
+ int __pyx_t_29;
+ int __pyx_t_30;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("local_maxi", 0);
+
+ /* "silx/image/bilinear.pyx":161
+ * int res, current0, current1
+ * int i0, i1
+ * float tmp, sum0 = 0, sum1 = 0, sum = 0 # <<<<<<<<<<<<<<
+ * float a00, a01, a02, a10, a11, a12, a20, a21, a22
+ * float d00, d11, d01, denom, delta0, delta1
+ */
+ __pyx_v_sum0 = 0.0;
+ __pyx_v_sum1 = 0.0;
+ __pyx_v_sum = 0.0;
+
+ /* "silx/image/bilinear.pyx":164
+ * float a00, a01, a02, a10, a11, a12, a20, a21, a22
+ * float d00, d11, d01, denom, delta0, delta1
+ * res = self.c_local_maxi(round(coord[0]) * self.width + round(coord[1])) # <<<<<<<<<<<<<<
+ *
+ * current0 = res // self.width
+ */
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_coord, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyInt_FromSize_t(__pyx_v_self->width); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_coord, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_round, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = __Pyx_PyInt_As_size_t(__pyx_t_1); if (unlikely((__pyx_t_4 == (size_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_res = ((struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self->__pyx_vtab)->c_local_maxi(__pyx_v_self, __pyx_t_4);
+
+ /* "silx/image/bilinear.pyx":166
+ * res = self.c_local_maxi(round(coord[0]) * self.width + round(coord[1]))
+ *
+ * current0 = res // self.width # <<<<<<<<<<<<<<
+ * current1 = res % self.width
+ * if (current0 > 0) and (current0 < self.height - 1) and (current1 > 0) and (current1 < self.width - 1):
+ */
+ __pyx_v_current0 = (__pyx_v_res / __pyx_v_self->width);
+
+ /* "silx/image/bilinear.pyx":167
+ *
+ * current0 = res // self.width
+ * current1 = res % self.width # <<<<<<<<<<<<<<
+ * if (current0 > 0) and (current0 < self.height - 1) and (current1 > 0) and (current1 < self.width - 1):
+ * # Use second order polynomial Taylor expansion
+ */
+ __pyx_v_current1 = (__pyx_v_res % __pyx_v_self->width);
+
+ /* "silx/image/bilinear.pyx":168
+ * current0 = res // self.width
+ * current1 = res % self.width
+ * if (current0 > 0) and (current0 < self.height - 1) and (current1 > 0) and (current1 < self.width - 1): # <<<<<<<<<<<<<<
+ * # Use second order polynomial Taylor expansion
+ * a00 = self.data[current0 - 1, current1 - 1]
+ */
+ __pyx_t_6 = ((__pyx_v_current0 > 0) != 0);
+ if (__pyx_t_6) {
+ } else {
+ __pyx_t_5 = __pyx_t_6;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_6 = ((__pyx_v_current0 < (__pyx_v_self->height - 1)) != 0);
+ if (__pyx_t_6) {
+ } else {
+ __pyx_t_5 = __pyx_t_6;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_6 = ((__pyx_v_current1 > 0) != 0);
+ if (__pyx_t_6) {
+ } else {
+ __pyx_t_5 = __pyx_t_6;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_6 = ((__pyx_v_current1 < (__pyx_v_self->width - 1)) != 0);
+ __pyx_t_5 = __pyx_t_6;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "silx/image/bilinear.pyx":170
+ * if (current0 > 0) and (current0 < self.height - 1) and (current1 > 0) and (current1 < self.width - 1):
+ * # Use second order polynomial Taylor expansion
+ * a00 = self.data[current0 - 1, current1 - 1] # <<<<<<<<<<<<<<
+ * a01 = self.data[current0 - 1, current1 ]
+ * a02 = self.data[current0 - 1, current1 + 1]
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_7 = (__pyx_v_current0 - 1);
+ __pyx_t_8 = (__pyx_v_current1 - 1);
+ __pyx_v_a00 = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_7 * __pyx_v_self->data.strides[0]) )) + __pyx_t_8)) )));
+
+ /* "silx/image/bilinear.pyx":171
+ * # Use second order polynomial Taylor expansion
+ * a00 = self.data[current0 - 1, current1 - 1]
+ * a01 = self.data[current0 - 1, current1 ] # <<<<<<<<<<<<<<
+ * a02 = self.data[current0 - 1, current1 + 1]
+ * a10 = self.data[current0 , current1 - 1]
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_9 = (__pyx_v_current0 - 1);
+ __pyx_t_10 = __pyx_v_current1;
+ __pyx_v_a01 = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_9 * __pyx_v_self->data.strides[0]) )) + __pyx_t_10)) )));
+
+ /* "silx/image/bilinear.pyx":172
+ * a00 = self.data[current0 - 1, current1 - 1]
+ * a01 = self.data[current0 - 1, current1 ]
+ * a02 = self.data[current0 - 1, current1 + 1] # <<<<<<<<<<<<<<
+ * a10 = self.data[current0 , current1 - 1]
+ * a11 = self.data[current0 , current1 ]
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_11 = (__pyx_v_current0 - 1);
+ __pyx_t_12 = (__pyx_v_current1 + 1);
+ __pyx_v_a02 = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_11 * __pyx_v_self->data.strides[0]) )) + __pyx_t_12)) )));
+
+ /* "silx/image/bilinear.pyx":173
+ * a01 = self.data[current0 - 1, current1 ]
+ * a02 = self.data[current0 - 1, current1 + 1]
+ * a10 = self.data[current0 , current1 - 1] # <<<<<<<<<<<<<<
+ * a11 = self.data[current0 , current1 ]
+ * a12 = self.data[current0 , current1 + 1]
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_13 = __pyx_v_current0;
+ __pyx_t_14 = (__pyx_v_current1 - 1);
+ __pyx_v_a10 = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_13 * __pyx_v_self->data.strides[0]) )) + __pyx_t_14)) )));
+
+ /* "silx/image/bilinear.pyx":174
+ * a02 = self.data[current0 - 1, current1 + 1]
+ * a10 = self.data[current0 , current1 - 1]
+ * a11 = self.data[current0 , current1 ] # <<<<<<<<<<<<<<
+ * a12 = self.data[current0 , current1 + 1]
+ * a20 = self.data[current0 + 1, current1 - 1]
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_15 = __pyx_v_current0;
+ __pyx_t_16 = __pyx_v_current1;
+ __pyx_v_a11 = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_15 * __pyx_v_self->data.strides[0]) )) + __pyx_t_16)) )));
+
+ /* "silx/image/bilinear.pyx":175
+ * a10 = self.data[current0 , current1 - 1]
+ * a11 = self.data[current0 , current1 ]
+ * a12 = self.data[current0 , current1 + 1] # <<<<<<<<<<<<<<
+ * a20 = self.data[current0 + 1, current1 - 1]
+ * a21 = self.data[current0 + 1, current1 ]
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_17 = __pyx_v_current0;
+ __pyx_t_18 = (__pyx_v_current1 + 1);
+ __pyx_v_a12 = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_17 * __pyx_v_self->data.strides[0]) )) + __pyx_t_18)) )));
+
+ /* "silx/image/bilinear.pyx":176
+ * a11 = self.data[current0 , current1 ]
+ * a12 = self.data[current0 , current1 + 1]
+ * a20 = self.data[current0 + 1, current1 - 1] # <<<<<<<<<<<<<<
+ * a21 = self.data[current0 + 1, current1 ]
+ * a22 = self.data[current0 + 1, current1 - 1]
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_19 = (__pyx_v_current0 + 1);
+ __pyx_t_20 = (__pyx_v_current1 - 1);
+ __pyx_v_a20 = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_19 * __pyx_v_self->data.strides[0]) )) + __pyx_t_20)) )));
+
+ /* "silx/image/bilinear.pyx":177
+ * a12 = self.data[current0 , current1 + 1]
+ * a20 = self.data[current0 + 1, current1 - 1]
+ * a21 = self.data[current0 + 1, current1 ] # <<<<<<<<<<<<<<
+ * a22 = self.data[current0 + 1, current1 - 1]
+ * d00 = a12 - 2.0 * a11 + a10
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_21 = (__pyx_v_current0 + 1);
+ __pyx_t_22 = __pyx_v_current1;
+ __pyx_v_a21 = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_21 * __pyx_v_self->data.strides[0]) )) + __pyx_t_22)) )));
+
+ /* "silx/image/bilinear.pyx":178
+ * a20 = self.data[current0 + 1, current1 - 1]
+ * a21 = self.data[current0 + 1, current1 ]
+ * a22 = self.data[current0 + 1, current1 - 1] # <<<<<<<<<<<<<<
+ * d00 = a12 - 2.0 * a11 + a10
+ * d11 = a21 - 2.0 * a11 + a01
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_23 = (__pyx_v_current0 + 1);
+ __pyx_t_24 = (__pyx_v_current1 - 1);
+ __pyx_v_a22 = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_23 * __pyx_v_self->data.strides[0]) )) + __pyx_t_24)) )));
+
+ /* "silx/image/bilinear.pyx":179
+ * a21 = self.data[current0 + 1, current1 ]
+ * a22 = self.data[current0 + 1, current1 - 1]
+ * d00 = a12 - 2.0 * a11 + a10 # <<<<<<<<<<<<<<
+ * d11 = a21 - 2.0 * a11 + a01
+ * d01 = (a00 - a02 - a20 + a22) / 4.0
+ */
+ __pyx_v_d00 = ((__pyx_v_a12 - (2.0 * __pyx_v_a11)) + __pyx_v_a10);
+
+ /* "silx/image/bilinear.pyx":180
+ * a22 = self.data[current0 + 1, current1 - 1]
+ * d00 = a12 - 2.0 * a11 + a10
+ * d11 = a21 - 2.0 * a11 + a01 # <<<<<<<<<<<<<<
+ * d01 = (a00 - a02 - a20 + a22) / 4.0
+ * denom = 2.0 * (d00 * d11 - d01 * d01)
+ */
+ __pyx_v_d11 = ((__pyx_v_a21 - (2.0 * __pyx_v_a11)) + __pyx_v_a01);
+
+ /* "silx/image/bilinear.pyx":181
+ * d00 = a12 - 2.0 * a11 + a10
+ * d11 = a21 - 2.0 * a11 + a01
+ * d01 = (a00 - a02 - a20 + a22) / 4.0 # <<<<<<<<<<<<<<
+ * denom = 2.0 * (d00 * d11 - d01 * d01)
+ * if abs(denom) < 1e-10:
+ */
+ __pyx_v_d01 = ((((__pyx_v_a00 - __pyx_v_a02) - __pyx_v_a20) + __pyx_v_a22) / 4.0);
+
+ /* "silx/image/bilinear.pyx":182
+ * d11 = a21 - 2.0 * a11 + a01
+ * d01 = (a00 - a02 - a20 + a22) / 4.0
+ * denom = 2.0 * (d00 * d11 - d01 * d01) # <<<<<<<<<<<<<<
+ * if abs(denom) < 1e-10:
+ * logger.debug("Singular determinant, Hessian undefined")
+ */
+ __pyx_v_denom = (2.0 * ((__pyx_v_d00 * __pyx_v_d11) - (__pyx_v_d01 * __pyx_v_d01)));
+
+ /* "silx/image/bilinear.pyx":183
+ * d01 = (a00 - a02 - a20 + a22) / 4.0
+ * denom = 2.0 * (d00 * d11 - d01 * d01)
+ * if abs(denom) < 1e-10: # <<<<<<<<<<<<<<
+ * logger.debug("Singular determinant, Hessian undefined")
+ * else:
+ */
+ __pyx_t_5 = ((fabsf(__pyx_v_denom) < 1e-10) != 0);
+ if (__pyx_t_5) {
+
+ /* "silx/image/bilinear.pyx":184
+ * denom = 2.0 * (d00 * d11 - d01 * d01)
+ * if abs(denom) < 1e-10:
+ * logger.debug("Singular determinant, Hessian undefined") # <<<<<<<<<<<<<<
+ * else:
+ * delta0 = ((a12 - a10) * d01 + (a01 - a21) * d11) / denom
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_debug); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "silx/image/bilinear.pyx":186
+ * logger.debug("Singular determinant, Hessian undefined")
+ * else:
+ * delta0 = ((a12 - a10) * d01 + (a01 - a21) * d11) / denom # <<<<<<<<<<<<<<
+ * delta1 = ((a10 - a12) * d00 + (a21 - a01) * d01) / denom
+ * if abs(delta0) <= 1.0 and abs(delta1) <= 1.0:
+ */
+ __pyx_v_delta0 = ((((__pyx_v_a12 - __pyx_v_a10) * __pyx_v_d01) + ((__pyx_v_a01 - __pyx_v_a21) * __pyx_v_d11)) / __pyx_v_denom);
+
+ /* "silx/image/bilinear.pyx":187
+ * else:
+ * delta0 = ((a12 - a10) * d01 + (a01 - a21) * d11) / denom
+ * delta1 = ((a10 - a12) * d00 + (a21 - a01) * d01) / denom # <<<<<<<<<<<<<<
+ * if abs(delta0) <= 1.0 and abs(delta1) <= 1.0:
+ * # Result is OK if lower than 0.5.
+ */
+ __pyx_v_delta1 = ((((__pyx_v_a10 - __pyx_v_a12) * __pyx_v_d00) + ((__pyx_v_a21 - __pyx_v_a01) * __pyx_v_d01)) / __pyx_v_denom);
+
+ /* "silx/image/bilinear.pyx":188
+ * delta0 = ((a12 - a10) * d01 + (a01 - a21) * d11) / denom
+ * delta1 = ((a10 - a12) * d00 + (a21 - a01) * d01) / denom
+ * if abs(delta0) <= 1.0 and abs(delta1) <= 1.0: # <<<<<<<<<<<<<<
+ * # Result is OK if lower than 0.5.
+ * return (delta0 + float(current0), delta1 + float(current1))
+ */
+ __pyx_t_6 = ((fabsf(__pyx_v_delta0) <= 1.0) != 0);
+ if (__pyx_t_6) {
+ } else {
+ __pyx_t_5 = __pyx_t_6;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = ((fabsf(__pyx_v_delta1) <= 1.0) != 0);
+ __pyx_t_5 = __pyx_t_6;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "silx/image/bilinear.pyx":190
+ * if abs(delta0) <= 1.0 and abs(delta1) <= 1.0:
+ * # Result is OK if lower than 0.5.
+ * return (delta0 + float(current0), delta1 + float(current1)) # <<<<<<<<<<<<<<
+ * else:
+ * logger.debug("Failed to find root using second order expansion")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyFloat_FromDouble((__pyx_v_delta0 + ((double)__pyx_v_current0))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyFloat_FromDouble((__pyx_v_delta1 + ((double)__pyx_v_current1))); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "silx/image/bilinear.pyx":192
+ * return (delta0 + float(current0), delta1 + float(current1))
+ * else:
+ * logger.debug("Failed to find root using second order expansion") # <<<<<<<<<<<<<<
+ * # refinement of the position by a simple center of mass of the last valid region used
+ * for i0 in range(current0 - 1, current0 + 2):
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_debug); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ }
+ __pyx_L8:;
+
+ /* "silx/image/bilinear.pyx":194
+ * logger.debug("Failed to find root using second order expansion")
+ * # refinement of the position by a simple center of mass of the last valid region used
+ * for i0 in range(current0 - 1, current0 + 2): # <<<<<<<<<<<<<<
+ * for i1 in range(current1 - 1, current1 + 2):
+ * tmp = self.data[i0, i1]
+ */
+ __pyx_t_25 = (__pyx_v_current0 + 2);
+ for (__pyx_t_26 = (__pyx_v_current0 - 1); __pyx_t_26 < __pyx_t_25; __pyx_t_26+=1) {
+ __pyx_v_i0 = __pyx_t_26;
+
+ /* "silx/image/bilinear.pyx":195
+ * # refinement of the position by a simple center of mass of the last valid region used
+ * for i0 in range(current0 - 1, current0 + 2):
+ * for i1 in range(current1 - 1, current1 + 2): # <<<<<<<<<<<<<<
+ * tmp = self.data[i0, i1]
+ * sum0 += tmp * i0
+ */
+ __pyx_t_27 = (__pyx_v_current1 + 2);
+ for (__pyx_t_28 = (__pyx_v_current1 - 1); __pyx_t_28 < __pyx_t_27; __pyx_t_28+=1) {
+ __pyx_v_i1 = __pyx_t_28;
+
+ /* "silx/image/bilinear.pyx":196
+ * for i0 in range(current0 - 1, current0 + 2):
+ * for i1 in range(current1 - 1, current1 + 2):
+ * tmp = self.data[i0, i1] # <<<<<<<<<<<<<<
+ * sum0 += tmp * i0
+ * sum1 += tmp * i1
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_29 = __pyx_v_i0;
+ __pyx_t_30 = __pyx_v_i1;
+ __pyx_v_tmp = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_29 * __pyx_v_self->data.strides[0]) )) + __pyx_t_30)) )));
+
+ /* "silx/image/bilinear.pyx":197
+ * for i1 in range(current1 - 1, current1 + 2):
+ * tmp = self.data[i0, i1]
+ * sum0 += tmp * i0 # <<<<<<<<<<<<<<
+ * sum1 += tmp * i1
+ * sum += tmp
+ */
+ __pyx_v_sum0 = (__pyx_v_sum0 + (__pyx_v_tmp * __pyx_v_i0));
+
+ /* "silx/image/bilinear.pyx":198
+ * tmp = self.data[i0, i1]
+ * sum0 += tmp * i0
+ * sum1 += tmp * i1 # <<<<<<<<<<<<<<
+ * sum += tmp
+ * if sum > 0:
+ */
+ __pyx_v_sum1 = (__pyx_v_sum1 + (__pyx_v_tmp * __pyx_v_i1));
+
+ /* "silx/image/bilinear.pyx":199
+ * sum0 += tmp * i0
+ * sum1 += tmp * i1
+ * sum += tmp # <<<<<<<<<<<<<<
+ * if sum > 0:
+ * return (sum0 / sum, sum1 / sum)
+ */
+ __pyx_v_sum = (__pyx_v_sum + __pyx_v_tmp);
+ }
+ }
+
+ /* "silx/image/bilinear.pyx":200
+ * sum1 += tmp * i1
+ * sum += tmp
+ * if sum > 0: # <<<<<<<<<<<<<<
+ * return (sum0 / sum, sum1 / sum)
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_sum > 0.0) != 0);
+ if (__pyx_t_5) {
+
+ /* "silx/image/bilinear.pyx":201
+ * sum += tmp
+ * if sum > 0:
+ * return (sum0 / sum, sum1 / sum) # <<<<<<<<<<<<<<
+ *
+ * return (float(current0), float(current1))
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = PyFloat_FromDouble((__pyx_v_sum0 / __pyx_v_sum)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyFloat_FromDouble((__pyx_v_sum1 / __pyx_v_sum)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "silx/image/bilinear.pyx":203
+ * return (sum0 / sum, sum1 / sum)
+ *
+ * return (float(current0), float(current1)) # <<<<<<<<<<<<<<
+ *
+ * cpdef size_t coarse_local_maxi(self, size_t x):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyFloat_FromDouble(((double)__pyx_v_current0)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyFloat_FromDouble(((double)__pyx_v_current1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "silx/image/bilinear.pyx":143
+ * @cython.wraparound(False)
+ * @cython.cdivision(True)
+ * def local_maxi(self, coord): # <<<<<<<<<<<<<<
+ * """Return the nearest local maximum ... with sub-pixel refinement
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.local_maxi", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":205
+ * return (float(current0), float(current1))
+ *
+ * cpdef size_t coarse_local_maxi(self, size_t x): # <<<<<<<<<<<<<<
+ * """Return the nearest local maximum ... without sub-pixel refinement
+ *
+ */
+
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_11coarse_local_maxi(PyObject *__pyx_v_self, PyObject *__pyx_arg_x); /*proto*/
+static size_t __pyx_f_4silx_5image_8bilinear_13BilinearImage_coarse_local_maxi(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, size_t __pyx_v_x, int __pyx_skip_dispatch) {
+ size_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ size_t __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("coarse_local_maxi", 0);
+ /* Check if called by wrapper */
+ if (unlikely(__pyx_skip_dispatch)) ;
+ /* Check if overridden in Python */
+ else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_coarse_local_maxi); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_4silx_5image_8bilinear_13BilinearImage_11coarse_local_maxi)) {
+ __pyx_t_3 = __Pyx_PyInt_FromSize_t(__pyx_v_x); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_1);
+ __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_7 = __Pyx_PyInt_As_size_t(__pyx_t_2); if (unlikely((__pyx_t_7 == (size_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_7;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "silx/image/bilinear.pyx":211
+ * :return: local maximum index
+ * """
+ * return self.c_local_maxi(x) # <<<<<<<<<<<<<<
+ *
+ * @cython.boundscheck(False)
+ */
+ __pyx_r = ((struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self->__pyx_vtab)->c_local_maxi(__pyx_v_self, __pyx_v_x);
+ goto __pyx_L0;
+
+ /* "silx/image/bilinear.pyx":205
+ * return (float(current0), float(current1))
+ *
+ * cpdef size_t coarse_local_maxi(self, size_t x): # <<<<<<<<<<<<<<
+ * """Return the nearest local maximum ... without sub-pixel refinement
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_WriteUnraisable("silx.image.bilinear.BilinearImage.coarse_local_maxi", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_11coarse_local_maxi(PyObject *__pyx_v_self, PyObject *__pyx_arg_x); /*proto*/
+static char __pyx_doc_4silx_5image_8bilinear_13BilinearImage_10coarse_local_maxi[] = "BilinearImage.coarse_local_maxi(self, size_t x) -> size_t\nReturn the nearest local maximum ... without sub-pixel refinement\n\n :param idx: start index (=row*width+column)\n :return: local maximum index\n ";
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_11coarse_local_maxi(PyObject *__pyx_v_self, PyObject *__pyx_arg_x) {
+ size_t __pyx_v_x;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("coarse_local_maxi (wrapper)", 0);
+ assert(__pyx_arg_x); {
+ __pyx_v_x = __Pyx_PyInt_As_size_t(__pyx_arg_x); if (unlikely((__pyx_v_x == (size_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.coarse_local_maxi", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_10coarse_local_maxi(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self), ((size_t)__pyx_v_x));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_10coarse_local_maxi(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, size_t __pyx_v_x) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("coarse_local_maxi", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_f_4silx_5image_8bilinear_13BilinearImage_coarse_local_maxi(__pyx_v_self, __pyx_v_x, 1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.coarse_local_maxi", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":216
+ * @cython.wraparound(False)
+ * @cython.cdivision(True)
+ * cdef size_t c_local_maxi(self, size_t idx) nogil: # <<<<<<<<<<<<<<
+ * """Return the nearest local maximum without sub-pixel refinement
+ *
+ */
+
+static size_t __pyx_f_4silx_5image_8bilinear_13BilinearImage_c_local_maxi(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, size_t __pyx_v_idx) {
+ int __pyx_v_current0;
+ int __pyx_v_current1;
+ int __pyx_v_i0;
+ int __pyx_v_i1;
+ int __pyx_v_start0;
+ int __pyx_v_stop0;
+ int __pyx_v_start1;
+ int __pyx_v_stop1;
+ int __pyx_v_new0;
+ int __pyx_v_new1;
+ float __pyx_v_tmp;
+ float __pyx_v_value;
+ float __pyx_v_old_value;
+ size_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ long __pyx_t_7;
+ long __pyx_t_8;
+ size_t __pyx_t_9;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_t_13;
+ int __pyx_t_14;
+ int __pyx_t_15;
+ int __pyx_t_16;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "silx/image/bilinear.pyx":225
+ * """
+ * cdef:
+ * int current0 = idx // self.width # <<<<<<<<<<<<<<
+ * int current1 = idx % self.width
+ * int i0, i1, start0, stop0, start1, stop1, new0, new1
+ */
+ __pyx_v_current0 = (__pyx_v_idx / __pyx_v_self->width);
+
+ /* "silx/image/bilinear.pyx":226
+ * cdef:
+ * int current0 = idx // self.width
+ * int current1 = idx % self.width # <<<<<<<<<<<<<<
+ * int i0, i1, start0, stop0, start1, stop1, new0, new1
+ * float tmp, value, old_value
+ */
+ __pyx_v_current1 = (__pyx_v_idx % __pyx_v_self->width);
+
+ /* "silx/image/bilinear.pyx":230
+ * float tmp, value, old_value
+ *
+ * value = self.data[current0, current1] # <<<<<<<<<<<<<<
+ * old_value = value - 1.0
+ * new0, new1 = current0, current1
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_1 = __pyx_v_current0;
+ __pyx_t_2 = __pyx_v_current1;
+ __pyx_v_value = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_1 * __pyx_v_self->data.strides[0]) )) + __pyx_t_2)) )));
+
+ /* "silx/image/bilinear.pyx":231
+ *
+ * value = self.data[current0, current1]
+ * old_value = value - 1.0 # <<<<<<<<<<<<<<
+ * new0, new1 = current0, current1
+ *
+ */
+ __pyx_v_old_value = (__pyx_v_value - 1.0);
+
+ /* "silx/image/bilinear.pyx":232
+ * value = self.data[current0, current1]
+ * old_value = value - 1.0
+ * new0, new1 = current0, current1 # <<<<<<<<<<<<<<
+ *
+ * while value > old_value:
+ */
+ __pyx_t_3 = __pyx_v_current0;
+ __pyx_t_4 = __pyx_v_current1;
+ __pyx_v_new0 = __pyx_t_3;
+ __pyx_v_new1 = __pyx_t_4;
+
+ /* "silx/image/bilinear.pyx":234
+ * new0, new1 = current0, current1
+ *
+ * while value > old_value: # <<<<<<<<<<<<<<
+ * old_value = value
+ * start0 = max(0, current0 - 1)
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_value > __pyx_v_old_value) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "silx/image/bilinear.pyx":235
+ *
+ * while value > old_value:
+ * old_value = value # <<<<<<<<<<<<<<
+ * start0 = max(0, current0 - 1)
+ * stop0 = min(self.height, current0 + 2)
+ */
+ __pyx_v_old_value = __pyx_v_value;
+
+ /* "silx/image/bilinear.pyx":236
+ * while value > old_value:
+ * old_value = value
+ * start0 = max(0, current0 - 1) # <<<<<<<<<<<<<<
+ * stop0 = min(self.height, current0 + 2)
+ * start1 = max(0, current1 - 1)
+ */
+ __pyx_t_6 = (__pyx_v_current0 - 1);
+ __pyx_t_7 = 0;
+ if (((__pyx_t_6 > __pyx_t_7) != 0)) {
+ __pyx_t_8 = __pyx_t_6;
+ } else {
+ __pyx_t_8 = __pyx_t_7;
+ }
+ __pyx_v_start0 = __pyx_t_8;
+
+ /* "silx/image/bilinear.pyx":237
+ * old_value = value
+ * start0 = max(0, current0 - 1)
+ * stop0 = min(self.height, current0 + 2) # <<<<<<<<<<<<<<
+ * start1 = max(0, current1 - 1)
+ * stop1 = min(self.width, current1 + 2)
+ */
+ __pyx_t_8 = (__pyx_v_current0 + 2);
+ __pyx_t_9 = __pyx_v_self->height;
+ if (((__pyx_t_8 < __pyx_t_9) != 0)) {
+ __pyx_t_10 = __pyx_t_8;
+ } else {
+ __pyx_t_10 = __pyx_t_9;
+ }
+ __pyx_v_stop0 = __pyx_t_10;
+
+ /* "silx/image/bilinear.pyx":238
+ * start0 = max(0, current0 - 1)
+ * stop0 = min(self.height, current0 + 2)
+ * start1 = max(0, current1 - 1) # <<<<<<<<<<<<<<
+ * stop1 = min(self.width, current1 + 2)
+ * for i0 in range(start0, stop0):
+ */
+ __pyx_t_8 = (__pyx_v_current1 - 1);
+ __pyx_t_6 = 0;
+ if (((__pyx_t_8 > __pyx_t_6) != 0)) {
+ __pyx_t_7 = __pyx_t_8;
+ } else {
+ __pyx_t_7 = __pyx_t_6;
+ }
+ __pyx_v_start1 = __pyx_t_7;
+
+ /* "silx/image/bilinear.pyx":239
+ * stop0 = min(self.height, current0 + 2)
+ * start1 = max(0, current1 - 1)
+ * stop1 = min(self.width, current1 + 2) # <<<<<<<<<<<<<<
+ * for i0 in range(start0, stop0):
+ * for i1 in range(start1, stop1):
+ */
+ __pyx_t_7 = (__pyx_v_current1 + 2);
+ __pyx_t_10 = __pyx_v_self->width;
+ if (((__pyx_t_7 < __pyx_t_10) != 0)) {
+ __pyx_t_9 = __pyx_t_7;
+ } else {
+ __pyx_t_9 = __pyx_t_10;
+ }
+ __pyx_v_stop1 = __pyx_t_9;
+
+ /* "silx/image/bilinear.pyx":240
+ * start1 = max(0, current1 - 1)
+ * stop1 = min(self.width, current1 + 2)
+ * for i0 in range(start0, stop0): # <<<<<<<<<<<<<<
+ * for i1 in range(start1, stop1):
+ * tmp = self.data[i0, i1]
+ */
+ __pyx_t_4 = __pyx_v_stop0;
+ for (__pyx_t_3 = __pyx_v_start0; __pyx_t_3 < __pyx_t_4; __pyx_t_3+=1) {
+ __pyx_v_i0 = __pyx_t_3;
+
+ /* "silx/image/bilinear.pyx":241
+ * stop1 = min(self.width, current1 + 2)
+ * for i0 in range(start0, stop0):
+ * for i1 in range(start1, stop1): # <<<<<<<<<<<<<<
+ * tmp = self.data[i0, i1]
+ * if tmp > value:
+ */
+ __pyx_t_11 = __pyx_v_stop1;
+ for (__pyx_t_12 = __pyx_v_start1; __pyx_t_12 < __pyx_t_11; __pyx_t_12+=1) {
+ __pyx_v_i1 = __pyx_t_12;
+
+ /* "silx/image/bilinear.pyx":242
+ * for i0 in range(start0, stop0):
+ * for i1 in range(start1, stop1):
+ * tmp = self.data[i0, i1] # <<<<<<<<<<<<<<
+ * if tmp > value:
+ * new0, new1 = i0, i1
+ */
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_13 = __pyx_v_i0;
+ __pyx_t_14 = __pyx_v_i1;
+ __pyx_v_tmp = (*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_self->data.data + __pyx_t_13 * __pyx_v_self->data.strides[0]) )) + __pyx_t_14)) )));
+
+ /* "silx/image/bilinear.pyx":243
+ * for i1 in range(start1, stop1):
+ * tmp = self.data[i0, i1]
+ * if tmp > value: # <<<<<<<<<<<<<<
+ * new0, new1 = i0, i1
+ * value = tmp
+ */
+ __pyx_t_5 = ((__pyx_v_tmp > __pyx_v_value) != 0);
+ if (__pyx_t_5) {
+
+ /* "silx/image/bilinear.pyx":244
+ * tmp = self.data[i0, i1]
+ * if tmp > value:
+ * new0, new1 = i0, i1 # <<<<<<<<<<<<<<
+ * value = tmp
+ * current0, current1 = new0, new1
+ */
+ __pyx_t_15 = __pyx_v_i0;
+ __pyx_t_16 = __pyx_v_i1;
+ __pyx_v_new0 = __pyx_t_15;
+ __pyx_v_new1 = __pyx_t_16;
+
+ /* "silx/image/bilinear.pyx":245
+ * if tmp > value:
+ * new0, new1 = i0, i1
+ * value = tmp # <<<<<<<<<<<<<<
+ * current0, current1 = new0, new1
+ * return self.width * current0 + current1
+ */
+ __pyx_v_value = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+ }
+ }
+
+ /* "silx/image/bilinear.pyx":246
+ * new0, new1 = i0, i1
+ * value = tmp
+ * current0, current1 = new0, new1 # <<<<<<<<<<<<<<
+ * return self.width * current0 + current1
+ *
+ */
+ __pyx_t_4 = __pyx_v_new0;
+ __pyx_t_3 = __pyx_v_new1;
+ __pyx_v_current0 = __pyx_t_4;
+ __pyx_v_current1 = __pyx_t_3;
+ }
+
+ /* "silx/image/bilinear.pyx":247
+ * value = tmp
+ * current0, current1 = new0, new1
+ * return self.width * current0 + current1 # <<<<<<<<<<<<<<
+ *
+ * @cython.boundscheck(False)
+ */
+ __pyx_r = ((__pyx_v_self->width * __pyx_v_current0) + __pyx_v_current1);
+ goto __pyx_L0;
+
+ /* "silx/image/bilinear.pyx":216
+ * @cython.wraparound(False)
+ * @cython.cdivision(True)
+ * cdef size_t c_local_maxi(self, size_t idx) nogil: # <<<<<<<<<<<<<<
+ * """Return the nearest local maximum without sub-pixel refinement
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_WriteUnraisable("silx.image.bilinear.BilinearImage.c_local_maxi", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":250
+ *
+ * @cython.boundscheck(False)
+ * def map_coordinates(self, coordinates): # <<<<<<<<<<<<<<
+ * """Map coordinates of the array on the image
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_13map_coordinates(PyObject *__pyx_v_self, PyObject *__pyx_v_coordinates); /*proto*/
+static char __pyx_doc_4silx_5image_8bilinear_13BilinearImage_12map_coordinates[] = "BilinearImage.map_coordinates(self, coordinates)\nMap coordinates of the array on the image\n\n :param coordinates: 2-tuple of array of the same size (row_array, column_array)\n :return: array of values at given coordinates\n ";
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_13map_coordinates(PyObject *__pyx_v_self, PyObject *__pyx_v_coordinates) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("map_coordinates (wrapper)", 0);
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_12map_coordinates(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self), ((PyObject *)__pyx_v_coordinates));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_12map_coordinates(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_coordinates) {
+ __Pyx_memviewslice __pyx_v_d0 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_d1 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_res = { 0, 0, { 0 }, { 0 }, { 0 } };
+ size_t __pyx_v_size;
+ size_t __pyx_v_i;
+ PyObject *__pyx_v_shape = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ size_t __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ __Pyx_memviewslice __pyx_t_7 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_8;
+ size_t __pyx_t_9;
+ size_t __pyx_t_10;
+ size_t __pyx_t_11;
+ size_t __pyx_t_12;
+ PyObject *__pyx_t_13 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("map_coordinates", 0);
+
+ /* "silx/image/bilinear.pyx":259
+ * float[:] d0, d1, res
+ * size_t size, i
+ * shape = coordinates[0].shape # <<<<<<<<<<<<<<
+ * size = coordinates[0].size
+ * d0 = numpy.ascontiguousarray(coordinates[0].ravel(), dtype=numpy.float32)
+ */
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_coordinates, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_shape = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "silx/image/bilinear.pyx":260
+ * size_t size, i
+ * shape = coordinates[0].shape
+ * size = coordinates[0].size # <<<<<<<<<<<<<<
+ * d0 = numpy.ascontiguousarray(coordinates[0].ravel(), dtype=numpy.float32)
+ * d1 = numpy.ascontiguousarray(coordinates[1].ravel(), dtype=numpy.float32)
+ */
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_coordinates, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_3 = __Pyx_PyInt_As_size_t(__pyx_t_1); if (unlikely((__pyx_t_3 == (size_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_size = __pyx_t_3;
+
+ /* "silx/image/bilinear.pyx":261
+ * shape = coordinates[0].shape
+ * size = coordinates[0].size
+ * d0 = numpy.ascontiguousarray(coordinates[0].ravel(), dtype=numpy.float32) # <<<<<<<<<<<<<<
+ * d1 = numpy.ascontiguousarray(coordinates[1].ravel(), dtype=numpy.float32)
+ * assert size == d1.size
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_coordinates, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_ravel); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float32); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_t_6);
+ if (unlikely(!__pyx_t_7.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_d0 = __pyx_t_7;
+ __pyx_t_7.memview = NULL;
+ __pyx_t_7.data = NULL;
+
+ /* "silx/image/bilinear.pyx":262
+ * size = coordinates[0].size
+ * d0 = numpy.ascontiguousarray(coordinates[0].ravel(), dtype=numpy.float32)
+ * d1 = numpy.ascontiguousarray(coordinates[1].ravel(), dtype=numpy.float32) # <<<<<<<<<<<<<<
+ * assert size == d1.size
+ * res = numpy.empty(size, dtype=numpy.float32)
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_5 = __Pyx_GetItemInt(__pyx_v_coordinates, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_ravel); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_6 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float32); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_t_4);
+ if (unlikely(!__pyx_t_7.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_d1 = __pyx_t_7;
+ __pyx_t_7.memview = NULL;
+ __pyx_t_7.data = NULL;
+
+ /* "silx/image/bilinear.pyx":263
+ * d0 = numpy.ascontiguousarray(coordinates[0].ravel(), dtype=numpy.float32)
+ * d1 = numpy.ascontiguousarray(coordinates[1].ravel(), dtype=numpy.float32)
+ * assert size == d1.size # <<<<<<<<<<<<<<
+ * res = numpy.empty(size, dtype=numpy.float32)
+ * with nogil:
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ __pyx_t_4 = __Pyx_PyInt_FromSize_t(__pyx_v_size); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __pyx_memoryview_fromslice(__pyx_v_d1, 1, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_4, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (unlikely(!__pyx_t_8)) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "silx/image/bilinear.pyx":264
+ * d1 = numpy.ascontiguousarray(coordinates[1].ravel(), dtype=numpy.float32)
+ * assert size == d1.size
+ * res = numpy.empty(size, dtype=numpy.float32) # <<<<<<<<<<<<<<
+ * with nogil:
+ * for i in range(size):
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyInt_FromSize_t(__pyx_v_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_t_5);
+ if (unlikely(!__pyx_t_7.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_res = __pyx_t_7;
+ __pyx_t_7.memview = NULL;
+ __pyx_t_7.data = NULL;
+
+ /* "silx/image/bilinear.pyx":265
+ * assert size == d1.size
+ * res = numpy.empty(size, dtype=numpy.float32)
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(size):
+ * res[i] = self.c_funct(d1[i], d0[i])
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "silx/image/bilinear.pyx":266
+ * res = numpy.empty(size, dtype=numpy.float32)
+ * with nogil:
+ * for i in range(size): # <<<<<<<<<<<<<<
+ * res[i] = self.c_funct(d1[i], d0[i])
+ * return numpy.asarray(res).reshape(shape)
+ */
+ __pyx_t_3 = __pyx_v_size;
+ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_3; __pyx_t_9+=1) {
+ __pyx_v_i = __pyx_t_9;
+
+ /* "silx/image/bilinear.pyx":267
+ * with nogil:
+ * for i in range(size):
+ * res[i] = self.c_funct(d1[i], d0[i]) # <<<<<<<<<<<<<<
+ * return numpy.asarray(res).reshape(shape)
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = __pyx_v_i;
+ *((float *) ( /* dim=0 */ (__pyx_v_res.data + __pyx_t_12 * __pyx_v_res.strides[0]) )) = ((struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self->__pyx_vtab)->c_funct(__pyx_v_self, (*((float *) ( /* dim=0 */ (__pyx_v_d1.data + __pyx_t_10 * __pyx_v_d1.strides[0]) ))), (*((float *) ( /* dim=0 */ (__pyx_v_d0.data + __pyx_t_11 * __pyx_v_d0.strides[0]) ))));
+ }
+ }
+
+ /* "silx/image/bilinear.pyx":265
+ * assert size == d1.size
+ * res = numpy.empty(size, dtype=numpy.float32)
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(size):
+ * res[i] = self.c_funct(d1[i], d0[i])
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/image/bilinear.pyx":268
+ * for i in range(size):
+ * res[i] = self.c_funct(d1[i], d0[i])
+ * return numpy.asarray(res).reshape(shape) # <<<<<<<<<<<<<<
+ *
+ * @cython.boundscheck(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_res, 1, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_13 = PyTuple_New(1+1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_13, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_13, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_shape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_13 = PyTuple_New(1+1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_13, 0+1, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_13, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "silx/image/bilinear.pyx":250
+ *
+ * @cython.boundscheck(False)
+ * def map_coordinates(self, coordinates): # <<<<<<<<<<<<<<
+ * """Map coordinates of the array on the image
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.map_coordinates", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_d0, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_d1, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_res, 1);
+ __Pyx_XDECREF(__pyx_v_shape);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":271
+ *
+ * @cython.boundscheck(False)
+ * def profile_line(self, src, dst, int linewidth=1): # <<<<<<<<<<<<<<
+ * """Return the intensity profile of an image measured along a scan line.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_15profile_line(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_5image_8bilinear_13BilinearImage_14profile_line[] = "BilinearImage.profile_line(self, src, dst, int linewidth=1)\nReturn the intensity profile of an image measured along a scan line.\n\n :param src: The start point of the scan line.\n :type src: 2-tuple of numeric scalar\n :param dst: The end point of the scan line.\n The destination point is included in the profile,\n in contrast to standard numpy indexing.\n :type dst: 2-tuple of numeric scalar\n :param int linewidth: Width of the scanline (unit image pixel).\n :return: The intensity profile along the scan line.\n The length of the profile is the ceil of the computed length\n of the scan line.\n :rtype: 1d array\n\n Inspired from skimage\n ";
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_15profile_line(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_src = 0;
+ PyObject *__pyx_v_dst = 0;
+ int __pyx_v_linewidth;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("profile_line (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_src,&__pyx_n_s_dst,&__pyx_n_s_linewidth,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_src)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dst)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("profile_line", 0, 2, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_linewidth);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "profile_line") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_src = values[0];
+ __pyx_v_dst = values[1];
+ if (values[2]) {
+ __pyx_v_linewidth = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_linewidth == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_linewidth = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("profile_line", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.profile_line", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_14profile_line(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self), __pyx_v_src, __pyx_v_dst, __pyx_v_linewidth);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_14profile_line(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self, PyObject *__pyx_v_src, PyObject *__pyx_v_dst, int __pyx_v_linewidth) {
+ float __pyx_v_src_row;
+ float __pyx_v_src_col;
+ float __pyx_v_dst_row;
+ float __pyx_v_dst_col;
+ float __pyx_v_d_row;
+ float __pyx_v_d_col;
+ float __pyx_v_length;
+ float __pyx_v_col_width;
+ float __pyx_v_row_width;
+ float __pyx_v_sum;
+ float __pyx_v_row;
+ float __pyx_v_col;
+ float __pyx_v_new_row;
+ float __pyx_v_new_col;
+ int __pyx_v_lengt;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_v_cnt;
+ __Pyx_memviewslice __pyx_v_result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ float __pyx_t_5;
+ float __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ __Pyx_memviewslice __pyx_t_11 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_12;
+ int __pyx_t_13;
+ int __pyx_t_14;
+ int __pyx_t_15;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("profile_line", 0);
+
+ /* "silx/image/bilinear.pyx":293
+ * int lengt, i, j, cnt
+ * float[::1] result
+ * src_row, src_col = src # <<<<<<<<<<<<<<
+ * dst_row, dst_col = dst
+ * if (src_row == dst_row) and (src_col == dst_col):
+ */
+ if ((likely(PyTuple_CheckExact(__pyx_v_src))) || (PyList_CheckExact(__pyx_v_src))) {
+ PyObject* sequence = __pyx_v_src;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1);
+ } else {
+ __pyx_t_1 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_2 = PyList_GET_ITEM(sequence, 1);
+ }
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_2);
+ #else
+ __pyx_t_1 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ #endif
+ } else {
+ Py_ssize_t index = -1;
+ __pyx_t_3 = PyObject_GetIter(__pyx_v_src); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = Py_TYPE(__pyx_t_3)->tp_iternext;
+ index = 0; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L3_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_1);
+ index = 1; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_2);
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = NULL;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4_unpacking_done;
+ __pyx_L3_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_L4_unpacking_done:;
+ }
+ __pyx_t_5 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_5 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_6 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_src_row = __pyx_t_5;
+ __pyx_v_src_col = __pyx_t_6;
+
+ /* "silx/image/bilinear.pyx":294
+ * float[::1] result
+ * src_row, src_col = src
+ * dst_row, dst_col = dst # <<<<<<<<<<<<<<
+ * if (src_row == dst_row) and (src_col == dst_col):
+ * logger.warning("Source and destination points are the same")
+ */
+ if ((likely(PyTuple_CheckExact(__pyx_v_dst))) || (PyList_CheckExact(__pyx_v_dst))) {
+ PyObject* sequence = __pyx_v_dst;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_1 = PyTuple_GET_ITEM(sequence, 1);
+ } else {
+ __pyx_t_2 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_1 = PyList_GET_ITEM(sequence, 1);
+ }
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_1);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ #endif
+ } else {
+ Py_ssize_t index = -1;
+ __pyx_t_3 = PyObject_GetIter(__pyx_v_dst); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = Py_TYPE(__pyx_t_3)->tp_iternext;
+ index = 0; __pyx_t_2 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L5_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_2);
+ index = 1; __pyx_t_1 = __pyx_t_4(__pyx_t_3); if (unlikely(!__pyx_t_1)) goto __pyx_L5_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_4(__pyx_t_3), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = NULL;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L6_unpacking_done;
+ __pyx_L5_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_L6_unpacking_done:;
+ }
+ __pyx_t_6 = __pyx_PyFloat_AsFloat(__pyx_t_2); if (unlikely((__pyx_t_6 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_5 = __pyx_PyFloat_AsFloat(__pyx_t_1); if (unlikely((__pyx_t_5 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_dst_row = __pyx_t_6;
+ __pyx_v_dst_col = __pyx_t_5;
+
+ /* "silx/image/bilinear.pyx":295
+ * src_row, src_col = src
+ * dst_row, dst_col = dst
+ * if (src_row == dst_row) and (src_col == dst_col): # <<<<<<<<<<<<<<
+ * logger.warning("Source and destination points are the same")
+ * return numpy.array([self.c_funct(src_col, src_row)])
+ */
+ __pyx_t_8 = ((__pyx_v_src_row == __pyx_v_dst_row) != 0);
+ if (__pyx_t_8) {
+ } else {
+ __pyx_t_7 = __pyx_t_8;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_8 = ((__pyx_v_src_col == __pyx_v_dst_col) != 0);
+ __pyx_t_7 = __pyx_t_8;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "silx/image/bilinear.pyx":296
+ * dst_row, dst_col = dst
+ * if (src_row == dst_row) and (src_col == dst_col):
+ * logger.warning("Source and destination points are the same") # <<<<<<<<<<<<<<
+ * return numpy.array([self.c_funct(src_col, src_row)])
+ * d_row = dst_row - src_row
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_warning); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/bilinear.pyx":297
+ * if (src_row == dst_row) and (src_col == dst_col):
+ * logger.warning("Source and destination points are the same")
+ * return numpy.array([self.c_funct(src_col, src_row)]) # <<<<<<<<<<<<<<
+ * d_row = dst_row - src_row
+ * d_col = dst_col - src_col
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyFloat_FromDouble(((struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self->__pyx_vtab)->c_funct(__pyx_v_self, __pyx_v_src_col, __pyx_v_src_row)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_9 = PyList_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyList_SET_ITEM(__pyx_t_9, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_9); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "silx/image/bilinear.pyx":298
+ * logger.warning("Source and destination points are the same")
+ * return numpy.array([self.c_funct(src_col, src_row)])
+ * d_row = dst_row - src_row # <<<<<<<<<<<<<<
+ * d_col = dst_col - src_col
+ *
+ */
+ __pyx_v_d_row = (__pyx_v_dst_row - __pyx_v_src_row);
+
+ /* "silx/image/bilinear.pyx":299
+ * return numpy.array([self.c_funct(src_col, src_row)])
+ * d_row = dst_row - src_row
+ * d_col = dst_col - src_col # <<<<<<<<<<<<<<
+ *
+ * # Offsets to deal with linewidth
+ */
+ __pyx_v_d_col = (__pyx_v_dst_col - __pyx_v_src_col);
+
+ /* "silx/image/bilinear.pyx":302
+ *
+ * # Offsets to deal with linewidth
+ * length = sqrt(d_row * d_row + d_col * d_col) # <<<<<<<<<<<<<<
+ * row_width = d_col / length
+ * col_width = - d_row / length
+ */
+ __pyx_v_length = sqrt(((__pyx_v_d_row * __pyx_v_d_row) + (__pyx_v_d_col * __pyx_v_d_col)));
+
+ /* "silx/image/bilinear.pyx":303
+ * # Offsets to deal with linewidth
+ * length = sqrt(d_row * d_row + d_col * d_col)
+ * row_width = d_col / length # <<<<<<<<<<<<<<
+ * col_width = - d_row / length
+ *
+ */
+ if (unlikely(__pyx_v_length == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_row_width = (__pyx_v_d_col / __pyx_v_length);
+
+ /* "silx/image/bilinear.pyx":304
+ * length = sqrt(d_row * d_row + d_col * d_col)
+ * row_width = d_col / length
+ * col_width = - d_row / length # <<<<<<<<<<<<<<
+ *
+ * lengt = <int> ceil(length + 1)
+ */
+ __pyx_t_5 = (-__pyx_v_d_row);
+ if (unlikely(__pyx_v_length == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_col_width = (__pyx_t_5 / __pyx_v_length);
+
+ /* "silx/image/bilinear.pyx":306
+ * col_width = - d_row / length
+ *
+ * lengt = <int> ceil(length + 1) # <<<<<<<<<<<<<<
+ * d_row /= <float> (lengt -1)
+ * d_col /= <float> (lengt -1)
+ */
+ __pyx_v_lengt = ((int)ceil((__pyx_v_length + 1.0)));
+
+ /* "silx/image/bilinear.pyx":307
+ *
+ * lengt = <int> ceil(length + 1)
+ * d_row /= <float> (lengt -1) # <<<<<<<<<<<<<<
+ * d_col /= <float> (lengt -1)
+ *
+ */
+ __pyx_t_5 = ((float)(__pyx_v_lengt - 1));
+ if (unlikely(__pyx_t_5 == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_d_row = (__pyx_v_d_row / __pyx_t_5);
+
+ /* "silx/image/bilinear.pyx":308
+ * lengt = <int> ceil(length + 1)
+ * d_row /= <float> (lengt -1)
+ * d_col /= <float> (lengt -1) # <<<<<<<<<<<<<<
+ *
+ * result = numpy.zeros(lengt, dtype=numpy.float32)
+ */
+ __pyx_t_5 = ((float)(__pyx_v_lengt - 1));
+ if (unlikely(__pyx_t_5 == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_d_col = (__pyx_v_d_col / __pyx_t_5);
+
+ /* "silx/image/bilinear.pyx":310
+ * d_col /= <float> (lengt -1)
+ *
+ * result = numpy.zeros(lengt, dtype=numpy.float32) # <<<<<<<<<<<<<<
+ *
+ * # Offset position to the center of the bottom pixels of the profile
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_lengt); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float32); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_10, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_11 = __Pyx_PyObject_to_MemoryviewSlice_dc_float(__pyx_t_2);
+ if (unlikely(!__pyx_t_11.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_result = __pyx_t_11;
+ __pyx_t_11.memview = NULL;
+ __pyx_t_11.data = NULL;
+
+ /* "silx/image/bilinear.pyx":313
+ *
+ * # Offset position to the center of the bottom pixels of the profile
+ * src_row -= row_width * (linewidth - 1) / 2. # <<<<<<<<<<<<<<
+ * src_col -= col_width * (linewidth - 1) / 2.
+ *
+ */
+ __pyx_v_src_row = (__pyx_v_src_row - ((__pyx_v_row_width * (__pyx_v_linewidth - 1)) / 2.));
+
+ /* "silx/image/bilinear.pyx":314
+ * # Offset position to the center of the bottom pixels of the profile
+ * src_row -= row_width * (linewidth - 1) / 2.
+ * src_col -= col_width * (linewidth - 1) / 2. # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_src_col = (__pyx_v_src_col - ((__pyx_v_col_width * (__pyx_v_linewidth - 1)) / 2.));
+
+ /* "silx/image/bilinear.pyx":316
+ * src_col -= col_width * (linewidth - 1) / 2.
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(lengt):
+ * sum = 0
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "silx/image/bilinear.pyx":317
+ *
+ * with nogil:
+ * for i in range(lengt): # <<<<<<<<<<<<<<
+ * sum = 0
+ * cnt = 0
+ */
+ __pyx_t_12 = __pyx_v_lengt;
+ for (__pyx_t_13 = 0; __pyx_t_13 < __pyx_t_12; __pyx_t_13+=1) {
+ __pyx_v_i = __pyx_t_13;
+
+ /* "silx/image/bilinear.pyx":318
+ * with nogil:
+ * for i in range(lengt):
+ * sum = 0 # <<<<<<<<<<<<<<
+ * cnt = 0
+ *
+ */
+ __pyx_v_sum = 0.0;
+
+ /* "silx/image/bilinear.pyx":319
+ * for i in range(lengt):
+ * sum = 0
+ * cnt = 0 # <<<<<<<<<<<<<<
+ *
+ * row = src_row + i * d_row
+ */
+ __pyx_v_cnt = 0;
+
+ /* "silx/image/bilinear.pyx":321
+ * cnt = 0
+ *
+ * row = src_row + i * d_row # <<<<<<<<<<<<<<
+ * col = src_col + i * d_col
+ *
+ */
+ __pyx_v_row = (__pyx_v_src_row + (__pyx_v_i * __pyx_v_d_row));
+
+ /* "silx/image/bilinear.pyx":322
+ *
+ * row = src_row + i * d_row
+ * col = src_col + i * d_col # <<<<<<<<<<<<<<
+ *
+ * for j in range(linewidth):
+ */
+ __pyx_v_col = (__pyx_v_src_col + (__pyx_v_i * __pyx_v_d_col));
+
+ /* "silx/image/bilinear.pyx":324
+ * col = src_col + i * d_col
+ *
+ * for j in range(linewidth): # <<<<<<<<<<<<<<
+ * new_row = row + j * row_width
+ * new_col = col + j * col_width
+ */
+ __pyx_t_14 = __pyx_v_linewidth;
+ for (__pyx_t_15 = 0; __pyx_t_15 < __pyx_t_14; __pyx_t_15+=1) {
+ __pyx_v_j = __pyx_t_15;
+
+ /* "silx/image/bilinear.pyx":325
+ *
+ * for j in range(linewidth):
+ * new_row = row + j * row_width # <<<<<<<<<<<<<<
+ * new_col = col + j * col_width
+ * if ((new_col >= 0) and (new_col < self.width) and
+ */
+ __pyx_v_new_row = (__pyx_v_row + (__pyx_v_j * __pyx_v_row_width));
+
+ /* "silx/image/bilinear.pyx":326
+ * for j in range(linewidth):
+ * new_row = row + j * row_width
+ * new_col = col + j * col_width # <<<<<<<<<<<<<<
+ * if ((new_col >= 0) and (new_col < self.width) and
+ * (new_row >= 0) and (new_row < self.height)):
+ */
+ __pyx_v_new_col = (__pyx_v_col + (__pyx_v_j * __pyx_v_col_width));
+
+ /* "silx/image/bilinear.pyx":327
+ * new_row = row + j * row_width
+ * new_col = col + j * col_width
+ * if ((new_col >= 0) and (new_col < self.width) and # <<<<<<<<<<<<<<
+ * (new_row >= 0) and (new_row < self.height)):
+ * cnt = cnt + 1
+ */
+ __pyx_t_8 = ((__pyx_v_new_col >= 0.0) != 0);
+ if (__pyx_t_8) {
+ } else {
+ __pyx_t_7 = __pyx_t_8;
+ goto __pyx_L18_bool_binop_done;
+ }
+ __pyx_t_8 = ((__pyx_v_new_col < __pyx_v_self->width) != 0);
+ if (__pyx_t_8) {
+ } else {
+ __pyx_t_7 = __pyx_t_8;
+ goto __pyx_L18_bool_binop_done;
+ }
+
+ /* "silx/image/bilinear.pyx":328
+ * new_col = col + j * col_width
+ * if ((new_col >= 0) and (new_col < self.width) and
+ * (new_row >= 0) and (new_row < self.height)): # <<<<<<<<<<<<<<
+ * cnt = cnt + 1
+ * sum = sum + self.c_funct(new_col, new_row)
+ */
+ __pyx_t_8 = ((__pyx_v_new_row >= 0.0) != 0);
+ if (__pyx_t_8) {
+ } else {
+ __pyx_t_7 = __pyx_t_8;
+ goto __pyx_L18_bool_binop_done;
+ }
+ __pyx_t_8 = ((__pyx_v_new_row < __pyx_v_self->height) != 0);
+ __pyx_t_7 = __pyx_t_8;
+ __pyx_L18_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "silx/image/bilinear.pyx":329
+ * if ((new_col >= 0) and (new_col < self.width) and
+ * (new_row >= 0) and (new_row < self.height)):
+ * cnt = cnt + 1 # <<<<<<<<<<<<<<
+ * sum = sum + self.c_funct(new_col, new_row)
+ * if cnt:
+ */
+ __pyx_v_cnt = (__pyx_v_cnt + 1);
+
+ /* "silx/image/bilinear.pyx":330
+ * (new_row >= 0) and (new_row < self.height)):
+ * cnt = cnt + 1
+ * sum = sum + self.c_funct(new_col, new_row) # <<<<<<<<<<<<<<
+ * if cnt:
+ * result[i] += sum / cnt
+ */
+ __pyx_v_sum = (__pyx_v_sum + ((struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self->__pyx_vtab)->c_funct(__pyx_v_self, __pyx_v_new_col, __pyx_v_new_row));
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+
+ /* "silx/image/bilinear.pyx":331
+ * cnt = cnt + 1
+ * sum = sum + self.c_funct(new_col, new_row)
+ * if cnt: # <<<<<<<<<<<<<<
+ * result[i] += sum / cnt
+ *
+ */
+ __pyx_t_7 = (__pyx_v_cnt != 0);
+ if (__pyx_t_7) {
+
+ /* "silx/image/bilinear.pyx":332
+ * sum = sum + self.c_funct(new_col, new_row)
+ * if cnt:
+ * result[i] += sum / cnt # <<<<<<<<<<<<<<
+ *
+ * # Ensures the result is exported as numpy array and not memory view.
+ */
+ if (unlikely(__pyx_v_cnt == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L11_error;}
+ }
+ __pyx_t_14 = __pyx_v_i;
+ if (__pyx_t_14 < 0) __pyx_t_14 += __pyx_v_result.shape[0];
+ *((float *) ( /* dim=0 */ ((char *) (((float *) __pyx_v_result.data) + __pyx_t_14)) )) += (__pyx_v_sum / __pyx_v_cnt);
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+ }
+ }
+
+ /* "silx/image/bilinear.pyx":316
+ * src_col -= col_width * (linewidth - 1) / 2.
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(lengt):
+ * sum = 0
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L12;
+ }
+ __pyx_L11_error: {
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L1_error;
+ }
+ __pyx_L12:;
+ }
+ }
+
+ /* "silx/image/bilinear.pyx":335
+ *
+ * # Ensures the result is exported as numpy array and not memory view.
+ * return numpy.asarray(result) # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_asarray); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_result, 1, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_9, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "silx/image/bilinear.pyx":271
+ *
+ * @cython.boundscheck(False)
+ * def profile_line(self, src, dst, int linewidth=1): # <<<<<<<<<<<<<<
+ * """Return the intensity profile of an image measured along a scan line.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.profile_line", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_result, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":43
+ * """
+ * cdef:
+ * readonly float[:, ::1] data # <<<<<<<<<<<<<<
+ * readonly float maxi, mini
+ * readonly size_t width, height
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_4data_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_4data_1__get__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_4data___get__(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_4data___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ if (unlikely(!__pyx_v_self->data.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_self->data, 2, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.data.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":44
+ * cdef:
+ * readonly float[:, ::1] data
+ * readonly float maxi, mini # <<<<<<<<<<<<<<
+ * readonly size_t width, height
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_4maxi_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_4maxi_1__get__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_4maxi___get__(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_4maxi___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyFloat_FromDouble(__pyx_v_self->maxi); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.maxi.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_4mini_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_4mini_1__get__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_4mini___get__(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_4mini___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyFloat_FromDouble(__pyx_v_self->mini); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 44; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.mini.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/bilinear.pyx":45
+ * readonly float[:, ::1] data
+ * readonly float maxi, mini
+ * readonly size_t width, height # <<<<<<<<<<<<<<
+ *
+ * cpdef size_t coarse_local_maxi(self, size_t)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_5width_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_5width_1__get__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_5width___get__(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_5width___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->width); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.width.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_6height_1__get__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_pw_4silx_5image_8bilinear_13BilinearImage_6height_1__get__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_4silx_5image_8bilinear_13BilinearImage_6height___get__(((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_8bilinear_13BilinearImage_6height___get__(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_FromSize_t(__pyx_v_self->height); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("silx.image.bilinear.BilinearImage.height.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__11);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__11);
+ __Pyx_GIVEREF(__pyx_slice__11);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__12); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__13);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__13);
+ __Pyx_GIVEREF(__pyx_slice__13);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+static struct __pyx_vtabstruct_4silx_5image_8bilinear_BilinearImage __pyx_vtable_4silx_5image_8bilinear_BilinearImage;
+
+static PyObject *__pyx_tp_new_4silx_5image_8bilinear_BilinearImage(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)o);
+ p->__pyx_vtab = __pyx_vtabptr_4silx_5image_8bilinear_BilinearImage;
+ p->data.data = NULL;
+ p->data.memview = NULL;
+ if (unlikely(__pyx_pw_4silx_5image_8bilinear_13BilinearImage_1__cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_4silx_5image_8bilinear_BilinearImage(PyObject *o) {
+ struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *p = (struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_pw_4silx_5image_8bilinear_13BilinearImage_3__dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ __PYX_XDEC_MEMVIEW(&p->data, 1);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static PyObject *__pyx_getprop_4silx_5image_8bilinear_13BilinearImage_data(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_pw_4silx_5image_8bilinear_13BilinearImage_4data_1__get__(o);
+}
+
+static PyObject *__pyx_getprop_4silx_5image_8bilinear_13BilinearImage_maxi(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_pw_4silx_5image_8bilinear_13BilinearImage_4maxi_1__get__(o);
+}
+
+static PyObject *__pyx_getprop_4silx_5image_8bilinear_13BilinearImage_mini(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_pw_4silx_5image_8bilinear_13BilinearImage_4mini_1__get__(o);
+}
+
+static PyObject *__pyx_getprop_4silx_5image_8bilinear_13BilinearImage_width(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_pw_4silx_5image_8bilinear_13BilinearImage_5width_1__get__(o);
+}
+
+static PyObject *__pyx_getprop_4silx_5image_8bilinear_13BilinearImage_height(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_pw_4silx_5image_8bilinear_13BilinearImage_6height_1__get__(o);
+}
+
+static PyMethodDef __pyx_methods_4silx_5image_8bilinear_BilinearImage[] = {
+ {"opp_f", (PyCFunction)__pyx_pw_4silx_5image_8bilinear_13BilinearImage_7opp_f, METH_O, __pyx_doc_4silx_5image_8bilinear_13BilinearImage_6opp_f},
+ {"local_maxi", (PyCFunction)__pyx_pw_4silx_5image_8bilinear_13BilinearImage_9local_maxi, METH_O, __pyx_doc_4silx_5image_8bilinear_13BilinearImage_8local_maxi},
+ {"coarse_local_maxi", (PyCFunction)__pyx_pw_4silx_5image_8bilinear_13BilinearImage_11coarse_local_maxi, METH_O, __pyx_doc_4silx_5image_8bilinear_13BilinearImage_10coarse_local_maxi},
+ {"map_coordinates", (PyCFunction)__pyx_pw_4silx_5image_8bilinear_13BilinearImage_13map_coordinates, METH_O, __pyx_doc_4silx_5image_8bilinear_13BilinearImage_12map_coordinates},
+ {"profile_line", (PyCFunction)__pyx_pw_4silx_5image_8bilinear_13BilinearImage_15profile_line, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_5image_8bilinear_13BilinearImage_14profile_line},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_4silx_5image_8bilinear_BilinearImage[] = {
+ {(char *)"data", __pyx_getprop_4silx_5image_8bilinear_13BilinearImage_data, 0, 0, 0},
+ {(char *)"maxi", __pyx_getprop_4silx_5image_8bilinear_13BilinearImage_maxi, 0, 0, 0},
+ {(char *)"mini", __pyx_getprop_4silx_5image_8bilinear_13BilinearImage_mini, 0, 0, 0},
+ {(char *)"width", __pyx_getprop_4silx_5image_8bilinear_13BilinearImage_width, 0, 0, 0},
+ {(char *)"height", __pyx_getprop_4silx_5image_8bilinear_13BilinearImage_height, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_4silx_5image_8bilinear_BilinearImage = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.bilinear.BilinearImage", /*tp_name*/
+ sizeof(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_4silx_5image_8bilinear_BilinearImage, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ __pyx_pw_4silx_5image_8bilinear_13BilinearImage_5__call__, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "Bilinear interpolator for images ... or any data on a regular grid\n ", /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_4silx_5image_8bilinear_BilinearImage, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_4silx_5image_8bilinear_BilinearImage, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_4silx_5image_8bilinear_BilinearImage, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.bilinear.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.bilinear.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.bilinear.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.bilinear._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "bilinear",
+ 0, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_15_09_2016, __pyx_k_15_09_2016, sizeof(__pyx_k_15_09_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_Bilinear_interpolator_peak_finde, __pyx_k_Bilinear_interpolator_peak_finde, sizeof(__pyx_k_Bilinear_interpolator_peak_finde), 0, 0, 1, 0},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Failed_to_find_root_using_second, __pyx_k_Failed_to_find_root_using_second, sizeof(__pyx_k_Failed_to_find_root_using_second), 0, 0, 1, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_kp_s_J_Kieffer, __pyx_k_J_Kieffer, sizeof(__pyx_k_J_Kieffer), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_kp_s_Singular_determinant_Hessian_und, __pyx_k_Singular_determinant_Hessian_und, sizeof(__pyx_k_Singular_determinant_Hessian_und), 0, 0, 1, 0},
+ {&__pyx_kp_s_Source_and_destination_points_ar, __pyx_k_Source_and_destination_points_ar, sizeof(__pyx_k_Source_and_destination_points_ar), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+ {&__pyx_n_s_asarray, __pyx_k_asarray, sizeof(__pyx_k_asarray), 0, 0, 1, 1},
+ {&__pyx_n_s_ascontiguousarray, __pyx_k_ascontiguousarray, sizeof(__pyx_k_ascontiguousarray), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_n_s_coarse_local_maxi, __pyx_k_coarse_local_maxi, sizeof(__pyx_k_coarse_local_maxi), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_coord, __pyx_k_coord, sizeof(__pyx_k_coord), 0, 0, 1, 1},
+ {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_debug, __pyx_k_debug, sizeof(__pyx_k_debug), 0, 0, 1, 1},
+ {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1},
+ {&__pyx_n_s_dst, __pyx_k_dst, sizeof(__pyx_k_dst), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_float32, __pyx_k_float32, sizeof(__pyx_k_float32), 0, 0, 1, 1},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_n_s_getLogger, __pyx_k_getLogger, sizeof(__pyx_k_getLogger), 0, 0, 1, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_linewidth, __pyx_k_linewidth, sizeof(__pyx_k_linewidth), 0, 0, 1, 1},
+ {&__pyx_n_s_logger, __pyx_k_logger, sizeof(__pyx_k_logger), 0, 0, 1, 1},
+ {&__pyx_n_s_logging, __pyx_k_logging, sizeof(__pyx_k_logging), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_max, __pyx_k_max, sizeof(__pyx_k_max), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_n_s_min, __pyx_k_min, sizeof(__pyx_k_min), 0, 0, 1, 1},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_ravel, __pyx_k_ravel, sizeof(__pyx_k_ravel), 0, 0, 1, 1},
+ {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+ {&__pyx_n_s_round, __pyx_k_round, sizeof(__pyx_k_round), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_kp_s_silx_image_bilinear, __pyx_k_silx_image_bilinear, sizeof(__pyx_k_silx_image_bilinear), 0, 0, 1, 0},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_src, __pyx_k_src, sizeof(__pyx_k_src), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_n_s_warning, __pyx_k_warning, sizeof(__pyx_k_warning), 0, 0, 1, 1},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_round = __Pyx_GetBuiltinName(__pyx_n_s_round); if (!__pyx_builtin_round) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "silx/image/bilinear.pyx":184
+ * denom = 2.0 * (d00 * d11 - d01 * d01)
+ * if abs(denom) < 1e-10:
+ * logger.debug("Singular determinant, Hessian undefined") # <<<<<<<<<<<<<<
+ * else:
+ * delta0 = ((a12 - a10) * d01 + (a01 - a21) * d11) / denom
+ */
+ __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_Singular_determinant_Hessian_und); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "silx/image/bilinear.pyx":192
+ * return (delta0 + float(current0), delta1 + float(current1))
+ * else:
+ * logger.debug("Failed to find root using second order expansion") # <<<<<<<<<<<<<<
+ * # refinement of the position by a simple center of mass of the last valid region used
+ * for i0 in range(current0 - 1, current0 + 2):
+ */
+ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_Failed_to_find_root_using_second); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "silx/image/bilinear.pyx":296
+ * dst_row, dst_col = dst
+ * if (src_row == dst_row) and (src_col == dst_col):
+ * logger.warning("Source and destination points are the same") # <<<<<<<<<<<<<<
+ * return numpy.array([self.c_funct(src_col, src_row)])
+ * d_row = dst_row - src_row
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_Source_and_destination_points_ar); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__7);
+ __Pyx_GIVEREF(__pyx_tuple__7);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__11 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__11);
+ __Pyx_GIVEREF(__pyx_slice__11);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__12 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__12)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__12);
+ __Pyx_GIVEREF(__pyx_slice__12);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__13 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__13)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__13);
+ __Pyx_GIVEREF(__pyx_slice__13);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__14);
+ __Pyx_GIVEREF(__pyx_tuple__14);
+
+ /* "silx/image/bilinear.pyx":36
+ * from libc.math cimport floor, ceil, sin, cos, sqrt, atan2
+ * import logging
+ * logger = logging.getLogger("silx.image.bilinear") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_silx_image_bilinear); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__19);
+ __Pyx_GIVEREF(__pyx_tuple__19);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initbilinear(void); /*proto*/
+PyMODINIT_FUNC initbilinear(void)
+#else
+PyMODINIT_FUNC PyInit_bilinear(void); /*proto*/
+PyMODINIT_FUNC PyInit_bilinear(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_bilinear(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("bilinear", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_silx__image__bilinear) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "silx.image.bilinear")) {
+ if (unlikely(PyDict_SetItemString(modules, "silx.image.bilinear", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ __pyx_vtabptr_4silx_5image_8bilinear_BilinearImage = &__pyx_vtable_4silx_5image_8bilinear_BilinearImage;
+ __pyx_vtable_4silx_5image_8bilinear_BilinearImage.coarse_local_maxi = (size_t (*)(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *, size_t, int __pyx_skip_dispatch))__pyx_f_4silx_5image_8bilinear_13BilinearImage_coarse_local_maxi;
+ __pyx_vtable_4silx_5image_8bilinear_BilinearImage.c_local_maxi = (size_t (*)(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *, size_t))__pyx_f_4silx_5image_8bilinear_13BilinearImage_c_local_maxi;
+ __pyx_vtable_4silx_5image_8bilinear_BilinearImage.c_funct = (float (*)(struct __pyx_obj_4silx_5image_8bilinear_BilinearImage *, float, float))__pyx_f_4silx_5image_8bilinear_13BilinearImage_c_funct;
+ if (PyType_Ready(&__pyx_type_4silx_5image_8bilinear_BilinearImage) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_4silx_5image_8bilinear_BilinearImage.tp_print = 0;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_4silx_5image_8bilinear_BilinearImage, "__call__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_4silx_5image_8bilinear_13BilinearImage_4__call__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_4silx_5image_8bilinear_13BilinearImage_4__call__.doc = __pyx_doc_4silx_5image_8bilinear_13BilinearImage_4__call__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_4silx_5image_8bilinear_13BilinearImage_4__call__;
+ }
+ }
+ #endif
+ if (__Pyx_SetVtable(__pyx_type_4silx_5image_8bilinear_BilinearImage.tp_dict, __pyx_vtabptr_4silx_5image_8bilinear_BilinearImage) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyObject_SetAttrString(__pyx_m, "BilinearImage", (PyObject *)&__pyx_type_4silx_5image_8bilinear_BilinearImage) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_4silx_5image_8bilinear_BilinearImage = &__pyx_type_4silx_5image_8bilinear_BilinearImage;
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "silx/image/bilinear.pyx":26
+ * # THE SOFTWARE.
+ *
+ * __authors__ = ["J. Kieffer"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "15/09/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_J_Kieffer);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_J_Kieffer);
+ __Pyx_GIVEREF(__pyx_kp_s_J_Kieffer);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/bilinear.pyx":27
+ *
+ * __authors__ = ["J. Kieffer"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "15/09/2016"
+ * __doc__ = "Bilinear interpolator, peak finder, line-profile for images"
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/image/bilinear.pyx":28
+ * __authors__ = ["J. Kieffer"]
+ * __license__ = "MIT"
+ * __date__ = "15/09/2016" # <<<<<<<<<<<<<<
+ * __doc__ = "Bilinear interpolator, peak finder, line-profile for images"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_15_09_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/image/bilinear.pyx":29
+ * __license__ = "MIT"
+ * __date__ = "15/09/2016"
+ * __doc__ = "Bilinear interpolator, peak finder, line-profile for images" # <<<<<<<<<<<<<<
+ *
+ * import cython
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_doc, __pyx_kp_s_Bilinear_interpolator_peak_finde) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/image/bilinear.pyx":33
+ * import cython
+ * from cython.view cimport array as cvarray
+ * import numpy # <<<<<<<<<<<<<<
+ * from libc.math cimport floor, ceil, sin, cos, sqrt, atan2
+ * import logging
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/bilinear.pyx":35
+ * import numpy
+ * from libc.math cimport floor, ceil, sin, cos, sqrt, atan2
+ * import logging # <<<<<<<<<<<<<<
+ * logger = logging.getLogger("silx.image.bilinear")
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/bilinear.pyx":36
+ * from libc.math cimport floor, ceil, sin, cos, sqrt, atan2
+ * import logging
+ * logger = logging.getLogger("silx.image.bilinear") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_getLogger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logger, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/bilinear.pyx":1
+ * # -*- coding: utf-8 -*- # <<<<<<<<<<<<<<
+ * #
+ * # Project: silx (originally pyFAI)
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init silx.image.bilinear", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init silx.image.bilinear");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* exc_type = tstate->curexc_type;
+ if (unlikely(exc_type)) {
+ if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+ PyObject *exc_value, *exc_tb;
+ exc_value = tstate->curexc_value;
+ exc_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+ Py_DECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#else
+ if (unlikely(PyErr_Occurred())) {
+ if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+ PyErr_Clear();
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+ if (unlikely(retval)) {
+ Py_DECREF(retval);
+ __Pyx_RaiseTooManyValuesError(expected);
+ return -1;
+ } else {
+ return __Pyx_IterFinish();
+ }
+ return 0;
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) {
+ const size_t neg_one = (size_t) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(size_t) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (size_t) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(size_t) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(size_t) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(size_t, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(size_t) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, long, PyLong_AsLong(x))
+ } else if (sizeof(size_t) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ size_t val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (size_t) -1;
+ }
+ } else {
+ size_t val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (size_t) -1;
+ val = __Pyx_PyInt_As_size_t(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to size_t");
+ return (size_t) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to size_t");
+ return (size_t) -1;
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static PyObject *__pyx_memview_get_float(const char *itemp) {
+ return (PyObject *) PyFloat_FromDouble(*(float *) itemp);
+}
+static int __pyx_memview_set_float(const char *itemp, PyObject *obj) {
+ float value = __pyx_PyFloat_AsFloat(obj);
+ if ((value == (float)-1) && PyErr_Occurred())
+ return 0;
+ *(float *) itemp = value;
+ return 1;
+}
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_float(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 2,
+ &__Pyx_TypeInfo_float, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_float(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_float, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_float(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_float, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/image/bilinear.pyx b/silx/image/bilinear.pyx
new file mode 100644
index 0000000..ce440b4
--- /dev/null
+++ b/silx/image/bilinear.pyx
@@ -0,0 +1,335 @@
+# -*- coding: utf-8 -*-
+#
+# Project: silx (originally pyFAI)
+# https://github.com/silx-kit/silx
+#
+# Copyright (C) 2012-2017 European Synchrotron Radiation Facility, Grenoble, France
+#
+# 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.
+
+__authors__ = ["J. Kieffer"]
+__license__ = "MIT"
+__date__ = "15/09/2016"
+__doc__ = "Bilinear interpolator, peak finder, line-profile for images"
+
+import cython
+from cython.view cimport array as cvarray
+import numpy
+from libc.math cimport floor, ceil, sin, cos, sqrt, atan2
+import logging
+logger = logging.getLogger("silx.image.bilinear")
+
+
+cdef class BilinearImage:
+ """Bilinear interpolator for images ... or any data on a regular grid
+ """
+ cdef:
+ readonly float[:, ::1] data
+ readonly float maxi, mini
+ readonly size_t width, height
+
+ cpdef size_t coarse_local_maxi(self, size_t)
+ cdef size_t c_local_maxi(self, size_t) nogil
+ cdef float c_funct(self, float, float) nogil
+
+ def __cinit__(self, data not None):
+ """Constructor
+
+ :param data: image as a 2D array
+ """
+ assert data.ndim == 2
+ self.height = data.shape[0]
+ self.width = data.shape[1]
+ self.maxi = data.max()
+ self.mini = data.min()
+ self.data = numpy.ascontiguousarray(data, dtype=numpy.float32)
+
+ def __dealloc__(self):
+ self.data = None
+
+ def __call__(self, coord):
+ """Function f((y, x)) where f is a continuous function
+ made from the image and (y,x)=(row, column) is the pixel coordinates
+ in natural C-order
+
+ :param x: 2-tuple of float (row, column)
+ :return: Interpolated signal from the image
+ """
+ return self.c_funct(coord[1], coord[0])
+
+ @cython.boundscheck(False)
+ @cython.wraparound(False)
+ cdef float c_funct(self, float x, float y) nogil:
+ """Function f(x, y) where f is a continuous function
+ made from the image.
+
+ :param x (float): column coordinate
+ :param y (float): row coordinate
+ :return: Interpolated signal from the image (nearest for outside)
+
+ Cython only function due to NOGIL
+ """
+ cdef:
+ float d0 = min(max(y, 0.0), (self.height - 1.0))
+ float d1 = min(max(x, 0.0), (self.width - 1.0))
+ int i0, i1, j0, j1
+ float x0, x1, y0, y1, res
+
+ x0 = floor(d0)
+ x1 = ceil(d0)
+ y0 = floor(d1)
+ y1 = ceil(d1)
+ i0 = < int > x0
+ i1 = < int > x1
+ j0 = < int > y0
+ j1 = < int > y1
+ if (i0 == i1) and (j0 == j1):
+ res = self.data[i0, j0]
+ elif i0 == i1:
+ res = (self.data[i0, j0] * (y1 - d1)) + (self.data[i0, j1] * (d1 - y0))
+ elif j0 == j1:
+ res = (self.data[i0, j0] * (x1 - d0)) + (self.data[i1, j0] * (d0 - x0))
+ else:
+ res = (self.data[i0, j0] * (x1 - d0) * (y1 - d1)) \
+ + (self.data[i1, j0] * (d0 - x0) * (y1 - d1)) \
+ + (self.data[i0, j1] * (x1 - d0) * (d1 - y0)) \
+ + (self.data[i1, j1] * (d0 - x0) * (d1 - y0))
+ return res
+
+ @cython.boundscheck(False)
+ @cython.wraparound(False)
+ def opp_f(self, coord):
+ """Function -f((y,x)) for peak finding via minimizer.
+
+ Gives large number outside the boundaries to return into the image
+
+ :param x: 2-tuple of float in natural C order, i.e (row, column)
+ :return: Negative interpolated signal from the image
+ """
+ cdef:
+ float d0, d1, res
+ d0, d1 = coord
+ if d0 < 0:
+ res = self.mini + d0
+ elif d1 < 0:
+ res = self.mini + d1
+ elif d0 > (self.height - 1):
+ res = self.mini - d0 + self.height - 1
+ elif d1 > self.width - 1:
+ res = self.mini - d1 + self.width - 1
+ else:
+ res = self.c_funct(d1, d0)
+ return - res
+
+ @cython.boundscheck(False)
+ @cython.wraparound(False)
+ @cython.cdivision(True)
+ def local_maxi(self, coord):
+ """Return the nearest local maximum ... with sub-pixel refinement
+
+ Nearest maximum search:
+ steepest ascent
+
+ Sub-pixel refinement:
+ Second order Taylor expansion of the function;
+ At the maximum, the first derivative is null
+ delta = x-i = -Inverse[Hessian].gradient
+ if Hessian is singular or \|delta\|>1: use a center of mass.
+
+ :param coord: 2-tuple of scalar (row, column)
+ :return: 2-tuple of float with the nearest local maximum
+ """
+ cdef:
+ int res, current0, current1
+ int i0, i1
+ float tmp, sum0 = 0, sum1 = 0, sum = 0
+ float a00, a01, a02, a10, a11, a12, a20, a21, a22
+ float d00, d11, d01, denom, delta0, delta1
+ res = self.c_local_maxi(round(coord[0]) * self.width + round(coord[1]))
+
+ current0 = res // self.width
+ current1 = res % self.width
+ if (current0 > 0) and (current0 < self.height - 1) and (current1 > 0) and (current1 < self.width - 1):
+ # Use second order polynomial Taylor expansion
+ a00 = self.data[current0 - 1, current1 - 1]
+ a01 = self.data[current0 - 1, current1 ]
+ a02 = self.data[current0 - 1, current1 + 1]
+ a10 = self.data[current0 , current1 - 1]
+ a11 = self.data[current0 , current1 ]
+ a12 = self.data[current0 , current1 + 1]
+ a20 = self.data[current0 + 1, current1 - 1]
+ a21 = self.data[current0 + 1, current1 ]
+ a22 = self.data[current0 + 1, current1 - 1]
+ d00 = a12 - 2.0 * a11 + a10
+ d11 = a21 - 2.0 * a11 + a01
+ d01 = (a00 - a02 - a20 + a22) / 4.0
+ denom = 2.0 * (d00 * d11 - d01 * d01)
+ if abs(denom) < 1e-10:
+ logger.debug("Singular determinant, Hessian undefined")
+ else:
+ delta0 = ((a12 - a10) * d01 + (a01 - a21) * d11) / denom
+ delta1 = ((a10 - a12) * d00 + (a21 - a01) * d01) / denom
+ if abs(delta0) <= 1.0 and abs(delta1) <= 1.0:
+ # Result is OK if lower than 0.5.
+ return (delta0 + float(current0), delta1 + float(current1))
+ else:
+ logger.debug("Failed to find root using second order expansion")
+ # refinement of the position by a simple center of mass of the last valid region used
+ for i0 in range(current0 - 1, current0 + 2):
+ for i1 in range(current1 - 1, current1 + 2):
+ tmp = self.data[i0, i1]
+ sum0 += tmp * i0
+ sum1 += tmp * i1
+ sum += tmp
+ if sum > 0:
+ return (sum0 / sum, sum1 / sum)
+
+ return (float(current0), float(current1))
+
+ cpdef size_t coarse_local_maxi(self, size_t x):
+ """Return the nearest local maximum ... without sub-pixel refinement
+
+ :param idx: start index (=row*width+column)
+ :return: local maximum index
+ """
+ return self.c_local_maxi(x)
+
+ @cython.boundscheck(False)
+ @cython.wraparound(False)
+ @cython.cdivision(True)
+ cdef size_t c_local_maxi(self, size_t idx) nogil:
+ """Return the nearest local maximum without sub-pixel refinement
+
+ :param idx: start index (=row*width+column)
+ :return: local maximum index
+
+ This method is Cython only due to the NOGIL
+ """
+ cdef:
+ int current0 = idx // self.width
+ int current1 = idx % self.width
+ int i0, i1, start0, stop0, start1, stop1, new0, new1
+ float tmp, value, old_value
+
+ value = self.data[current0, current1]
+ old_value = value - 1.0
+ new0, new1 = current0, current1
+
+ while value > old_value:
+ old_value = value
+ start0 = max(0, current0 - 1)
+ stop0 = min(self.height, current0 + 2)
+ start1 = max(0, current1 - 1)
+ stop1 = min(self.width, current1 + 2)
+ for i0 in range(start0, stop0):
+ for i1 in range(start1, stop1):
+ tmp = self.data[i0, i1]
+ if tmp > value:
+ new0, new1 = i0, i1
+ value = tmp
+ current0, current1 = new0, new1
+ return self.width * current0 + current1
+
+ @cython.boundscheck(False)
+ def map_coordinates(self, coordinates):
+ """Map coordinates of the array on the image
+
+ :param coordinates: 2-tuple of array of the same size (row_array, column_array)
+ :return: array of values at given coordinates
+ """
+ cdef:
+ float[:] d0, d1, res
+ size_t size, i
+ shape = coordinates[0].shape
+ size = coordinates[0].size
+ d0 = numpy.ascontiguousarray(coordinates[0].ravel(), dtype=numpy.float32)
+ d1 = numpy.ascontiguousarray(coordinates[1].ravel(), dtype=numpy.float32)
+ assert size == d1.size
+ res = numpy.empty(size, dtype=numpy.float32)
+ with nogil:
+ for i in range(size):
+ res[i] = self.c_funct(d1[i], d0[i])
+ return numpy.asarray(res).reshape(shape)
+
+ @cython.boundscheck(False)
+ def profile_line(self, src, dst, int linewidth=1):
+ """Return the intensity profile of an image measured along a scan line.
+
+ :param src: The start point of the scan line.
+ :type src: 2-tuple of numeric scalar
+ :param dst: The end point of the scan line.
+ The destination point is included in the profile,
+ in contrast to standard numpy indexing.
+ :type dst: 2-tuple of numeric scalar
+ :param int linewidth: Width of the scanline (unit image pixel).
+ :return: The intensity profile along the scan line.
+ The length of the profile is the ceil of the computed length
+ of the scan line.
+ :rtype: 1d array
+
+ Inspired from skimage
+ """
+ cdef:
+ float src_row, src_col, dst_row, dst_col, d_row, d_col
+ float length, col_width, row_width, sum, row, col, new_row, new_col
+ int lengt, i, j, cnt
+ float[::1] result
+ src_row, src_col = src
+ dst_row, dst_col = dst
+ if (src_row == dst_row) and (src_col == dst_col):
+ logger.warning("Source and destination points are the same")
+ return numpy.array([self.c_funct(src_col, src_row)])
+ d_row = dst_row - src_row
+ d_col = dst_col - src_col
+
+ # Offsets to deal with linewidth
+ length = sqrt(d_row * d_row + d_col * d_col)
+ row_width = d_col / length
+ col_width = - d_row / length
+
+ lengt = <int> ceil(length + 1)
+ d_row /= <float> (lengt -1)
+ d_col /= <float> (lengt -1)
+
+ result = numpy.zeros(lengt, dtype=numpy.float32)
+
+ # Offset position to the center of the bottom pixels of the profile
+ src_row -= row_width * (linewidth - 1) / 2.
+ src_col -= col_width * (linewidth - 1) / 2.
+
+ with nogil:
+ for i in range(lengt):
+ sum = 0
+ cnt = 0
+
+ row = src_row + i * d_row
+ col = src_col + i * d_col
+
+ for j in range(linewidth):
+ new_row = row + j * row_width
+ new_col = col + j * col_width
+ if ((new_col >= 0) and (new_col < self.width) and
+ (new_row >= 0) and (new_row < self.height)):
+ cnt = cnt + 1
+ sum = sum + self.c_funct(new_col, new_row)
+ if cnt:
+ result[i] += sum / cnt
+
+ # Ensures the result is exported as numpy array and not memory view.
+ return numpy.asarray(result)
diff --git a/silx/image/medianfilter.py b/silx/image/medianfilter.py
new file mode 100644
index 0000000..a986b4d
--- /dev/null
+++ b/silx/image/medianfilter.py
@@ -0,0 +1,111 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2017 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.
+#
+# ############################################################################*/
+
+"""
+This module provides :func:`medfilt2d`, a 2D median filter function
+with the choice between 2 implementations: 'cpp' and 'opencl'.
+"""
+
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "04/05/2017"
+
+from silx.math import medianfilter as medianfilter_cpp
+try:
+ from silx.opencl import medfilt as medfilt_opencl
+except ImportError:
+ medfilt_opencl = None
+import logging
+
+
+_logger = logging.getLogger(__name__)
+
+
+MEDFILT_ENGINES = ['cpp', 'opencl']
+
+
+def medfilt2d(image, kernel_size=3, engine='cpp'):
+ """Apply a median filter on an image.
+
+ This median filter is using a 'nearest' padding for values
+ past the array edges. If you want more padding options or
+ functionalities for the median filter (conditional filter
+ for example) please have a look at
+ :mod:`silx.math.medianfilter`.
+
+ :param numpy.ndarray image: the 2D array for which we want to apply
+ the median filter.
+ :param kernel_size: the dimension of the kernel.
+ Kernel size must be odd.
+ If a scalar is given, then it is used as the size in both dimension.
+ Default: (3, 3)
+ :type kernel_size: A int or a list of 2 int (kernel_height, kernel_width)
+ :param engine: the type of implementation to use.
+ Valid values are: 'cpp' (default) and 'opencl'
+
+ :returns: the array with the median value for each pixel.
+
+ .. note:: if the opencl implementation is requested but
+ is not present or fails, the cpp implementation is called.
+
+ """
+ if engine not in MEDFILT_ENGINES:
+ err = 'silx doesn\'t have an implementation for the requested engine: '
+ err += '%s' % engine
+ raise ValueError(err)
+
+ if len(image.shape) is not 2:
+ raise ValueError('medfilt2d deals with arrays of dimension 2 only')
+
+ if engine == 'cpp':
+ return medianfilter_cpp.medfilt(data=image,
+ kernel_size=kernel_size,
+ conditional=False)
+ elif engine == 'opencl':
+ if medfilt_opencl is None:
+ wrn = 'opencl median filter module import failed'
+ wrn += 'Launching cpp implementation.'
+ _logger.warning(wrn)
+ # instead call the cpp implementation
+ return medianfilter_cpp.medfilt(data=image,
+ kernel_size=kernel_size,
+ conditional=False)
+ else:
+ try:
+ medianfilter = medfilt_opencl.MedianFilter2D(image.shape,
+ devicetype="gpu")
+ res = medianfilter.medfilt2d(image, kernel_size)
+ except(RuntimeError, MemoryError, ImportError):
+ wrn = 'Exception occured in opencl median filter. '
+ wrn += 'To get more information see debug log.'
+ wrn += 'Launching cpp implementation.'
+ _logger.warning(wrn)
+ _logger.debug("median filter - openCL implementation issue.",
+ exc_info=True)
+ # instead call the cpp implementation
+ res = medianfilter_cpp.medfilt(data=image,
+ kernel_size=kernel_size,
+ conditional=False)
+
+ return res
diff --git a/silx/image/setup.py b/silx/image/setup.py
new file mode 100644
index 0000000..6473d9f
--- /dev/null
+++ b/silx/image/setup.py
@@ -0,0 +1,46 @@
+# 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.
+#
+# ############################################################################*/
+
+__authors__ = ["J. Kieffer"]
+__license__ = "MIT"
+__date__ = "18/07/2016"
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('image', parent_package, top_path)
+ config.add_subpackage('test')
+ config.add_extension('bilinear',
+ sources=["bilinear.pyx"],
+ language='c')
+ config.add_extension('shapes',
+ sources=["shapes.pyx"],
+ language='c')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
diff --git a/silx/image/shapes.c b/silx/image/shapes.c
new file mode 100644
index 0000000..19c5913
--- /dev/null
+++ b/silx/image/shapes.c
@@ -0,0 +1,19516 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__silx__image__shapes
+#define __PYX_HAVE_API__silx__image__shapes
+#include "math.h"
+#include "pythread.h"
+#include "string.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+ "silx/image/shapes.pyx",
+ "stringsource",
+};
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_4silx_5image_6shapes_Polygon;
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+
+/* "silx/image/shapes.pyx":49
+ *
+ *
+ * cdef class Polygon(object): # <<<<<<<<<<<<<<
+ * """Define a polygon that provides inside check and mask generation.
+ *
+ */
+struct __pyx_obj_4silx_5image_6shapes_Polygon {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_4silx_5image_6shapes_Polygon *__pyx_vtab;
+ __Pyx_memviewslice vertices;
+ int nvert;
+};
+
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "silx/image/shapes.pyx":49
+ *
+ *
+ * cdef class Polygon(object): # <<<<<<<<<<<<<<
+ * """Define a polygon that provides inside check and mask generation.
+ *
+ */
+
+struct __pyx_vtabstruct_4silx_5image_6shapes_Polygon {
+ int (*c_is_inside)(struct __pyx_obj_4silx_5image_6shapes_Polygon *, float, float);
+};
+static struct __pyx_vtabstruct_4silx_5image_6shapes_Polygon *__pyx_vtabptr_4silx_5image_6shapes_Polygon;
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE unsigned int __Pyx_abs_int(int x) {
+ if (unlikely(x == -INT_MAX-1))
+ return ((unsigned int)INT_MAX) + 1U;
+ return (unsigned int) abs(x);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static PyObject *__pyx_memview_get_float(const char *itemp);
+static int __pyx_memview_set_float(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_char(unsigned char value);
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_As_unsigned_char(PyObject *);
+
+static PyObject *__pyx_memview_get_unsigned_char(const char *itemp);
+static int __pyx_memview_set_unsigned_char(const char *itemp, PyObject *obj);
+
+static PyObject *__pyx_memview_get_int(const char *itemp);
+static int __pyx_memview_set_int(const char *itemp, PyObject *obj);
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_float(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_unsigned_char(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_int(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static int __pyx_f_4silx_5image_6shapes_7Polygon_c_is_inside(struct __pyx_obj_4silx_5image_6shapes_Polygon *__pyx_v_self, float __pyx_v_row, float __pyx_v_col); /* proto*/
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'libc.math' */
+
+/* Module declarations from 'silx.image.shapes' */
+static PyTypeObject *__pyx_ptype_4silx_5image_6shapes_Polygon = 0;
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_float = { "float", NULL, sizeof(float), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_unsigned_char = { "unsigned char", NULL, sizeof(unsigned char), { 0 }, 0, IS_UNSIGNED(unsigned char) ? 'U' : 'I', IS_UNSIGNED(unsigned char), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_int = { "int", NULL, sizeof(int), { 0 }, 0, IS_UNSIGNED(int) ? 'U' : 'I', IS_UNSIGNED(int), 0 };
+#define __Pyx_MODULE_NAME "silx.image.shapes"
+int __pyx_module_is_main_silx__image__shapes = 0;
+
+/* Implementation of 'silx.image.shapes' */
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_min;
+static PyObject *__pyx_builtin_max;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_builtin_IndexError;
+static int __pyx_pf_4silx_5image_6shapes_7Polygon___init__(struct __pyx_obj_4silx_5image_6shapes_Polygon *__pyx_v_self, PyObject *__pyx_v_vertices); /* proto */
+static PyObject *__pyx_pf_4silx_5image_6shapes_7Polygon_2is_inside(struct __pyx_obj_4silx_5image_6shapes_Polygon *__pyx_v_self, PyObject *__pyx_v_row, PyObject *__pyx_v_col); /* proto */
+static PyObject *__pyx_pf_4silx_5image_6shapes_7Polygon_4make_mask(struct __pyx_obj_4silx_5image_6shapes_Polygon *__pyx_v_self, int __pyx_v_height, int __pyx_v_width); /* proto */
+static PyObject *__pyx_pf_4silx_5image_6shapes_polygon_fill_mask(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vertices, PyObject *__pyx_v_shape); /* proto */
+static PyObject *__pyx_pf_4silx_5image_6shapes_2draw_line(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_row0, int __pyx_v_col0, int __pyx_v_row1, int __pyx_v_col1, int __pyx_v_width); /* proto */
+static PyObject *__pyx_pf_4silx_5image_6shapes_4circle_fill(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_crow, int __pyx_v_ccol, float __pyx_v_radius); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_4silx_5image_6shapes_Polygon(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_O[] = "O";
+static char __pyx_k_a[] = "a";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_c[] = "c";
+static char __pyx_k_da[] = "da";
+static char __pyx_k_db[] = "db";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k_col[] = "col";
+static char __pyx_k_dev[] = "dev";
+static char __pyx_k_max[] = "max";
+static char __pyx_k_min[] = "min";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_row[] = "row";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_ccol[] = "ccol";
+static char __pyx_k_col0[] = "col0";
+static char __pyx_k_col1[] = "col1";
+static char __pyx_k_cols[] = "cols";
+static char __pyx_k_crow[] = "crow";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_dcol[] = "dcol";
+static char __pyx_k_drow[] = "drow";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_row0[] = "row0";
+static char __pyx_k_row1[] = "row1";
+static char __pyx_k_rows[] = "rows";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_delta[] = "delta";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_empty[] = "empty";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_index[] = "index";
+static char __pyx_k_int32[] = "int32";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_uint8[] = "uint8";
+static char __pyx_k_where[] = "where";
+static char __pyx_k_width[] = "width";
+static char __pyx_k_zeros[] = "zeros";
+static char __pyx_k_arange[] = "arange";
+static char __pyx_k_coords[] = "coords";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_height[] = "height";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_offset[] = "offset";
+static char __pyx_k_radius[] = "radius";
+static char __pyx_k_status[] = "__status__";
+static char __pyx_k_step_a[] = "step_a";
+static char __pyx_k_step_b[] = "step_b";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_asarray[] = "asarray";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_float32[] = "float32";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_a_coords[] = "a_coords";
+static char __pyx_k_b_coords[] = "b_coords";
+static char __pyx_k_i_radius[] = "i_radius";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_vertices[] = "vertices";
+static char __pyx_k_T_Vincent[] = "T. Vincent";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_draw_line[] = "draw_line";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_make_mask[] = "make_mask";
+static char __pyx_k_03_06_2016[] = "03/06/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_len_coords[] = "len_coords";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_circle_fill[] = "circle_fill";
+static char __pyx_k_Jrme_Kieffer[] = "J\303\251r\303\264me Kieffer";
+static char __pyx_k_invert_coords[] = "invert_coords";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_ascontiguousarray[] = "ascontiguousarray";
+static char __pyx_k_polygon_fill_mask[] = "polygon_fill_mask";
+static char __pyx_k_silx_image_shapes[] = "silx.image.shapes";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_mntdirect__scisoft_users_tvince[] = "/mntdirect/_scisoft/users/tvincent/src/silx/silx/image/shapes.pyx";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_This_module_provides_functions_m[] = "This module provides functions making masks on an image.\n\n- :func:`circle_fill` function generates coordinates of a circle in an image.\n- :func:`draw_line` function generates coordinates of a line in an image.\n- :func:`polygon_fill_mask` function generates a mask from a set of points\n defining a polygon.\n\nThe :class:`Polygon` class provides checking if a point is inside a polygon.\n\nThe whole module uses the (row, col) (i.e., (y, x))) convention\nfor 2D coordinates.\n";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static PyObject *__pyx_kp_s_03_06_2016;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_kp_s_Jrme_Kieffer;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_kp_s_T_Vincent;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_n_s_a;
+static PyObject *__pyx_n_s_a_coords;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_arange;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_asarray;
+static PyObject *__pyx_n_s_ascontiguousarray;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_b;
+static PyObject *__pyx_n_s_b_coords;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_ccol;
+static PyObject *__pyx_n_s_circle_fill;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_n_s_col;
+static PyObject *__pyx_n_s_col0;
+static PyObject *__pyx_n_s_col1;
+static PyObject *__pyx_n_s_cols;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_coords;
+static PyObject *__pyx_n_s_crow;
+static PyObject *__pyx_n_s_da;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_db;
+static PyObject *__pyx_n_s_dcol;
+static PyObject *__pyx_n_s_delta;
+static PyObject *__pyx_n_s_dev;
+static PyObject *__pyx_n_s_draw_line;
+static PyObject *__pyx_n_s_drow;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_empty;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float32;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_height;
+static PyObject *__pyx_n_s_i_radius;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_index;
+static PyObject *__pyx_n_s_int32;
+static PyObject *__pyx_n_s_invert_coords;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_len_coords;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_make_mask;
+static PyObject *__pyx_n_s_max;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_n_s_min;
+static PyObject *__pyx_kp_s_mntdirect__scisoft_users_tvince;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_n_s_offset;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_n_s_polygon_fill_mask;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_radius;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_row;
+static PyObject *__pyx_n_s_row0;
+static PyObject *__pyx_n_s_row1;
+static PyObject *__pyx_n_s_rows;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_silx_image_shapes;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_status;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_step_a;
+static PyObject *__pyx_n_s_step_b;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_n_s_uint8;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_n_s_vertices;
+static PyObject *__pyx_n_s_where;
+static PyObject *__pyx_n_s_width;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_n_s_zeros;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__12;
+static PyObject *__pyx_slice__13;
+static PyObject *__pyx_slice__14;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__26;
+static PyObject *__pyx_codeobj__17;
+static PyObject *__pyx_codeobj__19;
+static PyObject *__pyx_codeobj__21;
+
+/* "silx/image/shapes.pyx":59
+ * cdef int nvert
+ *
+ * def __init__(self, vertices): # <<<<<<<<<<<<<<
+ * self.vertices = numpy.ascontiguousarray(vertices, dtype=numpy.float32)
+ * self.nvert = self.vertices.shape[0]
+ */
+
+/* Python wrapper */
+static int __pyx_pw_4silx_5image_6shapes_7Polygon_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_4silx_5image_6shapes_7Polygon_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_vertices = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_vertices,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_vertices)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_vertices = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.shapes.Polygon.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_5image_6shapes_7Polygon___init__(((struct __pyx_obj_4silx_5image_6shapes_Polygon *)__pyx_v_self), __pyx_v_vertices);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_4silx_5image_6shapes_7Polygon___init__(struct __pyx_obj_4silx_5image_6shapes_Polygon *__pyx_v_self, PyObject *__pyx_v_vertices) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ __Pyx_memviewslice __pyx_t_6 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "silx/image/shapes.pyx":60
+ *
+ * def __init__(self, vertices):
+ * self.vertices = numpy.ascontiguousarray(vertices, dtype=numpy.float32) # <<<<<<<<<<<<<<
+ * self.nvert = self.vertices.shape[0]
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_vertices);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_vertices);
+ __Pyx_GIVEREF(__pyx_v_vertices);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_float(__pyx_t_5);
+ if (unlikely(!__pyx_t_6.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_self->vertices, 0);
+ __pyx_v_self->vertices = __pyx_t_6;
+ __pyx_t_6.memview = NULL;
+ __pyx_t_6.data = NULL;
+
+ /* "silx/image/shapes.pyx":61
+ * def __init__(self, vertices):
+ * self.vertices = numpy.ascontiguousarray(vertices, dtype=numpy.float32)
+ * self.nvert = self.vertices.shape[0] # <<<<<<<<<<<<<<
+ *
+ * def is_inside(self, row, col):
+ */
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_v_self->nvert = (__pyx_v_self->vertices.shape[0]);
+
+ /* "silx/image/shapes.pyx":59
+ * cdef int nvert
+ *
+ * def __init__(self, vertices): # <<<<<<<<<<<<<<
+ * self.vertices = numpy.ascontiguousarray(vertices, dtype=numpy.float32)
+ * self.nvert = self.vertices.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
+ __Pyx_AddTraceback("silx.image.shapes.Polygon.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/shapes.pyx":63
+ * self.nvert = self.vertices.shape[0]
+ *
+ * def is_inside(self, row, col): # <<<<<<<<<<<<<<
+ * """Check if (row, col) is inside or outside the polygon
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_6shapes_7Polygon_3is_inside(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_5image_6shapes_7Polygon_2is_inside[] = "Polygon.is_inside(self, row, col)\nCheck if (row, col) is inside or outside the polygon\n\n :param float row:\n :param float col:\n :return: True if position is inside polygon, False otherwise\n ";
+static PyObject *__pyx_pw_4silx_5image_6shapes_7Polygon_3is_inside(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_row = 0;
+ PyObject *__pyx_v_col = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_inside (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_row,&__pyx_n_s_col,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_row)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_col)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("is_inside", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "is_inside") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_row = values[0];
+ __pyx_v_col = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("is_inside", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.shapes.Polygon.is_inside", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_5image_6shapes_7Polygon_2is_inside(((struct __pyx_obj_4silx_5image_6shapes_Polygon *)__pyx_v_self), __pyx_v_row, __pyx_v_col);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_6shapes_7Polygon_2is_inside(struct __pyx_obj_4silx_5image_6shapes_Polygon *__pyx_v_self, PyObject *__pyx_v_row, PyObject *__pyx_v_col) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ float __pyx_t_1;
+ float __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_inside", 0);
+
+ /* "silx/image/shapes.pyx":70
+ * :return: True if position is inside polygon, False otherwise
+ * """
+ * return self.c_is_inside(row, col) # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_PyFloat_AsFloat(__pyx_v_row); if (unlikely((__pyx_t_1 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __pyx_PyFloat_AsFloat(__pyx_v_col); if (unlikely((__pyx_t_2 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __Pyx_PyBool_FromLong(((struct __pyx_vtabstruct_4silx_5image_6shapes_Polygon *)__pyx_v_self->__pyx_vtab)->c_is_inside(__pyx_v_self, __pyx_t_1, __pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "silx/image/shapes.pyx":63
+ * self.nvert = self.vertices.shape[0]
+ *
+ * def is_inside(self, row, col): # <<<<<<<<<<<<<<
+ * """Check if (row, col) is inside or outside the polygon
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("silx.image.shapes.Polygon.is_inside", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/shapes.pyx":75
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * cdef bint c_is_inside(self, float row, float col) nogil: # <<<<<<<<<<<<<<
+ * """Check if (row, col) is inside or outside the polygon
+ *
+ */
+
+static int __pyx_f_4silx_5image_6shapes_7Polygon_c_is_inside(struct __pyx_obj_4silx_5image_6shapes_Polygon *__pyx_v_self, float __pyx_v_row, float __pyx_v_col) {
+ int __pyx_v_index;
+ int __pyx_v_is_inside;
+ float __pyx_v_pt1x;
+ float __pyx_v_pt1y;
+ float __pyx_v_pt2x;
+ float __pyx_v_pt2y;
+ float __pyx_v_xinters;
+ int __pyx_r;
+ long __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ float __pyx_t_13;
+ float __pyx_t_14;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "silx/image/shapes.pyx":86
+ * cdef int index, is_inside
+ * cdef float pt1x, pt1y, pt2x, pt2y, xinters
+ * is_inside = 0 # <<<<<<<<<<<<<<
+ *
+ * pt1x = self.vertices[self.nvert-1, 1]
+ */
+ __pyx_v_is_inside = 0;
+
+ /* "silx/image/shapes.pyx":88
+ * is_inside = 0
+ *
+ * pt1x = self.vertices[self.nvert-1, 1] # <<<<<<<<<<<<<<
+ * pt1y = self.vertices[self.nvert-1, 0]
+ * for index in range(self.nvert):
+ */
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_1 = (__pyx_v_self->nvert - 1);
+ __pyx_t_2 = 1;
+ __pyx_v_pt1x = (*((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->vertices.data + __pyx_t_1 * __pyx_v_self->vertices.strides[0]) ) + __pyx_t_2 * __pyx_v_self->vertices.strides[1]) )));
+
+ /* "silx/image/shapes.pyx":89
+ *
+ * pt1x = self.vertices[self.nvert-1, 1]
+ * pt1y = self.vertices[self.nvert-1, 0] # <<<<<<<<<<<<<<
+ * for index in range(self.nvert):
+ * pt2x = self.vertices[index, 1]
+ */
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_3 = (__pyx_v_self->nvert - 1);
+ __pyx_t_4 = 0;
+ __pyx_v_pt1y = (*((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->vertices.data + __pyx_t_3 * __pyx_v_self->vertices.strides[0]) ) + __pyx_t_4 * __pyx_v_self->vertices.strides[1]) )));
+
+ /* "silx/image/shapes.pyx":90
+ * pt1x = self.vertices[self.nvert-1, 1]
+ * pt1y = self.vertices[self.nvert-1, 0]
+ * for index in range(self.nvert): # <<<<<<<<<<<<<<
+ * pt2x = self.vertices[index, 1]
+ * pt2y = self.vertices[index, 0]
+ */
+ __pyx_t_5 = __pyx_v_self->nvert;
+ for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "silx/image/shapes.pyx":91
+ * pt1y = self.vertices[self.nvert-1, 0]
+ * for index in range(self.nvert):
+ * pt2x = self.vertices[index, 1] # <<<<<<<<<<<<<<
+ * pt2y = self.vertices[index, 0]
+ *
+ */
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_t_8 = 1;
+ __pyx_v_pt2x = (*((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->vertices.data + __pyx_t_7 * __pyx_v_self->vertices.strides[0]) ) + __pyx_t_8 * __pyx_v_self->vertices.strides[1]) )));
+
+ /* "silx/image/shapes.pyx":92
+ * for index in range(self.nvert):
+ * pt2x = self.vertices[index, 1]
+ * pt2y = self.vertices[index, 0] # <<<<<<<<<<<<<<
+ *
+ * if (((pt1y <= row and row < pt2y) or
+ */
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_t_10 = 0;
+ __pyx_v_pt2y = (*((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->vertices.data + __pyx_t_9 * __pyx_v_self->vertices.strides[0]) ) + __pyx_t_10 * __pyx_v_self->vertices.strides[1]) )));
+
+ /* "silx/image/shapes.pyx":94
+ * pt2y = self.vertices[index, 0]
+ *
+ * if (((pt1y <= row and row < pt2y) or # <<<<<<<<<<<<<<
+ * (pt2y <= row and row < pt1y)) and
+ * # Extra (optional) condition to avoid some computation
+ */
+ __pyx_t_12 = ((__pyx_v_pt1y <= __pyx_v_row) != 0);
+ if (!__pyx_t_12) {
+ goto __pyx_L8_next_or;
+ } else {
+ }
+ __pyx_t_12 = ((__pyx_v_row < __pyx_v_pt2y) != 0);
+ if (!__pyx_t_12) {
+ } else {
+ goto __pyx_L7_next_and;
+ }
+ __pyx_L8_next_or:;
+
+ /* "silx/image/shapes.pyx":95
+ *
+ * if (((pt1y <= row and row < pt2y) or
+ * (pt2y <= row and row < pt1y)) and # <<<<<<<<<<<<<<
+ * # Extra (optional) condition to avoid some computation
+ * (col <= pt1x or col <= pt2x)):
+ */
+ __pyx_t_12 = ((__pyx_v_pt2y <= __pyx_v_row) != 0);
+ if (__pyx_t_12) {
+ } else {
+ __pyx_t_11 = __pyx_t_12;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_12 = ((__pyx_v_row < __pyx_v_pt1y) != 0);
+ if (__pyx_t_12) {
+ } else {
+ __pyx_t_11 = __pyx_t_12;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_L7_next_and:;
+
+ /* "silx/image/shapes.pyx":97
+ * (pt2y <= row and row < pt1y)) and
+ * # Extra (optional) condition to avoid some computation
+ * (col <= pt1x or col <= pt2x)): # <<<<<<<<<<<<<<
+ * xinters = (row - pt1y) * (pt2x - pt1x) / (pt2y - pt1y) + pt1x
+ * is_inside ^= col < xinters
+ */
+ __pyx_t_12 = ((__pyx_v_col <= __pyx_v_pt1x) != 0);
+ if (!__pyx_t_12) {
+ } else {
+ __pyx_t_11 = __pyx_t_12;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_12 = ((__pyx_v_col <= __pyx_v_pt2x) != 0);
+ __pyx_t_11 = __pyx_t_12;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_11) {
+
+ /* "silx/image/shapes.pyx":98
+ * # Extra (optional) condition to avoid some computation
+ * (col <= pt1x or col <= pt2x)):
+ * xinters = (row - pt1y) * (pt2x - pt1x) / (pt2y - pt1y) + pt1x # <<<<<<<<<<<<<<
+ * is_inside ^= col < xinters
+ * pt1x, pt1y = pt2x, pt2y
+ */
+ __pyx_v_xinters = ((((__pyx_v_row - __pyx_v_pt1y) * (__pyx_v_pt2x - __pyx_v_pt1x)) / (__pyx_v_pt2y - __pyx_v_pt1y)) + __pyx_v_pt1x);
+
+ /* "silx/image/shapes.pyx":99
+ * (col <= pt1x or col <= pt2x)):
+ * xinters = (row - pt1y) * (pt2x - pt1x) / (pt2y - pt1y) + pt1x
+ * is_inside ^= col < xinters # <<<<<<<<<<<<<<
+ * pt1x, pt1y = pt2x, pt2y
+ * return is_inside
+ */
+ __pyx_v_is_inside = (__pyx_v_is_inside ^ (__pyx_v_col < __pyx_v_xinters));
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "silx/image/shapes.pyx":100
+ * xinters = (row - pt1y) * (pt2x - pt1x) / (pt2y - pt1y) + pt1x
+ * is_inside ^= col < xinters
+ * pt1x, pt1y = pt2x, pt2y # <<<<<<<<<<<<<<
+ * return is_inside
+ *
+ */
+ __pyx_t_13 = __pyx_v_pt2x;
+ __pyx_t_14 = __pyx_v_pt2y;
+ __pyx_v_pt1x = __pyx_t_13;
+ __pyx_v_pt1y = __pyx_t_14;
+ }
+
+ /* "silx/image/shapes.pyx":101
+ * is_inside ^= col < xinters
+ * pt1x, pt1y = pt2x, pt2y
+ * return is_inside # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = __pyx_v_is_inside;
+ goto __pyx_L0;
+
+ /* "silx/image/shapes.pyx":75
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * cdef bint c_is_inside(self, float row, float col) nogil: # <<<<<<<<<<<<<<
+ * """Check if (row, col) is inside or outside the polygon
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_WriteUnraisable("silx.image.shapes.Polygon.c_is_inside", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "silx/image/shapes.pyx":106
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * def make_mask(self, int height, int width): # <<<<<<<<<<<<<<
+ * """Create a mask array representing the filled polygon
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_6shapes_7Polygon_5make_mask(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_5image_6shapes_7Polygon_4make_mask[] = "Polygon.make_mask(self, int height, int width)\nCreate a mask array representing the filled polygon\n\n :param int height: Height of the mask array\n :param int width: Width of the mask array\n :return: 2D array (height, width)\n ";
+static PyObject *__pyx_pw_4silx_5image_6shapes_7Polygon_5make_mask(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ int __pyx_v_height;
+ int __pyx_v_width;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("make_mask (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_height,&__pyx_n_s_width,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_height)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_width)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("make_mask", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "make_mask") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_height = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_height == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_width = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_width == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("make_mask", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.shapes.Polygon.make_mask", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_5image_6shapes_7Polygon_4make_mask(((struct __pyx_obj_4silx_5image_6shapes_Polygon *)__pyx_v_self), __pyx_v_height, __pyx_v_width);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_6shapes_7Polygon_4make_mask(struct __pyx_obj_4silx_5image_6shapes_Polygon *__pyx_v_self, int __pyx_v_height, int __pyx_v_width) {
+ __Pyx_memviewslice __pyx_v_mask = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_row_min;
+ int __pyx_v_row_max;
+ int __pyx_v_col_min;
+ int __pyx_v_col_max;
+ int __pyx_v_row;
+ int __pyx_v_col;
+ int __pyx_v_index;
+ float __pyx_v_pt1x;
+ float __pyx_v_pt1y;
+ float __pyx_v_pt2x;
+ float __pyx_v_pt2y;
+ int __pyx_v_xinters;
+ int __pyx_v_is_inside;
+ int __pyx_v_current;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ __Pyx_memviewslice __pyx_t_6 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ long __pyx_t_7;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __Pyx_memviewslice __pyx_t_12 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ long __pyx_t_15;
+ Py_ssize_t __pyx_t_16;
+ int __pyx_t_17;
+ int __pyx_t_18;
+ int __pyx_t_19;
+ Py_ssize_t __pyx_t_20;
+ int __pyx_t_21;
+ Py_ssize_t __pyx_t_22;
+ int __pyx_t_23;
+ int __pyx_t_24;
+ int __pyx_t_25;
+ float __pyx_t_26;
+ float __pyx_t_27;
+ long __pyx_t_28;
+ int __pyx_t_29;
+ int __pyx_t_30;
+ int __pyx_t_31;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("make_mask", 0);
+
+ /* "silx/image/shapes.pyx":113
+ * :return: 2D array (height, width)
+ * """
+ * cdef unsigned char[:, :] mask = numpy.zeros((height, width), # <<<<<<<<<<<<<<
+ * dtype=numpy.uint8)
+ * cdef int row_min, row_max, col_min, col_max # mask subpart to update
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_height); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_width); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+
+ /* "silx/image/shapes.pyx":114
+ * """
+ * cdef unsigned char[:, :] mask = numpy.zeros((height, width),
+ * dtype=numpy.uint8) # <<<<<<<<<<<<<<
+ * cdef int row_min, row_max, col_min, col_max # mask subpart to update
+ * cdef int row, col, index # Loop indixes
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_uint8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "silx/image/shapes.pyx":113
+ * :return: 2D array (height, width)
+ * """
+ * cdef unsigned char[:, :] mask = numpy.zeros((height, width), # <<<<<<<<<<<<<<
+ * dtype=numpy.uint8)
+ * cdef int row_min, row_max, col_min, col_max # mask subpart to update
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dsds_unsigned_char(__pyx_t_5);
+ if (unlikely(!__pyx_t_6.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_mask = __pyx_t_6;
+ __pyx_t_6.memview = NULL;
+ __pyx_t_6.data = NULL;
+
+ /* "silx/image/shapes.pyx":120
+ * cdef int xinters, is_inside, current
+ *
+ * row_min = max(int(min(self.vertices[:, 0])), 0) # <<<<<<<<<<<<<<
+ * row_max = min(int(max(self.vertices[:, 0])) + 1, height)
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_8 = __pyx_v_self->vertices;
+ __PYX_INC_MEMVIEW(&__pyx_t_8, 1);
+ __pyx_t_10 = -1;
+ __pyx_t_9.data = __pyx_t_8.data;
+ __pyx_t_9.memview = __pyx_t_8.memview;
+ __PYX_INC_MEMVIEW(&__pyx_t_9, 0);
+ __pyx_t_9.shape[0] = __pyx_t_8.shape[0];
+__pyx_t_9.strides[0] = __pyx_t_8.strides[0];
+ __pyx_t_9.suboffsets[0] = -1;
+
+{
+ Py_ssize_t __pyx_tmp_idx = 0;
+ Py_ssize_t __pyx_tmp_shape = __pyx_t_8.shape[1];
+ Py_ssize_t __pyx_tmp_stride = __pyx_t_8.strides[1];
+ if (0 && (__pyx_tmp_idx < 0))
+ __pyx_tmp_idx += __pyx_tmp_shape;
+ if (0 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
+ PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 1)");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9.data += __pyx_tmp_idx * __pyx_tmp_stride;
+}
+
+__PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __pyx_t_5 = __pyx_memoryview_fromslice(__pyx_t_9, 1, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_min, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyNumber_Int(__pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_3 = __Pyx_PyInt_From_long(__pyx_t_7); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_t_4, Py_GT); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (__pyx_t_11) {
+ __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_t_7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __pyx_t_2;
+ __pyx_t_2 = 0;
+ } else {
+ __Pyx_INCREF(__pyx_t_4);
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_10 = __Pyx_PyInt_As_int(__pyx_t_5); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_row_min = __pyx_t_10;
+
+ /* "silx/image/shapes.pyx":121
+ *
+ * row_min = max(int(min(self.vertices[:, 0])), 0)
+ * row_max = min(int(max(self.vertices[:, 0])) + 1, height) # <<<<<<<<<<<<<<
+ *
+ * # Can be replaced by prange(row_min, row_max, nogil=True)
+ */
+ __pyx_t_10 = __pyx_v_height;
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}}
+ __pyx_t_8 = __pyx_v_self->vertices;
+ __PYX_INC_MEMVIEW(&__pyx_t_8, 1);
+ __pyx_t_13 = -1;
+ __pyx_t_12.data = __pyx_t_8.data;
+ __pyx_t_12.memview = __pyx_t_8.memview;
+ __PYX_INC_MEMVIEW(&__pyx_t_12, 0);
+ __pyx_t_12.shape[0] = __pyx_t_8.shape[0];
+__pyx_t_12.strides[0] = __pyx_t_8.strides[0];
+ __pyx_t_12.suboffsets[0] = -1;
+
+{
+ Py_ssize_t __pyx_tmp_idx = 0;
+ Py_ssize_t __pyx_tmp_shape = __pyx_t_8.shape[1];
+ Py_ssize_t __pyx_tmp_stride = __pyx_t_8.strides[1];
+ if (0 && (__pyx_tmp_idx < 0))
+ __pyx_tmp_idx += __pyx_tmp_shape;
+ if (0 && (__pyx_tmp_idx < 0 || __pyx_tmp_idx >= __pyx_tmp_shape)) {
+ PyErr_SetString(PyExc_IndexError, "Index out of bounds (axis 1)");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_12.data += __pyx_tmp_idx * __pyx_tmp_stride;
+}
+
+__PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __pyx_t_5 = __pyx_memoryview_fromslice(__pyx_t_12, 1, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_12, 1);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_max, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyNumber_Int(__pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyNumber_Add(__pyx_t_4, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_t_5, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_11) {
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_t_10); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __pyx_t_3;
+ __pyx_t_3 = 0;
+ } else {
+ __Pyx_INCREF(__pyx_t_5);
+ __pyx_t_4 = __pyx_t_5;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_10 = __Pyx_PyInt_As_int(__pyx_t_4); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_row_max = __pyx_t_10;
+
+ /* "silx/image/shapes.pyx":124
+ *
+ * # Can be replaced by prange(row_min, row_max, nogil=True)
+ * with nogil: # <<<<<<<<<<<<<<
+ * for row in range(row_min, row_max):
+ * # For each line of the image, mark intersection of all segments
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "silx/image/shapes.pyx":125
+ * # Can be replaced by prange(row_min, row_max, nogil=True)
+ * with nogil:
+ * for row in range(row_min, row_max): # <<<<<<<<<<<<<<
+ * # For each line of the image, mark intersection of all segments
+ * # in the line and then run a xor scan to fill inner parts
+ */
+ __pyx_t_10 = __pyx_v_row_max;
+ for (__pyx_t_13 = __pyx_v_row_min; __pyx_t_13 < __pyx_t_10; __pyx_t_13+=1) {
+ __pyx_v_row = __pyx_t_13;
+
+ /* "silx/image/shapes.pyx":129
+ * # in the line and then run a xor scan to fill inner parts
+ * # Adapted from http://alienryderflex.com/polygon_fill/
+ * pt1x = self.vertices[self.nvert-1, 1] # <<<<<<<<<<<<<<
+ * pt1y = self.vertices[self.nvert-1, 0]
+ * col_min = width - 1
+ */
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L4_error;}}
+ __pyx_t_7 = (__pyx_v_self->nvert - 1);
+ __pyx_t_14 = 1;
+ __pyx_v_pt1x = (*((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->vertices.data + __pyx_t_7 * __pyx_v_self->vertices.strides[0]) ) + __pyx_t_14 * __pyx_v_self->vertices.strides[1]) )));
+
+ /* "silx/image/shapes.pyx":130
+ * # Adapted from http://alienryderflex.com/polygon_fill/
+ * pt1x = self.vertices[self.nvert-1, 1]
+ * pt1y = self.vertices[self.nvert-1, 0] # <<<<<<<<<<<<<<
+ * col_min = width - 1
+ * col_max = 0
+ */
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L4_error;}}
+ __pyx_t_15 = (__pyx_v_self->nvert - 1);
+ __pyx_t_16 = 0;
+ __pyx_v_pt1y = (*((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->vertices.data + __pyx_t_15 * __pyx_v_self->vertices.strides[0]) ) + __pyx_t_16 * __pyx_v_self->vertices.strides[1]) )));
+
+ /* "silx/image/shapes.pyx":131
+ * pt1x = self.vertices[self.nvert-1, 1]
+ * pt1y = self.vertices[self.nvert-1, 0]
+ * col_min = width - 1 # <<<<<<<<<<<<<<
+ * col_max = 0
+ * is_inside = 0 # Init with whether first col is inside or not
+ */
+ __pyx_v_col_min = (__pyx_v_width - 1);
+
+ /* "silx/image/shapes.pyx":132
+ * pt1y = self.vertices[self.nvert-1, 0]
+ * col_min = width - 1
+ * col_max = 0 # <<<<<<<<<<<<<<
+ * is_inside = 0 # Init with whether first col is inside or not
+ *
+ */
+ __pyx_v_col_max = 0;
+
+ /* "silx/image/shapes.pyx":133
+ * col_min = width - 1
+ * col_max = 0
+ * is_inside = 0 # Init with whether first col is inside or not # <<<<<<<<<<<<<<
+ *
+ * for index in range(self.nvert):
+ */
+ __pyx_v_is_inside = 0;
+
+ /* "silx/image/shapes.pyx":135
+ * is_inside = 0 # Init with whether first col is inside or not
+ *
+ * for index in range(self.nvert): # <<<<<<<<<<<<<<
+ * pt2x = self.vertices[index, 1]
+ * pt2y = self.vertices[index, 0]
+ */
+ __pyx_t_17 = __pyx_v_self->nvert;
+ for (__pyx_t_18 = 0; __pyx_t_18 < __pyx_t_17; __pyx_t_18+=1) {
+ __pyx_v_index = __pyx_t_18;
+
+ /* "silx/image/shapes.pyx":136
+ *
+ * for index in range(self.nvert):
+ * pt2x = self.vertices[index, 1] # <<<<<<<<<<<<<<
+ * pt2y = self.vertices[index, 0]
+ *
+ */
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L4_error;}}
+ __pyx_t_19 = __pyx_v_index;
+ __pyx_t_20 = 1;
+ __pyx_v_pt2x = (*((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->vertices.data + __pyx_t_19 * __pyx_v_self->vertices.strides[0]) ) + __pyx_t_20 * __pyx_v_self->vertices.strides[1]) )));
+
+ /* "silx/image/shapes.pyx":137
+ * for index in range(self.nvert):
+ * pt2x = self.vertices[index, 1]
+ * pt2y = self.vertices[index, 0] # <<<<<<<<<<<<<<
+ *
+ * if ((pt1y <= row and row < pt2y) or
+ */
+ if (unlikely(!__pyx_v_self->vertices.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");{__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L4_error;}}
+ __pyx_t_21 = __pyx_v_index;
+ __pyx_t_22 = 0;
+ __pyx_v_pt2y = (*((float *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_self->vertices.data + __pyx_t_21 * __pyx_v_self->vertices.strides[0]) ) + __pyx_t_22 * __pyx_v_self->vertices.strides[1]) )));
+
+ /* "silx/image/shapes.pyx":139
+ * pt2y = self.vertices[index, 0]
+ *
+ * if ((pt1y <= row and row < pt2y) or # <<<<<<<<<<<<<<
+ * (pt2y <= row and row < pt1y)):
+ * # Intersection casted to int so that ]x, x+1] => x
+ */
+ __pyx_t_23 = ((__pyx_v_pt1y <= __pyx_v_row) != 0);
+ if (!__pyx_t_23) {
+ goto __pyx_L12_next_or;
+ } else {
+ }
+ __pyx_t_23 = ((__pyx_v_row < __pyx_v_pt2y) != 0);
+ if (!__pyx_t_23) {
+ } else {
+ __pyx_t_11 = __pyx_t_23;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_L12_next_or:;
+
+ /* "silx/image/shapes.pyx":140
+ *
+ * if ((pt1y <= row and row < pt2y) or
+ * (pt2y <= row and row < pt1y)): # <<<<<<<<<<<<<<
+ * # Intersection casted to int so that ]x, x+1] => x
+ * xinters = (<int>ceil(pt1x + (row - pt1y) *
+ */
+ __pyx_t_23 = ((__pyx_v_pt2y <= __pyx_v_row) != 0);
+ if (__pyx_t_23) {
+ } else {
+ __pyx_t_11 = __pyx_t_23;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_23 = ((__pyx_v_row < __pyx_v_pt1y) != 0);
+ __pyx_t_11 = __pyx_t_23;
+ __pyx_L11_bool_binop_done:;
+ if (__pyx_t_11) {
+
+ /* "silx/image/shapes.pyx":143
+ * # Intersection casted to int so that ]x, x+1] => x
+ * xinters = (<int>ceil(pt1x + (row - pt1y) *
+ * (pt2x - pt1x) / (pt2y - pt1y))) - 1 # <<<<<<<<<<<<<<
+ *
+ * # Update column range to patch
+ */
+ __pyx_v_xinters = (((int)ceil((__pyx_v_pt1x + (((__pyx_v_row - __pyx_v_pt1y) * (__pyx_v_pt2x - __pyx_v_pt1x)) / (__pyx_v_pt2y - __pyx_v_pt1y))))) - 1);
+
+ /* "silx/image/shapes.pyx":146
+ *
+ * # Update column range to patch
+ * if xinters < col_min: # <<<<<<<<<<<<<<
+ * col_min = xinters
+ * if xinters > col_max:
+ */
+ __pyx_t_11 = ((__pyx_v_xinters < __pyx_v_col_min) != 0);
+ if (__pyx_t_11) {
+
+ /* "silx/image/shapes.pyx":147
+ * # Update column range to patch
+ * if xinters < col_min:
+ * col_min = xinters # <<<<<<<<<<<<<<
+ * if xinters > col_max:
+ * col_max = xinters
+ */
+ __pyx_v_col_min = __pyx_v_xinters;
+ goto __pyx_L15;
+ }
+ __pyx_L15:;
+
+ /* "silx/image/shapes.pyx":148
+ * if xinters < col_min:
+ * col_min = xinters
+ * if xinters > col_max: # <<<<<<<<<<<<<<
+ * col_max = xinters
+ *
+ */
+ __pyx_t_11 = ((__pyx_v_xinters > __pyx_v_col_max) != 0);
+ if (__pyx_t_11) {
+
+ /* "silx/image/shapes.pyx":149
+ * col_min = xinters
+ * if xinters > col_max:
+ * col_max = xinters # <<<<<<<<<<<<<<
+ *
+ * if xinters < 0:
+ */
+ __pyx_v_col_max = __pyx_v_xinters;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "silx/image/shapes.pyx":151
+ * col_max = xinters
+ *
+ * if xinters < 0: # <<<<<<<<<<<<<<
+ * # Add an intersection to init value of xor scan
+ * is_inside ^= 1
+ */
+ __pyx_t_11 = ((__pyx_v_xinters < 0) != 0);
+ if (__pyx_t_11) {
+
+ /* "silx/image/shapes.pyx":153
+ * if xinters < 0:
+ * # Add an intersection to init value of xor scan
+ * is_inside ^= 1 # <<<<<<<<<<<<<<
+ * elif xinters < width:
+ * # Mark intersection in mask
+ */
+ __pyx_v_is_inside = (__pyx_v_is_inside ^ 1);
+ goto __pyx_L17;
+ }
+
+ /* "silx/image/shapes.pyx":154
+ * # Add an intersection to init value of xor scan
+ * is_inside ^= 1
+ * elif xinters < width: # <<<<<<<<<<<<<<
+ * # Mark intersection in mask
+ * mask[row, xinters] ^= 1
+ */
+ __pyx_t_11 = ((__pyx_v_xinters < __pyx_v_width) != 0);
+ if (__pyx_t_11) {
+
+ /* "silx/image/shapes.pyx":156
+ * elif xinters < width:
+ * # Mark intersection in mask
+ * mask[row, xinters] ^= 1 # <<<<<<<<<<<<<<
+ * # else: do not consider intersection on the right
+ *
+ */
+ __pyx_t_24 = __pyx_v_row;
+ __pyx_t_25 = __pyx_v_xinters;
+ *((unsigned char *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mask.data + __pyx_t_24 * __pyx_v_mask.strides[0]) ) + __pyx_t_25 * __pyx_v_mask.strides[1]) )) ^= 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "silx/image/shapes.pyx":159
+ * # else: do not consider intersection on the right
+ *
+ * pt1x, pt1y = pt2x, pt2y # <<<<<<<<<<<<<<
+ *
+ * if col_min < col_max:
+ */
+ __pyx_t_26 = __pyx_v_pt2x;
+ __pyx_t_27 = __pyx_v_pt2y;
+ __pyx_v_pt1x = __pyx_t_26;
+ __pyx_v_pt1y = __pyx_t_27;
+ }
+
+ /* "silx/image/shapes.pyx":161
+ * pt1x, pt1y = pt2x, pt2y
+ *
+ * if col_min < col_max: # <<<<<<<<<<<<<<
+ * # Clip column range to mask
+ * if col_min < 0:
+ */
+ __pyx_t_11 = ((__pyx_v_col_min < __pyx_v_col_max) != 0);
+ if (__pyx_t_11) {
+
+ /* "silx/image/shapes.pyx":163
+ * if col_min < col_max:
+ * # Clip column range to mask
+ * if col_min < 0: # <<<<<<<<<<<<<<
+ * col_min = 0
+ * if col_max > width - 1:
+ */
+ __pyx_t_11 = ((__pyx_v_col_min < 0) != 0);
+ if (__pyx_t_11) {
+
+ /* "silx/image/shapes.pyx":164
+ * # Clip column range to mask
+ * if col_min < 0:
+ * col_min = 0 # <<<<<<<<<<<<<<
+ * if col_max > width - 1:
+ * col_max = width - 1
+ */
+ __pyx_v_col_min = 0;
+ goto __pyx_L19;
+ }
+ __pyx_L19:;
+
+ /* "silx/image/shapes.pyx":165
+ * if col_min < 0:
+ * col_min = 0
+ * if col_max > width - 1: # <<<<<<<<<<<<<<
+ * col_max = width - 1
+ *
+ */
+ __pyx_t_11 = ((__pyx_v_col_max > (__pyx_v_width - 1)) != 0);
+ if (__pyx_t_11) {
+
+ /* "silx/image/shapes.pyx":166
+ * col_min = 0
+ * if col_max > width - 1:
+ * col_max = width - 1 # <<<<<<<<<<<<<<
+ *
+ * # xor exclusive scan
+ */
+ __pyx_v_col_max = (__pyx_v_width - 1);
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "silx/image/shapes.pyx":169
+ *
+ * # xor exclusive scan
+ * for col in range(col_min, col_max + 1): # <<<<<<<<<<<<<<
+ * current = mask[row, col]
+ * mask[row, col] = is_inside
+ */
+ __pyx_t_28 = (__pyx_v_col_max + 1);
+ for (__pyx_t_17 = __pyx_v_col_min; __pyx_t_17 < __pyx_t_28; __pyx_t_17+=1) {
+ __pyx_v_col = __pyx_t_17;
+
+ /* "silx/image/shapes.pyx":170
+ * # xor exclusive scan
+ * for col in range(col_min, col_max + 1):
+ * current = mask[row, col] # <<<<<<<<<<<<<<
+ * mask[row, col] = is_inside
+ * is_inside = current ^ is_inside
+ */
+ __pyx_t_18 = __pyx_v_row;
+ __pyx_t_29 = __pyx_v_col;
+ __pyx_v_current = (*((unsigned char *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mask.data + __pyx_t_18 * __pyx_v_mask.strides[0]) ) + __pyx_t_29 * __pyx_v_mask.strides[1]) )));
+
+ /* "silx/image/shapes.pyx":171
+ * for col in range(col_min, col_max + 1):
+ * current = mask[row, col]
+ * mask[row, col] = is_inside # <<<<<<<<<<<<<<
+ * is_inside = current ^ is_inside
+ *
+ */
+ __pyx_t_30 = __pyx_v_row;
+ __pyx_t_31 = __pyx_v_col;
+ *((unsigned char *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_mask.data + __pyx_t_30 * __pyx_v_mask.strides[0]) ) + __pyx_t_31 * __pyx_v_mask.strides[1]) )) = __pyx_v_is_inside;
+
+ /* "silx/image/shapes.pyx":172
+ * current = mask[row, col]
+ * mask[row, col] = is_inside
+ * is_inside = current ^ is_inside # <<<<<<<<<<<<<<
+ *
+ * # Ensures the result is exported as numpy array and not memory view.
+ */
+ __pyx_v_is_inside = (__pyx_v_current ^ __pyx_v_is_inside);
+ }
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ }
+ }
+
+ /* "silx/image/shapes.pyx":124
+ *
+ * # Can be replaced by prange(row_min, row_max, nogil=True)
+ * with nogil: # <<<<<<<<<<<<<<
+ * for row in range(row_min, row_max):
+ * # For each line of the image, mark intersection of all segments
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L4_error: {
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L1_error;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/image/shapes.pyx":175
+ *
+ * # Ensures the result is exported as numpy array and not memory view.
+ * return numpy.asarray(mask) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_asarray); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __pyx_memoryview_fromslice(__pyx_v_mask, 2, (PyObject *(*)(char *)) __pyx_memview_get_unsigned_char, (int (*)(char *, PyObject *)) __pyx_memview_set_unsigned_char, 0);; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_1 = PyTuple_New(1+1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_1, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_1, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "silx/image/shapes.pyx":106
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * def make_mask(self, int height, int width): # <<<<<<<<<<<<<<
+ * """Create a mask array representing the filled polygon
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_12, 1);
+ __Pyx_AddTraceback("silx.image.shapes.Polygon.make_mask", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_mask, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/shapes.pyx":178
+ *
+ *
+ * def polygon_fill_mask(vertices, shape): # <<<<<<<<<<<<<<
+ * """Return a mask of boolean, True for pixels inside a polygon.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_6shapes_1polygon_fill_mask(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_5image_6shapes_polygon_fill_mask[] = "polygon_fill_mask(vertices, shape)\nReturn a mask of boolean, True for pixels inside a polygon.\n\n :param vertices: Strip of segments end points (row, column) or (y, x)\n :type vertices: numpy.ndarray like container of dimension Nx2\n :param shape: size of the mask as (height, width)\n :type shape: 2-tuple of int\n :return: Mask corresponding to the polygon\n :rtype: numpy.ndarray of dimension shape\n ";
+static PyMethodDef __pyx_mdef_4silx_5image_6shapes_1polygon_fill_mask = {"polygon_fill_mask", (PyCFunction)__pyx_pw_4silx_5image_6shapes_1polygon_fill_mask, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_5image_6shapes_polygon_fill_mask};
+static PyObject *__pyx_pw_4silx_5image_6shapes_1polygon_fill_mask(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_vertices = 0;
+ PyObject *__pyx_v_shape = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("polygon_fill_mask (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_vertices,&__pyx_n_s_shape,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_vertices)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("polygon_fill_mask", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "polygon_fill_mask") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_vertices = values[0];
+ __pyx_v_shape = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("polygon_fill_mask", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.shapes.polygon_fill_mask", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_5image_6shapes_polygon_fill_mask(__pyx_self, __pyx_v_vertices, __pyx_v_shape);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_6shapes_polygon_fill_mask(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_vertices, PyObject *__pyx_v_shape) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("polygon_fill_mask", 0);
+
+ /* "silx/image/shapes.pyx":188
+ * :rtype: numpy.ndarray of dimension shape
+ * """
+ * return Polygon(vertices).make_mask(shape[0], shape[1]) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_vertices);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_vertices);
+ __Pyx_GIVEREF(__pyx_v_vertices);
+ __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_4silx_5image_6shapes_Polygon)), __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_make_mask); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_shape, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_shape, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = NULL;
+ __pyx_t_6 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_6 = 1;
+ }
+ }
+ __pyx_t_7 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_6, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_6, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "silx/image/shapes.pyx":178
+ *
+ *
+ * def polygon_fill_mask(vertices, shape): # <<<<<<<<<<<<<<
+ * """Return a mask of boolean, True for pixels inside a polygon.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("silx.image.shapes.polygon_fill_mask", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/shapes.pyx":193
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * def draw_line(int row0, int col0, int row1, int col1, int width=1): # <<<<<<<<<<<<<<
+ * """Line includes both end points.
+ * Width is handled by drawing parallel lines, so junctions of lines belonging
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_6shapes_3draw_line(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_5image_6shapes_2draw_line[] = "draw_line(int row0, int col0, int row1, int col1, int width=1)\nLine includes both end points.\n Width is handled by drawing parallel lines, so junctions of lines belonging\n to different octant with width > 1 will not look nice.\n\n Using Bresenham line algorithm:\n Bresenham, J. E.\n Algorithm for computer control of a digital plotter.\n IBM Systems Journal. Vol 4 No 1. 1965. pp 25-30\n\n :param int row0: Start point row\n :param int col0: Start point col\n :param int row1: End point row\n :param int col1: End point col\n :param int width: Thickness of the line in pixels (default 1)\n Width must be at least 1.\n :return: Array coordinates of points inside the line (might be negative)\n :rtype: 2-tuple of numpy.ndarray (rows, cols)\n ";
+static PyMethodDef __pyx_mdef_4silx_5image_6shapes_3draw_line = {"draw_line", (PyCFunction)__pyx_pw_4silx_5image_6shapes_3draw_line, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_5image_6shapes_2draw_line};
+static PyObject *__pyx_pw_4silx_5image_6shapes_3draw_line(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ int __pyx_v_row0;
+ int __pyx_v_col0;
+ int __pyx_v_row1;
+ int __pyx_v_col1;
+ int __pyx_v_width;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("draw_line (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_row0,&__pyx_n_s_col0,&__pyx_n_s_row1,&__pyx_n_s_col1,&__pyx_n_s_width,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_row0)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_col0)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("draw_line", 0, 4, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_row1)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("draw_line", 0, 4, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_col1)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("draw_line", 0, 4, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_width);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "draw_line") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_row0 = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_row0 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_col0 = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_col0 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_row1 = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_row1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_col1 = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_col1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[4]) {
+ __pyx_v_width = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_width == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_width = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("draw_line", 0, 4, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.shapes.draw_line", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_5image_6shapes_2draw_line(__pyx_self, __pyx_v_row0, __pyx_v_col0, __pyx_v_row1, __pyx_v_col1, __pyx_v_width);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_6shapes_2draw_line(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_row0, int __pyx_v_col0, int __pyx_v_row1, int __pyx_v_col1, int __pyx_v_width) {
+ int __pyx_v_drow;
+ int __pyx_v_dcol;
+ int __pyx_v_invert_coords;
+ int __pyx_v_db;
+ int __pyx_v_da;
+ int __pyx_v_delta;
+ int __pyx_v_b;
+ int __pyx_v_a;
+ int __pyx_v_step_a;
+ int __pyx_v_step_b;
+ int __pyx_v_index;
+ int __pyx_v_offset;
+ __Pyx_memviewslice __pyx_v_b_coords = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_a_coords = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ unsigned int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_t_10;
+ __Pyx_memviewslice __pyx_t_11 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_12 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ long __pyx_t_13;
+ int __pyx_t_14;
+ int __pyx_t_15;
+ int __pyx_t_16;
+ int __pyx_t_17;
+ int __pyx_t_18;
+ int __pyx_t_19;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("draw_line", 0);
+
+ /* "silx/image/shapes.pyx":220
+ * cdef int[:, :] a_coords
+ *
+ * dcol = abs(col1 - col0) # <<<<<<<<<<<<<<
+ * drow = abs(row1 - row0)
+ * invert_coords = dcol < drow
+ */
+ __pyx_t_1 = __Pyx_abs_int((__pyx_v_col1 - __pyx_v_col0));
+ __pyx_v_dcol = __pyx_t_1;
+
+ /* "silx/image/shapes.pyx":221
+ *
+ * dcol = abs(col1 - col0)
+ * drow = abs(row1 - row0) # <<<<<<<<<<<<<<
+ * invert_coords = dcol < drow
+ *
+ */
+ __pyx_t_1 = __Pyx_abs_int((__pyx_v_row1 - __pyx_v_row0));
+ __pyx_v_drow = __pyx_t_1;
+
+ /* "silx/image/shapes.pyx":222
+ * dcol = abs(col1 - col0)
+ * drow = abs(row1 - row0)
+ * invert_coords = dcol < drow # <<<<<<<<<<<<<<
+ *
+ * if dcol == 0 and drow == 0:
+ */
+ __pyx_v_invert_coords = (__pyx_v_dcol < __pyx_v_drow);
+
+ /* "silx/image/shapes.pyx":224
+ * invert_coords = dcol < drow
+ *
+ * if dcol == 0 and drow == 0: # <<<<<<<<<<<<<<
+ * return (numpy.array((row0,), dtype=numpy.int32),
+ * numpy.array((col0,), dtype=numpy.int32))
+ */
+ __pyx_t_3 = ((__pyx_v_dcol == 0) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_drow == 0) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "silx/image/shapes.pyx":225
+ *
+ * if dcol == 0 and drow == 0:
+ * return (numpy.array((row0,), dtype=numpy.int32), # <<<<<<<<<<<<<<
+ * numpy.array((col0,), dtype=numpy.int32))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_row0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_int32); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "silx/image/shapes.pyx":226
+ * if dcol == 0 and drow == 0:
+ * return (numpy.array((row0,), dtype=numpy.int32),
+ * numpy.array((col0,), dtype=numpy.int32)) # <<<<<<<<<<<<<<
+ *
+ * if width < 1:
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_col0); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_int32); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "silx/image/shapes.pyx":225
+ *
+ * if dcol == 0 and drow == 0:
+ * return (numpy.array((row0,), dtype=numpy.int32), # <<<<<<<<<<<<<<
+ * numpy.array((col0,), dtype=numpy.int32))
+ *
+ */
+ __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_8 = 0;
+ __pyx_t_9 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "silx/image/shapes.pyx":228
+ * numpy.array((col0,), dtype=numpy.int32))
+ *
+ * if width < 1: # <<<<<<<<<<<<<<
+ * width = 1
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_width < 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "silx/image/shapes.pyx":229
+ *
+ * if width < 1:
+ * width = 1 # <<<<<<<<<<<<<<
+ *
+ * # Set a and b according to segment octant
+ */
+ __pyx_v_width = 1;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "silx/image/shapes.pyx":232
+ *
+ * # Set a and b according to segment octant
+ * if not invert_coords: # <<<<<<<<<<<<<<
+ * da = dcol
+ * db = drow
+ */
+ __pyx_t_2 = ((!(__pyx_v_invert_coords != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "silx/image/shapes.pyx":233
+ * # Set a and b according to segment octant
+ * if not invert_coords:
+ * da = dcol # <<<<<<<<<<<<<<
+ * db = drow
+ * step_a = 1 if col1 > col0 else -1
+ */
+ __pyx_v_da = __pyx_v_dcol;
+
+ /* "silx/image/shapes.pyx":234
+ * if not invert_coords:
+ * da = dcol
+ * db = drow # <<<<<<<<<<<<<<
+ * step_a = 1 if col1 > col0 else -1
+ * step_b = 1 if row1 > row0 else -1
+ */
+ __pyx_v_db = __pyx_v_drow;
+
+ /* "silx/image/shapes.pyx":235
+ * da = dcol
+ * db = drow
+ * step_a = 1 if col1 > col0 else -1 # <<<<<<<<<<<<<<
+ * step_b = 1 if row1 > row0 else -1
+ * a = col0
+ */
+ if (((__pyx_v_col1 > __pyx_v_col0) != 0)) {
+ __pyx_t_10 = 1;
+ } else {
+ __pyx_t_10 = -1;
+ }
+ __pyx_v_step_a = __pyx_t_10;
+
+ /* "silx/image/shapes.pyx":236
+ * db = drow
+ * step_a = 1 if col1 > col0 else -1
+ * step_b = 1 if row1 > row0 else -1 # <<<<<<<<<<<<<<
+ * a = col0
+ * b = row0
+ */
+ if (((__pyx_v_row1 > __pyx_v_row0) != 0)) {
+ __pyx_t_10 = 1;
+ } else {
+ __pyx_t_10 = -1;
+ }
+ __pyx_v_step_b = __pyx_t_10;
+
+ /* "silx/image/shapes.pyx":237
+ * step_a = 1 if col1 > col0 else -1
+ * step_b = 1 if row1 > row0 else -1
+ * a = col0 # <<<<<<<<<<<<<<
+ * b = row0
+ *
+ */
+ __pyx_v_a = __pyx_v_col0;
+
+ /* "silx/image/shapes.pyx":238
+ * step_b = 1 if row1 > row0 else -1
+ * a = col0
+ * b = row0 # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_b = __pyx_v_row0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "silx/image/shapes.pyx":241
+ *
+ * else:
+ * da = drow # <<<<<<<<<<<<<<
+ * db = dcol
+ * step_a = 1 if row1 > row0 else -1
+ */
+ __pyx_v_da = __pyx_v_drow;
+
+ /* "silx/image/shapes.pyx":242
+ * else:
+ * da = drow
+ * db = dcol # <<<<<<<<<<<<<<
+ * step_a = 1 if row1 > row0 else -1
+ * step_b = 1 if col1 > col0 else -1
+ */
+ __pyx_v_db = __pyx_v_dcol;
+
+ /* "silx/image/shapes.pyx":243
+ * da = drow
+ * db = dcol
+ * step_a = 1 if row1 > row0 else -1 # <<<<<<<<<<<<<<
+ * step_b = 1 if col1 > col0 else -1
+ * a = row0
+ */
+ if (((__pyx_v_row1 > __pyx_v_row0) != 0)) {
+ __pyx_t_10 = 1;
+ } else {
+ __pyx_t_10 = -1;
+ }
+ __pyx_v_step_a = __pyx_t_10;
+
+ /* "silx/image/shapes.pyx":244
+ * db = dcol
+ * step_a = 1 if row1 > row0 else -1
+ * step_b = 1 if col1 > col0 else -1 # <<<<<<<<<<<<<<
+ * a = row0
+ * b = col0
+ */
+ if (((__pyx_v_col1 > __pyx_v_col0) != 0)) {
+ __pyx_t_10 = 1;
+ } else {
+ __pyx_t_10 = -1;
+ }
+ __pyx_v_step_b = __pyx_t_10;
+
+ /* "silx/image/shapes.pyx":245
+ * step_a = 1 if row1 > row0 else -1
+ * step_b = 1 if col1 > col0 else -1
+ * a = row0 # <<<<<<<<<<<<<<
+ * b = col0
+ *
+ */
+ __pyx_v_a = __pyx_v_row0;
+
+ /* "silx/image/shapes.pyx":246
+ * step_b = 1 if col1 > col0 else -1
+ * a = row0
+ * b = col0 # <<<<<<<<<<<<<<
+ *
+ * b_coords = numpy.empty((da + 1, width), dtype=numpy.int32)
+ */
+ __pyx_v_b = __pyx_v_col0;
+ }
+ __pyx_L7:;
+
+ /* "silx/image/shapes.pyx":248
+ * b = col0
+ *
+ * b_coords = numpy.empty((da + 1, width), dtype=numpy.int32) # <<<<<<<<<<<<<<
+ * a_coords = numpy.empty((da + 1, width), dtype=numpy.int32)
+ *
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyInt_From_long((__pyx_v_da + 1)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_width); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_5 = 0;
+ __pyx_t_8 = 0;
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_int32); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_8, __pyx_t_6); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_11 = __Pyx_PyObject_to_MemoryviewSlice_dsds_int(__pyx_t_4);
+ if (unlikely(!__pyx_t_11.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_b_coords = __pyx_t_11;
+ __pyx_t_11.memview = NULL;
+ __pyx_t_11.data = NULL;
+
+ /* "silx/image/shapes.pyx":249
+ *
+ * b_coords = numpy.empty((da + 1, width), dtype=numpy.int32)
+ * a_coords = numpy.empty((da + 1, width), dtype=numpy.int32) # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_empty); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyInt_From_long((__pyx_v_da + 1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_width); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_4 = 0;
+ __pyx_t_8 = 0;
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, __pyx_t_9); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_12 = __Pyx_PyObject_to_MemoryviewSlice_dsds_int(__pyx_t_5);
+ if (unlikely(!__pyx_t_12.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_a_coords = __pyx_t_12;
+ __pyx_t_12.memview = NULL;
+ __pyx_t_12.data = NULL;
+
+ /* "silx/image/shapes.pyx":251
+ * a_coords = numpy.empty((da + 1, width), dtype=numpy.int32)
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * b -= (width - 1) // 2
+ * delta = 2 * db - da
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "silx/image/shapes.pyx":252
+ *
+ * with nogil:
+ * b -= (width - 1) // 2 # <<<<<<<<<<<<<<
+ * delta = 2 * db - da
+ * for index in range(da + 1):
+ */
+ __pyx_v_b = (__pyx_v_b - __Pyx_div_long((__pyx_v_width - 1), 2));
+
+ /* "silx/image/shapes.pyx":253
+ * with nogil:
+ * b -= (width - 1) // 2
+ * delta = 2 * db - da # <<<<<<<<<<<<<<
+ * for index in range(da + 1):
+ * for offset in range(width):
+ */
+ __pyx_v_delta = ((2 * __pyx_v_db) - __pyx_v_da);
+
+ /* "silx/image/shapes.pyx":254
+ * b -= (width - 1) // 2
+ * delta = 2 * db - da
+ * for index in range(da + 1): # <<<<<<<<<<<<<<
+ * for offset in range(width):
+ * b_coords[index, offset] = b + offset
+ */
+ __pyx_t_13 = (__pyx_v_da + 1);
+ for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_13; __pyx_t_10+=1) {
+ __pyx_v_index = __pyx_t_10;
+
+ /* "silx/image/shapes.pyx":255
+ * delta = 2 * db - da
+ * for index in range(da + 1):
+ * for offset in range(width): # <<<<<<<<<<<<<<
+ * b_coords[index, offset] = b + offset
+ * a_coords[index, offset] = a
+ */
+ __pyx_t_14 = __pyx_v_width;
+ for (__pyx_t_15 = 0; __pyx_t_15 < __pyx_t_14; __pyx_t_15+=1) {
+ __pyx_v_offset = __pyx_t_15;
+
+ /* "silx/image/shapes.pyx":256
+ * for index in range(da + 1):
+ * for offset in range(width):
+ * b_coords[index, offset] = b + offset # <<<<<<<<<<<<<<
+ * a_coords[index, offset] = a
+ *
+ */
+ __pyx_t_16 = __pyx_v_index;
+ __pyx_t_17 = __pyx_v_offset;
+ *((int *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_b_coords.data + __pyx_t_16 * __pyx_v_b_coords.strides[0]) ) + __pyx_t_17 * __pyx_v_b_coords.strides[1]) )) = (__pyx_v_b + __pyx_v_offset);
+
+ /* "silx/image/shapes.pyx":257
+ * for offset in range(width):
+ * b_coords[index, offset] = b + offset
+ * a_coords[index, offset] = a # <<<<<<<<<<<<<<
+ *
+ * if delta >= 0: # M2: Move by step_a + step_b
+ */
+ __pyx_t_18 = __pyx_v_index;
+ __pyx_t_19 = __pyx_v_offset;
+ *((int *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_a_coords.data + __pyx_t_18 * __pyx_v_a_coords.strides[0]) ) + __pyx_t_19 * __pyx_v_a_coords.strides[1]) )) = __pyx_v_a;
+ }
+
+ /* "silx/image/shapes.pyx":259
+ * a_coords[index, offset] = a
+ *
+ * if delta >= 0: # M2: Move by step_a + step_b # <<<<<<<<<<<<<<
+ * b += step_b
+ * delta -= 2 * da
+ */
+ __pyx_t_2 = ((__pyx_v_delta >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "silx/image/shapes.pyx":260
+ *
+ * if delta >= 0: # M2: Move by step_a + step_b
+ * b += step_b # <<<<<<<<<<<<<<
+ * delta -= 2 * da
+ * # else M1: Move by step_a
+ */
+ __pyx_v_b = (__pyx_v_b + __pyx_v_step_b);
+
+ /* "silx/image/shapes.pyx":261
+ * if delta >= 0: # M2: Move by step_a + step_b
+ * b += step_b
+ * delta -= 2 * da # <<<<<<<<<<<<<<
+ * # else M1: Move by step_a
+ *
+ */
+ __pyx_v_delta = (__pyx_v_delta - (2 * __pyx_v_da));
+ goto __pyx_L15;
+ }
+ __pyx_L15:;
+
+ /* "silx/image/shapes.pyx":264
+ * # else M1: Move by step_a
+ *
+ * a += step_a # <<<<<<<<<<<<<<
+ * delta += 2 * db
+ *
+ */
+ __pyx_v_a = (__pyx_v_a + __pyx_v_step_a);
+
+ /* "silx/image/shapes.pyx":265
+ *
+ * a += step_a
+ * delta += 2 * db # <<<<<<<<<<<<<<
+ *
+ * if not invert_coords:
+ */
+ __pyx_v_delta = (__pyx_v_delta + (2 * __pyx_v_db));
+ }
+ }
+
+ /* "silx/image/shapes.pyx":251
+ * a_coords = numpy.empty((da + 1, width), dtype=numpy.int32)
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * b -= (width - 1) // 2
+ * delta = 2 * db - da
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+ }
+ }
+
+ /* "silx/image/shapes.pyx":267
+ * delta += 2 * db
+ *
+ * if not invert_coords: # <<<<<<<<<<<<<<
+ * return (numpy.asarray(b_coords).reshape(-1),
+ * numpy.asarray(a_coords).reshape(-1))
+ */
+ __pyx_t_2 = ((!(__pyx_v_invert_coords != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "silx/image/shapes.pyx":268
+ *
+ * if not invert_coords:
+ * return (numpy.asarray(b_coords).reshape(-1), # <<<<<<<<<<<<<<
+ * numpy.asarray(a_coords).reshape(-1))
+ * else:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_asarray); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __pyx_memoryview_fromslice(__pyx_v_b_coords, 2, (PyObject *(*)(char *)) __pyx_memview_get_int, (int (*)(char *, PyObject *)) __pyx_memview_set_int, 0);; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_9); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_reshape); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "silx/image/shapes.pyx":269
+ * if not invert_coords:
+ * return (numpy.asarray(b_coords).reshape(-1),
+ * numpy.asarray(a_coords).reshape(-1)) # <<<<<<<<<<<<<<
+ * else:
+ * return (numpy.asarray(a_coords).reshape(-1),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_a_coords, 2, (PyObject *(*)(char *)) __pyx_memview_get_int, (int (*)(char *, PyObject *)) __pyx_memview_set_int, 0);; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_8);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_7, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_reshape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "silx/image/shapes.pyx":268
+ *
+ * if not invert_coords:
+ * return (numpy.asarray(b_coords).reshape(-1), # <<<<<<<<<<<<<<
+ * numpy.asarray(a_coords).reshape(-1))
+ * else:
+ */
+ __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_5 = 0;
+ __pyx_t_8 = 0;
+ __pyx_r = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "silx/image/shapes.pyx":271
+ * numpy.asarray(a_coords).reshape(-1))
+ * else:
+ * return (numpy.asarray(a_coords).reshape(-1), # <<<<<<<<<<<<<<
+ * numpy.asarray(b_coords).reshape(-1))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __pyx_memoryview_fromslice(__pyx_v_a_coords, 2, (PyObject *(*)(char *)) __pyx_memview_get_int, (int (*)(char *, PyObject *)) __pyx_memview_set_int, 0);; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_GOTREF(__pyx_t_9);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "silx/image/shapes.pyx":272
+ * else:
+ * return (numpy.asarray(a_coords).reshape(-1),
+ * numpy.asarray(b_coords).reshape(-1)) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_b_coords, 2, (PyObject *(*)(char *)) __pyx_memview_get_int, (int (*)(char *, PyObject *)) __pyx_memview_set_int, 0);; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_reshape); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "silx/image/shapes.pyx":271
+ * numpy.asarray(a_coords).reshape(-1))
+ * else:
+ * return (numpy.asarray(a_coords).reshape(-1), # <<<<<<<<<<<<<<
+ * numpy.asarray(b_coords).reshape(-1))
+ *
+ */
+ __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_9 = 0;
+ __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "silx/image/shapes.pyx":193
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * def draw_line(int row0, int col0, int row1, int col1, int width=1): # <<<<<<<<<<<<<<
+ * """Line includes both end points.
+ * Width is handled by drawing parallel lines, so junctions of lines belonging
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_12, 1);
+ __Pyx_AddTraceback("silx.image.shapes.draw_line", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_b_coords, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_a_coords, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/image/shapes.pyx":275
+ *
+ *
+ * def circle_fill(int crow, int ccol, float radius): # <<<<<<<<<<<<<<
+ * """Generates coordinate of image points lying in a disk.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_5image_6shapes_5circle_fill(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_5image_6shapes_4circle_fill[] = "circle_fill(int crow, int ccol, float radius)\nGenerates coordinate of image points lying in a disk.\n\n :param int crow: Row of the center of the disk\n :param int ccol: Column of the center of the disk\n :param float radius: Radius of the disk\n :return: Array coordinates of points inside the disk (might be negative)\n :rtype: 2-tuple of numpy.ndarray (rows, cols)\n ";
+static PyMethodDef __pyx_mdef_4silx_5image_6shapes_5circle_fill = {"circle_fill", (PyCFunction)__pyx_pw_4silx_5image_6shapes_5circle_fill, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_5image_6shapes_4circle_fill};
+static PyObject *__pyx_pw_4silx_5image_6shapes_5circle_fill(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ int __pyx_v_crow;
+ int __pyx_v_ccol;
+ float __pyx_v_radius;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("circle_fill (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_crow,&__pyx_n_s_ccol,&__pyx_n_s_radius,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_crow)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_ccol)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("circle_fill", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_radius)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("circle_fill", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "circle_fill") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ }
+ __pyx_v_crow = __Pyx_PyInt_As_int(values[0]); if (unlikely((__pyx_v_crow == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_ccol = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_ccol == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_radius = __pyx_PyFloat_AsFloat(values[2]); if (unlikely((__pyx_v_radius == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("circle_fill", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.image.shapes.circle_fill", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_5image_6shapes_4circle_fill(__pyx_self, __pyx_v_crow, __pyx_v_ccol, __pyx_v_radius);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_5image_6shapes_4circle_fill(CYTHON_UNUSED PyObject *__pyx_self, int __pyx_v_crow, int __pyx_v_ccol, float __pyx_v_radius) {
+ int __pyx_v_i_radius;
+ int __pyx_v_len_coords;
+ PyObject *__pyx_v_coords = NULL;
+ PyObject *__pyx_v_rows = NULL;
+ PyObject *__pyx_v_cols = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *(*__pyx_t_10)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("circle_fill", 0);
+
+ /* "silx/image/shapes.pyx":286
+ * cdef int i_radius, len_coords
+ *
+ * radius = fabs(radius) # <<<<<<<<<<<<<<
+ * i_radius = <int>radius
+ *
+ */
+ __pyx_v_radius = fabs(__pyx_v_radius);
+
+ /* "silx/image/shapes.pyx":287
+ *
+ * radius = fabs(radius)
+ * i_radius = <int>radius # <<<<<<<<<<<<<<
+ *
+ * coords = numpy.arange(-i_radius, ceil(radius) + 1,
+ */
+ __pyx_v_i_radius = ((int)__pyx_v_radius);
+
+ /* "silx/image/shapes.pyx":289
+ * i_radius = <int>radius
+ *
+ * coords = numpy.arange(-i_radius, ceil(radius) + 1, # <<<<<<<<<<<<<<
+ * dtype=numpy.float32) ** 2
+ * len_coords = len(coords)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_arange); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyInt_From_int((-__pyx_v_i_radius)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = PyFloat_FromDouble((ceil(__pyx_v_radius) + 1.0)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "silx/image/shapes.pyx":290
+ *
+ * coords = numpy.arange(-i_radius, ceil(radius) + 1,
+ * dtype=numpy.float32) ** 2 # <<<<<<<<<<<<<<
+ * len_coords = len(coords)
+ * # rows, cols = where(row**2 + col**2 < radius**2)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "silx/image/shapes.pyx":289
+ * i_radius = <int>radius
+ *
+ * coords = numpy.arange(-i_radius, ceil(radius) + 1, # <<<<<<<<<<<<<<
+ * dtype=numpy.float32) ** 2
+ * len_coords = len(coords)
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 289; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "silx/image/shapes.pyx":290
+ *
+ * coords = numpy.arange(-i_radius, ceil(radius) + 1,
+ * dtype=numpy.float32) ** 2 # <<<<<<<<<<<<<<
+ * len_coords = len(coords)
+ * # rows, cols = where(row**2 + col**2 < radius**2)
+ */
+ __pyx_t_3 = PyNumber_Power(__pyx_t_5, __pyx_int_2, Py_None); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_coords = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "silx/image/shapes.pyx":291
+ * coords = numpy.arange(-i_radius, ceil(radius) + 1,
+ * dtype=numpy.float32) ** 2
+ * len_coords = len(coords) # <<<<<<<<<<<<<<
+ * # rows, cols = where(row**2 + col**2 < radius**2)
+ * rows, cols = numpy.where(coords.reshape(1, len_coords) +
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_coords); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_len_coords = __pyx_t_6;
+
+ /* "silx/image/shapes.pyx":293
+ * len_coords = len(coords)
+ * # rows, cols = where(row**2 + col**2 < radius**2)
+ * rows, cols = numpy.where(coords.reshape(1, len_coords) + # <<<<<<<<<<<<<<
+ * coords.reshape(len_coords, 1) < radius ** 2)
+ * return rows + crow - i_radius, cols + ccol - i_radius
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_where); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_coords, __pyx_n_s_reshape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_len_coords); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = NULL;
+ __pyx_t_6 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_6 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ __Pyx_INCREF(__pyx_int_1);
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_6, __pyx_int_1);
+ __Pyx_GIVEREF(__pyx_int_1);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_6, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "silx/image/shapes.pyx":294
+ * # rows, cols = where(row**2 + col**2 < radius**2)
+ * rows, cols = numpy.where(coords.reshape(1, len_coords) +
+ * coords.reshape(len_coords, 1) < radius ** 2) # <<<<<<<<<<<<<<
+ * return rows + crow - i_radius, cols + ccol - i_radius
+ */
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_coords, __pyx_n_s_reshape); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_len_coords); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = NULL;
+ __pyx_t_6 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ __pyx_t_6 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_6); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_6, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_int_1);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_6, __pyx_int_1);
+ __Pyx_GIVEREF(__pyx_int_1);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_9, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "silx/image/shapes.pyx":293
+ * len_coords = len(coords)
+ * # rows, cols = where(row**2 + col**2 < radius**2)
+ * rows, cols = numpy.where(coords.reshape(1, len_coords) + # <<<<<<<<<<<<<<
+ * coords.reshape(len_coords, 1) < radius ** 2)
+ * return rows + crow - i_radius, cols + ccol - i_radius
+ */
+ __pyx_t_8 = PyNumber_Add(__pyx_t_5, __pyx_t_2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "silx/image/shapes.pyx":294
+ * # rows, cols = where(row**2 + col**2 < radius**2)
+ * rows, cols = numpy.where(coords.reshape(1, len_coords) +
+ * coords.reshape(len_coords, 1) < radius ** 2) # <<<<<<<<<<<<<<
+ * return rows + crow - i_radius, cols + ccol - i_radius
+ */
+ __pyx_t_2 = PyFloat_FromDouble(powf(__pyx_v_radius, 2.0)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_8, __pyx_t_2, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if ((likely(PyTuple_CheckExact(__pyx_t_3))) || (PyList_CheckExact(__pyx_t_3))) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1);
+ } else {
+ __pyx_t_4 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_8 = PyList_GET_ITEM(sequence, 1);
+ }
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_8);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_8 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ Py_ssize_t index = -1;
+ __pyx_t_5 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_10 = Py_TYPE(__pyx_t_5)->tp_iternext;
+ index = 0; __pyx_t_4 = __pyx_t_10(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L3_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_4);
+ index = 1; __pyx_t_8 = __pyx_t_10(__pyx_t_5); if (unlikely(!__pyx_t_8)) goto __pyx_L3_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_10(__pyx_t_5), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = NULL;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L4_unpacking_done;
+ __pyx_L3_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_10 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_L4_unpacking_done:;
+ }
+
+ /* "silx/image/shapes.pyx":293
+ * len_coords = len(coords)
+ * # rows, cols = where(row**2 + col**2 < radius**2)
+ * rows, cols = numpy.where(coords.reshape(1, len_coords) + # <<<<<<<<<<<<<<
+ * coords.reshape(len_coords, 1) < radius ** 2)
+ * return rows + crow - i_radius, cols + ccol - i_radius
+ */
+ __pyx_v_rows = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_cols = __pyx_t_8;
+ __pyx_t_8 = 0;
+
+ /* "silx/image/shapes.pyx":295
+ * rows, cols = numpy.where(coords.reshape(1, len_coords) +
+ * coords.reshape(len_coords, 1) < radius ** 2)
+ * return rows + crow - i_radius, cols + ccol - i_radius # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_crow); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = PyNumber_Add(__pyx_v_rows, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_i_radius); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyNumber_Subtract(__pyx_t_8, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_ccol); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = PyNumber_Add(__pyx_v_cols, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_i_radius); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = PyNumber_Subtract(__pyx_t_8, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "silx/image/shapes.pyx":275
+ *
+ *
+ * def circle_fill(int crow, int ccol, float radius): # <<<<<<<<<<<<<<
+ * """Generates coordinate of image points lying in a disk.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("silx.image.shapes.circle_fill", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_coords);
+ __Pyx_XDECREF(__pyx_v_rows);
+ __Pyx_XDECREF(__pyx_v_cols);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__12);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__12);
+ __Pyx_GIVEREF(__pyx_slice__12);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__13); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__14);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__14);
+ __Pyx_GIVEREF(__pyx_slice__14);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+static struct __pyx_vtabstruct_4silx_5image_6shapes_Polygon __pyx_vtable_4silx_5image_6shapes_Polygon;
+
+static PyObject *__pyx_tp_new_4silx_5image_6shapes_Polygon(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_obj_4silx_5image_6shapes_Polygon *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_obj_4silx_5image_6shapes_Polygon *)o);
+ p->__pyx_vtab = __pyx_vtabptr_4silx_5image_6shapes_Polygon;
+ p->vertices.data = NULL;
+ p->vertices.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc_4silx_5image_6shapes_Polygon(PyObject *o) {
+ struct __pyx_obj_4silx_5image_6shapes_Polygon *p = (struct __pyx_obj_4silx_5image_6shapes_Polygon *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ __PYX_XDEC_MEMVIEW(&p->vertices, 1);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static PyMethodDef __pyx_methods_4silx_5image_6shapes_Polygon[] = {
+ {"is_inside", (PyCFunction)__pyx_pw_4silx_5image_6shapes_7Polygon_3is_inside, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_5image_6shapes_7Polygon_2is_inside},
+ {"make_mask", (PyCFunction)__pyx_pw_4silx_5image_6shapes_7Polygon_5make_mask, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_5image_6shapes_7Polygon_4make_mask},
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_4silx_5image_6shapes_Polygon = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.shapes.Polygon", /*tp_name*/
+ sizeof(struct __pyx_obj_4silx_5image_6shapes_Polygon), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_4silx_5image_6shapes_Polygon, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "Polygon(vertices)\nDefine a polygon that provides inside check and mask generation.\n\n :param vertices: corners of the polygon\n :type vertices: Nx2 array of floats of (row, col)\n ", /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_4silx_5image_6shapes_Polygon, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_pw_4silx_5image_6shapes_7Polygon_1__init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_4silx_5image_6shapes_Polygon, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.shapes.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.shapes.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.shapes.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.image.shapes._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "shapes",
+ __pyx_k_This_module_provides_functions_m, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_03_06_2016, __pyx_k_03_06_2016, sizeof(__pyx_k_03_06_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_kp_s_Jrme_Kieffer, __pyx_k_Jrme_Kieffer, sizeof(__pyx_k_Jrme_Kieffer), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_kp_s_T_Vincent, __pyx_k_T_Vincent, sizeof(__pyx_k_T_Vincent), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_n_s_a, __pyx_k_a, sizeof(__pyx_k_a), 0, 0, 1, 1},
+ {&__pyx_n_s_a_coords, __pyx_k_a_coords, sizeof(__pyx_k_a_coords), 0, 0, 1, 1},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_arange, __pyx_k_arange, sizeof(__pyx_k_arange), 0, 0, 1, 1},
+ {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+ {&__pyx_n_s_asarray, __pyx_k_asarray, sizeof(__pyx_k_asarray), 0, 0, 1, 1},
+ {&__pyx_n_s_ascontiguousarray, __pyx_k_ascontiguousarray, sizeof(__pyx_k_ascontiguousarray), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_b, __pyx_k_b, sizeof(__pyx_k_b), 0, 0, 1, 1},
+ {&__pyx_n_s_b_coords, __pyx_k_b_coords, sizeof(__pyx_k_b_coords), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_ccol, __pyx_k_ccol, sizeof(__pyx_k_ccol), 0, 0, 1, 1},
+ {&__pyx_n_s_circle_fill, __pyx_k_circle_fill, sizeof(__pyx_k_circle_fill), 0, 0, 1, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_n_s_col, __pyx_k_col, sizeof(__pyx_k_col), 0, 0, 1, 1},
+ {&__pyx_n_s_col0, __pyx_k_col0, sizeof(__pyx_k_col0), 0, 0, 1, 1},
+ {&__pyx_n_s_col1, __pyx_k_col1, sizeof(__pyx_k_col1), 0, 0, 1, 1},
+ {&__pyx_n_s_cols, __pyx_k_cols, sizeof(__pyx_k_cols), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_coords, __pyx_k_coords, sizeof(__pyx_k_coords), 0, 0, 1, 1},
+ {&__pyx_n_s_crow, __pyx_k_crow, sizeof(__pyx_k_crow), 0, 0, 1, 1},
+ {&__pyx_n_s_da, __pyx_k_da, sizeof(__pyx_k_da), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_db, __pyx_k_db, sizeof(__pyx_k_db), 0, 0, 1, 1},
+ {&__pyx_n_s_dcol, __pyx_k_dcol, sizeof(__pyx_k_dcol), 0, 0, 1, 1},
+ {&__pyx_n_s_delta, __pyx_k_delta, sizeof(__pyx_k_delta), 0, 0, 1, 1},
+ {&__pyx_n_s_dev, __pyx_k_dev, sizeof(__pyx_k_dev), 0, 0, 1, 1},
+ {&__pyx_n_s_draw_line, __pyx_k_draw_line, sizeof(__pyx_k_draw_line), 0, 0, 1, 1},
+ {&__pyx_n_s_drow, __pyx_k_drow, sizeof(__pyx_k_drow), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_float32, __pyx_k_float32, sizeof(__pyx_k_float32), 0, 0, 1, 1},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_height, __pyx_k_height, sizeof(__pyx_k_height), 0, 0, 1, 1},
+ {&__pyx_n_s_i_radius, __pyx_k_i_radius, sizeof(__pyx_k_i_radius), 0, 0, 1, 1},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1},
+ {&__pyx_n_s_int32, __pyx_k_int32, sizeof(__pyx_k_int32), 0, 0, 1, 1},
+ {&__pyx_n_s_invert_coords, __pyx_k_invert_coords, sizeof(__pyx_k_invert_coords), 0, 0, 1, 1},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_len_coords, __pyx_k_len_coords, sizeof(__pyx_k_len_coords), 0, 0, 1, 1},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_make_mask, __pyx_k_make_mask, sizeof(__pyx_k_make_mask), 0, 0, 1, 1},
+ {&__pyx_n_s_max, __pyx_k_max, sizeof(__pyx_k_max), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_n_s_min, __pyx_k_min, sizeof(__pyx_k_min), 0, 0, 1, 1},
+ {&__pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_k_mntdirect__scisoft_users_tvince, sizeof(__pyx_k_mntdirect__scisoft_users_tvince), 0, 0, 1, 0},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_n_s_offset, __pyx_k_offset, sizeof(__pyx_k_offset), 0, 0, 1, 1},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_n_s_polygon_fill_mask, __pyx_k_polygon_fill_mask, sizeof(__pyx_k_polygon_fill_mask), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_radius, __pyx_k_radius, sizeof(__pyx_k_radius), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+ {&__pyx_n_s_row, __pyx_k_row, sizeof(__pyx_k_row), 0, 0, 1, 1},
+ {&__pyx_n_s_row0, __pyx_k_row0, sizeof(__pyx_k_row0), 0, 0, 1, 1},
+ {&__pyx_n_s_row1, __pyx_k_row1, sizeof(__pyx_k_row1), 0, 0, 1, 1},
+ {&__pyx_n_s_rows, __pyx_k_rows, sizeof(__pyx_k_rows), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_silx_image_shapes, __pyx_k_silx_image_shapes, sizeof(__pyx_k_silx_image_shapes), 0, 0, 1, 1},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_status, __pyx_k_status, sizeof(__pyx_k_status), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_step_a, __pyx_k_step_a, sizeof(__pyx_k_step_a), 0, 0, 1, 1},
+ {&__pyx_n_s_step_b, __pyx_k_step_b, sizeof(__pyx_k_step_b), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_n_s_uint8, __pyx_k_uint8, sizeof(__pyx_k_uint8), 0, 0, 1, 1},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_n_s_vertices, __pyx_k_vertices, sizeof(__pyx_k_vertices), 0, 0, 1, 1},
+ {&__pyx_n_s_where, __pyx_k_where, sizeof(__pyx_k_where), 0, 0, 1, 1},
+ {&__pyx_n_s_width, __pyx_k_width, sizeof(__pyx_k_width), 0, 0, 1, 1},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_min = __Pyx_GetBuiltinName(__pyx_n_s_min); if (!__pyx_builtin_min) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_max = __Pyx_GetBuiltinName(__pyx_n_s_max); if (!__pyx_builtin_max) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "silx/image/shapes.pyx":268
+ *
+ * if not invert_coords:
+ * return (numpy.asarray(b_coords).reshape(-1), # <<<<<<<<<<<<<<
+ * numpy.asarray(a_coords).reshape(-1))
+ * else:
+ */
+ __pyx_tuple_ = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "silx/image/shapes.pyx":269
+ * if not invert_coords:
+ * return (numpy.asarray(b_coords).reshape(-1),
+ * numpy.asarray(a_coords).reshape(-1)) # <<<<<<<<<<<<<<
+ * else:
+ * return (numpy.asarray(a_coords).reshape(-1),
+ */
+ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "silx/image/shapes.pyx":271
+ * numpy.asarray(a_coords).reshape(-1))
+ * else:
+ * return (numpy.asarray(a_coords).reshape(-1), # <<<<<<<<<<<<<<
+ * numpy.asarray(b_coords).reshape(-1))
+ *
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "silx/image/shapes.pyx":272
+ * else:
+ * return (numpy.asarray(a_coords).reshape(-1),
+ * numpy.asarray(b_coords).reshape(-1)) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__7);
+ __Pyx_GIVEREF(__pyx_tuple__7);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__12 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__12)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__12);
+ __Pyx_GIVEREF(__pyx_slice__12);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__13 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__13)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__13);
+ __Pyx_GIVEREF(__pyx_slice__13);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__14 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__14)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__14);
+ __Pyx_GIVEREF(__pyx_slice__14);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+
+ /* "silx/image/shapes.pyx":178
+ *
+ *
+ * def polygon_fill_mask(vertices, shape): # <<<<<<<<<<<<<<
+ * """Return a mask of boolean, True for pixels inside a polygon.
+ *
+ */
+ __pyx_tuple__16 = PyTuple_Pack(2, __pyx_n_s_vertices, __pyx_n_s_shape); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+ __pyx_codeobj__17 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__16, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_polygon_fill_mask, 178, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/image/shapes.pyx":193
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * def draw_line(int row0, int col0, int row1, int col1, int width=1): # <<<<<<<<<<<<<<
+ * """Line includes both end points.
+ * Width is handled by drawing parallel lines, so junctions of lines belonging
+ */
+ __pyx_tuple__18 = PyTuple_Pack(19, __pyx_n_s_row0, __pyx_n_s_col0, __pyx_n_s_row1, __pyx_n_s_col1, __pyx_n_s_width, __pyx_n_s_drow, __pyx_n_s_dcol, __pyx_n_s_invert_coords, __pyx_n_s_db, __pyx_n_s_da, __pyx_n_s_delta, __pyx_n_s_b, __pyx_n_s_a, __pyx_n_s_step_a, __pyx_n_s_step_b, __pyx_n_s_index, __pyx_n_s_offset, __pyx_n_s_b_coords, __pyx_n_s_a_coords); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+ __pyx_codeobj__19 = (PyObject*)__Pyx_PyCode_New(5, 0, 19, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__18, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_draw_line, 193, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/image/shapes.pyx":275
+ *
+ *
+ * def circle_fill(int crow, int ccol, float radius): # <<<<<<<<<<<<<<
+ * """Generates coordinate of image points lying in a disk.
+ *
+ */
+ __pyx_tuple__20 = PyTuple_Pack(8, __pyx_n_s_crow, __pyx_n_s_ccol, __pyx_n_s_radius, __pyx_n_s_i_radius, __pyx_n_s_len_coords, __pyx_n_s_coords, __pyx_n_s_rows, __pyx_n_s_cols); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+ __pyx_codeobj__21 = (PyObject*)__Pyx_PyCode_New(3, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__20, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_circle_fill, 275, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__22);
+ __Pyx_GIVEREF(__pyx_tuple__22);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__23)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__23);
+ __Pyx_GIVEREF(__pyx_tuple__23);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__24);
+ __Pyx_GIVEREF(__pyx_tuple__24);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__25);
+ __Pyx_GIVEREF(__pyx_tuple__25);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__26);
+ __Pyx_GIVEREF(__pyx_tuple__26);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initshapes(void); /*proto*/
+PyMODINIT_FUNC initshapes(void)
+#else
+PyMODINIT_FUNC PyInit_shapes(void); /*proto*/
+PyMODINIT_FUNC PyInit_shapes(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_shapes(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("shapes", __pyx_methods, __pyx_k_This_module_provides_functions_m, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_silx__image__shapes) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "silx.image.shapes")) {
+ if (unlikely(PyDict_SetItemString(modules, "silx.image.shapes", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ __pyx_vtabptr_4silx_5image_6shapes_Polygon = &__pyx_vtable_4silx_5image_6shapes_Polygon;
+ __pyx_vtable_4silx_5image_6shapes_Polygon.c_is_inside = (int (*)(struct __pyx_obj_4silx_5image_6shapes_Polygon *, float, float))__pyx_f_4silx_5image_6shapes_7Polygon_c_is_inside;
+ if (PyType_Ready(&__pyx_type_4silx_5image_6shapes_Polygon) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_4silx_5image_6shapes_Polygon.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type_4silx_5image_6shapes_Polygon.tp_dict, __pyx_vtabptr_4silx_5image_6shapes_Polygon) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyObject_SetAttrString(__pyx_m, "Polygon", (PyObject *)&__pyx_type_4silx_5image_6shapes_Polygon) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_4silx_5image_6shapes_Polygon = &__pyx_type_4silx_5image_6shapes_Polygon;
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "silx/image/shapes.pyx":38
+ * """
+ *
+ * __authors__ = ["Jrme Kieffer", "T. Vincent"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "03/06/2016"
+ */
+ __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_Jrme_Kieffer);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_Jrme_Kieffer);
+ __Pyx_GIVEREF(__pyx_kp_s_Jrme_Kieffer);
+ __Pyx_INCREF(__pyx_kp_s_T_Vincent);
+ PyList_SET_ITEM(__pyx_t_1, 1, __pyx_kp_s_T_Vincent);
+ __Pyx_GIVEREF(__pyx_kp_s_T_Vincent);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/shapes.pyx":39
+ *
+ * __authors__ = ["Jrme Kieffer", "T. Vincent"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "03/06/2016"
+ * __status__ = "dev"
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/image/shapes.pyx":40
+ * __authors__ = ["Jrme Kieffer", "T. Vincent"]
+ * __license__ = "MIT"
+ * __date__ = "03/06/2016" # <<<<<<<<<<<<<<
+ * __status__ = "dev"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_03_06_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/image/shapes.pyx":41
+ * __license__ = "MIT"
+ * __date__ = "03/06/2016"
+ * __status__ = "dev" # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_status, __pyx_n_s_dev) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/image/shapes.pyx":45
+ *
+ * cimport cython
+ * import numpy # <<<<<<<<<<<<<<
+ * from libc.math cimport ceil, fabs
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/shapes.pyx":178
+ *
+ *
+ * def polygon_fill_mask(vertices, shape): # <<<<<<<<<<<<<<
+ * """Return a mask of boolean, True for pixels inside a polygon.
+ *
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_5image_6shapes_1polygon_fill_mask, NULL, __pyx_n_s_silx_image_shapes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_polygon_fill_mask, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/shapes.pyx":193
+ * @cython.wraparound(False)
+ * @cython.boundscheck(False)
+ * def draw_line(int row0, int col0, int row1, int col1, int width=1): # <<<<<<<<<<<<<<
+ * """Line includes both end points.
+ * Width is handled by drawing parallel lines, so junctions of lines belonging
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_5image_6shapes_3draw_line, NULL, __pyx_n_s_silx_image_shapes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_draw_line, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/shapes.pyx":275
+ *
+ *
+ * def circle_fill(int crow, int ccol, float radius): # <<<<<<<<<<<<<<
+ * """Generates coordinate of image points lying in a disk.
+ *
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_5image_6shapes_5circle_fill, NULL, __pyx_n_s_silx_image_shapes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_circle_fill, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/image/shapes.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * # /[inserted by cython to avoid comment start]*##########################################################################
+ * #
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init silx.image.shapes", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init silx.image.shapes");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* exc_type = tstate->curexc_type;
+ if (unlikely(exc_type)) {
+ if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+ PyObject *exc_value, *exc_tb;
+ exc_value = tstate->curexc_value;
+ exc_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+ Py_DECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#else
+ if (unlikely(PyErr_Occurred())) {
+ if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+ PyErr_Clear();
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+ if (unlikely(retval)) {
+ Py_DECREF(retval);
+ __Pyx_RaiseTooManyValuesError(expected);
+ return -1;
+ } else {
+ return __Pyx_IterFinish();
+ }
+ return 0;
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static PyObject *__pyx_memview_get_float(const char *itemp) {
+ return (PyObject *) PyFloat_FromDouble(*(float *) itemp);
+}
+static int __pyx_memview_set_float(const char *itemp, PyObject *obj) {
+ float value = __pyx_PyFloat_AsFloat(obj);
+ if ((value == (float)-1) && PyErr_Occurred())
+ return 0;
+ *(float *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_char(unsigned char value) {
+ const unsigned char neg_one = (unsigned char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(unsigned char) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned char) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(unsigned char) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(unsigned char) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned char) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(unsigned char),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_As_unsigned_char(PyObject *x) {
+ const unsigned char neg_one = (unsigned char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(unsigned char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (unsigned char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(unsigned char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(unsigned char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(unsigned char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(unsigned char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, long, PyLong_AsLong(x))
+ } else if (sizeof(unsigned char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ unsigned char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (unsigned char) -1;
+ }
+ } else {
+ unsigned char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (unsigned char) -1;
+ val = __Pyx_PyInt_As_unsigned_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to unsigned char");
+ return (unsigned char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to unsigned char");
+ return (unsigned char) -1;
+}
+
+static PyObject *__pyx_memview_get_unsigned_char(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_unsigned_char(*(unsigned char *) itemp);
+}
+static int __pyx_memview_set_unsigned_char(const char *itemp, PyObject *obj) {
+ unsigned char value = __Pyx_PyInt_As_unsigned_char(obj);
+ if ((value == (unsigned char)-1) && PyErr_Occurred())
+ return 0;
+ *(unsigned char *) itemp = value;
+ return 1;
+}
+
+static PyObject *__pyx_memview_get_int(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_int(*(int *) itemp);
+}
+static int __pyx_memview_set_int(const char *itemp, PyObject *obj) {
+ int value = __Pyx_PyInt_As_int(obj);
+ if ((value == (int)-1) && PyErr_Occurred())
+ return 0;
+ *(int *) itemp = value;
+ return 1;
+}
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_float(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 2,
+ &__Pyx_TypeInfo_float, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_unsigned_char(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 2,
+ &__Pyx_TypeInfo_unsigned_char, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dsds_int(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 2,
+ &__Pyx_TypeInfo_int, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/image/shapes.pyx b/silx/image/shapes.pyx
new file mode 100644
index 0000000..59942da
--- /dev/null
+++ b/silx/image/shapes.pyx
@@ -0,0 +1,295 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ############################################################################*/
+"""This module provides functions making masks on an image.
+
+- :func:`circle_fill` function generates coordinates of a circle in an image.
+- :func:`draw_line` function generates coordinates of a line in an image.
+- :func:`polygon_fill_mask` function generates a mask from a set of points
+ defining a polygon.
+
+The :class:`Polygon` class provides checking if a point is inside a polygon.
+
+The whole module uses the (row, col) (i.e., (y, x))) convention
+for 2D coordinates.
+"""
+
+__authors__ = ["Jérôme Kieffer", "T. Vincent"]
+__license__ = "MIT"
+__date__ = "03/06/2016"
+__status__ = "dev"
+
+
+cimport cython
+import numpy
+from libc.math cimport ceil, fabs
+
+
+cdef class Polygon(object):
+ """Define a polygon that provides inside check and mask generation.
+
+ :param vertices: corners of the polygon
+ :type vertices: Nx2 array of floats of (row, col)
+ """
+
+ cdef float[:,:] vertices
+ cdef int nvert
+
+ def __init__(self, vertices):
+ self.vertices = numpy.ascontiguousarray(vertices, dtype=numpy.float32)
+ self.nvert = self.vertices.shape[0]
+
+ def is_inside(self, row, col):
+ """Check if (row, col) is inside or outside the polygon
+
+ :param float row:
+ :param float col:
+ :return: True if position is inside polygon, False otherwise
+ """
+ return self.c_is_inside(row, col)
+
+ @cython.cdivision(True)
+ @cython.wraparound(False)
+ @cython.boundscheck(False)
+ cdef bint c_is_inside(self, float row, float col) nogil:
+ """Check if (row, col) is inside or outside the polygon
+
+ Pure C_Cython class implementation.
+
+ :param float row:
+ :param float col:
+ :return: True if position is inside polygon, False otherwise
+ """
+ cdef int index, is_inside
+ cdef float pt1x, pt1y, pt2x, pt2y, xinters
+ is_inside = 0
+
+ pt1x = self.vertices[self.nvert-1, 1]
+ pt1y = self.vertices[self.nvert-1, 0]
+ for index in range(self.nvert):
+ pt2x = self.vertices[index, 1]
+ pt2y = self.vertices[index, 0]
+
+ if (((pt1y <= row and row < pt2y) or
+ (pt2y <= row and row < pt1y)) and
+ # Extra (optional) condition to avoid some computation
+ (col <= pt1x or col <= pt2x)):
+ xinters = (row - pt1y) * (pt2x - pt1x) / (pt2y - pt1y) + pt1x
+ is_inside ^= col < xinters
+ pt1x, pt1y = pt2x, pt2y
+ return is_inside
+
+ @cython.cdivision(True)
+ @cython.wraparound(False)
+ @cython.boundscheck(False)
+ def make_mask(self, int height, int width):
+ """Create a mask array representing the filled polygon
+
+ :param int height: Height of the mask array
+ :param int width: Width of the mask array
+ :return: 2D array (height, width)
+ """
+ cdef unsigned char[:, :] mask = numpy.zeros((height, width),
+ dtype=numpy.uint8)
+ cdef int row_min, row_max, col_min, col_max # mask subpart to update
+ cdef int row, col, index # Loop indixes
+ cdef float pt1x, pt1y, pt2x, pt2y # segment end points
+ cdef int xinters, is_inside, current
+
+ row_min = max(int(min(self.vertices[:, 0])), 0)
+ row_max = min(int(max(self.vertices[:, 0])) + 1, height)
+
+ # Can be replaced by prange(row_min, row_max, nogil=True)
+ with nogil:
+ for row in range(row_min, row_max):
+ # For each line of the image, mark intersection of all segments
+ # in the line and then run a xor scan to fill inner parts
+ # Adapted from http://alienryderflex.com/polygon_fill/
+ pt1x = self.vertices[self.nvert-1, 1]
+ pt1y = self.vertices[self.nvert-1, 0]
+ col_min = width - 1
+ col_max = 0
+ is_inside = 0 # Init with whether first col is inside or not
+
+ for index in range(self.nvert):
+ pt2x = self.vertices[index, 1]
+ pt2y = self.vertices[index, 0]
+
+ if ((pt1y <= row and row < pt2y) or
+ (pt2y <= row and row < pt1y)):
+ # Intersection casted to int so that ]x, x+1] => x
+ xinters = (<int>ceil(pt1x + (row - pt1y) *
+ (pt2x - pt1x) / (pt2y - pt1y))) - 1
+
+ # Update column range to patch
+ if xinters < col_min:
+ col_min = xinters
+ if xinters > col_max:
+ col_max = xinters
+
+ if xinters < 0:
+ # Add an intersection to init value of xor scan
+ is_inside ^= 1
+ elif xinters < width:
+ # Mark intersection in mask
+ mask[row, xinters] ^= 1
+ # else: do not consider intersection on the right
+
+ pt1x, pt1y = pt2x, pt2y
+
+ if col_min < col_max:
+ # Clip column range to mask
+ if col_min < 0:
+ col_min = 0
+ if col_max > width - 1:
+ col_max = width - 1
+
+ # xor exclusive scan
+ for col in range(col_min, col_max + 1):
+ current = mask[row, col]
+ mask[row, col] = is_inside
+ is_inside = current ^ is_inside
+
+ # Ensures the result is exported as numpy array and not memory view.
+ return numpy.asarray(mask)
+
+
+def polygon_fill_mask(vertices, shape):
+ """Return a mask of boolean, True for pixels inside a polygon.
+
+ :param vertices: Strip of segments end points (row, column) or (y, x)
+ :type vertices: numpy.ndarray like container of dimension Nx2
+ :param shape: size of the mask as (height, width)
+ :type shape: 2-tuple of int
+ :return: Mask corresponding to the polygon
+ :rtype: numpy.ndarray of dimension shape
+ """
+ return Polygon(vertices).make_mask(shape[0], shape[1])
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+def draw_line(int row0, int col0, int row1, int col1, int width=1):
+ """Line includes both end points.
+ Width is handled by drawing parallel lines, so junctions of lines belonging
+ to different octant with width > 1 will not look nice.
+
+ Using Bresenham line algorithm:
+ Bresenham, J. E.
+ Algorithm for computer control of a digital plotter.
+ IBM Systems Journal. Vol 4 No 1. 1965. pp 25-30
+
+ :param int row0: Start point row
+ :param int col0: Start point col
+ :param int row1: End point row
+ :param int col1: End point col
+ :param int width: Thickness of the line in pixels (default 1)
+ Width must be at least 1.
+ :return: Array coordinates of points inside the line (might be negative)
+ :rtype: 2-tuple of numpy.ndarray (rows, cols)
+ """
+ cdef int drow, dcol, invert_coords
+ cdef int db, da, delta, b, a, step_a, step_b
+ cdef int index, offset # Loop indices
+
+ # Store coordinates of points of the line
+ cdef int[:, :] b_coords
+ cdef int[:, :] a_coords
+
+ dcol = abs(col1 - col0)
+ drow = abs(row1 - row0)
+ invert_coords = dcol < drow
+
+ if dcol == 0 and drow == 0:
+ return (numpy.array((row0,), dtype=numpy.int32),
+ numpy.array((col0,), dtype=numpy.int32))
+
+ if width < 1:
+ width = 1
+
+ # Set a and b according to segment octant
+ if not invert_coords:
+ da = dcol
+ db = drow
+ step_a = 1 if col1 > col0 else -1
+ step_b = 1 if row1 > row0 else -1
+ a = col0
+ b = row0
+
+ else:
+ da = drow
+ db = dcol
+ step_a = 1 if row1 > row0 else -1
+ step_b = 1 if col1 > col0 else -1
+ a = row0
+ b = col0
+
+ b_coords = numpy.empty((da + 1, width), dtype=numpy.int32)
+ a_coords = numpy.empty((da + 1, width), dtype=numpy.int32)
+
+ with nogil:
+ b -= (width - 1) // 2
+ delta = 2 * db - da
+ for index in range(da + 1):
+ for offset in range(width):
+ b_coords[index, offset] = b + offset
+ a_coords[index, offset] = a
+
+ if delta >= 0: # M2: Move by step_a + step_b
+ b += step_b
+ delta -= 2 * da
+ # else M1: Move by step_a
+
+ a += step_a
+ delta += 2 * db
+
+ if not invert_coords:
+ return (numpy.asarray(b_coords).reshape(-1),
+ numpy.asarray(a_coords).reshape(-1))
+ else:
+ return (numpy.asarray(a_coords).reshape(-1),
+ numpy.asarray(b_coords).reshape(-1))
+
+
+def circle_fill(int crow, int ccol, float radius):
+ """Generates coordinate of image points lying in a disk.
+
+ :param int crow: Row of the center of the disk
+ :param int ccol: Column of the center of the disk
+ :param float radius: Radius of the disk
+ :return: Array coordinates of points inside the disk (might be negative)
+ :rtype: 2-tuple of numpy.ndarray (rows, cols)
+ """
+ cdef int i_radius, len_coords
+
+ radius = fabs(radius)
+ i_radius = <int>radius
+
+ coords = numpy.arange(-i_radius, ceil(radius) + 1,
+ dtype=numpy.float32) ** 2
+ len_coords = len(coords)
+ # rows, cols = where(row**2 + col**2 < radius**2)
+ rows, cols = numpy.where(coords.reshape(1, len_coords) +
+ coords.reshape(len_coords, 1) < radius ** 2)
+ return rows + crow - i_radius, cols + ccol - i_radius
diff --git a/silx/image/sift.py b/silx/image/sift.py
new file mode 100644
index 0000000..1a9ac8c
--- /dev/null
+++ b/silx/image/sift.py
@@ -0,0 +1 @@
+from silx.opencl.sift import * \ No newline at end of file
diff --git a/silx/image/test/__init__.py b/silx/image/test/__init__.py
new file mode 100644
index 0000000..e99eaa2
--- /dev/null
+++ b/silx/image/test/__init__.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+#
+# Project: silx
+# https://github.com/silx-kit/silx
+#
+# Copyright (C) 2012-2016 European Synchrotron Radiation Facility, Grenoble, France
+#
+# 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.
+
+__authors__ = ["J. Kieffer"]
+__license__ = "MIT"
+__date__ = "25/08/2016"
+
+import unittest
+from . import test_bilinear
+from . import test_shapes
+from . import test_medianfilter
+
+
+def suite():
+ """Test suite for module silx.image.test"""
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(test_bilinear.suite())
+ test_suite.addTest(test_medianfilter.suite())
+ test_suite.addTest(test_shapes.suite())
+ return test_suite
diff --git a/silx/image/test/test_bilinear.py b/silx/image/test/test_bilinear.py
new file mode 100644
index 0000000..1789aca
--- /dev/null
+++ b/silx/image/test/test_bilinear.py
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+#
+# Project: silx (originally pyFAI)
+# https://github.com/silx-kit/silx
+#
+# Copyright (C) 2012-2016 European Synchrotron Radiation Facility, Grenoble, France
+# 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.
+
+__authors__ = ["J. Kieffer"]
+__license__ = "MIT"
+__date__ = "02/08/2016"
+
+import unittest
+import numpy
+import logging
+logger = logging.getLogger("test_bilinear")
+from ..bilinear import BilinearImage
+
+
+class TestBilinear(unittest.TestCase):
+ """basic maximum search test"""
+ N = 1000
+
+ def test_max_search_round(self):
+ """test maximum search using random points: maximum is at the pixel center"""
+ a = numpy.arange(100) - 40.
+ b = numpy.arange(100) - 60.
+ ga = numpy.exp(-a * a / 4000)
+ gb = numpy.exp(-b * b / 6000)
+ gg = numpy.outer(ga, gb)
+ b = BilinearImage(gg)
+ ok = 0
+ for s in range(self.N):
+ i, j = numpy.random.randint(100), numpy.random.randint(100)
+ k, l = b.local_maxi((i, j))
+ if abs(k - 40) > 1e-4 or abs(l - 60) > 1e-4:
+ logger.warning("Wrong guess maximum (%i,%i) -> (%.1f,%.1f)", i, j, k, l)
+ else:
+ logger.debug("Good guess maximum (%i,%i) -> (%.1f,%.1f)", i, j, k, l)
+ ok += 1
+ logger.debug("Success rate: %.1f", 100. * ok / self.N)
+ self.assertEqual(ok, self.N, "Maximum is always found")
+
+ def test_max_search_half(self):
+ """test maximum search using random points: maximum is at a pixel edge"""
+ a = numpy.arange(100) - 40.5
+ b = numpy.arange(100) - 60.5
+ ga = numpy.exp(-a * a / 4000)
+ gb = numpy.exp(-b * b / 6000)
+ gg = numpy.outer(ga, gb)
+ b = BilinearImage(gg)
+ ok = 0
+ for s in range(self.N):
+ i, j = numpy.random.randint(100), numpy.random.randint(100)
+ k, l = b.local_maxi((i, j))
+ if abs(k - 40.5) > 0.5 or abs(l - 60.5) > 0.5:
+ logger.warning("Wrong guess maximum (%i,%i) -> (%.1f,%.1f)", i, j, k, l)
+ else:
+ logger.debug("Good guess maximum (%i,%i) -> (%.1f,%.1f)", i, j, k, l)
+ ok += 1
+ logger.debug("Success rate: %.1f", 100. * ok / self.N)
+ self.assertEqual(ok, self.N, "Maximum is always found")
+
+ def test_map(self):
+ N = 100
+ y, x = numpy.ogrid[:N, :N + 10]
+ img = x + y
+ b = BilinearImage(img)
+ x2d = numpy.zeros_like(y) + x
+ y2d = numpy.zeros_like(x) + y
+ res1 = b.map_coordinates((y2d, x2d))
+ self.assertEquals(abs(res1 - img).max(), 0, "images are the same (corners)")
+
+ x2d = numpy.zeros_like(y) + (x[:, :-1] + 0.5)
+ y2d = numpy.zeros_like(x[:, :-1]) + y
+ res1 = b.map_coordinates((y2d, x2d))
+ self.assertEquals(abs(res1 - img[:, :-1] - 0.5).max(), 0, "images are the same (middle)")
+
+ x2d = numpy.zeros_like(y[:-1, :]) + (x[:, :-1] + 0.5)
+ y2d = numpy.zeros_like(x[:, :-1]) + (y[:-1, :] + 0.5)
+ res1 = b.map_coordinates((y2d, x2d))
+ self.assertEquals(abs(res1 - img[:-1, 1:]).max(), 0, "images are the same (center)")
+
+ def test_profile_grad(self):
+ N = 100
+ img = numpy.arange(N * N).reshape(N, N)
+ b = BilinearImage(img)
+ res1 = b.profile_line((0, 0), (N - 1, N - 1))
+ l = numpy.ceil(numpy.sqrt(2) * N)
+ self.assertEquals(len(res1), l, "Profile has correct length")
+ self.assertLess((res1[:-2] - res1[1:-1]).std(), 1e-3, "profile is linear (excluding last point)")
+
+ def test_profile_gaus(self):
+ N = 100
+ x = numpy.arange(N) - N // 2.0
+ g = numpy.exp(-x * x / (N * N))
+ img = numpy.outer(g, g)
+ b = BilinearImage(img)
+ res_hor = b.profile_line((N // 2, 0), (N // 2, N - 1))
+ res_ver = b.profile_line((0, N // 2), (N - 1, N // 2))
+ self.assertEquals(len(res_hor), N, "Profile has correct length")
+ self.assertEquals(len(res_ver), N, "Profile has correct length")
+ self.assertLess(abs(res_hor - g).max(), 1e-5, "correct horizontal profile")
+ self.assertLess(abs(res_ver - g).max(), 1e-5, "correct vertical profile")
+
+ # Profile with linewidth=3
+ expected_profile = img[:, N // 2 - 1:N // 2 + 2].mean(axis=1)
+ res_hor = b.profile_line((N // 2, 0), (N // 2, N - 1), linewidth=3)
+ res_ver = b.profile_line((0, N // 2), (N - 1, N // 2), linewidth=3)
+
+ self.assertEquals(len(res_hor), N, "Profile has correct length")
+ self.assertEquals(len(res_ver), N, "Profile has correct length")
+ self.assertLess(abs(res_hor - expected_profile).max(), 1e-5,
+ "correct horizontal profile")
+ self.assertLess(abs(res_ver - expected_profile).max(), 1e-5,
+ "correct vertical profile")
+
+
+def suite():
+ testsuite = unittest.TestSuite()
+ testsuite.addTest(TestBilinear("test_max_search_round"))
+ testsuite.addTest(TestBilinear("test_max_search_half"))
+ testsuite.addTest(TestBilinear("test_map"))
+ testsuite.addTest(TestBilinear("test_profile_grad"))
+ testsuite.addTest(TestBilinear("test_profile_gaus"))
+ return testsuite
diff --git a/silx/image/test/test_medianfilter.py b/silx/image/test/test_medianfilter.py
new file mode 100644
index 0000000..5b062d9
--- /dev/null
+++ b/silx/image/test/test_medianfilter.py
@@ -0,0 +1,76 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ############################################################################*/
+"""Tests that the different implementation of opencl (cpp, opencl) are
+ accessible
+"""
+
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "11/05/2017"
+
+import unittest
+from silx.image import medianfilter
+import numpy
+
+from silx.opencl.common import ocl
+
+
+class TestMedianFilterEngines(unittest.TestCase):
+ """Make sure we have access to all the different implementation of
+ median filter from image medfilt"""
+
+
+ IMG = numpy.arange(10000.).reshape(100, 100)
+
+ KERNEL = (1, 1)
+
+ def testCppMedFilt2d(self):
+ """test cpp engine for medfilt2d"""
+ res = medianfilter.medfilt2d(
+ image=TestMedianFilterEngines.IMG,
+ kernel_size=TestMedianFilterEngines.KERNEL,
+ engine='cpp')
+ self.assertTrue(numpy.array_equal(res, TestMedianFilterEngines.IMG))
+
+ @unittest.skipUnless(ocl, "PyOpenCl is missing")
+ def testOpenCLMedFilt2d(self):
+ """test cpp engine for medfilt2d"""
+ res = medianfilter.medfilt2d(
+ image=TestMedianFilterEngines.IMG,
+ kernel_size=TestMedianFilterEngines.KERNEL,
+ engine='opencl')
+ self.assertTrue(numpy.array_equal(res, TestMedianFilterEngines.IMG))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for testClass in (TestMedianFilterEngines, ):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(testClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/image/test/test_shapes.py b/silx/image/test/test_shapes.py
new file mode 100644
index 0000000..ed85165
--- /dev/null
+++ b/silx/image/test/test_shapes.py
@@ -0,0 +1,334 @@
+# 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.
+#
+# ############################################################################*/
+"""Tests for polygon functions
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import logging
+import unittest
+import numpy
+
+from silx.test.utils import ParametricTestCase
+from silx.image import shapes
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+_logger.setLevel(logging.WARNING)
+
+
+class TestPolygonFill(ParametricTestCase):
+ """basic poylgon test"""
+
+ def test_squares(self):
+ """Test polygon fill for a square polygons"""
+ mask_shape = 4, 4
+ tests = {
+ # test name: [(row min, row max), (col min, col max)]
+ 'square in': [(1, 3), (1, 3)],
+ 'square out': [(1, 3), (1, 10)],
+ 'square around': [(-1, 5), (-1, 5)],
+ }
+
+ for test_name, (rows, cols) in tests.items():
+ with self.subTest(msg=test_name, rows=rows, cols=cols,
+ mask_shape=mask_shape):
+ ref_mask = numpy.zeros(mask_shape, dtype=numpy.uint8)
+ ref_mask[max(0, rows[0]):rows[1],
+ max(0, cols[0]):cols[1]] = True
+
+ vertices = [(rows[0], cols[0]), (rows[1], cols[0]),
+ (rows[1], cols[1]), (rows[0], cols[1])]
+ mask = shapes.polygon_fill_mask(vertices, ref_mask.shape)
+ is_equal = numpy.all(numpy.equal(ref_mask, mask))
+ if not is_equal:
+ _logger.debug('%s failed with mask != ref_mask:',
+ test_name)
+ _logger.debug('result:\n%s', str(mask))
+ _logger.debug('ref:\n%s', str(ref_mask))
+ self.assertTrue(is_equal)
+
+ def test_eight(self):
+ """Tests with eight shape with different rotation and direction"""
+ ref_mask = numpy.array((
+ (1, 1, 1, 1, 1, 0),
+ (0, 1, 1, 1, 0, 0),
+ (0, 0, 1, 0, 0, 0),
+ (0, 0, 1, 0, 0, 0),
+ (0, 1, 1, 1, 0, 0),
+ (0, 0, 0, 0, 0, 0)), dtype=numpy.uint8)
+ ref_mask_rot = numpy.asarray(numpy.logical_not(ref_mask),
+ dtype=numpy.uint8)
+ ref_mask_rot[:, -1] = 0
+ ref_mask_rot[-1, :] = 0
+
+ tests = {
+ 'dir 1': ([(0, 0), (5, 5), (5, 0), (0, 5)], ref_mask),
+ 'dir 1, rot 90': ([(5, 0), (0, 5), (5, 5), (0, 0)], ref_mask_rot),
+ 'dir 1, rot 180': ([(5, 5), (0, 0), (0, 5), (5, 0)], ref_mask),
+ 'dir 1, rot -90': ([(0, 5), (5, 0), (0, 0), (5, 5)], ref_mask_rot),
+ 'dir 2': ([(0, 0), (0, 5), (5, 0), (5, 5)], ref_mask),
+ 'dir 2, rot 90': ([(5, 0), (0, 0), (5, 5), (0, 5)], ref_mask_rot),
+ 'dir 2, rot 180': ([(5, 5), (5, 0), (0, 5), (0, 0)], ref_mask),
+ 'dir 2, rot -90': ([(0, 5), (5, 5), (0, 0), (5, 0)], ref_mask_rot),
+ }
+
+ for test_name, (vertices, ref_mask) in tests.items():
+ with self.subTest(msg=test_name):
+ mask = shapes.polygon_fill_mask(vertices, ref_mask.shape)
+ is_equal = numpy.all(numpy.equal(ref_mask, mask))
+ if not is_equal:
+ _logger.debug('%s failed with mask != ref_mask:',
+ test_name)
+ _logger.debug('result:\n%s', str(mask))
+ _logger.debug('ref:\n%s', str(ref_mask))
+ self.assertTrue(is_equal)
+
+ def test_shapes(self):
+ """Tests with shapes and reference mask"""
+ tests = {
+ # name: (
+ # polygon corners as a list of (row, col),
+ # ref_mask)
+ 'concave polygon': (
+ [(1, 1), (4, 3), (1, 5), (2, 3)],
+ numpy.array((
+ (0, 0, 0, 0, 0, 0, 0, 0),
+ (0, 0, 0, 0, 0, 0, 0, 0),
+ (0, 0, 1, 1, 1, 0, 0, 0),
+ (0, 0, 0, 1, 0, 0, 0, 0),
+ (0, 0, 0, 0, 0, 0, 0, 0),
+ (0, 0, 0, 0, 0, 0, 0, 0)), dtype=numpy.uint8)),
+ 'concave polygon partly outside mask': (
+ [(-1, -1), (4, 3), (1, 5), (2, 3)],
+ numpy.array((
+ (1, 0, 0, 0, 0, 0),
+ (0, 1, 0, 0, 0, 0),
+ (0, 0, 1, 1, 1, 0),
+ (0, 0, 0, 1, 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)), dtype=numpy.uint8)),
+ 'polygon surrounding mask': (
+ [(-1, -1), (-1, 7), (7, 7), (7, -1), (0, -1),
+ (8, -2), (8, 8), (-2, 8)],
+ numpy.zeros((6, 6), dtype=numpy.uint8))
+ }
+
+ for test_name, (vertices, ref_mask) in tests.items():
+ with self.subTest(msg=test_name):
+ mask = shapes.polygon_fill_mask(vertices, ref_mask.shape)
+ is_equal = numpy.all(numpy.equal(ref_mask, mask))
+ if not is_equal:
+ _logger.debug('%s failed with mask != ref_mask:',
+ test_name)
+ _logger.debug('result:\n%s', str(mask))
+ _logger.debug('ref:\n%s', str(ref_mask))
+ self.assertTrue(is_equal)
+
+
+class TestDrawLine(ParametricTestCase):
+ """basic draw line test"""
+
+ def test_aligned_lines(self):
+ """Test drawing horizontal, vertical and diagonal lines"""
+
+ lines = { # test_name: (drow, dcol)
+ 'Horizontal line, col0 < col1': (0, 10),
+ 'Horizontal line, col0 > col1': (0, -10),
+ 'Vertical line, row0 < row1': (10, 0),
+ 'Vertical line, row0 > row1': (-10, 0),
+ 'Diagonal col0 < col1 and row0 < row1': (10, 10),
+ 'Diagonal col0 < col1 and row0 > row1': (-10, 10),
+ 'Diagonal col0 > col1 and row0 < row1': (10, -10),
+ 'Diagonal col0 > col1 and row0 > row1': (-10, -10),
+ }
+ row0, col0 = 1, 2 # Start point
+
+ for test_name, (drow, dcol) in lines.items():
+ row1 = row0 + drow
+ col1 = col0 + dcol
+ with self.subTest(msg=test_name, drow=drow, dcol=dcol):
+ # Build reference coordinates from drow and dcol
+ if drow == 0:
+ rows = row0 * numpy.ones(abs(dcol) + 1)
+ else:
+ step = 1 if drow > 0 else -1
+ rows = row0 + numpy.arange(0, drow + step, step)
+
+ if dcol == 0:
+ cols = col0 * numpy.ones(abs(drow) + 1)
+ else:
+ step = 1 if dcol > 0 else -1
+ cols = col0 + numpy.arange(0, dcol + step, step)
+ ref_coords = rows, cols
+
+ result = shapes.draw_line(row0, col0, row1, col1)
+ self.assertTrue(self.isEqual(test_name, result, ref_coords))
+
+ def test_noline(self):
+ """Test pt0 == pt1"""
+ for width in range(4):
+ with self.subTest(width=width):
+ result = shapes.draw_line(1, 2, 1, 2, width)
+ self.assertTrue(numpy.all(numpy.equal(result, [(1,), (2,)])))
+
+ def test_lines(self):
+ """Test lines not aligned with axes for 8 slopes and directions"""
+ row0, col0 = 1, 1
+
+ dy, dx = 3, 5
+ ref_coords = numpy.array(
+ [(0, 0), (1, 1), (1, 2), (2, 3), (2, 4), (3, 5)])
+
+ # Build lines for the 8 octants from this coordinantes
+ lines = { # name: (drow, dcol, ref_coords)
+ '1st octant': (dy, dx, ref_coords),
+ '2nd octant': (dx, dy, ref_coords[:, (1, 0)]), # invert x and y
+ '3rd octant': (dx, -dy, ref_coords[:, (1, 0)] * (1, -1)),
+ '4th octant': (dy, -dx, ref_coords * (1, -1)),
+ '5th octant': (-dy, -dx, ref_coords * (-1, -1)),
+ '6th octant': (-dx, -dy, ref_coords[:, (1, 0)] * (-1, -1)),
+ '7th octant': (-dx, dy, ref_coords[:, (1, 0)] * (-1, 1)),
+ '8th octant': (-dy, dx, ref_coords * (-1, 1))
+ }
+
+ # Test with different starting points with positive and negative coords
+ for row0, col0 in ((0, 0), (2, 3), (-4, 1), (-5, -6), (8, -7)):
+ for name, (drow, dcol, ref_coords) in lines.items():
+ row1 = row0 + drow
+ col1 = col0 + dcol
+ # Transpose from ((row0, col0), ...) to (rows, cols)
+ ref_coords = numpy.transpose(ref_coords + (row0, col0))
+
+ with self.subTest(msg=name,
+ pt0=(row0, col0), pt1=(row1, col1)):
+ result = shapes.draw_line(row0, col0, row1, col1)
+ self.assertTrue(self.isEqual(name, result, ref_coords))
+
+ def test_width(self):
+ """Test of line width"""
+
+ lines = { # test_name: row0, col0, row1, col1, width, ref
+ 'horizontal w=2':
+ (0, 0, 0, 1, 2, ((0, 1, 0, 1),
+ (0, 0, 1, 1))),
+ 'horizontal w=3':
+ (0, 0, 0, 1, 3, ((-1, 0, 1, -1, 0, 1),
+ (0, 0, 0, 1, 1, 1))),
+ 'vertical w=2':
+ (0, 0, 1, 0, 2, ((0, 0, 1, 1),
+ (0, 1, 0, 1))),
+ 'vertical w=3':
+ (0, 0, 1, 0, 3, ((0, 0, 0, 1, 1, 1),
+ (-1, 0, 1, -1, 0, 1))),
+ 'diagonal w=3':
+ (0, 0, 1, 1, 3, ((-1, 0, 1, 0, 1, 2),
+ (0, 0, 0, 1, 1, 1))),
+ '1st octant w=3':
+ (0, 0, 1, 2, 3,
+ numpy.array(((-1, 0), (0, 0), (1, 0),
+ (0, 1), (1, 1), (2, 1),
+ (0, 2), (1, 2), (2, 2))).T),
+ '2nd octant w=3':
+ (0, 0, 2, 1, 3,
+ numpy.array(((0, -1), (0, 0), (0, 1),
+ (1, 0), (1, 1), (1, 2),
+ (2, 0), (2, 1), (2, 2))).T),
+ }
+
+ for test_name, (row0, col0, row1, col1, width, ref) in lines.items():
+ with self.subTest(msg=test_name,
+ pt0=(row0, col0), pt1=(row1, col1), width=width):
+ result = shapes.draw_line(row0, col0, row1, col1, width)
+ self.assertTrue(self.isEqual(test_name, result, ref))
+
+ def isEqual(self, test_name, result, ref):
+ """Test equality of two numpy arrays and log them if different"""
+ is_equal = numpy.all(numpy.equal(result, ref))
+ if not is_equal:
+ _logger.debug('%s failed with result != ref:',
+ test_name)
+ _logger.debug('result:\n%s', str(result))
+ _logger.debug('ref:\n%s', str(ref))
+ return is_equal
+
+
+class TestCircleFill(ParametricTestCase):
+ """Tests for circle filling"""
+
+ def testCircle(self):
+ """Test circle_fill with different input parameters"""
+
+ square3x3 = numpy.array(((-1, -1, -1, 0, 0, 0, 1, 1, 1),
+ (-1, 0, 1, -1, 0, 1, -1, 0, 1)))
+
+ tests = [
+ #crow, ccol, radius, ref_coords = (ref_rows, ref_cols)
+ (0, 0, 1, ((0,), (0,))),
+ (10, 15, 1, ((10,), (15,))),
+ (0, 0, 1.5, square3x3),
+ (5, 10, 2, (5 + square3x3[0], 10 + square3x3[1])),
+ (10, 20, 3.5, (
+ 10 + numpy.array((-3, -3, -3,
+ -2, -2, -2, -2, -2,
+ -1, -1, -1, -1, -1, -1, -1,
+ 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2,
+ 3, 3, 3)),
+ 20 + numpy.array((-1, 0, 1,
+ -2, -1, 0, 1, 2,
+ -3, -2, -1, 0, 1, 2, 3,
+ -3, -2, -1, 0, 1, 2, 3,
+ -3, -2, -1, 0, 1, 2, 3,
+ -2, -1, 0, 1, 2,
+ -1, 0, 1)))),
+ ]
+
+ for crow, ccol, radius, ref_coords in tests:
+ with self.subTest(crow=crow, ccol=ccol, radius=radius):
+ coords = shapes.circle_fill(crow, ccol, radius)
+ is_equal = numpy.all(numpy.equal(coords, ref_coords))
+ if not is_equal:
+ _logger.debug('result:\n%s', str(coords))
+ _logger.debug('ref:\n%s', str(ref_coords))
+ self.assertTrue(is_equal)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for testClass in (TestPolygonFill, TestDrawLine, TestCircleFill):
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(testClass))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/io/__init__.py b/silx/io/__init__.py
new file mode 100644
index 0000000..4e3cace
--- /dev/null
+++ b/silx/io/__init__.py
@@ -0,0 +1,45 @@
+# 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.
+#
+# ###########################################################################*/
+"""I/O modules"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "20/01/2017"
+
+
+import logging
+
+
+# Init logging once for the whole module
+logging.basicConfig()
+
+from .utils import open # pylint:disable=redefined-builtin
+from .utils import save1D
+
+from .utils import is_dataset
+from .utils import is_file
+from .utils import is_group
+
+__all__ = ["save1D", "is_dataset", "is_file", "is_group"] # avoid to import open with "import *"
diff --git a/silx/io/configdict.py b/silx/io/configdict.py
new file mode 100644
index 0000000..21e24b7
--- /dev/null
+++ b/silx/io/configdict.py
@@ -0,0 +1,540 @@
+# /*##########################################################################
+# Copyright (C) 2004-2016 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# 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.
+#
+# ############################################################################*/
+"""
+This module handles read and write operations to INI files, with data type
+preservation and support for nesting subsections to any depth.
+
+Data to be written to INI must be stored in a dictionary with string keys.
+Data cannot be stored at the root level of the dictionary, it must be inside
+a sub-dictionary. This means that in the INI file, all parameters must be
+in a section, and if you need a `default` section you must define it
+explicitly.
+
+Usage example:
+==============
+
+Write a dictionary to an INI file::
+
+ from silx.io.configdict import ConfigDict
+
+ ddict = {
+ 'simple_types': {
+ 'float': 1.0,
+ 'int': 1,
+ 'string': 'Hello World',
+ },
+ 'containers': {
+ 'list': [-1, 'string', 3.0, False],
+ 'array': numpy.array([1.0, 2.0, 3.0]),
+ 'dict': {
+ 'key1': 'Hello World',
+ 'key2': 2.0,
+ }
+ }
+ }
+
+ ConfigDict(initdict=ddict).write("foo.ini")
+
+
+Read an INI file into a dictionary like structure::
+
+ from silx.io.configdict import ConfigDict
+
+ confdict = ConfigDict()
+ confdict.read("foo.ini")
+
+ print("Available sections in INI file:")
+ print(confdict.keys())
+
+ for key in confdict:
+ for subkey in confdict[key]:
+ print("Section %s, parameter %s:" % (key, subkey))
+ print(confdict[key][subkey])
+
+
+Classes:
+========
+
+- :class:`ConfigDict`
+- :class:`OptionStr`
+
+"""
+
+
+__author__ = ["E. Papillon", "V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "15/09/2016"
+
+from collections import OrderedDict
+import numpy
+import re
+import sys
+if sys.version < '3.0':
+ import ConfigParser as configparser
+else:
+ import configparser
+
+
+string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+
+
+def _boolean(sstr):
+ """Coerce a string to a boolean following the same convention as
+ :meth:`configparser.ConfigParser.getboolean`:
+ - '1', 'yes', 'true' and 'on' cause this function to return ``True``
+ - '0', 'no', 'false' and 'off' cause this function to return ``False``
+
+ :param sstr: String representation of a boolean
+ :return: ``True`` or ``False``
+ :raise: ``ValueError`` if ``sstr`` is not a valid string representation
+ of a boolean
+ """
+ if sstr.lower() in ['1', 'yes', 'true', 'on']:
+ return True
+ if sstr.lower() in ['0', 'no', 'false', 'off']:
+ return False
+ msg = "Cannot coerce string '%s' to a boolean value. " % sstr
+ msg += "Valid boolean strings: '1', 'yes', 'true', 'on', "
+ msg += "'0', 'no', 'false', 'off'"
+ raise ValueError(msg)
+
+
+def _parse_simple_types(sstr):
+ """Coerce a string representation of a value to the most appropriate data
+ type, by trial and error.
+
+ Typecasting is attempted to following data types (in this order):
+ `int`, `float`, `boolean`. If all of these conversions fail, ``sstr``
+ is assumed to be a string.
+
+ :param sstr: String representation of an unknown data type
+ :return: Value coerced into the most appropriate data type
+ """
+ try:
+ return int(sstr)
+ except ValueError:
+ try:
+ return float(sstr)
+ except ValueError:
+ try:
+ return _boolean(sstr)
+ except ValueError:
+ if sstr.strip() == "None":
+ return None
+ # un-escape string
+ sstr = sstr.lstrip("\\")
+ # un-escape commas
+ sstr = sstr.replace("\,", ",").replace("^@", ",")
+ return sstr
+
+
+def _parse_container(sstr):
+ """Parse a string representation of a list or a numpy array.
+
+ A string such as ``"-1, Hello World, 3.0"`` is interpreted as the list
+ ``[-1, "Hello World", 3.0]``. ``"-1, "no", 3.0\n\t1, 2"`` is interpreted
+ a list of 2 lists ``[[-1, False, 3.0], [1, 2]]``
+
+ Strings such as ``"[ [ 1. 2. 3.] [ 4. 5. 6.] ]"`` or
+ ``[ 1.0 2.0 3.0 ]`` are interpreted as numpy arrays. Only 1D and 2D
+ arrays are permitted.
+
+ :param sstr: String representation of an container type
+ :return: List or array
+ :raise: ``ValueError`` if string is not a list or an array
+ """
+ sstr = sstr.strip()
+
+ if not sstr:
+ raise ValueError
+
+ if sstr.find(',') == -1:
+ # it is not a list
+ if (sstr[0] == '[') and (sstr[-1] == ']'):
+ # this looks like an array
+ try:
+ # try parsing as a 1D array
+ return numpy.array([float(x) for x in sstr[1:-1].split()])
+ except ValueError:
+ # try parsing as a 2D array
+ if (sstr[2] == '[') and (sstr[-3] == ']'):
+ nrows = len(sstr[3:-3].split('] ['))
+ data = sstr[3:-3].replace('] [', ' ')
+ data = numpy.array([float(x) for x in
+ data.split()])
+ data.shape = nrows, -1
+ return data
+ # not a list and not an array
+ raise ValueError
+ else:
+ # if all commas are escaped, it is a strinq, not a list
+ if sstr.count(",") == sstr.count("\,"):
+ raise ValueError
+
+ dataline = [line for line in sstr.splitlines()]
+ if len(dataline) == 1:
+ return _parse_list_line(dataline[0])
+ else:
+ return [_parse_list_line(line) for line in dataline]
+
+
+def _parse_list_line(sstr):
+ """Parse the string representation of a simple 1D list:
+
+ ``"12, 13.1, True, Hello"`` ``->`` ``[12, 13.1, True, "Hello"]``
+
+ :param sstr: String
+ :return: List
+ """
+ sstr = sstr.strip()
+
+ # preserve escaped commas in strings before splitting list
+ # (_parse_simple_types recognizes ^@ as a comma)
+ sstr.replace("\,", "^@")
+ # it is a list
+ if sstr.endswith(','):
+ if ',' in sstr[:-1]:
+ return [_parse_simple_types(sstr2.strip())
+ for sstr2 in sstr[:-1].split(',')]
+ else:
+ return [_parse_simple_types(sstr[:-1].strip())]
+ else:
+ return [_parse_simple_types(sstr2.strip())
+ for sstr2 in sstr.split(',')]
+
+
+class OptionStr(str):
+ """String class providing typecasting methods to parse values in a
+ :class:`ConfigDict` generated configuration file.
+ """
+ def toint(self):
+ """
+ :return: integer
+ :raise: ``ValueError`` if conversion to ``int`` failed
+ """
+ return int(self)
+
+ def tofloat(self):
+ """
+ :return: Floating point value
+ :raise: ``ValueError`` if conversion to ``float`` failed
+ """
+ return float(self)
+
+ def toboolean(self):
+ """
+ '1', 'yes', 'true' and 'on' are interpreted as ``True``
+
+ '0', 'no', 'false' and 'off' are interpreted as ``False``
+
+ :return: Boolean
+ :raise: ``ValueError`` if conversion to ``bool`` failed
+ """
+ return _boolean(self)
+
+ def tostr(self):
+ """Return string after replacing escaped commas ``\,`` with regular
+ commas ``,`` and removing leading backslash.
+
+ :return: str(self)
+ """
+ return str(self.replace("\,", ",").lstrip("\\"))
+
+ def tocontainer(self):
+ """Return a list or a numpy array.
+
+ Any string containing a comma (``,``) character will be interpreted
+ as a list: for instance ``-1, Hello World, 3.0``, or ``2.0,``
+
+ The format for numpy arrays is a blank space delimited list of values
+ between square brackets: ``[ 1.3 2.2 3.1 ]``, or
+ ``[ [ 1 2 3 ] [ 1 4 9 ] ]``"""
+ return _parse_container(self)
+
+ def tobestguess(self):
+ """Parse string without prior knowledge of type.
+
+ Conversion to following types is attempted, in this order:
+ `list`, `numpy array`, `int`, `float`, `boolean`.
+ If all of these conversions fail, the string is returned after
+ removing escape characters.
+ """
+ try:
+ return _parse_container(self)
+ except ValueError:
+ return _parse_simple_types(self)
+
+
+class ConfigDict(OrderedDict):
+ """Store configuration parameters as an ordered dictionary.
+
+ Parameters can be grouped into sections, by storing them as
+ sub-dictionaries.
+
+ Keys must be strings. Values can be: integers, booleans, lists,
+ numpy arrays, floats, strings.
+
+ Methods are provided to write a configuration file in a variant of INI
+ format. A :class:`ConfigDict` can load (or be initialized from) a list of files.
+
+ The main differences between files written/read by this class and standard
+ ``ConfigParser`` files are:
+
+ - sections can be nested to any depth
+ - value types are guessed when the file is read back
+ - to prevent strings from being interpreted as lists, commas are
+ escaped with a backslash (``\,``)
+ - strings may be prefixed with a leading backslash (``\``) to prevent
+ conversion to numeric or boolean values
+
+ :param defaultdict: Default dictionary used to initialize the
+ :class:`ConfigDict` instance and reinitialize it in case
+ :meth:`reset` is called
+ :param initdict: Additional initialisation dictionary, added into dict
+ after initialisation with ``defaultdict``
+ :param filelist: List of configuration files to be read and added into
+ dict after ``defaultdict`` and ``initdict``
+ """
+ def __init__(self, defaultdict=None, initdict=None, filelist=None):
+ self.default = defaultdict if defaultdict is not None else OrderedDict()
+ OrderedDict.__init__(self, self.default)
+ self.filelist = []
+
+ if initdict is not None:
+ self.update(initdict)
+ if filelist is not None:
+ self.read(filelist)
+
+ def reset(self):
+ """ Revert to default values
+ """
+ self.clear()
+ self.update(self.default)
+
+ def clear(self):
+ """ Clear dictionnary
+ """
+ OrderedDict.clear(self)
+ self.filelist = []
+
+ def __tolist(self, mylist):
+ """ If ``mylist` is not a list, encapsulate it in a list and return
+ it.
+
+ :param mylist: List to encapsulate
+ :returns: ``mylist`` if it is a list, ``[mylist]`` if it isn't
+ """
+ if mylist is None:
+ return None
+ if not isinstance(mylist, list):
+ return [mylist]
+ else:
+ return mylist
+
+ def getfiles(self):
+ """Return list of configuration file names"""
+ return self.filelist
+
+ def getlastfile(self):
+ """Return last configuration file name"""
+ return self.filelist[len(self.filelist) - 1]
+
+ def __convert(self, option):
+ """Used as ``configparser.ConfigParser().optionxform`` to transform
+ option names on every read, get, or set operation.
+
+ This overrides the default :mod:`ConfigParser` behavior, in order to
+ preserve case rather converting names to lowercase.
+
+ :param option: Option name (any string)
+ :return: ``option`` unchanged
+ """
+ return option
+
+ def read(self, filelist, sections=None):
+ """
+ Read all specified configuration files into the internal dictionary.
+
+ :param filelist: List of names of files to be added into the internal
+ dictionary
+ :param sections: If not ``None``, add only the content of the
+ specified sections
+ :type sections: list
+ """
+ filelist = self.__tolist(filelist)
+ sections = self.__tolist(sections)
+ cfg = configparser.ConfigParser()
+ cfg.optionxform = self.__convert
+ cfg.read(filelist)
+ self.__read(cfg, sections)
+
+ for ffile in filelist:
+ self.filelist.append([ffile, sections])
+
+ def __read(self, cfg, sections=None):
+ """Read a :class:`configparser.ConfigParser` instance into the
+ internal dictionary.
+
+ :param cfg: Instance of :class:`configparser.ConfigParser`
+ :param sections: If not ``None``, add only the content of the
+ specified sections into the internal dictionary
+ """
+ cfgsect = cfg.sections()
+
+ if sections is None:
+ readsect = cfgsect
+ else:
+ readsect = [sect for sect in cfgsect if sect in sections]
+
+ for sect in readsect:
+ ddict = self
+ for subsectw in sect.split('.'):
+ subsect = subsectw.replace("_|_", ".")
+ if not subsect in ddict:
+ ddict[subsect] = OrderedDict()
+ ddict = ddict[subsect]
+ for opt in cfg.options(sect):
+ ddict[opt] = self.__parse_data(cfg.get(sect, opt))
+
+ def __parse_data(self, data):
+ """Parse an option returned by ``ConfigParser``.
+
+ :param data: Option string to be parsed
+
+ The original option is a string, we try to parse it as one of
+ following types: `numpx array`, `list`, `float`, `int`, `boolean`,
+ `string`
+ """
+ return OptionStr(data).tobestguess()
+
+ def tostring(self):
+ """Return INI file content generated by :meth:`write` as a string
+ """
+ import StringIO
+ tmp = StringIO.StringIO()
+ self.__write(tmp, self)
+ return tmp.getvalue()
+
+ def write(self, ffile):
+ """Write the current dictionary to the given filename or
+ file handle.
+
+ :param ffile: Output file name or file handle. If a file name is
+ provided, the method opens it, writes it and closes it again.
+ """
+ if not hasattr(ffile, "write"):
+ fp = open(ffile, "w")
+ else:
+ fp = ffile
+
+ self.__write(fp, self)
+
+ if not hasattr(ffile, "write"):
+ fp.close()
+
+ def _escape_str(self, sstr):
+ """Escape strings and special characters in strings with a ``\``
+ character to ensure they are read back as strings and not parsed.
+
+ :param sstr: String to be escaped
+ :returns sstr: String with escape characters (if needed)
+
+ This way, we ensure these strings cannot be interpreted as a numeric
+ or boolean types and commas in strings are not interpreted as list
+ items separators. We also escape ``%`` when it is not followed by a
+ ``(``, as required by :mod:`configparser` because ``%`` is used in
+ the interpolation syntax
+ (https://docs.python.org/3/library/configparser.html#interpolation-of-values).
+ """
+ non_str = r'^([0-9]+|[0-9]*\.[0-9]*|none|false|true|on|off|yes|no)$'
+ if re.match(non_str, sstr.lower()):
+ sstr = "\\" + sstr
+ # Escape commas
+ sstr = sstr.replace(",", "\,")
+
+ if sys.version > '3.0':
+ # Escape % characters except in "%%" and "%("
+ sstr = re.sub(r'%([^%\(])', r'%%\1', sstr)
+
+ return sstr
+
+ def __write(self, fp, ddict, secthead=None):
+ """Do the actual file writing when called by the ``write`` method.
+
+ :param fp: File handle
+ :param ddict: Dictionary to be written to file
+ :param secthead: Prefix for section name, used for handling nested
+ dictionaries recursively.
+ """
+ dictkey = []
+
+ for key in ddict.keys():
+ if hasattr(ddict[key], 'keys'):
+ # subsections are added at the end of a section
+ dictkey.append(key)
+ elif isinstance(ddict[key], list):
+ fp.write('%s = ' % key)
+ llist = []
+ sep = ', '
+ for item in ddict[key]:
+ if isinstance(item, list):
+ if len(item) == 1:
+ if isinstance(item[0], string_types):
+ self._escape_str(item[0])
+ llist.append('%s,' % self._escape_str(item[0]))
+ else:
+ llist.append('%s,' % item[0])
+ else:
+ item2 = []
+ for val in item:
+ if isinstance(val, string_types):
+ val = self._escape_str(val)
+ item2.append(val)
+ llist.append(', '.join([str(val) for val in item2]))
+ sep = '\n\t'
+ elif isinstance(item, string_types):
+ llist.append(self._escape_str(item))
+ else:
+ llist.append(str(item))
+ fp.write('%s\n' % (sep.join(llist)))
+ elif isinstance(ddict[key], string_types):
+ fp.write('%s = %s\n' % (key, self._escape_str(ddict[key])))
+ else:
+ if isinstance(ddict[key], numpy.ndarray):
+ fp.write('%s =' % key + ' [ ' +
+ ' '.join([str(val) for val in ddict[key]]) +
+ ' ]\n')
+ else:
+ fp.write('%s = %s\n' % (key, ddict[key]))
+
+ for key in dictkey:
+ if secthead is None:
+ newsecthead = key.replace(".", "_|_")
+ else:
+ newsecthead = '%s.%s' % (secthead, key.replace(".", "_|_"))
+
+ fp.write('\n[%s]\n' % newsecthead)
+ self.__write(fp, ddict[key], newsecthead)
diff --git a/silx/io/dictdump.py b/silx/io/dictdump.py
new file mode 100644
index 0000000..ae7a457
--- /dev/null
+++ b/silx/io/dictdump.py
@@ -0,0 +1,366 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""This module offers a set of functions to dump a python dictionary indexed
+by text strings to following file formats: `HDF5, INI, JSON`
+"""
+
+from collections import OrderedDict
+import json
+import logging
+import numpy
+import os.path
+import sys
+
+try:
+ import h5py
+except ImportError as e:
+ h5py_missing = True
+ h5py_import_error = e
+else:
+ h5py_missing = False
+
+from .configdict import ConfigDict
+from .utils import is_group, is_file
+
+from silx.io import open as h5open
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "10/02/2017"
+
+logger = logging.getLogger(__name__)
+
+string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+
+
+def _prepare_hdf5_dataset(array_like):
+ """Cast a python object into a numpy array in a HDF5 friendly format.
+
+ :param array_like: Input dataset in a type that can be digested by
+ ``numpy.array()`` (`str`, `list`, `numpy.ndarray`…)
+ :return: ``numpy.ndarray`` ready to be written as an HDF5 dataset
+ """
+ # simple strings
+ if isinstance(array_like, string_types):
+ array_like = numpy.string_(array_like)
+
+ # Ensure our data is a numpy.ndarray
+ if not isinstance(array_like, (numpy.ndarray, numpy.string_)):
+ array = numpy.array(array_like)
+ else:
+ array = array_like
+
+ # handle list of strings or numpy array of strings
+ if not isinstance(array, numpy.string_):
+ data_kind = array.dtype.kind
+ # unicode: convert to byte strings
+ # (http://docs.h5py.org/en/latest/strings.html)
+ if data_kind.lower() in ["s", "u"]:
+ array = numpy.asarray(array, dtype=numpy.string_)
+
+ return array
+
+
+def dicttoh5(treedict, h5file, h5path='/',
+ mode="w", overwrite_data=False,
+ create_dataset_args=None):
+ """Write a nested dictionary to a HDF5 file, using keys as member names.
+
+ If a dictionary value is a sub-dictionary, a group is created. If it is
+ any other data type, it is cast into a numpy array and written as a
+ :mod:`h5py` dataset. Dictionary keys must be strings and cannot contain
+ the ``/`` character.
+
+ .. note::
+
+ This function requires `h5py <http://www.h5py.org/>`_ to be installed.
+
+ :param treedict: Nested dictionary/tree structure with strings as keys
+ and array-like objects as leafs. The ``"/"`` character is not allowed
+ in keys.
+ :param h5file: HDF5 file name or handle. If a file name is provided, the
+ function opens the file in the specified mode and closes it again
+ before completing.
+ :param h5path: Target path in HDF5 file in which scan groups are created.
+ Default is root (``"/"``)
+ :param mode: Can be ``"r+"`` (read/write, file must exist),
+ ``"w"`` (write, existing file is lost), ``"w-"`` (write, fail if
+ exists) or ``"a"`` (read/write if exists, create otherwise).
+ This parameter is ignored if ``h5file`` is a file handle.
+ :param overwrite_data: If ``True``, existing groups and datasets can be
+ overwritten, if ``False`` they are skipped. This parameter is only
+ relevant if ``h5file_mode`` is ``"r+"`` or ``"a"``.
+ :param create_dataset_args: Dictionary of args you want to pass to
+ ``h5f.create_dataset``. This allows you to specify filters and
+ compression parameters. Don't specify ``name`` and ``data``.
+
+ Example::
+
+ from silx.io.dictdump import dicttoh5
+
+ city_area = {
+ "Europe": {
+ "France": {
+ "Isère": {
+ "Grenoble": "18.44 km2"
+ },
+ "Nord": {
+ "Tourcoing": "15.19 km2"
+ },
+ },
+ },
+ }
+
+ create_ds_args = {'compression': "gzip",
+ 'shuffle': True,
+ 'fletcher32': True}
+
+ dicttoh5(city_area, "cities.h5", h5path="/area",
+ create_dataset_args=create_ds_args)
+ """
+ if h5py_missing:
+ raise h5py_import_error
+
+ if not isinstance(h5file, h5py.File):
+ h5f = h5py.File(h5file, mode)
+ else:
+ h5f = h5file
+
+ if not h5path.endswith("/"):
+ h5path += "/"
+
+ for key in treedict:
+
+ if isinstance(treedict[key], dict) and len(treedict[key]):
+ # non-empty group: recurse
+ dicttoh5(treedict[key], h5f, h5path + key,
+ overwrite_data=overwrite_data,
+ create_dataset_args=create_dataset_args)
+
+ elif treedict[key] is None or (isinstance(treedict[key], dict) and
+ not len(treedict[key])):
+ # Create empty group
+ h5f.create_group(h5path + key)
+
+ else:
+ ds = _prepare_hdf5_dataset(treedict[key])
+ # can't apply filters on scalars (datasets with shape == () )
+ if ds.shape == () or create_dataset_args is None:
+ h5f.create_dataset(h5path + key,
+ data=ds)
+ else:
+ h5f.create_dataset(h5path + key,
+ data=ds,
+ **create_dataset_args)
+
+ if isinstance(h5file, string_types):
+ h5f.close()
+
+
+def _name_contains_string_in_list(name, strlist):
+ if strlist is None:
+ return False
+ for filter_str in strlist:
+ if filter_str in name:
+ return True
+ return False
+
+
+def h5todict(h5file, path="/", exclude_names=None):
+ """Read a HDF5 file and return a nested dictionary with the complete file
+ structure and all data.
+
+ Example of usage::
+
+ from silx.io.dictdump import h5todict
+
+ # initialize dict with file header and scan header
+ header94 = h5todict("oleg.dat",
+ "/94.1/instrument/specfile")
+ # add positioners subdict
+ header94["positioners"] = h5todict("oleg.dat",
+ "/94.1/instrument/positioners")
+ # add scan data without mca data
+ header94["detector data"] = h5todict("oleg.dat",
+ "/94.1/measurement",
+ exclude_names="mca_")
+
+
+ .. note:: This function requires `h5py <http://www.h5py.org/>`_ to be
+ installed.
+
+ .. note:: If you write a dictionary to a HDF5 file with
+ :func:`dicttoh5` and then read it back with :func:`h5todict`, data
+ types are not preserved. All values are cast to numpy arrays before
+ being written to file, and they are read back as numpy arrays (or
+ scalars). In some cases, you may find that a list of heterogeneous
+ data types is converted to a numpy array of strings.
+
+ :param h5file: File name or :class:`h5py.File` object or spech5 file or
+ fabioh5 file.
+ :param str path: Name of HDF5 group to use as dictionary root level,
+ to read only a sub-group in the file
+ :param list[str] exclude_names: Groups and datasets whose name contains
+ a string in this list will be ignored. Default is None (ignore nothing)
+ :return: Nested dictionary
+ """
+ if h5py_missing:
+ raise h5py_import_error
+
+ if not is_file(h5file):
+ h5f = h5open(h5file)
+ else:
+ h5f = h5file
+
+ ddict = {}
+ for key in h5f[path]:
+ if _name_contains_string_in_list(key, exclude_names):
+ continue
+ if is_group(h5f[path + "/" + key]):
+ ddict[key] = h5todict(h5f,
+ path + "/" + key,
+ exclude_names=exclude_names)
+ else:
+ # Convert HDF5 dataset to numpy array
+ ddict[key] = h5f[path + "/" + key][...]
+
+ if not is_file(h5file):
+ # close file, if we opened it
+ h5f.close()
+
+ return ddict
+
+
+def dicttojson(ddict, jsonfile, indent=None, mode="w"):
+ """Serialize ``ddict`` as a JSON formatted stream to ``jsonfile``.
+
+ :param ddict: Dictionary (or any object compatible with ``json.dump``).
+ :param jsonfile: JSON file name or file-like object.
+ If a file name is provided, the function opens the file in the
+ specified mode and closes it again.
+ :param indent: If indent is a non-negative integer, then JSON array
+ elements and object members will be pretty-printed with that indent
+ level. An indent level of ``0`` will only insert newlines.
+ ``None`` (the default) selects the most compact representation.
+ :param mode: File opening mode (``w``, ``a``, ``w+``…)
+ """
+ if not hasattr(jsonfile, "write"):
+ jsonf = open(jsonfile, mode)
+ else:
+ jsonf = jsonfile
+
+ json.dump(ddict, jsonf, indent=indent)
+
+ if not hasattr(jsonfile, "write"):
+ jsonf.close()
+
+
+def dicttoini(ddict, inifile, mode="w"):
+ """Output dict as configuration file (similar to Microsoft Windows INI).
+
+ :param dict: Dictionary of configuration parameters
+ :param inifile: INI file name or file-like object.
+ If a file name is provided, the function opens the file in the
+ specified mode and closes it again.
+ :param mode: File opening mode (``w``, ``a``, ``w+``…)
+ """
+ if not hasattr(inifile, "write"):
+ inif = open(inifile, mode)
+ else:
+ inif = inifile
+
+ ConfigDict(initdict=ddict).write(inif)
+
+ if not hasattr(inifile, "write"):
+ inif.close()
+
+
+def dump(ddict, ffile, mode="w", fmat=None):
+ """Dump dictionary to a file
+
+ :param ddict: Dictionary with string keys
+ :param ffile: File name or file-like object with a ``write`` method
+ :param str fmat: Output format: ``"json"``, ``"hdf5"`` or ``"ini"``.
+ When None (the default), it uses the filename extension as the format.
+ Dumping to a HDF5 file requires `h5py <http://www.h5py.org/>`_ to be
+ installed.
+ :param str mode: File opening mode (``w``, ``a``, ``w+``…)
+ Default is *"w"*, write mode, overwrite if exists.
+ :raises IOError: if file format is not supported
+ """
+ if fmat is None:
+ # If file-like object get its name, else use ffile as filename
+ filename = getattr(ffile, 'name', ffile)
+ fmat = os.path.splitext(filename)[1][1:] # Strip extension leading '.'
+ fmat = fmat.lower()
+
+ if fmat == "json":
+ dicttojson(ddict, ffile, indent=2, mode=mode)
+ elif fmat in ["hdf5", "h5"]:
+ if h5py_missing:
+ logger.error("Cannot dump to HDF5 format, missing h5py library")
+ raise h5py_import_error
+ dicttoh5(ddict, ffile, mode=mode)
+ elif fmat in ["ini", "cfg"]:
+ dicttoini(ddict, ffile, mode=mode)
+ else:
+ raise IOError("Unknown format " + fmat)
+
+
+def load(ffile, fmat=None):
+ """Load dictionary from a file
+
+ When loading from a JSON or INI file, an OrderedDict is returned to
+ preserve the values' insertion order.
+
+ :param ffile: File name or file-like object with a ``read`` method
+ :param fmat: Input format: ``json``, ``hdf5`` or ``ini``.
+ When None (the default), it uses the filename extension as the format.
+ Loading from a HDF5 file requires `h5py <http://www.h5py.org/>`_ to be
+ installed.
+ :return: Dictionary (ordered dictionary for JSON and INI)
+ :raises IOError: if file format is not supported
+ """
+ if not hasattr(ffile, "read"):
+ f = open(ffile, "r")
+ fname = ffile
+ else:
+ f = ffile
+ fname = ffile.name
+
+ if fmat is None: # Use file extension as format
+ fmat = os.path.splitext(fname)[1][1:] # Strip extension leading '.'
+ fmat = fmat.lower()
+
+ if fmat == "json":
+ return json.load(f, object_pairs_hook=OrderedDict)
+ if fmat in ["hdf5", "h5"]:
+ if h5py_missing:
+ logger.error("Cannot load from HDF5 format, missing h5py library")
+ raise h5py_import_error
+ return h5todict(fname)
+ elif fmat in ["ini", "cfg"]:
+ return ConfigDict(filelist=[fname])
+ else:
+ raise IOError("Unknown format " + fmat)
diff --git a/silx/io/fabioh5.py b/silx/io/fabioh5.py
new file mode 100644
index 0000000..092ac0c
--- /dev/null
+++ b/silx/io/fabioh5.py
@@ -0,0 +1,1151 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""This module provides functions to read fabio images as an HDF5 file.
+
+ >>> import silx.io.fabioh5
+ >>> f = silx.io.fabioh5.File("foobar.edf")
+
+.. note:: This module has a dependency on the `h5py <http://www.h5py.org/>`_
+ and `fabio <https://github.com/silx-kit/fabio>`_ libraries,
+ which are not a mandatory dependencies for `silx`. You might need
+ to install it if you don't already have it.
+"""
+
+import collections
+import numpy
+import numbers
+import logging
+from silx.third_party import six
+
+_logger = logging.getLogger(__name__)
+
+try:
+ import fabio
+except ImportError as e:
+ _logger.error("Module %s requires fabio", __name__)
+ raise e
+
+try:
+ import h5py
+except ImportError as e:
+ _logger.error("Module %s requires h5py", __name__)
+ raise e
+
+
+class Node(object):
+ """Main class for all fabioh5 classes. Help to manage a tree."""
+
+ def __init__(self, name, parent=None):
+ self.__parent = parent
+ self.__basename = name
+
+ @property
+ def h5py_class(self):
+ """Returns the h5py classes which is mimicked by this class. It can be
+ one of `h5py.File, h5py.Group` or `h5py.Dataset`
+
+ :rtype: Class
+ """
+ raise NotImplementedError()
+
+ @property
+ def parent(self):
+ """Returns the parent of the node.
+
+ :rtype: Node
+ """
+ return self.__parent
+
+ @property
+ def file(self):
+ """Returns the file node of this node.
+
+ :rtype: Node
+ """
+ node = self
+ while node.__parent is not None:
+ node = node.__parent
+ if isinstance(node, File):
+ return node
+ else:
+ return None
+
+ def _set_parent(self, parent):
+ """Set the parent of this node.
+
+ It do not update the parent object.
+
+ :param Node parent: New parent for this node
+ """
+ self.__parent = parent
+
+ @property
+ def attrs(self):
+ """Returns HDF5 attributes of this node.
+
+ :rtype: dict
+ """
+ return {}
+
+ @property
+ def name(self):
+ """Returns the HDF5 name of this node.
+ """
+ if self.__parent is None:
+ return "/"
+ if self.__parent.name == "/":
+ return "/" + self.basename
+ return self.__parent.name + "/" + self.basename
+
+ @property
+ def basename(self):
+ """Returns the HDF5 basename of this node.
+ """
+ return self.__basename
+
+
+class Dataset(Node):
+ """Class which handle a numpy data as a mimic of a h5py.Dataset.
+ """
+
+ def __init__(self, name, data, parent=None, attrs=None):
+ self.__data = data
+ Node.__init__(self, name, parent)
+ if attrs is None:
+ self.__attrs = {}
+ else:
+ self.__attrs = attrs
+
+ def _set_data(self, data):
+ """Set the data exposed by the dataset.
+
+ It have to be called only one time before the data is used. It should
+ not be edited after use.
+
+ :param numpy.ndarray data: Data associated to the dataset
+ """
+ self.__data = data
+
+ def _get_data(self):
+ """Returns the exposed data
+
+ :rtype: numpy.ndarray
+ """
+ return self.__data
+
+ @property
+ def attrs(self):
+ """Returns HDF5 attributes of this node.
+
+ :rtype: dict
+ """
+ return self.__attrs
+
+ @property
+ def h5py_class(self):
+ """Returns the h5py classes which is mimicked by this class. It can be
+ one of `h5py.File, h5py.Group` or `h5py.Dataset`
+
+ :rtype: Class
+ """
+ return h5py.Dataset
+
+ @property
+ def dtype(self):
+ """Returns the numpy datatype exposed by this dataset.
+
+ :rtype: numpy.dtype
+ """
+ return self._get_data().dtype
+
+ @property
+ def shape(self):
+ """Returns the shape of the data exposed by this dataset.
+
+ :rtype: tuple
+ """
+ if isinstance(self._get_data(), numpy.ndarray):
+ return self._get_data().shape
+ else:
+ return tuple()
+
+ @property
+ def size(self):
+ """Returns the size of the data exposed by this dataset.
+
+ :rtype: int
+ """
+ if isinstance(self._get_data(), numpy.ndarray):
+ return self._get_data().size
+ else:
+ # It is returned as float64 1.0 by h5py
+ return numpy.float64(1.0)
+
+ def __len__(self):
+ """Returns the size of the data exposed by this dataset.
+
+ :rtype: int
+ """
+ if isinstance(self._get_data(), numpy.ndarray):
+ return len(self._get_data())
+ else:
+ # It is returned as float64 1.0 by h5py
+ raise TypeError("Attempt to take len() of scalar dataset")
+
+ def __getitem__(self, item):
+ """Returns the slice of the data exposed by this dataset.
+
+ :rtype: numpy.ndarray
+ """
+ if not isinstance(self._get_data(), numpy.ndarray):
+ if item == Ellipsis:
+ return numpy.array(self._get_data())
+ elif item == tuple():
+ return self._get_data()
+ else:
+ raise ValueError("Scalar can only be reached with an ellipsis or an empty tuple")
+ return self._get_data().__getitem__(item)
+
+ def __str__(self):
+ basename = self.name.split("/")[-1]
+ return '<FabIO dataset "%s": shape %s, type "%s">' % \
+ (basename, self.shape, self.dtype.str)
+
+ def __getslice__(self, i, j):
+ """Returns the slice of the data exposed by this dataset.
+
+ Deprecated but still in use for python 2.7
+
+ :rtype: numpy.ndarray
+ """
+ return self.__getitem__(slice(i, j, None))
+
+ @property
+ def value(self):
+ """Returns the data exposed by this dataset.
+
+ Deprecated by h5py. It is prefered to use indexing `[()]`.
+
+ :rtype: numpy.ndarray
+ """
+ return self._get_data()
+
+ @property
+ def compression(self):
+ """Returns compression as provided by `h5py.Dataset`.
+
+ There is no compression."""
+ return None
+
+ @property
+ def compression_opts(self):
+ """Returns compression options as provided by `h5py.Dataset`.
+
+ There is no compression."""
+ return None
+
+ @property
+ def chunks(self):
+ """Returns chunks as provided by `h5py.Dataset`.
+
+ There is no chunks."""
+ return None
+
+
+class LazyLoadableDataset(Dataset):
+ """Abstract dataset which provide a lazy loading of the data.
+
+ The class have to be inherited and the :meth:`_create_data` have to be
+ implemented to return the numpy data exposed by the dataset. This factory
+ is only called ones, when the data is needed.
+ """
+
+ def __init__(self, name, parent=None, attrs=None):
+ super(LazyLoadableDataset, self).__init__(name, None, parent, attrs=attrs)
+ self.__is_initialized = False
+
+ def _create_data(self):
+ """
+ Factory to create the data exposed by the dataset when it is needed.
+
+ It have to be implemented to work.
+
+ :rtype: numpy.ndarray
+ """
+ raise NotImplementedError()
+
+ def _get_data(self):
+ """Returns the data exposed by the dataset.
+
+ Overwrite Dataset method :meth:`_get_data` to implement the lazy
+ loading feature.
+
+ :rtype: numpy.ndarray
+ """
+ if not self.__is_initialized:
+ data = self._create_data()
+ self._set_data(data)
+ self.__is_initialized = True
+ return super(LazyLoadableDataset, self)._get_data()
+
+
+class Group(Node):
+ """Class which mimic a `h5py.Group`."""
+
+ def __init__(self, name, parent=None, attrs=None):
+ Node.__init__(self, name, parent)
+ self.__items = collections.OrderedDict()
+ if attrs is None:
+ attrs = {}
+ self.__attrs = attrs
+
+ def _get_items(self):
+ """Returns the child items as a name-node dictionary.
+
+ :rtype: dict
+ """
+ return self.__items
+
+ def add_node(self, node):
+ """Add a child to this group.
+
+ :param Node node: Child to add to this group
+ """
+ self._get_items()[node.basename] = node
+ node._set_parent(self)
+
+ @property
+ def h5py_class(self):
+ """Returns the h5py classes which is mimicked by this class.
+
+ It returns `h5py.Group`
+
+ :rtype: Class
+ """
+ return h5py.Group
+
+ @property
+ def attrs(self):
+ """Returns HDF5 attributes of this node.
+
+ :rtype: dict
+ """
+ return self.__attrs
+
+ def items(self):
+ """Returns items iterator containing name-node mapping.
+
+ :rtype: iterator
+ """
+ return self._get_items().items()
+
+ def get(self, name, default=None, getclass=False, getlink=False):
+ """ Retrieve an item or other information.
+
+ If getlink only is true, the returned value is always HardLink
+ cause this implementation do not use links. Like the original
+ implementation.
+
+ :param str name: name of the item
+ :param object default: default value returned if the name is not found
+ :param bool getclass: if true, the returned object is the class of the object found
+ :param bool getlink: if true, links object are returned instead of the target
+ :return: An object, else None
+ :rtype: object
+ """
+ if name not in self._get_items():
+ return default
+
+ if getlink:
+ node = h5py.HardLink()
+ else:
+ node = self._get_items()[name]
+
+ if getclass:
+ obj = node.h5py_class
+ else:
+ obj = node
+ return obj
+
+ def __len__(self):
+ """Returns the number of child contained in this group.
+
+ :rtype: int
+ """
+ return len(self._get_items())
+
+ def __iter__(self):
+ """Iterate over member names"""
+ for x in self._get_items().__iter__():
+ yield x
+
+ def __getitem__(self, name):
+ """Return a child from is name.
+
+ :param name str: name of a member or a path throug members using '/'
+ separator. A '/' as a prefix access to the root item of the tree.
+ :rtype: Node
+ """
+
+ if name is None or name == "":
+ raise ValueError("No name")
+
+ if "/" not in name:
+ return self._get_items()[name]
+
+ if name.startswith("/"):
+ root = self
+ while root.parent is not None:
+ root = root.parent
+ if name == "/":
+ return root
+ return root[name[1:]]
+
+ path = name.split("/")
+ result = self
+ for item_name in path:
+ if not isinstance(result, Group):
+ raise KeyError("Unable to open object (Component not found)")
+ result = result._get_items()[item_name]
+
+ return result
+
+ def __contains__(self, name):
+ """Returns true is a name is an existing child of this group.
+
+ :rtype: bool
+ """
+ return name in self._get_items()
+
+ def keys(self):
+ return self._get_items().keys()
+
+
+class LazyLoadableGroup(Group):
+ """Abstract group which provide a lazy loading of the child.
+
+ The class have to be inherited and the :meth:`_create_child` have to be
+ implemented to add (:meth:`_add_node`) all child. This factory
+ is only called ones, when child are needed.
+ """
+
+ def __init__(self, name, parent=None, attrs=None):
+ Group.__init__(self, name, parent, attrs)
+ self.__is_initialized = False
+
+ def _get_items(self):
+ """Returns internal structure which contains child.
+
+ It overwrite method :meth:`_get_items` to implement the lazy
+ loading feature.
+
+ :rtype: dict
+ """
+ if not self.__is_initialized:
+ self.__is_initialized = True
+ self._create_child()
+ return Group._get_items(self)
+
+ def _create_child(self):
+ """
+ Factory to create the child contained by the group when it is needed.
+
+ It have to be implemented to work.
+ """
+ raise NotImplementedError()
+
+
+class FrameData(LazyLoadableDataset):
+ """Expose a cube of image from a Fabio file using `FabioReader` as
+ cache."""
+
+ def __init__(self, name, fabio_reader, parent=None):
+ attrs = {"interpretation": "image"}
+ LazyLoadableDataset.__init__(self, name, parent, attrs=attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_data(self):
+ return self.__fabio_reader.get_data()
+
+
+class RawHeaderData(LazyLoadableDataset):
+ """Lazy loadable raw header"""
+
+ def __init__(self, name, fabio_file, parent=None):
+ LazyLoadableDataset.__init__(self, name, parent)
+ self.__fabio_file = fabio_file
+
+ def _create_data(self):
+ """Initialize hold data by merging all headers of each frames.
+ """
+ headers = []
+ for frame in range(self.__fabio_file.nframes):
+ if self.__fabio_file.nframes == 1:
+ header = self.__fabio_file.header
+ else:
+ header = self.__fabio_file.getframe(frame).header
+
+ data = []
+ for key, value in header.items():
+ data.append("%s: %s" % (str(key), str(value)))
+
+ headers.append(u"\n".join(data))
+
+ # create the header list
+ return numpy.array(headers)
+
+
+class MetadataGroup(LazyLoadableGroup):
+ """Abstract class for groups containing a reference to a fabio image.
+ """
+
+ def __init__(self, name, metadata_reader, kind, parent=None, attrs=None):
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__metadata_reader = metadata_reader
+ self.__kind = kind
+
+ def _create_child(self):
+ keys = self.__metadata_reader.get_keys(self.__kind)
+ for name in keys:
+ data = self.__metadata_reader.get_value(self.__kind, name)
+ dataset = Dataset(name, data)
+ self.add_node(dataset)
+
+ @property
+ def _metadata_reader(self):
+ return self.__metadata_reader
+
+
+class DetectorGroup(LazyLoadableGroup):
+ """Define the detector group (sub group of instrument) using Fabio data.
+ """
+
+ def __init__(self, name, fabio_reader, parent=None, attrs=None):
+ if attrs is None:
+ attrs = {"NX_class": "NXdetector"}
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_child(self):
+ data = FrameData("data", self.__fabio_reader)
+ self.add_node(data)
+
+ # TODO we should add here Nexus informations we can extract from the
+ # metadata
+
+ others = MetadataGroup("others", self.__fabio_reader, kind=FabioReader.DEFAULT)
+ self.add_node(others)
+
+
+class ImageGroup(LazyLoadableGroup):
+ """Define the image group (sub group of measurement) using Fabio data.
+ """
+
+ def __init__(self, name, fabio_reader, parent=None, attrs=None):
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_child(self):
+ data = FrameData("data", self.__fabio_reader)
+ self.add_node(data)
+
+ # TODO detector should be a real soft-link
+ detector = DetectorGroup("info", self.__fabio_reader)
+ self.add_node(detector)
+
+
+class SampleGroup(LazyLoadableGroup):
+ """Define the image group (sub group of measurement) using Fabio data.
+ """
+
+ def __init__(self, name, fabio_reader, parent=None):
+ attrs = {"NXclass": "NXsample"}
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_child(self):
+ if self.__fabio_reader.has_ub_matrix():
+ scalar = {"interpretation": "scalar"}
+ data = self.__fabio_reader.get_unit_cell_abc()
+ data = Dataset("unit_cell_abc", data, attrs=scalar)
+ self.add_node(data)
+ unit_cell_data = numpy.zeros((1, 6), numpy.float32)
+ unit_cell_data[0, :3] = data
+ data = self.__fabio_reader.get_unit_cell_alphabetagamma()
+ data = Dataset("unit_cell_alphabetagamma", data, attrs=scalar)
+ self.add_node(data)
+ unit_cell_data[0, 3:] = data
+ data = Dataset("unit_cell", unit_cell_data, attrs=scalar)
+ self.add_node(data)
+ data = self.__fabio_reader.get_ub_matrix()
+ data = Dataset("ub_matrix", data, attrs=scalar)
+ self.add_node(data)
+
+
+class MeasurementGroup(LazyLoadableGroup):
+ """Define the measurement group for fabio file.
+ """
+
+ def __init__(self, name, fabio_reader, parent=None, attrs=None):
+ LazyLoadableGroup.__init__(self, name, parent, attrs)
+ self.__fabio_reader = fabio_reader
+
+ def _create_child(self):
+ keys = self.__fabio_reader.get_keys(FabioReader.COUNTER)
+
+ # create image measurement but take care that no other metadata use
+ # this name
+ for i in range(1000):
+ name = "image_%i" % i
+ if name not in keys:
+ data = ImageGroup(name, self.__fabio_reader)
+ self.add_node(data)
+ break
+ else:
+ raise Exception("image_i for 0..1000 already used")
+
+ # add all counters
+ for name in keys:
+ data = self.__fabio_reader.get_value(FabioReader.COUNTER, name)
+ dataset = Dataset(name, data)
+ self.add_node(dataset)
+
+
+class FabioReader(object):
+ """Class which read and cache data and metadata from a fabio image."""
+
+ DEFAULT = 0
+ COUNTER = 1
+ POSITIONER = 2
+
+ def __init__(self, fabio_file):
+ self.__fabio_file = fabio_file
+ self.__counters = {}
+ self.__positioners = {}
+ self.__measurements = {}
+ self.__data = None
+ self.__frame_count = self.__fabio_file.nframes
+ self._read(self.__fabio_file)
+
+ def fabio_file(self):
+ return self.__fabio_file
+
+ def _create_data(self):
+ """Initialize hold data by merging all frames into a single cube.
+
+ Choose the cube size which fit the best the data. If some images are
+ smaller than expected, the empty space is set to 0.
+
+ The computation is cached into the class, and only done ones.
+ """
+ images = []
+ for frame in range(self.__fabio_file.nframes):
+ if self.__fabio_file.nframes == 1:
+ image = self.__fabio_file.data
+ else:
+ image = self.__fabio_file.getframe(frame).data
+ images.append(image)
+
+ # get the max size
+ max_shape = [0, 0]
+ for image in images:
+ if image.shape[0] > max_shape[0]:
+ max_shape[0] = image.shape[0]
+ if image.shape[1] > max_shape[1]:
+ max_shape[1] = image.shape[1]
+ max_shape = tuple(max_shape)
+
+ # fix smallest images
+ for index, image in enumerate(images):
+ if image.shape == max_shape:
+ continue
+ right_image = numpy.zeros(max_shape)
+ right_image[0:image.shape[0], 0:image.shape[1]] = image
+ images[index] = right_image
+
+ # create a cube
+ return numpy.array(images)
+
+ def __get_dict(self, kind):
+ """Returns a dictionary from according to an expected kind"""
+ if kind == self.DEFAULT:
+ return self.__measurements
+ elif kind == self.COUNTER:
+ return self.__counters
+ elif kind == self.POSITIONER:
+ return self.__positioners
+ else:
+ raise Exception("Unexpected kind %s", kind)
+
+ def get_data(self):
+ """Returns a cube from all available data from frames
+
+ :rtype: numpy.ndarray
+ """
+ if self.__data is None:
+ self.__data = self._create_data()
+ return self.__data
+
+ def get_keys(self, kind):
+ """Get all available keys according to a kind of metadata.
+
+ :rtype: list
+ """
+ return self.__get_dict(kind).keys()
+
+ def get_value(self, kind, name):
+ """Get a metadata value according to the kind and the name.
+
+ :rtype: numpy.ndarray
+ """
+ value = self.__get_dict(kind)[name]
+ if not isinstance(value, numpy.ndarray):
+ value = self._convert_metadata_vector(value)
+ self.__get_dict(kind)[name] = value
+ return value
+
+ def _set_counter_value(self, frame_id, name, value):
+ """Set a counter metadata according to the frame id"""
+ if name not in self.__counters:
+ self.__counters[name] = [None] * self.__frame_count
+ self.__counters[name][frame_id] = value
+
+ def _set_positioner_value(self, frame_id, name, value):
+ """Set a positioner metadata according to the frame id"""
+ if name not in self.__positioners:
+ self.__positioners[name] = [None] * self.__frame_count
+ self.__positioners[name][frame_id] = value
+
+ def _set_measurement_value(self, frame_id, name, value):
+ """Set a measurement metadata according to the frame id"""
+ if name not in self.__measurements:
+ self.__measurements[name] = [None] * self.__frame_count
+ self.__measurements[name][frame_id] = value
+
+ def _read(self, fabio_file):
+ """Read all metadata from the fabio file and store it into this
+ object."""
+ for frame in range(fabio_file.nframes):
+ if fabio_file.nframes == 1:
+ header = fabio_file.header
+ else:
+ header = fabio_file.getframe(frame).header
+ self._read_frame(frame, header)
+
+ def _read_frame(self, frame_id, header):
+ """Read all metadata from a frame and store it into this
+ object."""
+ for key, value in header.items():
+ self._read_key(frame_id, key, value)
+
+ def _read_key(self, frame_id, name, value):
+ """Read a key from the metadata and cache it into this object."""
+ self._set_measurement_value(frame_id, name, value)
+
+ def _convert_metadata_vector(self, values):
+ """Convert a list of numpy data into a numpy array with the better
+ fitting type."""
+ converted = []
+ types = set([])
+ has_none = False
+ for v in values:
+ if v is None:
+ converted.append(None)
+ has_none = True
+ else:
+ c = self._convert_value(v)
+ converted.append(c)
+ types.add(c.dtype)
+
+ if has_none and len(types) == 0:
+ # That's a list of none values
+ return numpy.array([0] * len(values), numpy.int8)
+
+ result_type = numpy.result_type(*types)
+
+ if issubclass(result_type.type, numpy.string_):
+ # use the raw data to create the array
+ result = values
+ elif issubclass(result_type.type, numpy.unicode_):
+ # use the raw data to create the array
+ result = values
+ else:
+ result = converted
+
+ if has_none:
+ # Fix missing data according to the array type
+ if result_type.kind in ["S", "U"]:
+ none_value = ""
+ elif result_type.kind == "f":
+ none_value = numpy.float("NaN")
+ elif result_type.kind == "i":
+ none_value = numpy.int(0)
+ elif result_type.kind == "u":
+ none_value = numpy.int(0)
+ elif result_type.kind == "b":
+ none_value = numpy.bool(False)
+ else:
+ none_value = None
+
+ for index, r in enumerate(result):
+ if r is not None:
+ continue
+ result[index] = none_value
+
+ return numpy.array(result, dtype=result_type)
+
+ def _convert_value(self, value):
+ """Convert a string into a numpy object (scalar or array).
+
+ The value is most of the time a string, but it can be python object
+ in case if TIFF decoder for example.
+ """
+ if isinstance(value, list):
+ # convert to a numpy array
+ return numpy.array(value)
+ if isinstance(value, dict):
+ # convert to a numpy associative array
+ key_dtype = numpy.min_scalar_type(list(value.keys()))
+ value_dtype = numpy.min_scalar_type(list(value.values()))
+ associative_type = [('key', key_dtype), ('value', value_dtype)]
+ assert key_dtype.kind != "O" and value_dtype.kind != "O"
+ return numpy.array(list(value.items()), dtype=associative_type)
+ if isinstance(value, numbers.Number):
+ dtype = numpy.min_scalar_type(value)
+ assert dtype.kind != "O"
+ return dtype.type(value)
+
+ if isinstance(value, six.binary_type):
+ try:
+ value = value.decode('utf-8')
+ except UnicodeDecodeError:
+ return numpy.void(value)
+
+ if " " in value:
+ result = self._convert_list(value)
+ else:
+ result = self._convert_scalar_value(value)
+ return result
+
+ def _convert_scalar_value(self, value):
+ """Convert a string into a numpy int or float.
+
+ If it is not possible it returns a numpy string.
+ """
+ try:
+ value = int(value)
+ dtype = numpy.min_scalar_type(value)
+ assert dtype.kind != "O"
+ return dtype.type(value)
+ except ValueError:
+ try:
+ # numpy.min_scalar_type is not able to do very well the job
+ # when there is a lot of digit after the dot
+ # https://github.com/numpy/numpy/issues/8207
+ # Let's count the digit of the string
+ digits = len(value) - 1 # minus the dot
+ if digits <= 7:
+ # A float32 is accurate with about 7 digits
+ return numpy.float32(value)
+ elif digits <= 16:
+ # A float64 is accurate with about 16 digits
+ return numpy.float64(value)
+ else:
+ if hasattr(numpy, "float128"):
+ return numpy.float128(value)
+ else:
+ return numpy.float64(value)
+ except ValueError:
+ return numpy.string_(value)
+
+ def _convert_list(self, value):
+ """Convert a string into a typed numpy array.
+
+ If it is not possible it returns a numpy string.
+ """
+ try:
+ numpy_values = []
+ values = value.split(" ")
+ types = set([])
+ for string_value in values:
+ v = self._convert_scalar_value(string_value)
+ numpy_values.append(v)
+ types.add(v.dtype.type)
+
+ result_type = numpy.result_type(*types)
+
+ if issubclass(result_type.type, numpy.string_):
+ # use the raw data to create the result
+ return numpy.string_(value)
+ elif issubclass(result_type.type, numpy.unicode_):
+ # use the raw data to create the result
+ return numpy.unicode_(value)
+ else:
+ return numpy.array(numpy_values, dtype=result_type)
+ except ValueError:
+ return numpy.string_(value)
+
+ def has_sample_information(self):
+ """Returns true if there is information about the sample in the
+ file
+
+ :rtype: bool
+ """
+ return self.has_ub_matrix()
+
+ def has_ub_matrix(self):
+ """Returns true if a UB matrix is available.
+
+ :rtype: bool
+ """
+ return False
+
+
+class EdfFabioReader(FabioReader):
+ """Class which read and cache data and metadata from a fabio image.
+
+ It is mostly the same as FabioReader, but counter_mne and
+ motor_mne are parsed using a special way.
+ """
+
+ def __init__(self, fabio_file):
+ FabioReader.__init__(self, fabio_file)
+ self.__unit_cell_abc = None
+ self.__unit_cell_alphabetagamma = None
+ self.__ub_matrix = None
+
+ def _read_frame(self, frame_id, header):
+ """Overwrite the method to check and parse special keys: counter and
+ motors keys."""
+ self.__catch_keys = set([])
+ if "motor_pos" in header and "motor_mne" in header:
+ self.__catch_keys.add("motor_pos")
+ self.__catch_keys.add("motor_mne")
+ self._read_mnemonic_key(frame_id, "motor", header)
+ if "counter_pos" in header and "counter_mne" in header:
+ self.__catch_keys.add("counter_pos")
+ self.__catch_keys.add("counter_mne")
+ self._read_mnemonic_key(frame_id, "counter", header)
+ FabioReader._read_frame(self, frame_id, header)
+
+ def _read_key(self, frame_id, name, value):
+ """Overwrite the method to filter counter or motor keys."""
+ if name in self.__catch_keys:
+ return
+ FabioReader._read_key(self, frame_id, name, value)
+
+ def _get_mnemonic_key(self, base_key, header):
+ mnemonic_values_key = base_key + "_mne"
+ mnemonic_values = header.get(mnemonic_values_key, "")
+ mnemonic_values = mnemonic_values.split()
+ pos_values_key = base_key + "_pos"
+ pos_values = header.get(pos_values_key, "")
+ pos_values = pos_values.split()
+
+ result = collections.OrderedDict()
+ nbitems = max(len(mnemonic_values), len(pos_values))
+ for i in range(nbitems):
+ if i < len(mnemonic_values):
+ mnemonic = mnemonic_values[i]
+ else:
+ # skip the element
+ continue
+
+ if i < len(pos_values):
+ pos = pos_values[i]
+ else:
+ pos = None
+
+ result[mnemonic] = pos
+ return result
+
+ def _read_mnemonic_key(self, frame_id, base_key, header):
+ """Parse a mnemonic key"""
+ is_counter = base_key == "counter"
+ is_positioner = base_key == "motor"
+ data = self._get_mnemonic_key(base_key, header)
+
+ for mnemonic, pos in data.items():
+ if is_counter:
+ self._set_counter_value(frame_id, mnemonic, pos)
+ elif is_positioner:
+ self._set_positioner_value(frame_id, mnemonic, pos)
+ else:
+ raise Exception("State unexpected (base_key: %s)" % base_key)
+
+ def has_ub_matrix(self):
+ """Returns true if a UB matrix is available.
+
+ :rtype: bool
+ """
+ header = self.fabio_file().header
+ expected_keys = set(["UB_mne", "UB_pos", "sample_mne", "sample_pos"])
+ return expected_keys.issubset(header)
+
+ def parse_ub_matrix(self):
+ header = self.fabio_file().header
+ ub_data = self._get_mnemonic_key("UB", header)
+ s_data = self._get_mnemonic_key("sample", header)
+ if len(ub_data) > 9:
+ _logger.warning("UB_mne and UB_pos contains more than expected keys.")
+ if len(s_data) > 6:
+ _logger.warning("sample_mne and sample_pos contains more than expected keys.")
+
+ data = numpy.array([s_data["U0"], s_data["U1"], s_data["U2"]], dtype=float)
+ unit_cell_abc = data
+
+ data = numpy.array([s_data["U3"], s_data["U4"], s_data["U5"]], dtype=float)
+ unit_cell_alphabetagamma = data
+
+ ub_matrix = numpy.array([[
+ [ub_data["UB0"], ub_data["UB1"], ub_data["UB2"]],
+ [ub_data["UB3"], ub_data["UB4"], ub_data["UB5"]],
+ [ub_data["UB6"], ub_data["UB7"], ub_data["UB8"]]]], dtype=float)
+
+ self.__unit_cell_abc = unit_cell_abc
+ self.__unit_cell_alphabetagamma = unit_cell_alphabetagamma
+ self.__ub_matrix = ub_matrix
+
+ def get_unit_cell_abc(self):
+ """Get a numpy array data as defined for the dataset unit_cell_abc
+ from the NXsample dataset.
+
+ :rtype: numpy.ndarray
+ """
+ if self.__unit_cell_abc is None:
+ self.parse_ub_matrix()
+ return self.__unit_cell_abc
+
+ def get_unit_cell_alphabetagamma(self):
+ """Get a numpy array data as defined for the dataset
+ unit_cell_alphabetagamma from the NXsample dataset.
+
+ :rtype: numpy.ndarray
+ """
+ if self.__unit_cell_alphabetagamma is None:
+ self.parse_ub_matrix()
+ return self.__unit_cell_alphabetagamma
+
+ def get_ub_matrix(self):
+ """Get a numpy array data as defined for the dataset ub_matrix
+ from the NXsample dataset.
+
+ :rtype: numpy.ndarray
+ """
+ if self.__ub_matrix is None:
+ self.parse_ub_matrix()
+ return self.__ub_matrix
+
+
+class File(Group):
+ """Class which handle a fabio image as a mimick of a h5py.File.
+ """
+
+ def __init__(self, file_name=None, fabio_image=None):
+ self.__must_be_closed = False
+ if file_name is not None and fabio_image is not None:
+ raise TypeError("Parameters file_name and fabio_image are mutually exclusive.")
+ if file_name is not None:
+ self.__fabio_image = fabio.open(file_name)
+ self.__must_be_closed = True
+ elif fabio_image is not None:
+ self.__fabio_image = fabio_image
+ Group.__init__(self, name="", parent=None, attrs={"NX_class": "NXroot"})
+ self.__fabio_reader = self.create_fabio_reader(self.__fabio_image)
+ scan = self.create_scan_group(self.__fabio_image, self.__fabio_reader)
+ self.add_node(scan)
+
+ def create_scan_group(self, fabio_image, fabio_reader):
+ """Factory to create the scan group.
+
+ :param FabioImage fabio_image: A Fabio image
+ :param FabioReader fabio_reader: A reader for the Fabio image
+ :rtype: Group
+ """
+
+ scan = Group("scan_0", attrs={"NX_class": "NXentry"})
+ instrument = Group("instrument", attrs={"NX_class": "NXinstrument"})
+ measurement = MeasurementGroup("measurement", fabio_reader, attrs={"NX_class": "NXcollection"})
+ file_ = Group("file", attrs={"NX_class": "NXcollection"})
+ positioners = MetadataGroup("positioners", fabio_reader, FabioReader.POSITIONER, attrs={"NX_class": "NXpositioner"})
+ raw_header = RawHeaderData("scan_header", fabio_image, self)
+ detector = DetectorGroup("detector_0", fabio_reader)
+
+ scan.add_node(instrument)
+ instrument.add_node(positioners)
+ instrument.add_node(file_)
+ instrument.add_node(detector)
+ file_.add_node(raw_header)
+ scan.add_node(measurement)
+
+ if fabio_reader.has_sample_information():
+ sample = SampleGroup("sample", fabio_reader)
+ scan.add_node(sample)
+
+ return scan
+
+ def create_fabio_reader(self, fabio_file):
+ """Factory to create fabio reader.
+
+ :rtype: FabioReader"""
+ if isinstance(fabio_file, fabio.edfimage.EdfImage):
+ metadata = EdfFabioReader(fabio_file)
+ else:
+ metadata = FabioReader(fabio_file)
+ return metadata
+
+ @property
+ def h5py_class(self):
+ return h5py.File
+
+ @property
+ def filename(self):
+ return self.__fabio_image.filename
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb): # pylint: disable=W0622
+ """Called at the end of a `with` statement.
+
+ It will close the internal FabioImage only if the FabioImage was
+ created by the class itself. The reference to the FabioImage is anyway
+ broken.
+ """
+ if self.__must_be_closed:
+ self.close()
+ else:
+ self.__fabio_image = None
+
+ def close(self):
+ """Close the object, and free up associated resources.
+
+ The associated FabioImage is closed anyway the object was created from
+ a filename or from a FabioImage.
+
+ After calling this method, attempts to use the object may fail.
+ """
+ # It looks like there is no close on FabioImage
+ # self.__fabio_image.close()
+ self.__fabio_image = None
diff --git a/silx/io/nxdata.py b/silx/io/nxdata.py
new file mode 100644
index 0000000..c0e53fc
--- /dev/null
+++ b/silx/io/nxdata.py
@@ -0,0 +1,535 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+"""This module provides a collection of functions to work with h5py-like
+groups following the NeXus *NXdata* specification.
+
+See http://download.nexusformat.org/sphinx/classes/base_classes/NXdata.html
+
+"""
+import logging
+import numpy
+from .utils import is_dataset, is_group
+from silx.third_party import six
+
+_logger = logging.getLogger(__name__)
+
+
+_INTERPDIM = {"scalar": 0,
+ "spectrum": 1,
+ "image": 2,
+ # "rgba-image": 3, "hsla-image": 3, "cmyk-image": 3, # TODO
+ "vertex": 1} # 3D scatter: 1D signal + 3 axes (x, y, z) of same legth
+"""Number of signal dimensions associated to each possible @interpretation
+attribute.
+"""
+
+
+def _nxdata_warning(msg):
+ """Log a warning message prefixed with
+ *"NXdata warning: "*
+
+ :param str msg: Warning message
+ """
+ _logger.warning("NXdata warning: " + msg)
+
+
+def _get_attr(item, attr_name, default=None):
+ """Return item.attrs[attr_name]. If it is a byte-string or an array of
+ byte-strings, return it as a default python string.
+
+ For Python 3, this involves a coercion from bytes into unicode.
+ For Python 2, there is nothing special to do, as strings are bytes.
+
+ :param item: Group or dataset
+ :param attr_name: Attribute name
+ :return: item.attrs[attr_name]
+ """
+ attr = item.attrs.get(attr_name, default)
+ if six.PY2:
+ return attr
+ if six.PY3:
+ if hasattr(attr, "decode"):
+ # byte-string
+ return attr.decode("ascii")
+ elif isinstance(attr, numpy.ndarray) and hasattr(attr[0], "decode"):
+ # array of byte-strinqs
+ return [element.decode("ascii") for element in attr]
+ else:
+ # attr is not a byte-strinq
+ return attr
+
+
+def is_valid_nxdata(group): # noqa
+ """Check if a h5py group is a **valid** NX_data group.
+
+ If the group does not have attribute *@NX_class=NXdata*, this function
+ simply returns *False*.
+
+ Else, warning messages are logged to troubleshoot malformed NXdata groups
+ prior to returning *False*.
+
+ :param group: h5py-like group
+ :return: True if this NXdata group is valid.
+ :raise: TypeError if group is not a h5py group, a spech5 group,
+ or a fabioh5 group
+ """
+ if not is_group(group):
+ raise TypeError("group must be a h5py-like group")
+ if _get_attr(group, "NX_class") != "NXdata":
+ return False
+ if "signal" not in group.attrs:
+ _logger.warning("NXdata group does not define a signal attr.")
+ return False
+
+ signal_name = _get_attr(group, "signal")
+ if signal_name not in group or not is_dataset(group[signal_name]):
+ _logger.warning(
+ "Cannot find signal dataset '%s' in NXdata group" % signal_name)
+ return False
+
+ ndim = len(group[signal_name].shape)
+
+ if "axes" in group.attrs:
+ axes_names = _get_attr(group, "axes")
+ if isinstance(axes_names, str):
+ axes_names = [axes_names]
+
+ if 1 < ndim < len(axes_names):
+ # ndim = 1 and several axes could be a scatter
+ _nxdata_warning(
+ "More @axes defined than there are " +
+ "signal dimensions: " +
+ "%d axes, %d dimensions." % (len(axes_names), ndim))
+ return False
+
+ # case of less axes than dimensions: number of axes must match
+ # dimensionality defined by @interpretation
+ if ndim > len(axes_names):
+ interpretation = _get_attr(group[signal_name], "interpretation", None)
+ if interpretation is None:
+ interpretation = _get_attr(group, "interpretation", None)
+ if interpretation is None:
+ _nxdata_warning("No @interpretation and not enough" +
+ " @axes defined.")
+ return False
+
+ if interpretation not in _INTERPDIM:
+ _nxdata_warning("Unrecognized @interpretation=" + interpretation +
+ " for data with wrong number of defined @axes.")
+ return False
+
+ if len(axes_names) != _INTERPDIM[interpretation]:
+ _nxdata_warning(
+ "%d-D signal with @interpretation=%s " % (ndim, interpretation) +
+ "must define %d or %d axes." % (ndim, _INTERPDIM[interpretation]))
+ return False
+
+ # Test consistency of @uncertainties
+ uncertainties_names = _get_attr(group, "uncertainties")
+ if uncertainties_names is None:
+ uncertainties_names = _get_attr(group[signal_name], "uncertainties")
+ if isinstance(uncertainties_names, str):
+ uncertainties_names = [uncertainties_names]
+ if uncertainties_names is not None:
+ if len(uncertainties_names) != len(axes_names):
+ _nxdata_warning("@uncertainties does not define the same " +
+ "number of fields than @axes")
+ return False
+
+ # Test individual axes
+ is_scatter = True # true if all axes have the same size as the signal
+ signal_size = 1
+ for dim in group[signal_name].shape:
+ signal_size *= dim
+ polynomial_axes_names = []
+ for i, axis_name in enumerate(axes_names):
+ if axis_name == ".":
+ continue
+ if axis_name not in group or not is_dataset(group[axis_name]):
+ _nxdata_warning("Could not find axis dataset '%s'" % axis_name)
+ return False
+
+ axis_size = 1
+ for dim in group[axis_name].shape:
+ axis_size *= dim
+
+ if len(group[axis_name].shape) != 1:
+ # too me, it makes only sense to have a n-D axis if it's total
+ # size is exactly the signal's size (weird n-d scatter)
+ if axis_size != signal_size:
+ _nxdata_warning("Axis %s is not a 1D dataset" % axis_name +
+ " and its shape does not match the signal's shape")
+ return False
+ axis_len = axis_size
+ else:
+ # for a 1-d axis,
+ fg_idx = _get_attr(group[axis_name], "first_good", 0)
+ lg_idx = _get_attr(group[axis_name], "last_good", len(group[axis_name]) - 1)
+ axis_len = lg_idx + 1 - fg_idx
+
+ if axis_len != signal_size:
+ if axis_len not in group[signal_name].shape + (1, 2):
+ _nxdata_warning(
+ "Axis %s number of elements does not " % axis_name +
+ "correspond to the length of any signal dimension,"
+ " it does not appear to be a constant or a linear calibration," +
+ " and this does not seem to be a scatter plot.")
+ return False
+ elif axis_len in (1, 2):
+ polynomial_axes_names.append(axis_name)
+ is_scatter = False
+ else:
+ if not is_scatter:
+ _nxdata_warning(
+ "Axis %s number of elements is equal " % axis_name +
+ "to the length of the signal, but this does not seem" +
+ " to be a scatter (other axes have different sizes)")
+ return False
+
+ # Test individual uncertainties
+ errors_name = axis_name + "_errors"
+ if errors_name not in group and uncertainties_names is not None:
+ errors_name = uncertainties_names[i]
+ if errors_name in group and axis_name not in polynomial_axes_names:
+ if group[errors_name].shape != group[axis_name].shape:
+ _nxdata_warning(
+ "Errors '%s' does not have the same " % errors_name +
+ "dimensions as axis '%s'." % axis_name)
+ return False
+
+ # test dimensions of errors associated with signal
+ if "errors" in group and is_dataset(group["errors"]):
+ if group["errors"].shape != group[signal_name].shape:
+ _nxdata_warning("Dataset containing standard deviations must " +
+ "have the same dimensions as the signal.")
+ return False
+ return True
+
+
+class NXdata(object):
+ """
+
+ :param group: h5py-like group following the NeXus *NXdata* specification.
+ """
+ def __init__(self, group):
+ if not is_valid_nxdata(group):
+ raise TypeError("group is not a valid NXdata class")
+ super(NXdata, self).__init__()
+
+ self._is_scatter = None
+ self._axes = None
+
+ self.group = group
+ """h5py-like group object compliant with NeXus NXdata specification.
+ """
+
+ self.signal = self.group[self.group.attrs["signal"]]
+ """Signal dataset in this NXdata group.
+ """
+
+ # ndim will be available in very recent h5py versions only
+ self.signal_ndim = getattr(self.signal, "ndim",
+ len(self.signal.shape))
+
+ self.signal_is_0d = self.signal_ndim == 0
+ self.signal_is_1d = self.signal_ndim == 1
+ self.signal_is_2d = self.signal_ndim == 2
+ self.signal_is_3d = self.signal_ndim == 3
+
+ self.axes_names = []
+ """List of axes names in a NXdata group.
+
+ This attribute is similar to :attr:`axes_dataset_names` except that
+ if an axis dataset has a "@long_name" attribute, it will be used
+ instead of the dataset name.
+ """
+ # check if axis dataset defines @long_name
+ for i, dsname in enumerate(self.axes_dataset_names):
+ if dsname is not None and "long_name" in self.group[dsname].attrs:
+ self.axes_names.append(self.group[dsname].attrs["long_name"])
+ else:
+ self.axes_names.append(dsname)
+
+ # excludes scatters
+ self.signal_is_1d = self.signal_is_1d and len(self.axes) <= 1 # excludes n-D scatters
+
+ @property
+ def interpretation(self):
+ """*@interpretation* attribute associated with the *signal*
+ dataset of the NXdata group. ``None`` if no interpretation
+ attribute is present.
+
+ The *interpretation* attribute provides information about the last
+ dimensions of the signal. The allowed values are:
+
+ - *"scalar"*: 0-D data to be plotted
+ - *"spectrum"*: 1-D data to be plotted
+ - *"image"*: 2-D data to be plotted
+ - *"vertex"*: 3-D data to be plotted
+
+ For example, a 3-D signal with interpretation *"spectrum"* should be
+ considered to be a 2-D array of 1-D data. A 3-D signal with
+ interpretation *"image"* should be interpreted as a 1-D array (a list)
+ of 2-D images. An n-D array with interpretation *"image"* should be
+ interpreted as an (n-2)-D array of images.
+
+ A warning message is logged if the returned interpretation is not one
+ of the allowed values, but no error is raised and the unknown
+ interpretation is returned anyway.
+ """
+ allowed_interpretations = [None, "scalar", "spectrum", "image",
+ # "rgba-image", "hsla-image", "cmyk-image" # TODO
+ "vertex"]
+
+ interpretation = _get_attr(self.signal, "interpretation", None)
+ if interpretation is None:
+ interpretation = _get_attr(self.group, "interpretation", None)
+
+ if interpretation not in allowed_interpretations:
+ _logger.warning("Interpretation %s is not valid." % interpretation +
+ " Valid values: " + ", ".join(allowed_interpretations))
+ return interpretation
+
+ @property
+ def axes(self):
+ """List of the axes datasets.
+
+ The list typically has as many elements as there are dimensions in the
+ signal dataset, the exception being scatter plots which typically
+ use a 1D signal and several 1D axes of the same size.
+
+ If an axis dataset applies to several dimensions of the signal, it
+ will be repeated in the list.
+
+ If a dimension of the signal has no dimension scale (i.e. there is a
+ "." in that position in the *@axes* array), `None` is inserted in the
+ output list in its position.
+
+ .. note::
+
+ In theory, the *@axes* attribute defines as many entries as there
+ are dimensions in the signal. In such a case, there is no ambiguity.
+ If this is not the case, this implementation relies on the existence
+ of an *@interpretation* (*spectrum* or *image*) attribute in the
+ *signal* dataset.
+
+ .. note::
+
+ If an axis dataset defines attributes @first_good or @last_good,
+ the output will be a numpy array resulting from slicing that
+ axis to keep only the good index range: axis[first_good:last_good + 1]
+
+ :rtype: list[Dataset or 1D array or None]
+ """
+ if self._axes is not None:
+ # use cache
+ return self._axes
+ ndims = len(self.signal.shape)
+ axes_names = _get_attr(self.group, "axes")
+ interpretation = self.interpretation
+
+ if axes_names is None:
+ self._axes = [None for _i in range(ndims)]
+ return self._axes
+
+ if isinstance(axes_names, str):
+ axes_names = [axes_names]
+
+ if len(axes_names) == ndims:
+ # axes is a list of strings, one axis per dim is explicitly defined
+ axes = [None] * ndims
+ for i, axis_n in enumerate(axes_names):
+ if axis_n != ".":
+ axes[i] = self.group[axis_n]
+ elif interpretation is not None:
+ # case of @interpretation attribute defined: we expect 1, 2 or 3 axes
+ # corresponding to the 1, 2, or 3 last dimensions of the signal
+ assert len(axes_names) == _INTERPDIM[interpretation]
+ axes = [None] * (ndims - _INTERPDIM[interpretation])
+ for axis_n in axes_names:
+ if axis_n != ".":
+ axes.append(self.group[axis_n])
+ else:
+ axes.append(None)
+ else: # scatter
+ axes = []
+ for axis_n in axes_names:
+ if axis_n != ".":
+ axes.append(self.group[axis_n])
+ else:
+ axes.append(None)
+ # keep only good range of axis data
+ for i, axis in enumerate(axes):
+ if axis is None:
+ continue
+ if "first_good" not in axis.attrs and "last_good" not in axis.attrs:
+ continue
+ fg_idx = _get_attr(axis, "first_good") or 0
+ lg_idx = _get_attr(axis, "last_good") or (len(axis) - 1)
+ axes[i] = axis[fg_idx:lg_idx + 1]
+
+ self._axes = axes
+ return self._axes
+
+ @property
+ def axes_dataset_names(self):
+ """
+ If an axis dataset applies to several dimensions of the signal, its
+ name will be repeated in the list.
+
+ If a dimension of the signal has no dimension scale (i.e. there is a
+ "." in that position in the *@axes* array), `None` is inserted in the
+ output list in its position.
+ """
+ axes_dataset_names = _get_attr(self.group, "axes")
+ if axes_dataset_names is None:
+ axes_dataset_names = _get_attr(self.group, "axes")
+
+ ndims = len(self.signal.shape)
+ if axes_dataset_names is None:
+ return [None] * ndims
+
+ if isinstance(axes_dataset_names, str):
+ axes_dataset_names = [axes_dataset_names]
+
+ for i, axis_name in enumerate(axes_dataset_names):
+ if axis_name == ".":
+ axes_dataset_names[i] = None
+
+ if len(axes_dataset_names) != ndims:
+ if self.is_scatter and ndims == 1:
+ return list(axes_dataset_names)
+ # @axes may only define 1 or 2 axes if @interpretation=spectrum/image.
+ # Use the existing names for the last few dims, and prepend with Nones.
+ assert len(axes_dataset_names) == _INTERPDIM[self.interpretation]
+ all_dimensions_names = [None] * (ndims - _INTERPDIM[self.interpretation])
+ for axis_name in axes_dataset_names:
+ all_dimensions_names.append(axis_name)
+ return all_dimensions_names
+
+ return list(axes_dataset_names)
+
+ def get_axis_errors(self, axis_name):
+ """Return errors (uncertainties) associated with an axis.
+
+ If the axis has attributes @first_good or @last_good, the output
+ is trimmed accordingly (a numpy array will be returned rather than a
+ dataset).
+
+ :param str axis_name: Name of axis dataset. This dataset **must exist**.
+ :return: Dataset with axis errors, or None
+ :raise: KeyError if this group does not contain a dataset named axis_name
+ """
+ if axis_name not in self.group:
+ # tolerate axis_name given as @long_name
+ for item in self.group:
+ long_name = _get_attr(self.group[item], "long_name")
+ if long_name is not None and long_name == axis_name:
+ axis_name = item
+ break
+
+ if axis_name not in self.group:
+ raise KeyError("group does not contain a dataset named '%s'" % axis_name)
+
+ len_axis = len(self.group[axis_name])
+
+ fg_idx = _get_attr(self.group[axis_name], "first_good", 0)
+ lg_idx = _get_attr(self.group[axis_name], "last_good", len_axis - 1)
+
+ # case of axisname_errors dataset present
+ errors_name = axis_name + "_errors"
+ if errors_name in self.group and is_dataset(self.group[errors_name]):
+ if fg_idx != 0 or lg_idx != (len_axis-1):
+ return self.group[errors_name][fg_idx:lg_idx + 1]
+ else:
+ return self.group[errors_name]
+ # case of uncertainties dataset name provided in @uncertainties
+ uncertainties_names = _get_attr(self.group, "uncertainties")
+ if uncertainties_names is None:
+ uncertainties_names = _get_attr(self.signal, "uncertainties")
+ if isinstance(uncertainties_names, str):
+ uncertainties_names = [uncertainties_names]
+ if uncertainties_names is not None:
+ # take the uncertainty with the same index as the axis in @axes
+ axes_ds_names = _get_attr(self.group, "axes")
+ if axes_ds_names is None:
+ axes_ds_names = _get_attr(self.signal, "axes")
+ if isinstance(axes_ds_names, str):
+ axes_ds_names = [axes_ds_names]
+ elif not isinstance(axes_ds_names, list):
+ # transform numpy.ndarray(dtype('S21')) into list(str)
+ axes_ds_names = map(str, axes_ds_names)
+ if axis_name not in axes_ds_names:
+ raise KeyError("group attr @axes does not mention a dataset " +
+ "named '%s'" % axis_name)
+ errors = self.group[uncertainties_names[list(axes_ds_names).index(axis_name)]]
+ if fg_idx == 0 and lg_idx == (len_axis-1):
+ return errors # dataset
+ else:
+ return errors[fg_idx:lg_idx + 1] # numpy array
+ return None
+
+ @property
+ def errors(self):
+ """Return errors (uncertainties) associated with the signal values.
+
+ :return: Dataset with errors, or None
+ """
+ if "errors" not in self.group:
+ return None
+ return self.group["errors"]
+
+ @property
+ def is_scatter(self):
+ """True if the signal is 1D and all the axes have the
+ same size as the signal."""
+ if self._is_scatter is not None:
+ return self._is_scatter
+ if not self.signal_is_1d:
+ self._is_scatter = False
+ else:
+ self._is_scatter = True
+ sigsize = 1
+ for dim in self.signal.shape:
+ sigsize *= dim
+ for axis in self.axes:
+ if axis is None:
+ continue
+ axis_size = 1
+ for dim in axis.shape:
+ axis_size *= dim
+ self._is_scatter = self._is_scatter and (axis_size == sigsize)
+ return self._is_scatter
+
+ @property
+ def is_x_y_value_scatter(self):
+ """True if this is a scatter with a signal and two axes."""
+ return self.is_scatter and len(self.axes) == 2
+
+ # we currently have no widget capable of plotting 4D data
+ @property
+ def is_unsupported_scatter(self):
+ """True if this is a scatter with a signal and more than 2 axes."""
+ return self.is_scatter and len(self.axes) > 2
diff --git a/silx/io/octaveh5.py b/silx/io/octaveh5.py
new file mode 100644
index 0000000..e63c026
--- /dev/null
+++ b/silx/io/octaveh5.py
@@ -0,0 +1,176 @@
+# 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.
+#
+# ############################################################################*/
+"""
+Python h5 module and octave h5 module have different ways to deal with
+h5 files.
+This module is used to make the link between octave and python using such files.
+(python is using a dictionary and octave a struct )
+
+This module provides tool to set HDF5 file for fasttomo input.
+
+Here is an example of a simple read and write :
+
+.. code-block:: python
+ :emphasize-lines: 3,5
+
+ # writing a structure
+ myStruct = {'MKEEP_MASK': 0.0, 'UNSHARP_SIGMA': 0.80000000000000004 }
+ writer = Octaveh5().open("my_h5file", 'a')
+ writer.write('mt_struct_name', myStruct)
+
+ # reading a h5 file
+ reader = Octaveh5().open("my_h5file")
+ strucDict = reader.get('mt_struct_name')
+
+.. note:: These functions depend on the `h5py <http://www.h5py.org/>`_
+ library, which is not a mandatory dependency for `silx`.
+
+"""
+
+import logging
+logger = logging.getLogger(__name__)
+import numpy as np
+
+try:
+ import h5py
+except ImportError as e:
+ logger.error("Module " + __name__ + " requires h5py")
+ raise e
+
+__authors__ = ["C. Nemoz", "H. Payno"]
+__license__ = "MIT"
+__date__ = "05/10/2016"
+
+
+class Octaveh5(object):
+ """This class allows communication between octave and python using hdf5 format.
+ """
+
+ def __init__(self, octave_targetted_version=3.8):
+ """Constructor
+
+ :param octave_targetted_version: the version of Octave for which we want to write this hdf5 file.
+
+ This is needed because for old Octave version we need to had a hack(adding one extra character)
+ """
+ self.file = None
+ self.octave_targetted_version = octave_targetted_version
+
+ def open(self, h5file, mode='r'):
+ """Open the h5 file which has been write by octave
+
+ :param h5file: The path of the file to read
+ :param mode: the opening mode of the file :'r', 'w'...
+ """
+ try:
+ self.file = h5py.File(h5file, mode)
+ return self
+ except IOError as e:
+ if mode == 'a':
+ reason = "\n %s: Can t find or create " % h5file
+ else:
+ reason = "\n %s: File not found" % h5file
+ self.file = None
+
+ logger.info(reason)
+ raise e
+
+ def get(self, struct_name):
+ """Read octave equivalent structures in hdf5 file
+
+ :param struct_name: the identification of the top level identity we want to get from an hdf5 structure
+ :return: the dictionnary of the requested struct. None if can t find it
+ """
+ if self.file is None:
+ info = "No file currently open"
+ logger.info(info)
+ return None
+
+ data_dict = {}
+ grr = (list(self.file[struct_name].items())[1])[1]
+ try:
+ gr_level2 = grr.items()
+ except AttributeError:
+ reason = "no gr_level2"
+ logger.info(reason)
+ return None
+
+ for key, val in iter(dict(gr_level2).items()):
+ data_dict[str(key)] = list(val.items())[1][1].value
+
+ if list(val.items())[0][1].value != np.string_('sq_string'):
+ data_dict[str(key)] = float(data_dict[str(key)])
+ else:
+ if list(val.items())[0][1].value == np.string_('sq_string'):
+ # in the case the string has been stored as an nd-array of char
+ if type(data_dict[str(key)]) is np.ndarray:
+ data_dict[str(key)] = "".join(chr(item) for item in data_dict[str(key)])
+ else:
+ data_dict[str(key)] = data_dict[str(key)].decode('UTF-8')
+
+ # In the case Octave have added an extra character at the end
+ if self.octave_targetted_version < 3.8:
+ data_dict[str(key)] = data_dict[str(key)][:-1]
+
+ return data_dict
+
+ def write(self, struct_name, data_dict):
+ """write data_dict under the group struct_name in the open hdf5 file
+
+ :param struct_name: the identificatioon of the structure to write in the hdf5
+ :param data_dict: The python dictionnary containing the informations to write
+ """
+ if self.file is None:
+ info = "No file currently open"
+ logger.info(info)
+ return
+
+ group_l1 = self.file.create_group(struct_name)
+ group_l1.attrs['OCTAVE_GLOBAL'] = np.uint8(1)
+ group_l1.attrs['OCTAVE_NEW_FORMAT'] = np.uint8(1)
+ group_l1.create_dataset("type", data=np.string_('scalar struct'), dtype="|S14")
+ group_l2 = group_l1.create_group('value')
+ for ftparams in data_dict:
+ group_l3 = group_l2.create_group(ftparams)
+ group_l3.attrs['OCTAVE_NEW_FORMAT'] = np.uint8(1)
+ if type(data_dict[ftparams]) == str:
+ group_l3.create_dataset("type", (), data=np.string_('sq_string'), dtype="|S10")
+ if self.octave_targetted_version < 3.8:
+ group_l3.create_dataset("value", data=np.string_(data_dict[ftparams] + '0'))
+ else:
+ group_l3.create_dataset("value", data=np.string_(data_dict[ftparams]))
+ else:
+ group_l3.create_dataset("type", (), data=np.string_('scalar'), dtype="|S7")
+ group_l3.create_dataset("value", data=data_dict[ftparams])
+
+ def close(self):
+ """Close the file after calling read function
+ """
+ if self.file:
+ self.file.close()
+
+ def __del__(self):
+ """Destructor
+ """
+ self.close()
diff --git a/silx/io/setup.py b/silx/io/setup.py
new file mode 100644
index 0000000..3483bcb
--- /dev/null
+++ b/silx/io/setup.py
@@ -0,0 +1,88 @@
+# coding: ascii
+#
+# JK: Numpy.distutils which imports this does not handle utf-8 in version<1.12
+#
+# /*##########################################################################
+#
+# 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["P. Knobel", "V.A. Sole"]
+__license__ = "MIT"
+__date__ = "03/10/2016"
+
+import os
+import sys
+
+import numpy
+from numpy.distutils.misc_util import Configuration
+
+
+# Locale and platform management
+SPECFILE_USE_GNU_SOURCE = os.getenv("SPECFILE_USE_GNU_SOURCE")
+if SPECFILE_USE_GNU_SOURCE is None:
+ SPECFILE_USE_GNU_SOURCE = 0
+ if sys.platform.lower().startswith("linux"):
+ warn = ("silx.io.specfile WARNING:",
+ "A cleaner locale independent implementation",
+ "may be achieved setting SPECFILE_USE_GNU_SOURCE to 1",
+ "For instance running this script as:",
+ "SPECFILE_USE_GNU_SOURCE=1 python setup.py build")
+ print(os.linesep.join(warn))
+else:
+ SPECFILE_USE_GNU_SOURCE = int(SPECFILE_USE_GNU_SOURCE)
+
+if sys.platform == "win32":
+ define_macros = [('WIN32', None)]
+elif os.name.lower().startswith('posix'):
+ define_macros = [('SPECFILE_POSIX', None)]
+ # the best choice is to have _GNU_SOURCE defined
+ # as a compilation flag because that allows the
+ # use of strtod_l
+ if SPECFILE_USE_GNU_SOURCE:
+ define_macros = [('_GNU_SOURCE', 1)]
+else:
+ define_macros = []
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('io', parent_package, top_path)
+ config.add_subpackage('test')
+
+ srcfiles = ['sfheader', 'sfinit', 'sflists', 'sfdata', 'sfindex',
+ 'sflabel', 'sfmca', 'sftools', 'locale_management']
+ sources = [os.path.join('specfile', 'src', ffile + '.c') for ffile in srcfiles]
+ sources.append(os.path.join('specfile', 'specfile.pyx'))
+
+ config.add_extension('specfile',
+ sources=sources,
+ define_macros=define_macros,
+ include_dirs=[os.path.join('specfile', 'include'),
+ numpy.get_include()],
+ language='c')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/io/specfile/include/Lists.h b/silx/io/specfile/include/Lists.h
new file mode 100644
index 0000000..bcda100
--- /dev/null
+++ b/silx/io/specfile/include/Lists.h
@@ -0,0 +1,51 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/***************************************************************************
+ *
+ * File: Lists.h
+ *
+ * Description: Include file for dealing with lists.
+ *
+ * Author: Vicente Rey
+ *
+ * Created: 22 May 1995
+ *
+ * (copyright by E.S.R.F. March 1995)
+ *
+ ***************************************************************************/
+#ifndef LISTS_H
+#define LISTS_H
+
+/* #include <malloc.h> */
+
+typedef struct _ObjectList {
+ struct _ObjectList *next;
+ struct _ObjectList *prev;
+ void *contents;
+} ObjectList;
+
+typedef struct _ListHeader {
+ struct _ObjectList *first;
+ struct _ObjectList *last;
+} ListHeader;
+
+extern ObjectList * findInList ( ListHeader *list, int (*proc)(void *,void *), void *value );
+extern long addToList ( ListHeader *list, void *object,long size);
+extern void unlinkFromList ( ListHeader *list, ObjectList *element);
+
+#endif /* LISTS_H */
diff --git a/silx/io/specfile/include/SpecFile.h b/silx/io/specfile/include/SpecFile.h
new file mode 100644
index 0000000..fce729c
--- /dev/null
+++ b/silx/io/specfile/include/SpecFile.h
@@ -0,0 +1,291 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/***************************************************************************
+ *
+ * File: SpecFile.h
+ *
+ * Description: Include file for treating spec data files.
+ *
+ * Author: Vicente Rey
+ *
+ * Created: 2 March 1995
+ *
+ * (copyright by E.S.R.F. March 1995)
+ *
+ ***************************************************************************/
+#ifndef SPECFILE_H
+#define SPECFILE_H
+
+#include <math.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include <time.h>
+#include <stdlib.h>
+/* #include <malloc.h> */
+#include <string.h>
+#include <Lists.h>
+
+#ifdef _WINDOWS /* compiling on windows */
+#include <windows.h>
+#include <io.h>
+#define SF_OPENFLAG O_RDONLY | O_BINARY
+#define SF_WRITEFLAG O_CREAT | O_WRONLY
+#define SF_UMASK 0666
+#else /* if not windows */
+#define SF_OPENFLAG O_RDONLY
+#define SF_WRITEFLAG O_CREAT | O_WRONLY
+#define SF_UMASK 0666
+#endif
+
+#ifdef _GENLIB /* for windows dll generation */
+#define DllExport __declspec (dllexport)
+#else
+#define DllExport
+#endif
+
+
+#ifdef SUN4
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
+/*
+ * Defines.
+ */
+#define ROW 0 /* data_info index for no. of data rows */
+#define COL 1 /* data_info index for no. of data columns*/
+#define REG 2 /* data_info index for regular */
+#define H 0
+#define K 1
+#define L 2
+#define ABORTED -1
+#define NOT_ABORTED 0
+
+#define SF_ERR_NO_ERRORS 0
+#define SF_ERR_MEMORY_ALLOC 1
+#define SF_ERR_FILE_OPEN 2
+#define SF_ERR_FILE_CLOSE 3
+#define SF_ERR_FILE_READ 4
+#define SF_ERR_FILE_WRITE 5
+#define SF_ERR_LINE_NOT_FOUND 6
+#define SF_ERR_SCAN_NOT_FOUND 7
+#define SF_ERR_HEADER_NOT_FOUND 8
+#define SF_ERR_LABEL_NOT_FOUND 9
+#define SF_ERR_MOTOR_NOT_FOUND 10
+#define SF_ERR_POSITION_NOT_FOUND 11
+#define SF_ERR_LINE_EMPTY 12
+#define SF_ERR_USER_NOT_FOUND 13
+#define SF_ERR_COL_NOT_FOUND 14
+#define SF_ERR_MCA_NOT_FOUND 15
+
+typedef struct _SfCursor {
+ long int scanno; /* nb of scans */
+ long int cursor; /* beginning of current scan */
+ long int hdafoffset; /* global offset of header after beginning of data */
+ long int datalines; /* contains nb of data lines */
+ long int dataoffset; /* contains data offset from begin of scan */
+ long int mcaspectra; /* contains nb of mca spectra in scan */
+ long int bytecnt; /* total file byte count */
+ long int what; /* scan of file block */
+ long int data; /* data flag */
+ long int file_header; /* address of file header for this scan */
+ long int fileh_size; /* size of it */
+} SfCursor;
+
+
+typedef struct _SpecFile{
+ int fd;
+ long m_time;
+ char *sfname;
+ struct _ListHeader list;
+ long int no_scans;
+ ObjectList *current;
+ char *scanbuffer;
+ long scanheadersize;
+ char *filebuffer;
+ long filebuffersize;
+ long scansize;
+ char **labels;
+ long int no_labels;
+ char **motor_names;
+ long int no_motor_names;
+ double *motor_pos;
+ long int no_motor_pos;
+ double **data;
+ long *data_info;
+ SfCursor cursor;
+ short updating;
+} SpecFile;
+
+typedef struct _SpecFileOut{
+ SpecFile *sf;
+ long *list;
+ long list_size;
+ long file_header;
+} SpecFileOut;
+
+typedef struct _SpecScan {
+ long int index;
+ long int scan_no;
+ long int order;
+ long int offset;
+ long int size;
+ long int last;
+ long int file_header;
+ long int data_offset;
+ long int hdafter_offset;
+ long int mcaspectra;
+} SpecScan;
+
+/*
+ * Function declarations.
+ */
+
+ /*
+ * Init
+ */
+/*
+ * init
+ */
+DllExport extern SpecFile *SfOpen ( char *name, int *error );
+DllExport extern short SfUpdate ( SpecFile *sf,int *error );
+DllExport extern int SfClose ( SpecFile *sf );
+
+/*
+ * indexes
+ */
+DllExport extern long SfScanNo ( SpecFile *sf );
+DllExport extern long *SfList ( SpecFile *sf, int *error );
+DllExport extern long SfCondList ( SpecFile *sf, long cond,
+ long **scan_list, int *error );
+DllExport extern long SfIndex ( SpecFile *sf, long number,
+ long order );
+DllExport extern long SfIndexes ( SpecFile *sf, long number,
+ long **indexlist );
+DllExport extern long SfNumber ( SpecFile *sf, long index );
+DllExport extern long SfOrder ( SpecFile *sf, long index );
+DllExport extern int SfNumberOrder ( SpecFile *sf, long index,
+ long *number, long *order );
+
+ /*
+ * Header
+ */
+DllExport extern char *SfCommand ( SpecFile *sf, long index, int *error );
+DllExport extern long SfNoColumns ( SpecFile *sf, long index, int *error );
+DllExport extern char *SfDate ( SpecFile *sf, long index, int *error );
+DllExport extern long SfEpoch ( SpecFile *sf, long index, int *error );
+DllExport extern long SfNoHeaderBefore ( SpecFile *sf, long index, int *error );
+DllExport extern double *SfHKL ( SpecFile *sf, long index, int *error );
+DllExport extern long SfHeader ( SpecFile *sf, long index, char *string,
+ char ***lines, int *error );
+DllExport extern long SfGeometry ( SpecFile *sf, long index,
+ char ***lines, int *error );
+DllExport extern long SfFileHeader ( SpecFile *sf, long index, char *string,
+ char ***lines, int *error );
+DllExport extern char *SfFileDate ( SpecFile *sf, long index, int *error );
+DllExport extern char *SfUser ( SpecFile *sf, long index, int *error );
+DllExport extern char *SfTitle ( SpecFile *sf, long index, int *error );
+
+ /*
+ * Labels
+ */
+DllExport extern long SfAllLabels ( SpecFile *sf, long index,
+ char ***labels, int *error );
+DllExport extern char *SfLabel ( SpecFile *sf, long index, long column,
+ int *error );
+
+ /*
+ * Motors
+ */
+DllExport extern long SfAllMotors ( SpecFile *sf, long index,
+ char ***names, int *error );
+DllExport extern char * SfMotor ( SpecFile *sf, long index,
+ long number, int *error );
+DllExport extern long SfAllMotorPos ( SpecFile *sf, long index,
+ double **pos, int *error );
+DllExport extern double SfMotorPos ( SpecFile *sf, long index,
+ long number, int *error );
+DllExport extern double SfMotorPosByName ( SpecFile *sf, long index,
+ char *name, int *error );
+
+ /*
+ * Data
+ */
+DllExport extern long SfNoDataLines ( SpecFile *sf, long index, int *error );
+DllExport extern int SfData ( SpecFile *sf, long index,
+ double ***data, long **data_info, int *error );
+DllExport extern long SfDataAsString ( SpecFile *sf, long index,
+ char ***data, int *error );
+DllExport extern long SfDataLine ( SpecFile *sf, long index, long line,
+ double **data_line, int *error );
+DllExport extern long SfDataCol ( SpecFile *sf, long index, long col,
+ double **data_col, int *error );
+DllExport extern long SfDataColByName ( SpecFile *sf, long index,
+ char *label, double **data_col, int *error );
+
+ /*
+ * MCA functions
+ */
+DllExport extern long SfNoMca ( SpecFile *sf, long index, int *error );
+DllExport extern int SfGetMca ( SpecFile *sf, long index, long mcano,
+ double **retdata, int *error );
+DllExport extern long SfMcaCalib ( SpecFile *sf, long index, double **calib,
+ int *error );
+
+ /*
+ * Write and write related functions
+ */
+DllExport extern SpecFileOut *SfoInit ( SpecFile *sf, int *error );
+DllExport extern void SfoClose ( SpecFileOut *sfo );
+DllExport extern long SfoSelectAll ( SpecFileOut *sfo, int *error );
+DllExport extern long SfoSelectOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport extern long SfoSelect ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport extern long SfoSelectRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport extern long SfoRemoveOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport extern long SfoRemove ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport extern long SfoRemoveRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport extern long SfoRemoveAll ( SpecFileOut *sfo, int *error );
+DllExport extern long SfoWrite ( SpecFileOut *sfo, char *name,
+ int *error );
+DllExport extern long SfoGetList ( SpecFileOut *sfo, long **list,
+ int *error );
+ /*
+ * Memory free functions
+ */
+DllExport extern void freeArrNZ ( void ***ptr, long no_lines );
+DllExport extern void freePtr ( void *ptr );
+
+ /*
+ * Sf Tools
+ */
+DllExport extern void SfShow ( SpecFile *sf );
+DllExport extern void SfShowScan ( SpecFile *sf ,long index);
+ /*
+ * Error
+ */
+DllExport extern char *SfError ( int code );
+
+#endif /* SPECFILE_H */
diff --git a/silx/io/specfile/include/SpecFileCython.h b/silx/io/specfile/include/SpecFileCython.h
new file mode 100644
index 0000000..3225e13
--- /dev/null
+++ b/silx/io/specfile/include/SpecFileCython.h
@@ -0,0 +1,28 @@
+#/*##########################################################################
+# 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.
+#
+#############################################################################*/
+
+/* The original SpecFile.h has a `#define L 2` directive
+ that breaks cython lists and memory views. */
+#include "SpecFile.h"
+#undef L
diff --git a/silx/io/specfile/include/SpecFileP.h b/silx/io/specfile/include/SpecFileP.h
new file mode 100644
index 0000000..de9904d
--- /dev/null
+++ b/silx/io/specfile/include/SpecFileP.h
@@ -0,0 +1,74 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/***************************************************************************
+ *
+ * File: SpecFileP.h
+ *
+ * Description: Include file for treating spec data files.
+ *
+ * Author: Vicente Rey
+ *
+ * Created: 2 March 1995
+ *
+ * (copyright by E.S.R.F. March 1995)
+ *
+ ***************************************************************************/
+#ifndef SPECFILE_P_H
+#define SPECFILE_P_H
+
+/*
+ * Defines.
+ */
+#define FILE_HEADER 0
+#define SCAN 1
+
+#define FROM_SCAN 0
+#define FROM_FILE 1
+
+#define SF_COMMENT 'C'
+#define SF_DATE 'D'
+#define SF_EPOCH 'E'
+#define SF_FILE_NAME 'F'
+#define SF_GEOMETRY 'G'
+#define SF_INTENSITY 'I'
+#define SF_LABEL 'L'
+#define SF_MON_NORM 'M'
+#define SF_COLUMNS 'N'
+#define SF_MOTOR_NAMES 'O'
+#define SF_MOTOR_POSITIONS 'P'
+#define SF_RECIP_SPACE 'Q'
+#define SF_RESULTS 'R'
+#define SF_SCAN_NUM 'S'
+#define SF_TIME_NORM 'T'
+#define SF_USER_DEFINED 'U'
+#define SF_TEMPERATURE 'X'
+#define SF_MCA_DATA '@'
+
+/*
+ * Library internal functions
+ */
+extern int sfSetCurrent ( SpecFile *sf, long index, int *error);
+extern ObjectList *findScanByIndex ( ListHeader *list, long index );
+extern ObjectList *findScanByNo ( ListHeader *list, long scan_no, long order );
+extern void freeArr ( void ***ptr, long lines );
+extern void freeAllData ( SpecFile *sf );
+extern long mulstrtod ( char *str, double **arr, int *error );
+extern int sfGetHeaderLine ( SpecFile *sf, int from, char character,
+ char **buf,int *error);
+
+#endif /* SPECFILE_P_H */
diff --git a/silx/io/specfile/include/locale_management.h b/silx/io/specfile/include/locale_management.h
new file mode 100644
index 0000000..d3b9f51
--- /dev/null
+++ b/silx/io/specfile/include/locale_management.h
@@ -0,0 +1,23 @@
+#/*##########################################################################
+# Copyright (C) 2012-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+#ifndef PyMca_LOCALE_MANAGEMENT_H
+#define PyMca_LOCALE_MANAGEMENT_H
+
+double PyMcaAtof(const char*);
+
+#endif
diff --git a/silx/io/specfile/specfile.c b/silx/io/specfile/specfile.c
new file mode 100644
index 0000000..17e3eb2
--- /dev/null
+++ b/silx/io/specfile/specfile.c
@@ -0,0 +1,21782 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__specfile
+#define __PYX_HAVE_API__specfile
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#include "SpecFileCython.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+ #if defined(__cplusplus)
+ #define CYTHON_CCOMPLEX 1
+ #elif defined(_Complex_I)
+ #define CYTHON_CCOMPLEX 1
+ #else
+ #define CYTHON_CCOMPLEX 0
+ #endif
+#endif
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #include <complex>
+ #else
+ #include <complex.h>
+ #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+ #undef _Complex_I
+ #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+ "specfile.pyx",
+ "__init__.pxd",
+ "type.pxd",
+};
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":723
+ * # in Cython to enable them only on the right systems.
+ *
+ * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":724
+ *
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":725
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int64 int64_t
+ * #ctypedef npy_int96 int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96 int96_t
+ * #ctypedef npy_int128 int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":730
+ * #ctypedef npy_int128 int128_t
+ *
+ * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":731
+ *
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":732
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64 uint64_t
+ * #ctypedef npy_uint96 uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96 uint96_t
+ * #ctypedef npy_uint128 uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":737
+ * #ctypedef npy_uint128 uint128_t
+ *
+ * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_float64 float64_t
+ * #ctypedef npy_float80 float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":738
+ *
+ * ctypedef npy_float32 float32_t
+ * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80 float80_t
+ * #ctypedef npy_float128 float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong longlong_t
+ *
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":749
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_ulong uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
+ * ctypedef npy_longlong longlong_t
+ *
+ * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":752
+ *
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":753
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_intp intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ * ctypedef npy_intp intp_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp uintp_t
+ *
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":756
+ *
+ * ctypedef npy_intp intp_t
+ * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_double float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_uintp uintp_t
+ *
+ * ctypedef npy_double float_t # <<<<<<<<<<<<<<
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":759
+ *
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ *
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":760
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cfloat cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< float > __pyx_t_float_complex;
+ #else
+ typedef float _Complex __pyx_t_float_complex;
+ #endif
+#else
+ typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< double > __pyx_t_double_complex;
+ #else
+ typedef double _Complex __pyx_t_double_complex;
+ #endif
+#else
+ typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_8specfile_SpecFile;
+struct __pyx_obj_8specfile___pyx_scope_struct____iter__;
+struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ *
+ * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":763
+ *
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":764
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cdouble complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "specfile_wrapper.pxd":35
+ * pass
+ * # Renaming struct because we have too many SpecFile items (files, classes)
+ * ctypedef _SpecFile SpecFileHandle # <<<<<<<<<<<<<<
+ *
+ * cdef extern from "SpecFileCython.h":
+ */
+typedef struct _SpecFile __pyx_t_16specfile_wrapper_SpecFileHandle;
+
+/* "specfile.pyx":647
+ *
+ *
+ * cdef class SpecFile(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+struct __pyx_obj_8specfile_SpecFile {
+ PyObject_HEAD
+ __pyx_t_16specfile_wrapper_SpecFileHandle *handle;
+ PyObject *filename;
+ int __pyx___open_failed;
+};
+
+
+/* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+struct __pyx_obj_8specfile___pyx_scope_struct____iter__ {
+ PyObject_HEAD
+ Py_ssize_t __pyx_v_mca_index;
+ PyObject *__pyx_v_self;
+ Py_ssize_t __pyx_t_0;
+ Py_ssize_t __pyx_t_1;
+};
+
+
+/* "specfile.pyx":698
+ * return specfile_wrapper.SfScanNo(self.handle)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next :class:`Scan` in a SpecFile each time this method
+ * is called.
+ */
+struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ {
+ PyObject_HEAD
+ Py_ssize_t __pyx_v_scan_index;
+ struct __pyx_obj_8specfile_SpecFile *__pyx_v_self;
+ Py_ssize_t __pyx_t_0;
+ Py_ssize_t __pyx_t_1;
+};
+
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o,n,NULL)
+static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_setattro))
+ return tp->tp_setattro(obj, attr_name, value);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_setattr))
+ return tp->tp_setattr(obj, PyString_AS_STRING(attr_name), value);
+#endif
+ return PyObject_SetAttr(obj, attr_name, value);
+}
+#else
+#define __Pyx_PyObject_DelAttrStr(o,n) PyObject_DelAttr(o,n)
+#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static CYTHON_INLINE int __Pyx_PySequence_Contains(PyObject* item, PyObject* seq, int eq) {
+ int result = PySequence_Contains(seq, item);
+ return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg);
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+#if PY_MAJOR_VERSION < 3
+#define __Pyx_PyString_Join __Pyx_PyBytes_Join
+#define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v))
+#else
+#define __Pyx_PyString_Join PyUnicode_Join
+#define __Pyx_PyBaseString_Join PyUnicode_Join
+#endif
+#if CYTHON_COMPILING_IN_CPYTHON
+ #if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyBytes_Join _PyString_Join
+ #else
+ #define __Pyx_PyBytes_Join _PyBytes_Join
+ #endif
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values);
+#endif
+
+static CYTHON_INLINE int __Pyx_PyDict_Contains(PyObject* item, PyObject* dict, int eq) {
+ int result = PyDict_Contains(dict, item);
+ return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+ PyObject *value;
+ value = PyDict_GetItemWithError(d, key);
+ if (unlikely(!value)) {
+ if (!PyErr_Occurred()) {
+ PyObject* args = PyTuple_Pack(1, key);
+ if (likely(args))
+ PyErr_SetObject(PyExc_KeyError, args);
+ Py_XDECREF(args);
+ }
+ return NULL;
+ }
+ Py_INCREF(value);
+ return value;
+}
+#else
+ #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
+ const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE PyObject* __Pyx_decode_bytes(
+ PyObject* string, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ return __Pyx_decode_c_bytes(
+ PyBytes_AS_STRING(string), PyBytes_GET_SIZE(string),
+ start, stop, encoding, errors, decode_func);
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \
+ __Pyx_SetItemInt_Generic(o, to_py_func(i), v)))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v);
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck);
+
+#include <string.h>
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases);
+
+static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname,
+ PyObject *mkw, PyObject *modname, PyObject *doc);
+static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict,
+ PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass);
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
+
+#define __Pyx_CyFunction_USED 1
+#include <structmember.h>
+#define __Pyx_CYFUNCTION_STATICMETHOD 0x01
+#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02
+#define __Pyx_CYFUNCTION_CCLASS 0x04
+#define __Pyx_CyFunction_GetClosure(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_closure)
+#define __Pyx_CyFunction_GetClassObj(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_classobj)
+#define __Pyx_CyFunction_Defaults(type, f) \
+ ((type *)(((__pyx_CyFunctionObject *) (f))->defaults))
+#define __Pyx_CyFunction_SetDefaultsGetter(f, g) \
+ ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g)
+typedef struct {
+ PyCFunctionObject func;
+#if PY_VERSION_HEX < 0x030500A0
+ PyObject *func_weakreflist;
+#endif
+ PyObject *func_dict;
+ PyObject *func_name;
+ PyObject *func_qualname;
+ PyObject *func_doc;
+ PyObject *func_globals;
+ PyObject *func_code;
+ PyObject *func_closure;
+ PyObject *func_classobj;
+ void *defaults;
+ int defaults_pyobjects;
+ int flags;
+ PyObject *defaults_tuple;
+ PyObject *defaults_kwdict;
+ PyObject *(*defaults_getter)(PyObject *);
+ PyObject *func_annotations;
+} __pyx_CyFunctionObject;
+static PyTypeObject *__pyx_CyFunctionType = 0;
+#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \
+ __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code)
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
+ int flags, PyObject* qualname,
+ PyObject *self,
+ PyObject *module, PyObject *globals,
+ PyObject* code);
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m,
+ size_t size,
+ int pyobjects);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m,
+ PyObject *tuple);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m,
+ PyObject *dict);
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
+ PyObject *dict);
+static int __Pyx_CyFunction_init(void);
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #define __Pyx_CREAL(z) ((z).real())
+ #define __Pyx_CIMAG(z) ((z).imag())
+ #else
+ #define __Pyx_CREAL(z) (__real__(z))
+ #define __Pyx_CIMAG(z) (__imag__(z))
+ #endif
+#else
+ #define __Pyx_CREAL(z) ((z).real)
+ #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+ #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+ #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+ #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+ #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eqf(a, b) ((a)==(b))
+ #define __Pyx_c_sumf(a, b) ((a)+(b))
+ #define __Pyx_c_difff(a, b) ((a)-(b))
+ #define __Pyx_c_prodf(a, b) ((a)*(b))
+ #define __Pyx_c_quotf(a, b) ((a)/(b))
+ #define __Pyx_c_negf(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+ #define __Pyx_c_conjf(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_absf(z) (::std::abs(z))
+ #define __Pyx_c_powf(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zerof(z) ((z)==0)
+ #define __Pyx_c_conjf(z) (conjf(z))
+ #if 1
+ #define __Pyx_c_absf(z) (cabsf(z))
+ #define __Pyx_c_powf(a, b) (cpowf(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eq(a, b) ((a)==(b))
+ #define __Pyx_c_sum(a, b) ((a)+(b))
+ #define __Pyx_c_diff(a, b) ((a)-(b))
+ #define __Pyx_c_prod(a, b) ((a)*(b))
+ #define __Pyx_c_quot(a, b) ((a)/(b))
+ #define __Pyx_c_neg(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zero(z) ((z)==(double)0)
+ #define __Pyx_c_conj(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (::std::abs(z))
+ #define __Pyx_c_pow(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zero(z) ((z)==0)
+ #define __Pyx_c_conj(z) (conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (cabs(z))
+ #define __Pyx_c_pow(a, b) (cpow(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+#define __Pyx_Generator_USED
+#include <structmember.h>
+#include <frameobject.h>
+typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
+typedef struct {
+ PyObject_HEAD
+ __pyx_generator_body_t body;
+ PyObject *closure;
+ PyObject *exc_type;
+ PyObject *exc_value;
+ PyObject *exc_traceback;
+ PyObject *gi_weakreflist;
+ PyObject *classobj;
+ PyObject *yieldfrom;
+ PyObject *gi_name;
+ PyObject *gi_qualname;
+ int resume_label;
+ char is_running;
+} __pyx_GeneratorObject;
+static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
+ PyObject *closure, PyObject *name, PyObject *qualname);
+static int __pyx_Generator_init(void);
+static int __Pyx_Generator_clear(PyObject* self);
+#if 1 || PY_VERSION_HEX < 0x030300B0
+static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue);
+#else
+#define __Pyx_PyGen_FetchStopIterationValue(pvalue) PyGen_FetchStopIterationValue(pvalue)
+#endif
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+ #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'specfile_wrapper' */
+
+/* Module declarations from 'specfile' */
+static PyTypeObject *__pyx_ptype_8specfile_SpecFile = 0;
+static PyTypeObject *__pyx_ptype_8specfile___pyx_scope_struct____iter__ = 0;
+static PyTypeObject *__pyx_ptype_8specfile___pyx_scope_struct_1___iter__ = 0;
+#define __Pyx_MODULE_NAME "specfile"
+int __pyx_module_is_main_specfile = 0;
+
+/* Implementation of 'specfile' */
+static PyObject *__pyx_builtin_Exception;
+static PyObject *__pyx_builtin_object;
+static PyObject *__pyx_builtin_property;
+static PyObject *__pyx_builtin_map;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_open;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_KeyError;
+static PyObject *__pyx_builtin_AttributeError;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_pf_8specfile_3MCA___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_scan); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_2_parse_channels(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_4_parse_calibration(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_6__len__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_8__getitem__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_8specfile_3MCA_10__iter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile__add_or_concatenate(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_dictionary, PyObject *__pyx_v_key, PyObject *__pyx_v_value); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_specfile, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_2index(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_4number(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_6order(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_8header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_10scan_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_12file_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_14scan_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_16mca_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_18file_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_20labels(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_22data(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_24mca(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_26motor_names(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_28motor_positions(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_30record_exists_in_hdr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_record); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_32data_line(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_line_index); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_34data_column_by_name(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_label); /* proto */
+static PyObject *__pyx_pf_8specfile_4Scan_36motor_position_by_name(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_pf_8specfile_2_string_to_char_star(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_string_); /* proto */
+static PyObject *__pyx_pf_8specfile_4is_specfile(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_filename); /* proto */
+static int __pyx_pf_8specfile_8SpecFile___cinit__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
+static int __pyx_pf_8specfile_8SpecFile_2__init__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_filename); /* proto */
+static void __pyx_pf_8specfile_8SpecFile_4__dealloc__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_pf_8specfile_8SpecFile_6__len__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_8__iter__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_11__getitem__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_13keys(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static int __pyx_pf_8specfile_8SpecFile_15__contains__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_17_get_error_string(CYTHON_UNUSED struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_error_code); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_19_handle_error(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_error_code); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_21index(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_number, PyObject *__pyx_v_scan_order); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_23number(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_25order(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_27_list(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_29list(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_31data(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_33data_column_by_name(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_label); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_35scan_header(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_37file_header(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_39columns(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_41command(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_43date(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_45labels(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_47motor_names(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_49motor_positions(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_51motor_position_by_name(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_53number_of_mca(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_55mca_calibration(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index); /* proto */
+static PyObject *__pyx_pf_8specfile_8SpecFile_57get_mca(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_mca_index); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static PyObject *__pyx_tp_new_8specfile_SpecFile(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_8specfile___pyx_scope_struct____iter__(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_8specfile___pyx_scope_struct_1___iter__(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_[] = "\n";
+static char __pyx_k_2[] = " {2,}";
+static char __pyx_k_3[] = "3";
+static char __pyx_k_B[] = "B";
+static char __pyx_k_F[] = "#F ";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_S[] = "#S ";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_w[] = "#(\\w+) *(.*)";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k__7[] = "#";
+static char __pyx_k_os[] = "os";
+static char __pyx_k_re[] = "re";
+static char __pyx_k_MCA[] = "MCA";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k__14[] = " ";
+static char __pyx_k__25[] = ".";
+static char __pyx_k__27[] = "', '";
+static char __pyx_k__28[] = "'";
+static char __pyx_k__29[] = "";
+static char __pyx_k_d_d[] = "%d.%d";
+static char __pyx_k_doc[] = "__doc__";
+static char __pyx_k_key[] = "key";
+static char __pyx_k_len[] = "__len__";
+static char __pyx_k_map[] = "map";
+static char __pyx_k_mca[] = "_mca";
+static char __pyx_k_msg[] = "msg";
+static char __pyx_k_ret[] = "ret";
+static char __pyx_k_sub[] = "sub";
+static char __pyx_k_sys[] = "sys";
+static char __pyx_k_w_2[] = "#@(\\w+) *(.*)";
+static char __pyx_k_Scan[] = "Scan";
+static char __pyx_k_args[] = "args";
+static char __pyx_k_data[] = "_data";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_hkey[] = "hkey";
+static char __pyx_k_init[] = "__init__";
+static char __pyx_k_iter[] = "__iter__";
+static char __pyx_k_join[] = "join";
+static char __pyx_k_keys[] = "keys";
+static char __pyx_k_line[] = "line";
+static char __pyx_k_list[] = "_list";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_open[] = "open";
+static char __pyx_k_path[] = "path";
+static char __pyx_k_scan[] = "scan";
+static char __pyx_k_self[] = "self";
+static char __pyx_k_send[] = "send";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_CALIB[] = "CALIB";
+static char __pyx_k_CHANN[] = "CHANN";
+static char __pyx_k_ascii[] = "ascii";
+static char __pyx_k_close[] = "close";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_empty[] = "empty";
+static char __pyx_k_group[] = "group";
+static char __pyx_k_index[] = "index";
+static char __pyx_k_label[] = "label";
+static char __pyx_k_match[] = "match";
+static char __pyx_k_mca_2[] = "mca";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_order[] = "order";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_split[] = "split";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_strip[] = "strip";
+static char __pyx_k_throw[] = "throw";
+static char __pyx_k_value[] = "value";
+static char __pyx_k_ERRORS[] = "ERRORS";
+static char __pyx_k_append[] = "append";
+static char __pyx_k_data_2[] = "data";
+static char __pyx_k_decode[] = "decode";
+static char __pyx_k_double[] = "double";
+static char __pyx_k_encode[] = "encode";
+static char __pyx_k_header[] = "_header";
+static char __pyx_k_hvalue[] = "hvalue";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_isfile[] = "isfile";
+static char __pyx_k_labels[] = "_labels";
+static char __pyx_k_length[] = "length";
+static char __pyx_k_logger[] = "_logger";
+static char __pyx_k_lstrip[] = "lstrip";
+static char __pyx_k_module[] = "__module__";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_number[] = "number";
+static char __pyx_k_object[] = "object";
+static char __pyx_k_record[] = "record";
+static char __pyx_k_scan_2[] = "_scan";
+static char __pyx_k_search[] = "search";
+static char __pyx_k_string[] = "string_";
+static char __pyx_k_SfError[] = "SfError";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_get_mca[] = "get_mca";
+static char __pyx_k_getitem[] = "__getitem__";
+static char __pyx_k_index_2[] = "_index";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_logging[] = "logging";
+static char __pyx_k_order_2[] = "_order";
+static char __pyx_k_os_path[] = "os.path";
+static char __pyx_k_prepare[] = "__prepare__";
+static char __pyx_k_version[] = "version";
+static char __pyx_k_warning[] = "warning";
+static char __pyx_k_KeyError[] = "KeyError";
+static char __pyx_k_L_header[] = "L_header";
+static char __pyx_k_P_Knobel[] = "P. Knobel";
+static char __pyx_k_Scan_mca[] = "Scan.mca";
+static char __pyx_k_channels[] = "channels";
+static char __pyx_k_filename[] = "filename";
+static char __pyx_k_header_2[] = "header";
+static char __pyx_k_labels_2[] = "labels";
+static char __pyx_k_number_2[] = "_number";
+static char __pyx_k_property[] = "property";
+static char __pyx_k_qualname[] = "__qualname__";
+static char __pyx_k_specfile[] = "_specfile";
+static char __pyx_k_Exception[] = "Exception";
+static char __pyx_k_MCA___len[] = "MCA.__len__";
+static char __pyx_k_Scan_data[] = "Scan.data";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_data_line[] = "data_line";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_getLogger[] = "getLogger";
+static char __pyx_k_increment[] = "increment";
+static char __pyx_k_match_mca[] = "match_mca";
+static char __pyx_k_mca_index[] = "mca_index";
+static char __pyx_k_metaclass[] = "__metaclass__";
+static char __pyx_k_transpose[] = "transpose";
+static char __pyx_k_27_09_2016[] = "27/09/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_MCA___init[] = "MCA.__init__";
+static char __pyx_k_MCA___iter[] = "MCA.__iter__";
+static char __pyx_k_Scan_index[] = "Scan.index";
+static char __pyx_k_Scan_order[] = "Scan.order";
+static char __pyx_k_Valid_keys[] = "\nValid keys: '";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_calib_line[] = "calib_line";
+static char __pyx_k_chann_line[] = "chann_line";
+static char __pyx_k_dictionary[] = "dictionary";
+static char __pyx_k_line_index[] = "line_index";
+static char __pyx_k_scan_index[] = "scan_index";
+static char __pyx_k_scan_order[] = "scan_order";
+static char __pyx_k_specfile_2[] = "specfile";
+static char __pyx_k_startswith[] = "startswith";
+static char __pyx_k_Scan___init[] = "Scan.__init__";
+static char __pyx_k_Scan_header[] = "Scan.header";
+static char __pyx_k_Scan_labels[] = "Scan.labels";
+static char __pyx_k_Scan_number[] = "Scan.number";
+static char __pyx_k_basicConfig[] = "basicConfig";
+static char __pyx_k_calib_lines[] = "calib_lines";
+static char __pyx_k_calibration[] = "calibration";
+static char __pyx_k_chann_lines[] = "chann_lines";
+static char __pyx_k_file_header[] = "file_header";
+static char __pyx_k_is_specfile[] = "is_specfile";
+static char __pyx_k_motor_names[] = "motor_names";
+static char __pyx_k_scan_header[] = "scan_header";
+static char __pyx_k_scan_number[] = "scan_number";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_SfNoMcaError[] = "SfNoMcaError";
+static char __pyx_k_handle_error[] = "_handle_error";
+static char __pyx_k_version_info[] = "version_info";
+static char __pyx_k_MCA___getitem[] = "MCA.__getitem__";
+static char __pyx_k_SfErrFileOpen[] = "SfErrFileOpen";
+static char __pyx_k_SfErrFileRead[] = "SfErrFileRead";
+static char __pyx_k_motor_names_2[] = "_motor_names";
+static char __pyx_k_number_of_mca[] = "number_of_mca";
+static char __pyx_k_AttributeError[] = "AttributeError";
+static char __pyx_k_Scan_data_line[] = "Scan.data_line";
+static char __pyx_k_SfErrFileClose[] = "SfErrFileClose";
+static char __pyx_k_SfErrFileWrite[] = "SfErrFileWrite";
+static char __pyx_k_SfErrLineEmpty[] = "SfErrLineEmpty";
+static char __pyx_k_parse_channels[] = "_parse_channels";
+static char __pyx_k_SpecFile___iter[] = "SpecFile.__iter__";
+static char __pyx_k_mca_header_dict[] = "mca_header_dict";
+static char __pyx_k_motor_positions[] = "motor_positions";
+static char __pyx_k_SF_ERR_FILE_OPEN[] = "SF_ERR_FILE_OPEN";
+static char __pyx_k_SF_ERR_NO_ERRORS[] = "SF_ERR_NO_ERRORS";
+static char __pyx_k_Scan_file_header[] = "Scan.file_header";
+static char __pyx_k_Scan_motor_names[] = "Scan.motor_names";
+static char __pyx_k_Scan_scan_header[] = "Scan.scan_header";
+static char __pyx_k_SfErrColNotFound[] = "SfErrColNotFound";
+static char __pyx_k_SfErrMcaNotFound[] = "SfErrMcaNotFound";
+static char __pyx_k_SfErrMemoryAlloc[] = "SfErrMemoryAlloc";
+static char __pyx_k_all_calib_values[] = "all_calib_values";
+static char __pyx_k_all_chann_values[] = "all_chann_values";
+static char __pyx_k_file_header_dict[] = "_file_header_dict";
+static char __pyx_k_get_error_string[] = "_get_error_string";
+static char __pyx_k_scan_header_dict[] = "_scan_header_dict";
+static char __pyx_k_SfErrLineNotFound[] = "SfErrLineNotFound";
+static char __pyx_k_SfErrScanNotFound[] = "SfErrScanNotFound";
+static char __pyx_k_SfErrUserNotFound[] = "SfErrUserNotFound";
+static char __pyx_k_file_header_lines[] = "_file_header_lines";
+static char __pyx_k_mca_header_dict_2[] = "_mca_header_dict";
+static char __pyx_k_motor_positions_2[] = "_motor_positions";
+static char __pyx_k_parse_calibration[] = "_parse_calibration";
+static char __pyx_k_scan_header_lines[] = "_scan_header_lines";
+static char __pyx_k_SfErrLabelNotFound[] = "SfErrLabelNotFound";
+static char __pyx_k_SfErrMotorNotFound[] = "SfErrMotorNotFound";
+static char __pyx_k_SfNoMca_returned_1[] = "(SfNoMca returned -1)";
+static char __pyx_k_add_or_concatenate[] = "_add_or_concatenate";
+static char __pyx_k_file_header_dict_2[] = "file_header_dict";
+static char __pyx_k_scan_header_dict_2[] = "scan_header_dict";
+static char __pyx_k_MCA__parse_channels[] = "MCA._parse_channels";
+static char __pyx_k_SfErrHeaderNotFound[] = "SfErrHeaderNotFound";
+static char __pyx_k_data_column_by_name[] = "data_column_by_name";
+static char __pyx_k_string_to_char_star[] = "_string_to_char_star";
+static char __pyx_k_Scan_mca_header_dict[] = "Scan.mca_header_dict";
+static char __pyx_k_Scan_motor_positions[] = "Scan.motor_positions";
+static char __pyx_k_record_exists_in_hdr[] = "record_exists_in_hdr";
+static char __pyx_k_SF_ERR_SCAN_NOT_FOUND[] = "SF_ERR_SCAN_NOT_FOUND";
+static char __pyx_k_Scan_file_header_dict[] = "Scan.file_header_dict";
+static char __pyx_k_Scan_scan_header_dict[] = "Scan.scan_header_dict";
+static char __pyx_k_SfErrPositionNotFound[] = "SfErrPositionNotFound";
+static char __pyx_k_one_line_calib_values[] = "one_line_calib_values";
+static char __pyx_k_one_line_chann_values[] = "one_line_chann_values";
+static char __pyx_k_MCA__parse_calibration[] = "MCA._parse_calibration";
+static char __pyx_k_motor_position_by_name[] = "motor_position_by_name";
+static char __pyx_k_Scan_data_column_by_name[] = "Scan.data_column_by_name";
+static char __pyx_k_Scan_record_exists_in_hdr[] = "Scan.record_exists_in_hdr";
+static char __pyx_k_Scan_motor_position_by_name[] = "Scan.motor_position_by_name";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_Error_while_closing_SpecFile[] = "Error while closing SpecFile";
+static char __pyx_k_number_and_M_the_order_eg_2_3[] = " number and M the order (eg '2.3').";
+static char __pyx_k_MCA_index_must_be_in_range_0_d[] = "MCA index must be in range 0-%d";
+static char __pyx_k_param_specfile_Parent_SpecFile[] = "\n\n :param specfile: Parent SpecFile from which this scan is extracted.\n :type specfile: :class:`SpecFile`\n :param scan_index: Unique index defining the scan in the SpecFile\n :type scan_index: int\n\n Interface to access a SpecFile scan\n\n A scan is a block of descriptive header lines followed by a 2D data array.\n\n Following three ways of accessing a scan are equivalent::\n\n sf = SpecFile(\"/path/to/specfile.dat\")\n\n # Explicit class instantiation\n scan2 = Scan(sf, scan_index=2)\n\n # 0-based index on a SpecFile object\n scan2 = sf[2]\n\n # Using a \"n.m\" key (scan number starting with 1, scan order)\n scan2 = sf[\"3.1\"]\n ";
+static char __pyx_k_users_payno_Documents_dev_esrf[] = "/users/payno/Documents/dev/esrf/silx/paynoSilx/silx/silx/io/specfile/specfile.pyx";
+static char __pyx_k_Base_exception_inherited_by_all[] = "Base exception inherited by all exceptions raised when a\n C function from the legacy SpecFile library returns an error\n code.\n ";
+static char __pyx_k_Scan_index_must_be_in_range_0_d[] = "Scan index must be in range 0-%d";
+static char __pyx_k_The_scan_identification_key_can[] = "The scan identification key can be an integer representing ";
+static char __pyx_k_This_module_is_a_cython_binding[] = "\nThis module is a cython binding to wrap the C SpecFile library, to access\nSpecFile data within a python program.\n\nDocumentation for the original C library SpecFile can be found on the ESRF\nwebsite:\n`The manual for the SpecFile Library <http://www.esrf.eu/files/live/sites/www/files/Instrumentation/software/beamline-control/BLISS/documentation/SpecFileManual.pdf>`_\n\nExamples\n========\n\nStart by importing :class:`SpecFile` and instantiate it:\n\n.. code-block:: python\n\n from silx.io.specfile import SpecFile\n\n sf = SpecFile(\"test.dat\")\n\nA :class:`SpecFile` instance can be accessed like a dictionary to obtain a\n:class:`Scan` instance.\n\nIf the key is a string representing two values\nseparated by a dot (e.g. ``\"1.2\"``), they will be treated as the scan number\n(``#S`` header line) and the scan order::\n\n # get second occurrence of scan \"#S 1\"\n myscan = sf[\"1.2\"]\n\n # access scan data as a numpy array\n nlines, ncolumns = myscan.data.shape\n\nIf the key is an integer, it will be treated as a 0-based index::\n\n first_scan = sf[0]\n second_scan = sf[1]\n\nIt is also possible to browse through all scans using :class:`SpecFile` as\nan iterator::\n\n for scan in sf:\n print(scan.scan_header_dict['S'])\n\nMCA spectra can be selectively loaded using an instance of :class:`MCA`\nprovided by :class:`Scan`::\n\n # Only one MCA spectrum is loaded in memory\n second_mca = first_scan.mca[1]\n\n # Iterating trough all MCA spectra in a scan:\n for mca_data in first_scan.mca:\n print(sum(mca_data))\n\nClasses\n=======\n\n- :class:`SpecFile`\n- :class:`Scan`\n- :class:`MCA`\n\nExceptions\n==========\n\n- :class:`SfError`\n- :class:`SfErrMemoryAlloc`\n- :class:`SfErrFileOpen`\n- :class:`SfErrFileClose`\n- :class:`SfErrFileRead`\n- :class:`SfErrFileWrite`\n- :class:`SfErrLineNotFound`\n- :class:`SfErrScanNotFound`\n- :class:`SfErrHeaderNotFound`\n- :class:`SfErrLabelNotFound`\n- :class:`SfErrMotorNotFound`""\n- :class:`SfErrPositionNotFound`\n- :class:`SfErrLineEmpty`\n- :class:`SfErrUserNotFound`\n- :class:`SfErrColNotFound`\n- :class:`SfErrMcaNotFound`\n\n";
+static char __pyx_k_param_scan_Parent_Scan_instance[] = "\n\n :param scan: Parent Scan instance\n :type scan: :class:`Scan`\n\n :var calibration: MCA calibration :math:`(a, b, c)` (as in\n :math:`a + b x + c x\302\262`) from ``#@CALIB`` scan header.\n :type calibration: list of 3 floats, default ``[0., 1., 0.]``\n :var channels: MCA channels list from ``#@CHANN`` scan header.\n In the absence of a ``#@CHANN`` header, this attribute is a list\n ``[0, \342\200\246, N-1]`` where ``N`` is the length of the first spectrum.\n In the absence of MCA spectra, this attribute defaults to ``None``.\n :type channels: list of int\n\n This class provides access to Multi-Channel Analysis data. A :class:`MCA`\n instance can be indexed to access 1D numpy arrays representing single \n MCA\302\240spectra.\n\n To create a :class:`MCA` instance, you must provide a parent :class:`Scan`\n instance, which in turn will provide a reference to the original\n :class:`SpecFile` instance::\n\n sf = SpecFile(\"/path/to/specfile.dat\")\n scan2 = Scan(sf, scan_index=2)\n mcas_in_scan2 = MCA(scan2)\n for i in len(mcas_in_scan2):\n mca_data = mcas_in_scan2[i]\n ... # do some something with mca_data (1D numpy array)\n\n A more pythonic way to do the same work, without having to explicitly\n instantiate ``scan`` and ``mcas_in_scan``, would be::\n\n sf = SpecFile(\"specfilename.dat\")\n # scan2 from previous example can be referred to as sf[2]\n # mcas_in_scan2 from previous example can be referred to as scan2.mca\n for mca_data in sf[2].mca:\n ... # do some something with mca_data (1D numpy array)\n\n ";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_Cannot_get_data_column_s_in_scan[] = "Cannot get data column %s in scan %d.%d";
+static char __pyx_k_Custom_exception_raised_when_SfN[] = "Custom exception raised when ``SfNoMca()`` returns ``-1``\n ";
+static char __pyx_k_Failed_to_retrieve_number_of_MCA[] = "Failed to retrieve number of MCA ";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_MCA_calibration_line_CALIB_not_f[] = "MCA calibration line (@CALIB) not found";
+static char __pyx_k_MCA_index_should_be_an_integer_s[] = "MCA index should be an integer (%s provided)";
+static char __pyx_k_No_MCA_spectrum_found_in_this_sc[] = "No MCA spectrum found in this scan";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_Parameter_value_must_be_a_string[] = "Parameter value must be a string.";
+static char __pyx_k_Unable_to_parse_file_header_line[] = "Unable to parse file header line ";
+static char __pyx_k_Unable_to_parse_scan_header_line[] = "Unable to parse scan header line ";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_the_unique_scan_index_or_a_strin[] = "the unique scan index or a string 'N.M' with N being the scan";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static PyObject *__pyx_kp_s_;
+static PyObject *__pyx_kp_s_2;
+static PyObject *__pyx_kp_s_27_09_2016;
+static PyObject *__pyx_kp_s_3;
+static PyObject *__pyx_n_s_AttributeError;
+static PyObject *__pyx_kp_s_Base_exception_inherited_by_all;
+static PyObject *__pyx_n_s_CALIB;
+static PyObject *__pyx_n_s_CHANN;
+static PyObject *__pyx_kp_s_Cannot_get_data_column_s_in_scan;
+static PyObject *__pyx_kp_s_Custom_exception_raised_when_SfN;
+static PyObject *__pyx_n_s_ERRORS;
+static PyObject *__pyx_kp_s_Error_while_closing_SpecFile;
+static PyObject *__pyx_n_s_Exception;
+static PyObject *__pyx_kp_s_F;
+static PyObject *__pyx_kp_s_Failed_to_retrieve_number_of_MCA;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_n_s_KeyError;
+static PyObject *__pyx_n_s_L;
+static PyObject *__pyx_n_s_L_header;
+static PyObject *__pyx_n_s_MCA;
+static PyObject *__pyx_n_s_MCA___getitem;
+static PyObject *__pyx_n_s_MCA___init;
+static PyObject *__pyx_n_s_MCA___iter;
+static PyObject *__pyx_n_s_MCA___len;
+static PyObject *__pyx_n_s_MCA__parse_calibration;
+static PyObject *__pyx_n_s_MCA__parse_channels;
+static PyObject *__pyx_kp_s_MCA_calibration_line_CALIB_not_f;
+static PyObject *__pyx_kp_s_MCA_index_must_be_in_range_0_d;
+static PyObject *__pyx_kp_s_MCA_index_should_be_an_integer_s;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_kp_s_No_MCA_spectrum_found_in_this_sc;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_kp_s_P_Knobel;
+static PyObject *__pyx_kp_s_Parameter_value_must_be_a_string;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_S;
+static PyObject *__pyx_n_s_SF_ERR_FILE_OPEN;
+static PyObject *__pyx_n_s_SF_ERR_NO_ERRORS;
+static PyObject *__pyx_n_s_SF_ERR_SCAN_NOT_FOUND;
+static PyObject *__pyx_n_s_Scan;
+static PyObject *__pyx_n_s_Scan___init;
+static PyObject *__pyx_n_s_Scan_data;
+static PyObject *__pyx_n_s_Scan_data_column_by_name;
+static PyObject *__pyx_n_s_Scan_data_line;
+static PyObject *__pyx_n_s_Scan_file_header;
+static PyObject *__pyx_n_s_Scan_file_header_dict;
+static PyObject *__pyx_n_s_Scan_header;
+static PyObject *__pyx_n_s_Scan_index;
+static PyObject *__pyx_kp_s_Scan_index_must_be_in_range_0_d;
+static PyObject *__pyx_n_s_Scan_labels;
+static PyObject *__pyx_n_s_Scan_mca;
+static PyObject *__pyx_n_s_Scan_mca_header_dict;
+static PyObject *__pyx_n_s_Scan_motor_names;
+static PyObject *__pyx_n_s_Scan_motor_position_by_name;
+static PyObject *__pyx_n_s_Scan_motor_positions;
+static PyObject *__pyx_n_s_Scan_number;
+static PyObject *__pyx_n_s_Scan_order;
+static PyObject *__pyx_n_s_Scan_record_exists_in_hdr;
+static PyObject *__pyx_n_s_Scan_scan_header;
+static PyObject *__pyx_n_s_Scan_scan_header_dict;
+static PyObject *__pyx_n_s_SfErrColNotFound;
+static PyObject *__pyx_n_s_SfErrFileClose;
+static PyObject *__pyx_n_s_SfErrFileOpen;
+static PyObject *__pyx_n_s_SfErrFileRead;
+static PyObject *__pyx_n_s_SfErrFileWrite;
+static PyObject *__pyx_n_s_SfErrHeaderNotFound;
+static PyObject *__pyx_n_s_SfErrLabelNotFound;
+static PyObject *__pyx_n_s_SfErrLineEmpty;
+static PyObject *__pyx_n_s_SfErrLineNotFound;
+static PyObject *__pyx_n_s_SfErrMcaNotFound;
+static PyObject *__pyx_n_s_SfErrMemoryAlloc;
+static PyObject *__pyx_n_s_SfErrMotorNotFound;
+static PyObject *__pyx_n_s_SfErrPositionNotFound;
+static PyObject *__pyx_n_s_SfErrScanNotFound;
+static PyObject *__pyx_n_s_SfErrUserNotFound;
+static PyObject *__pyx_n_s_SfError;
+static PyObject *__pyx_n_s_SfNoMcaError;
+static PyObject *__pyx_kp_s_SfNoMca_returned_1;
+static PyObject *__pyx_n_s_SpecFile___iter;
+static PyObject *__pyx_kp_s_The_scan_identification_key_can;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_parse_file_header_line;
+static PyObject *__pyx_kp_s_Unable_to_parse_scan_header_line;
+static PyObject *__pyx_kp_s_Valid_keys;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_kp_s__14;
+static PyObject *__pyx_kp_s__25;
+static PyObject *__pyx_kp_s__27;
+static PyObject *__pyx_kp_s__28;
+static PyObject *__pyx_kp_s__7;
+static PyObject *__pyx_n_s_add_or_concatenate;
+static PyObject *__pyx_n_s_all_calib_values;
+static PyObject *__pyx_n_s_all_chann_values;
+static PyObject *__pyx_n_s_append;
+static PyObject *__pyx_n_s_args;
+static PyObject *__pyx_n_s_ascii;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_basicConfig;
+static PyObject *__pyx_n_s_calib_line;
+static PyObject *__pyx_n_s_calib_lines;
+static PyObject *__pyx_n_s_calibration;
+static PyObject *__pyx_n_s_chann_line;
+static PyObject *__pyx_n_s_chann_lines;
+static PyObject *__pyx_n_s_channels;
+static PyObject *__pyx_n_s_close;
+static PyObject *__pyx_kp_u_d_d;
+static PyObject *__pyx_n_s_data;
+static PyObject *__pyx_n_s_data_2;
+static PyObject *__pyx_n_s_data_column_by_name;
+static PyObject *__pyx_n_s_data_line;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_decode;
+static PyObject *__pyx_n_s_dictionary;
+static PyObject *__pyx_n_s_doc;
+static PyObject *__pyx_n_s_double;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_empty;
+static PyObject *__pyx_n_s_encode;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_f;
+static PyObject *__pyx_n_s_file_header;
+static PyObject *__pyx_n_s_file_header_dict;
+static PyObject *__pyx_n_s_file_header_dict_2;
+static PyObject *__pyx_n_s_file_header_lines;
+static PyObject *__pyx_n_s_filename;
+static PyObject *__pyx_n_s_getLogger;
+static PyObject *__pyx_n_s_get_error_string;
+static PyObject *__pyx_n_s_get_mca;
+static PyObject *__pyx_n_s_getitem;
+static PyObject *__pyx_n_s_group;
+static PyObject *__pyx_n_s_handle_error;
+static PyObject *__pyx_n_s_header;
+static PyObject *__pyx_n_s_header_2;
+static PyObject *__pyx_n_s_hkey;
+static PyObject *__pyx_n_s_hvalue;
+static PyObject *__pyx_n_s_i;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_increment;
+static PyObject *__pyx_n_s_index;
+static PyObject *__pyx_n_s_index_2;
+static PyObject *__pyx_n_s_init;
+static PyObject *__pyx_n_s_is_specfile;
+static PyObject *__pyx_n_s_isfile;
+static PyObject *__pyx_n_s_iter;
+static PyObject *__pyx_n_s_join;
+static PyObject *__pyx_n_s_key;
+static PyObject *__pyx_n_s_keys;
+static PyObject *__pyx_n_s_label;
+static PyObject *__pyx_n_s_labels;
+static PyObject *__pyx_n_s_labels_2;
+static PyObject *__pyx_n_s_len;
+static PyObject *__pyx_n_s_length;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_line;
+static PyObject *__pyx_n_s_line_index;
+static PyObject *__pyx_n_s_list;
+static PyObject *__pyx_n_s_logger;
+static PyObject *__pyx_n_s_logging;
+static PyObject *__pyx_n_s_lstrip;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_map;
+static PyObject *__pyx_n_s_match;
+static PyObject *__pyx_n_s_match_mca;
+static PyObject *__pyx_n_s_mca;
+static PyObject *__pyx_n_s_mca_2;
+static PyObject *__pyx_n_s_mca_header_dict;
+static PyObject *__pyx_n_s_mca_header_dict_2;
+static PyObject *__pyx_n_s_mca_index;
+static PyObject *__pyx_n_s_metaclass;
+static PyObject *__pyx_n_s_module;
+static PyObject *__pyx_n_s_motor_names;
+static PyObject *__pyx_n_s_motor_names_2;
+static PyObject *__pyx_n_s_motor_position_by_name;
+static PyObject *__pyx_n_s_motor_positions;
+static PyObject *__pyx_n_s_motor_positions_2;
+static PyObject *__pyx_n_s_msg;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_number;
+static PyObject *__pyx_n_s_number_2;
+static PyObject *__pyx_kp_s_number_and_M_the_order_eg_2_3;
+static PyObject *__pyx_n_s_number_of_mca;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_object;
+static PyObject *__pyx_n_s_one_line_calib_values;
+static PyObject *__pyx_n_s_one_line_chann_values;
+static PyObject *__pyx_n_s_open;
+static PyObject *__pyx_n_s_order;
+static PyObject *__pyx_n_s_order_2;
+static PyObject *__pyx_n_s_os;
+static PyObject *__pyx_n_s_os_path;
+static PyObject *__pyx_kp_s_param_scan_Parent_Scan_instance;
+static PyObject *__pyx_kp_s_param_specfile_Parent_SpecFile;
+static PyObject *__pyx_n_s_parse_calibration;
+static PyObject *__pyx_n_s_parse_channels;
+static PyObject *__pyx_n_s_path;
+static PyObject *__pyx_n_s_prepare;
+static PyObject *__pyx_n_s_property;
+static PyObject *__pyx_n_s_qualname;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_re;
+static PyObject *__pyx_n_s_record;
+static PyObject *__pyx_n_s_record_exists_in_hdr;
+static PyObject *__pyx_n_s_ret;
+static PyObject *__pyx_n_s_scan;
+static PyObject *__pyx_n_s_scan_2;
+static PyObject *__pyx_n_s_scan_header;
+static PyObject *__pyx_n_s_scan_header_dict;
+static PyObject *__pyx_n_s_scan_header_dict_2;
+static PyObject *__pyx_n_s_scan_header_lines;
+static PyObject *__pyx_n_s_scan_index;
+static PyObject *__pyx_n_s_scan_number;
+static PyObject *__pyx_n_s_scan_order;
+static PyObject *__pyx_n_s_search;
+static PyObject *__pyx_n_s_self;
+static PyObject *__pyx_n_s_send;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_specfile;
+static PyObject *__pyx_n_s_specfile_2;
+static PyObject *__pyx_n_s_split;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_startswith;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_n_s_string;
+static PyObject *__pyx_n_s_string_to_char_star;
+static PyObject *__pyx_n_s_strip;
+static PyObject *__pyx_n_s_sub;
+static PyObject *__pyx_n_s_sys;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_kp_s_the_unique_scan_index_or_a_strin;
+static PyObject *__pyx_n_s_throw;
+static PyObject *__pyx_n_s_transpose;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_kp_s_users_payno_Documents_dev_esrf;
+static PyObject *__pyx_n_s_value;
+static PyObject *__pyx_n_s_version;
+static PyObject *__pyx_n_s_version_info;
+static PyObject *__pyx_kp_s_w;
+static PyObject *__pyx_kp_s_w_2;
+static PyObject *__pyx_n_s_warning;
+static PyObject *__pyx_float_0_;
+static PyObject *__pyx_float_1_;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_3;
+static PyObject *__pyx_int_4;
+static PyObject *__pyx_int_5;
+static PyObject *__pyx_int_6;
+static PyObject *__pyx_int_7;
+static PyObject *__pyx_int_8;
+static PyObject *__pyx_int_9;
+static PyObject *__pyx_int_10;
+static PyObject *__pyx_int_11;
+static PyObject *__pyx_int_12;
+static PyObject *__pyx_int_13;
+static PyObject *__pyx_int_14;
+static PyObject *__pyx_int_15;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__19;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__26;
+static PyObject *__pyx_tuple__30;
+static PyObject *__pyx_tuple__31;
+static PyObject *__pyx_tuple__32;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_tuple__34;
+static PyObject *__pyx_tuple__35;
+static PyObject *__pyx_tuple__36;
+static PyObject *__pyx_tuple__37;
+static PyObject *__pyx_tuple__39;
+static PyObject *__pyx_tuple__41;
+static PyObject *__pyx_tuple__43;
+static PyObject *__pyx_tuple__45;
+static PyObject *__pyx_tuple__47;
+static PyObject *__pyx_tuple__49;
+static PyObject *__pyx_tuple__51;
+static PyObject *__pyx_tuple__53;
+static PyObject *__pyx_tuple__55;
+static PyObject *__pyx_tuple__57;
+static PyObject *__pyx_tuple__59;
+static PyObject *__pyx_tuple__61;
+static PyObject *__pyx_tuple__63;
+static PyObject *__pyx_tuple__65;
+static PyObject *__pyx_tuple__67;
+static PyObject *__pyx_tuple__69;
+static PyObject *__pyx_tuple__71;
+static PyObject *__pyx_tuple__73;
+static PyObject *__pyx_tuple__75;
+static PyObject *__pyx_tuple__77;
+static PyObject *__pyx_tuple__79;
+static PyObject *__pyx_tuple__81;
+static PyObject *__pyx_tuple__83;
+static PyObject *__pyx_tuple__85;
+static PyObject *__pyx_tuple__87;
+static PyObject *__pyx_tuple__89;
+static PyObject *__pyx_tuple__91;
+static PyObject *__pyx_codeobj__38;
+static PyObject *__pyx_codeobj__40;
+static PyObject *__pyx_codeobj__42;
+static PyObject *__pyx_codeobj__44;
+static PyObject *__pyx_codeobj__46;
+static PyObject *__pyx_codeobj__48;
+static PyObject *__pyx_codeobj__50;
+static PyObject *__pyx_codeobj__52;
+static PyObject *__pyx_codeobj__54;
+static PyObject *__pyx_codeobj__56;
+static PyObject *__pyx_codeobj__58;
+static PyObject *__pyx_codeobj__60;
+static PyObject *__pyx_codeobj__62;
+static PyObject *__pyx_codeobj__64;
+static PyObject *__pyx_codeobj__66;
+static PyObject *__pyx_codeobj__68;
+static PyObject *__pyx_codeobj__70;
+static PyObject *__pyx_codeobj__72;
+static PyObject *__pyx_codeobj__74;
+static PyObject *__pyx_codeobj__76;
+static PyObject *__pyx_codeobj__78;
+static PyObject *__pyx_codeobj__80;
+static PyObject *__pyx_codeobj__82;
+static PyObject *__pyx_codeobj__84;
+static PyObject *__pyx_codeobj__86;
+static PyObject *__pyx_codeobj__88;
+static PyObject *__pyx_codeobj__90;
+static PyObject *__pyx_codeobj__92;
+
+/* "specfile.pyx":234
+ *
+ * """
+ * def __init__(self, scan): # <<<<<<<<<<<<<<
+ * self._scan = scan
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_3MCA___init__[] = "MCA.__init__(self, scan)";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_1__init__ = {"__init__", (PyCFunction)__pyx_pw_8specfile_3MCA_1__init__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_3MCA___init__};
+static PyObject *__pyx_pw_8specfile_3MCA_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_scan = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_scan,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_scan = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.MCA.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_3MCA___init__(__pyx_self, __pyx_v_self, __pyx_v_scan);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_scan) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "specfile.pyx":235
+ * """
+ * def __init__(self, scan):
+ * self._scan = scan # <<<<<<<<<<<<<<
+ *
+ * # Header dict
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_scan_2, __pyx_v_scan) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":238
+ *
+ * # Header dict
+ * self._header = scan.mca_header_dict # <<<<<<<<<<<<<<
+ *
+ * self.calibration = []
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_scan, __pyx_n_s_mca_header_dict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_header, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":240
+ * self._header = scan.mca_header_dict
+ *
+ * self.calibration = [] # <<<<<<<<<<<<<<
+ * """List of lists of calibration values,
+ * one list of 3 floats per MCA device or a single list applying to
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_calibration, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":244
+ * one list of 3 floats per MCA device or a single list applying to
+ * all devices """
+ * self._parse_calibration() # <<<<<<<<<<<<<<
+ *
+ * self.channels = []
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_parse_calibration); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":246
+ * self._parse_calibration()
+ *
+ * self.channels = [] # <<<<<<<<<<<<<<
+ * """List of lists of channels,
+ * one list of integers per MCA device or a single list applying to
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_channels, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":250
+ * one list of integers per MCA device or a single list applying to
+ * all devices"""
+ * self._parse_channels() # <<<<<<<<<<<<<<
+ *
+ * def _parse_channels(self):
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_parse_channels); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":234
+ *
+ * """
+ * def __init__(self, scan): # <<<<<<<<<<<<<<
+ * self._scan = scan
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.MCA.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":252
+ * self._parse_channels()
+ *
+ * def _parse_channels(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_3_parse_channels(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_3MCA_2_parse_channels[] = "MCA._parse_channels(self)\nFill :attr:`channels`";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_3_parse_channels = {"_parse_channels", (PyCFunction)__pyx_pw_8specfile_3MCA_3_parse_channels, METH_O, __pyx_doc_8specfile_3MCA_2_parse_channels};
+static PyObject *__pyx_pw_8specfile_3MCA_3_parse_channels(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_parse_channels (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_3MCA_2_parse_channels(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_2_parse_channels(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_v_chann_lines = NULL;
+ PyObject *__pyx_v_all_chann_values = NULL;
+ PyObject *__pyx_v_one_line_chann_values = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_v_start = NULL;
+ PyObject *__pyx_v_stop = NULL;
+ PyObject *__pyx_v_increment = NULL;
+ PyObject *__pyx_v_chann_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *(*__pyx_t_12)(PyObject *);
+ int __pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_parse_channels", 0);
+
+ /* "specfile.pyx":255
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ * if "CHANN" in self._header: # <<<<<<<<<<<<<<
+ * chann_lines = self._header["CHANN"].split("\n")
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_n_s_CHANN, __pyx_t_1, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":256
+ * # Channels list
+ * if "CHANN" in self._header:
+ * chann_lines = self._header["CHANN"].split("\n") # <<<<<<<<<<<<<<
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = PyObject_GetItem(__pyx_t_1, __pyx_n_s_CHANN); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_split); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_chann_lines = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":257
+ * if "CHANN" in self._header:
+ * chann_lines = self._header["CHANN"].split("\n")
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines] # <<<<<<<<<<<<<<
+ * for one_line_chann_values in all_chann_values:
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ */
+ __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (likely(PyList_CheckExact(__pyx_v_chann_lines)) || PyTuple_CheckExact(__pyx_v_chann_lines)) {
+ __pyx_t_1 = __pyx_v_chann_lines; __Pyx_INCREF(__pyx_t_1); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_chann_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_1))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_1);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_chann_line, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_chann_line, __pyx_n_s_split); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (__pyx_t_9) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_9); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_7 = __Pyx_PyObject_CallNoArg(__pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_4, (PyObject*)__pyx_t_7))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_all_chann_values = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":258
+ * chann_lines = self._header["CHANN"].split("\n")
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values: # <<<<<<<<<<<<<<
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ */
+ __pyx_t_4 = __pyx_v_all_chann_values; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ for (;;) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_1); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_one_line_chann_values, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":259
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values:
+ * length, start, stop, increment = map(int, one_line_chann_values) # <<<<<<<<<<<<<<
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ * elif len(self):
+ */
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+ PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
+ __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+ __Pyx_INCREF(__pyx_v_one_line_chann_values);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_v_one_line_chann_values);
+ __Pyx_GIVEREF(__pyx_v_one_line_chann_values);
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_map, __pyx_t_1, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if ((likely(PyTuple_CheckExact(__pyx_t_7))) || (PyList_CheckExact(__pyx_t_7))) {
+ PyObject* sequence = __pyx_t_7;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 4)) {
+ if (size > 4) __Pyx_RaiseTooManyValuesError(4);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_1 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_8 = PyTuple_GET_ITEM(sequence, 1);
+ __pyx_t_9 = PyTuple_GET_ITEM(sequence, 2);
+ __pyx_t_10 = PyTuple_GET_ITEM(sequence, 3);
+ } else {
+ __pyx_t_1 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_8 = PyList_GET_ITEM(sequence, 1);
+ __pyx_t_9 = PyList_GET_ITEM(sequence, 2);
+ __pyx_t_10 = PyList_GET_ITEM(sequence, 3);
+ }
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_10);
+ #else
+ {
+ Py_ssize_t i;
+ PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_8,&__pyx_t_9,&__pyx_t_10};
+ for (i=0; i < 4; i++) {
+ PyObject* item = PySequence_ITEM(sequence, i); if (unlikely(!item)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(item);
+ *(temps[i]) = item;
+ }
+ }
+ #endif
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ } else {
+ Py_ssize_t index = -1;
+ PyObject** temps[4] = {&__pyx_t_1,&__pyx_t_8,&__pyx_t_9,&__pyx_t_10};
+ __pyx_t_11 = PyObject_GetIter(__pyx_t_7); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_12 = Py_TYPE(__pyx_t_11)->tp_iternext;
+ for (index=0; index < 4; index++) {
+ PyObject* item = __pyx_t_12(__pyx_t_11); if (unlikely(!item)) goto __pyx_L8_unpacking_failed;
+ __Pyx_GOTREF(item);
+ *(temps[index]) = item;
+ }
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_12(__pyx_t_11), 4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_12 = NULL;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ goto __pyx_L9_unpacking_done;
+ __pyx_L8_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_12 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_L9_unpacking_done:;
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_1);
+ __pyx_t_1 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_start, __pyx_t_8);
+ __pyx_t_8 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_stop, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_increment, __pyx_t_10);
+ __pyx_t_10 = 0;
+
+ /* "specfile.pyx":260
+ * for one_line_chann_values in all_chann_values:
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ * self.channels.append(list(range(start, stop + 1, increment))) # <<<<<<<<<<<<<<
+ * elif len(self):
+ * # in the absence of #@CHANN, use shape of first MCA
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_channels); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_10 = PyNumber_Add(__pyx_v_stop, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_9 = PyTuple_New(3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_INCREF(__pyx_v_start);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_start);
+ __Pyx_GIVEREF(__pyx_v_start);
+ PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __Pyx_INCREF(__pyx_v_increment);
+ PyTuple_SET_ITEM(__pyx_t_9, 2, __pyx_v_increment);
+ __Pyx_GIVEREF(__pyx_v_increment);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_9, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_9, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_13 = __Pyx_PyObject_Append(__pyx_t_7, __pyx_t_10); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+
+ /* "specfile.pyx":258
+ * chann_lines = self._header["CHANN"].split("\n")
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values: # <<<<<<<<<<<<<<
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+
+ /* "specfile.pyx":261
+ * length, start, stop, increment = map(int, one_line_chann_values)
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ * elif len(self): # <<<<<<<<<<<<<<
+ * # in the absence of #@CHANN, use shape of first MCA
+ * length = self[0].shape[0]
+ */
+ __pyx_t_5 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = (__pyx_t_5 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":263
+ * elif len(self):
+ * # in the absence of #@CHANN, use shape of first MCA
+ * length = self[0].shape[0] # <<<<<<<<<<<<<<
+ * start, stop, increment = (0, length - 1, 1)
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ */
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_self, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_shape); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_10, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_v_length = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":264
+ * # in the absence of #@CHANN, use shape of first MCA
+ * length = self[0].shape[0]
+ * start, stop, increment = (0, length - 1, 1) # <<<<<<<<<<<<<<
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ */
+ __pyx_t_4 = __pyx_int_0;
+ __Pyx_INCREF(__pyx_t_4);
+ __pyx_t_10 = PyNumber_Subtract(__pyx_v_length, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_7 = __pyx_int_1;
+ __Pyx_INCREF(__pyx_t_7);
+ __pyx_v_start = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_stop = __pyx_t_10;
+ __pyx_t_10 = 0;
+ __pyx_v_increment = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "specfile.pyx":265
+ * length = self[0].shape[0]
+ * start, stop, increment = (0, length - 1, 1)
+ * self.channels.append(list(range(start, stop + 1, increment))) # <<<<<<<<<<<<<<
+ *
+ * def _parse_calibration(self):
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_channels); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_10 = PyNumber_Add(__pyx_v_stop, __pyx_int_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_start);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_start);
+ __Pyx_GIVEREF(__pyx_v_start);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __Pyx_INCREF(__pyx_v_increment);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_v_increment);
+ __Pyx_GIVEREF(__pyx_v_increment);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_4, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_4, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_13 = __Pyx_PyObject_Append(__pyx_t_7, __pyx_t_10); if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":252
+ * self._parse_channels()
+ *
+ * def _parse_channels(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("specfile.MCA._parse_channels", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_chann_lines);
+ __Pyx_XDECREF(__pyx_v_all_chann_values);
+ __Pyx_XDECREF(__pyx_v_one_line_chann_values);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XDECREF(__pyx_v_start);
+ __Pyx_XDECREF(__pyx_v_stop);
+ __Pyx_XDECREF(__pyx_v_increment);
+ __Pyx_XDECREF(__pyx_v_chann_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":267
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ * def _parse_calibration(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_5_parse_calibration(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_3MCA_4_parse_calibration[] = "MCA._parse_calibration(self)\nFill :attr:`calibration`";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_5_parse_calibration = {"_parse_calibration", (PyCFunction)__pyx_pw_8specfile_3MCA_5_parse_calibration, METH_O, __pyx_doc_8specfile_3MCA_4_parse_calibration};
+static PyObject *__pyx_pw_8specfile_3MCA_5_parse_calibration(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_parse_calibration (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_3MCA_4_parse_calibration(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_4_parse_calibration(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_v_calib_lines = NULL;
+ PyObject *__pyx_v_all_calib_values = NULL;
+ PyObject *__pyx_v_one_line_calib_values = NULL;
+ PyObject *__pyx_v_calib_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_parse_calibration", 0);
+
+ /* "specfile.pyx":270
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ * if "CALIB" in self._header: # <<<<<<<<<<<<<<
+ * calib_lines = self._header["CALIB"].split("\n")
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = (__Pyx_PySequence_Contains(__pyx_n_s_CALIB, __pyx_t_1, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":271
+ * # Channels list
+ * if "CALIB" in self._header:
+ * calib_lines = self._header["CALIB"].split("\n") # <<<<<<<<<<<<<<
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = PyObject_GetItem(__pyx_t_1, __pyx_n_s_CALIB); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_split); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_calib_lines = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":272
+ * if "CALIB" in self._header:
+ * calib_lines = self._header["CALIB"].split("\n")
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines] # <<<<<<<<<<<<<<
+ * for one_line_calib_values in all_calib_values:
+ * self.calibration.append(list(map(float, one_line_calib_values)))
+ */
+ __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (likely(PyList_CheckExact(__pyx_v_calib_lines)) || PyTuple_CheckExact(__pyx_v_calib_lines)) {
+ __pyx_t_1 = __pyx_v_calib_lines; __Pyx_INCREF(__pyx_t_1); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_calib_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_1))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_1);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_calib_line, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_calib_line, __pyx_n_s_split); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (__pyx_t_9) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_9); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_7 = __Pyx_PyObject_CallNoArg(__pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_4, (PyObject*)__pyx_t_7))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_all_calib_values = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":273
+ * calib_lines = self._header["CALIB"].split("\n")
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values: # <<<<<<<<<<<<<<
+ * self.calibration.append(list(map(float, one_line_calib_values)))
+ * else:
+ */
+ __pyx_t_4 = __pyx_v_all_calib_values; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ for (;;) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_1); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_one_line_calib_values, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":274
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values:
+ * self.calibration.append(list(map(float, one_line_calib_values))) # <<<<<<<<<<<<<<
+ * else:
+ * # in the absence of #@calib, use default
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_calibration); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(((PyObject *)((PyObject*)(&PyFloat_Type))));
+ PyTuple_SET_ITEM(__pyx_t_7, 0, ((PyObject *)((PyObject*)(&PyFloat_Type))));
+ __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyFloat_Type))));
+ __Pyx_INCREF(__pyx_v_one_line_calib_values);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_one_line_calib_values);
+ __Pyx_GIVEREF(__pyx_v_one_line_calib_values);
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_map, __pyx_t_7, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_7, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Append(__pyx_t_1, __pyx_t_8); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "specfile.pyx":273
+ * calib_lines = self._header["CALIB"].split("\n")
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values: # <<<<<<<<<<<<<<
+ * self.calibration.append(list(map(float, one_line_calib_values)))
+ * else:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":277
+ * else:
+ * # in the absence of #@calib, use default
+ * self.calibration.append([0., 1., 0.]) # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_calibration); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_8 = PyList_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_float_0_);
+ PyList_SET_ITEM(__pyx_t_8, 0, __pyx_float_0_);
+ __Pyx_GIVEREF(__pyx_float_0_);
+ __Pyx_INCREF(__pyx_float_1_);
+ PyList_SET_ITEM(__pyx_t_8, 1, __pyx_float_1_);
+ __Pyx_GIVEREF(__pyx_float_1_);
+ __Pyx_INCREF(__pyx_float_0_);
+ PyList_SET_ITEM(__pyx_t_8, 2, __pyx_float_0_);
+ __Pyx_GIVEREF(__pyx_float_0_);
+ __pyx_t_10 = __Pyx_PyObject_Append(__pyx_t_4, __pyx_t_8); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":267
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ * def _parse_calibration(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("specfile.MCA._parse_calibration", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_calib_lines);
+ __Pyx_XDECREF(__pyx_v_all_calib_values);
+ __Pyx_XDECREF(__pyx_v_one_line_calib_values);
+ __Pyx_XDECREF(__pyx_v_calib_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":279
+ * self.calibration.append([0., 1., 0.])
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_7__len__(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_3MCA_6__len__[] = "MCA.__len__(self)\n\n\n :return: Number of mca in Scan\n :rtype: int\n ";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_7__len__ = {"__len__", (PyCFunction)__pyx_pw_8specfile_3MCA_7__len__, METH_O, __pyx_doc_8specfile_3MCA_6__len__};
+static PyObject *__pyx_pw_8specfile_3MCA_7__len__(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_3MCA_6__len__(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_6__len__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "specfile.pyx":285
+ * :rtype: int
+ * """
+ * return self._scan._specfile.number_of_mca(self._scan.index) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, key):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_specfile); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_number_of_mca); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_index); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":279
+ * self.calibration.append([0., 1., 0.])
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("specfile.MCA.__len__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":287
+ * return self._scan._specfile.number_of_mca(self._scan.index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a single MCA data line
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_9__getitem__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_3MCA_8__getitem__[] = "MCA.__getitem__(self, key)\nReturn a single MCA data line\n\n :param key: 0-based index of MCA within Scan\n :type key: int\n\n :return: Single MCA\n :rtype: 1D numpy array\n ";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_9__getitem__ = {"__getitem__", (PyCFunction)__pyx_pw_8specfile_3MCA_9__getitem__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_3MCA_8__getitem__};
+static PyObject *__pyx_pw_8specfile_3MCA_9__getitem__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_key = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_key,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__getitem__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__getitem__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_key = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__getitem__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.MCA.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_3MCA_8__getitem__(__pyx_self, __pyx_v_self, __pyx_v_key);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_8__getitem__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+ PyObject *__pyx_v_mca_index = NULL;
+ PyObject *__pyx_v_msg = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "specfile.pyx":296
+ * :rtype: 1D numpy array
+ * """
+ * if not len(self): # <<<<<<<<<<<<<<
+ * raise IndexError("No MCA spectrum found in this scan")
+ *
+ */
+ __pyx_t_1 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":297
+ * """
+ * if not len(self):
+ * raise IndexError("No MCA spectrum found in this scan") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(key, int):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":299
+ * raise IndexError("No MCA spectrum found in this scan")
+ *
+ * if isinstance(key, int): # <<<<<<<<<<<<<<
+ * mca_index = key
+ * # allow negative index, like lists
+ */
+ __pyx_t_2 = PyInt_Check(__pyx_v_key);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":300
+ *
+ * if isinstance(key, int):
+ * mca_index = key # <<<<<<<<<<<<<<
+ * # allow negative index, like lists
+ * if mca_index < 0:
+ */
+ __Pyx_INCREF(__pyx_v_key);
+ __pyx_v_mca_index = __pyx_v_key;
+
+ /* "specfile.pyx":302
+ * mca_index = key
+ * # allow negative index, like lists
+ * if mca_index < 0: # <<<<<<<<<<<<<<
+ * mca_index = len(self) + mca_index
+ * else:
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_mca_index, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":303
+ * # allow negative index, like lists
+ * if mca_index < 0:
+ * mca_index = len(self) + mca_index # <<<<<<<<<<<<<<
+ * else:
+ * raise TypeError("MCA index should be an integer (%s provided)" %
+ */
+ __pyx_t_1 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = PyNumber_Add(__pyx_t_3, __pyx_v_mca_index); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_mca_index, __pyx_t_5);
+ __pyx_t_5 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":305
+ * mca_index = len(self) + mca_index
+ * else:
+ * raise TypeError("MCA index should be an integer (%s provided)" % # <<<<<<<<<<<<<<
+ * (type(key)))
+ *
+ */
+ __pyx_t_5 = __Pyx_PyString_Format(__pyx_kp_s_MCA_index_should_be_an_integer_s, ((PyObject *)Py_TYPE(__pyx_v_key))); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L4:;
+
+ /* "specfile.pyx":308
+ * (type(key)))
+ *
+ * if not 0 <= mca_index < len(self): # <<<<<<<<<<<<<<
+ * msg = "MCA index must be in range 0-%d" % (len(self) - 1)
+ * raise IndexError(msg)
+ */
+ __pyx_t_5 = PyObject_RichCompare(__pyx_int_0, __pyx_v_mca_index, Py_LE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__Pyx_PyObject_IsTrue(__pyx_t_5)) {
+ __Pyx_DECREF(__pyx_t_5);
+ __pyx_t_1 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = PyObject_RichCompare(__pyx_v_mca_index, __pyx_t_3, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_2 = ((!__pyx_t_4) != 0);
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":309
+ *
+ * if not 0 <= mca_index < len(self):
+ * msg = "MCA index must be in range 0-%d" % (len(self) - 1) # <<<<<<<<<<<<<<
+ * raise IndexError(msg)
+ *
+ */
+ __pyx_t_1 = PyObject_Length(__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_t_1 - 1)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MCA_index_must_be_in_range_0_d, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_msg = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "specfile.pyx":310
+ * if not 0 <= mca_index < len(self):
+ * msg = "MCA index must be in range 0-%d" % (len(self) - 1)
+ * raise IndexError(msg) # <<<<<<<<<<<<<<
+ *
+ * return self._scan._specfile.get_mca(self._scan.index,
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_msg);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_msg);
+ __Pyx_GIVEREF(__pyx_v_msg);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":312
+ * raise IndexError(msg)
+ *
+ * return self._scan._specfile.get_mca(self._scan.index, # <<<<<<<<<<<<<<
+ * mca_index)
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_specfile); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_get_mca); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_index); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "specfile.pyx":313
+ *
+ * return self._scan._specfile.get_mca(self._scan.index,
+ * mca_index) # <<<<<<<<<<<<<<
+ *
+ * def __iter__(self):
+ */
+ __pyx_t_6 = NULL;
+ __pyx_t_1 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ __pyx_t_1 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_6) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_mca_index);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_1, __pyx_v_mca_index);
+ __Pyx_GIVEREF(__pyx_v_mca_index);
+ __pyx_t_7 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":287
+ * return self._scan._specfile.number_of_mca(self._scan.index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a single MCA data line
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.MCA.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_mca_index);
+ __Pyx_XDECREF(__pyx_v_msg);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+static PyObject *__pyx_gb_8specfile_3MCA_12generator(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+
+/* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3MCA_11__iter__(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_3MCA_10__iter__[] = "MCA.__iter__(self)\nReturn the next MCA data line each time this method is called.\n\n :return: Single MCA\n :rtype: 1D numpy array\n ";
+static PyMethodDef __pyx_mdef_8specfile_3MCA_11__iter__ = {"__iter__", (PyCFunction)__pyx_pw_8specfile_3MCA_11__iter__, METH_O, __pyx_doc_8specfile_3MCA_10__iter__};
+static PyObject *__pyx_pw_8specfile_3MCA_11__iter__(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_3MCA_10__iter__(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_3MCA_10__iter__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *__pyx_cur_scope;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__iter__", 0);
+ __pyx_cur_scope = (struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)__pyx_tp_new_8specfile___pyx_scope_struct____iter__(__pyx_ptype_8specfile___pyx_scope_struct____iter__, __pyx_empty_tuple, NULL);
+ if (unlikely(!__pyx_cur_scope)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_cur_scope);
+ __pyx_cur_scope->__pyx_v_self = __pyx_v_self;
+ __Pyx_INCREF(__pyx_cur_scope->__pyx_v_self);
+ __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_self);
+ {
+ __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_8specfile_3MCA_12generator, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_MCA___iter); if (unlikely(!gen)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_cur_scope);
+ __Pyx_RefNannyFinishContext();
+ return (PyObject *) gen;
+ }
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_AddTraceback("specfile.MCA.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_gb_8specfile_3MCA_12generator(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+{
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *__pyx_cur_scope = ((struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)__pyx_generator->closure);
+ PyObject *__pyx_r = NULL;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("None", 0);
+ switch (__pyx_generator->resume_label) {
+ case 0: goto __pyx_L3_first_run;
+ case 1: goto __pyx_L6_resume_from_yield;
+ default: /* CPython raises the right error here */
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __pyx_L3_first_run:;
+ if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":321
+ * :rtype: 1D numpy array
+ * """
+ * for mca_index in range(len(self)): # <<<<<<<<<<<<<<
+ * yield self._scan._specfile.get_mca(self._scan.index, mca_index)
+ *
+ */
+ __pyx_t_1 = PyObject_Length(__pyx_cur_scope->__pyx_v_self); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_cur_scope->__pyx_v_mca_index = __pyx_t_2;
+
+ /* "specfile.pyx":322
+ * """
+ * for mca_index in range(len(self)):
+ * yield self._scan._specfile.get_mca(self._scan.index, mca_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_specfile); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_get_mca); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_cur_scope->__pyx_v_self, __pyx_n_s_scan_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_index); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyInt_FromSsize_t(__pyx_cur_scope->__pyx_v_mca_index); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_6 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
+ __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ /* return from generator, yielding value */
+ __pyx_generator->resume_label = 1;
+ return __pyx_r;
+ __pyx_L6_resume_from_yield:;
+ __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
+ __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
+ if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+
+ /* function exit code */
+ PyErr_SetNone(PyExc_StopIteration);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_generator->resume_label = -1;
+ __Pyx_Generator_clear((PyObject*)__pyx_generator);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+}
+
+/* "specfile.pyx":325
+ *
+ *
+ * def _add_or_concatenate(dictionary, key, value): # <<<<<<<<<<<<<<
+ * """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ * Else append/concatenate the new value to the existing one
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_1_add_or_concatenate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile__add_or_concatenate[] = "_add_or_concatenate(dictionary, key, value)\nIf key doesn't exist in dictionary, create a new ``key: value`` pair.\n Else append/concatenate the new value to the existing one\n ";
+static PyMethodDef __pyx_mdef_8specfile_1_add_or_concatenate = {"_add_or_concatenate", (PyCFunction)__pyx_pw_8specfile_1_add_or_concatenate, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile__add_or_concatenate};
+static PyObject *__pyx_pw_8specfile_1_add_or_concatenate(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_dictionary = 0;
+ PyObject *__pyx_v_key = 0;
+ PyObject *__pyx_v_value = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_add_or_concatenate (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_dictionary,&__pyx_n_s_key,&__pyx_n_s_value,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dictionary)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_add_or_concatenate", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_value)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_add_or_concatenate", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_add_or_concatenate") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ }
+ __pyx_v_dictionary = values[0];
+ __pyx_v_key = values[1];
+ __pyx_v_value = values[2];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_add_or_concatenate", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile._add_or_concatenate", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile__add_or_concatenate(__pyx_self, __pyx_v_dictionary, __pyx_v_key, __pyx_v_value);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile__add_or_concatenate(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_dictionary, PyObject *__pyx_v_key, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_add_or_concatenate", 0);
+
+ /* "specfile.pyx":329
+ * Else append/concatenate the new value to the existing one
+ * """
+ * try: # <<<<<<<<<<<<<<
+ * if not key in dictionary:
+ * dictionary[key] = value
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ /*try:*/ {
+
+ /* "specfile.pyx":330
+ * """
+ * try:
+ * if not key in dictionary: # <<<<<<<<<<<<<<
+ * dictionary[key] = value
+ * else:
+ */
+ __pyx_t_4 = (__Pyx_PySequence_Contains(__pyx_v_key, __pyx_v_dictionary, Py_NE)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_t_5 = (__pyx_t_4 != 0);
+ if (__pyx_t_5) {
+
+ /* "specfile.pyx":331
+ * try:
+ * if not key in dictionary:
+ * dictionary[key] = value # <<<<<<<<<<<<<<
+ * else:
+ * dictionary[key] += "\n" + value
+ */
+ if (unlikely(PyObject_SetItem(__pyx_v_dictionary, __pyx_v_key, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":333
+ * dictionary[key] = value
+ * else:
+ * dictionary[key] += "\n" + value # <<<<<<<<<<<<<<
+ * except TypeError:
+ * raise TypeError("Parameter value must be a string.")
+ */
+ __Pyx_INCREF(__pyx_v_key);
+ __pyx_t_6 = __pyx_v_key;
+ __pyx_t_7 = PyObject_GetItem(__pyx_v_dictionary, __pyx_t_6); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L3_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = PyNumber_Add(__pyx_kp_s_, __pyx_v_value); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = PyNumber_InPlaceAdd(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (unlikely(PyObject_SetItem(__pyx_v_dictionary, __pyx_t_6, __pyx_t_9) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __pyx_L11:;
+ }
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L10_try_end;
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "specfile.pyx":334
+ * else:
+ * dictionary[key] += "\n" + value
+ * except TypeError: # <<<<<<<<<<<<<<
+ * raise TypeError("Parameter value must be a string.")
+ *
+ */
+ __pyx_t_10 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_10) {
+ __Pyx_AddTraceback("specfile._add_or_concatenate", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_6, &__pyx_t_9, &__pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_GOTREF(__pyx_t_8);
+
+ /* "specfile.pyx":335
+ * dictionary[key] += "\n" + value
+ * except TypeError:
+ * raise TypeError("Parameter value must be a string.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_1);
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
+ goto __pyx_L1_error;
+ __pyx_L10_try_end:;
+ }
+
+ /* "specfile.pyx":325
+ *
+ *
+ * def _add_or_concatenate(dictionary, key, value): # <<<<<<<<<<<<<<
+ * """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ * Else append/concatenate the new value to the existing one
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("specfile._add_or_concatenate", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":363
+ * scan2 = sf["3.1"]
+ * """
+ * def __init__(self, specfile, scan_index): # <<<<<<<<<<<<<<
+ * self._specfile = specfile
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan___init__[] = "Scan.__init__(self, specfile, scan_index)";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_1__init__ = {"__init__", (PyCFunction)__pyx_pw_8specfile_4Scan_1__init__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan___init__};
+static PyObject *__pyx_pw_8specfile_4Scan_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_specfile = 0;
+ PyObject *__pyx_v_scan_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_specfile_2,&__pyx_n_s_scan_index,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_specfile_2)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_specfile = values[1];
+ __pyx_v_scan_index = values[2];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan___init__(__pyx_self, __pyx_v_self, __pyx_v_specfile, __pyx_v_scan_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_specfile, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_v_match = NULL;
+ PyObject *__pyx_v_match_mca = NULL;
+ PyObject *__pyx_v_hkey = NULL;
+ PyObject *__pyx_v_hvalue = NULL;
+ PyObject *__pyx_v_L_header = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ Py_ssize_t __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ int __pyx_t_14;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "specfile.pyx":364
+ * """
+ * def __init__(self, specfile, scan_index):
+ * self._specfile = specfile # <<<<<<<<<<<<<<
+ *
+ * self._index = scan_index
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_specfile, __pyx_v_specfile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":366
+ * self._specfile = specfile
+ *
+ * self._index = scan_index # <<<<<<<<<<<<<<
+ * self._number = specfile.number(scan_index)
+ * self._order = specfile.order(scan_index)
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_index_2, __pyx_v_scan_index) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":367
+ *
+ * self._index = scan_index
+ * self._number = specfile.number(scan_index) # <<<<<<<<<<<<<<
+ * self._order = specfile.order(scan_index)
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_specfile, __pyx_n_s_number); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_scan_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ __Pyx_INCREF(__pyx_v_scan_index);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_scan_index);
+ __Pyx_GIVEREF(__pyx_v_scan_index);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_number_2, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":368
+ * self._index = scan_index
+ * self._number = specfile.number(scan_index)
+ * self._order = specfile.order(scan_index) # <<<<<<<<<<<<<<
+ *
+ * self._scan_header_lines = self._specfile.scan_header(self._index)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_specfile, __pyx_n_s_order); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_scan_index); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_scan_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_scan_index);
+ __Pyx_GIVEREF(__pyx_v_scan_index);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_order_2, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":370
+ * self._order = specfile.order(scan_index)
+ *
+ * self._scan_header_lines = self._specfile.scan_header(self._index) # <<<<<<<<<<<<<<
+ * self._file_header_lines = self._specfile.file_header(self._index)
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_scan_header); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":371
+ *
+ * self._scan_header_lines = self._specfile.scan_header(self._index)
+ * self._file_header_lines = self._specfile.file_header(self._index) # <<<<<<<<<<<<<<
+ *
+ * if self._file_header_lines == self._scan_header_lines:
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_file_header); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":373
+ * self._file_header_lines = self._specfile.file_header(self._index)
+ *
+ * if self._file_header_lines == self._scan_header_lines: # <<<<<<<<<<<<<<
+ * self._file_header_lines = []
+ * self._header = self._file_header_lines + self._scan_header_lines
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":374
+ *
+ * if self._file_header_lines == self._scan_header_lines:
+ * self._file_header_lines = [] # <<<<<<<<<<<<<<
+ * self._header = self._file_header_lines + self._scan_header_lines
+ *
+ */
+ __pyx_t_4 = PyList_New(0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":375
+ * if self._file_header_lines == self._scan_header_lines:
+ * self._file_header_lines = []
+ * self._header = self._file_header_lines + self._scan_header_lines # <<<<<<<<<<<<<<
+ *
+ * self._scan_header_dict = {}
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_header, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":377
+ * self._header = self._file_header_lines + self._scan_header_lines
+ *
+ * self._scan_header_dict = {} # <<<<<<<<<<<<<<
+ * self._mca_header_dict = {}
+ * for line in self._scan_header_lines:
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_dict, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":378
+ *
+ * self._scan_header_dict = {}
+ * self._mca_header_dict = {} # <<<<<<<<<<<<<<
+ * for line in self._scan_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line)
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_mca_header_dict_2, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":379
+ * self._scan_header_dict = {}
+ * self._mca_header_dict = {}
+ * for line in self._scan_header_lines: # <<<<<<<<<<<<<<
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+ __pyx_t_5 = __pyx_t_1; __Pyx_INCREF(__pyx_t_5); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = Py_TYPE(__pyx_t_5)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_5))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_5)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_1); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_1 = __pyx_t_8(__pyx_t_5);
+ if (unlikely(!__pyx_t_1)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_line, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":380
+ * self._mca_header_dict = {}
+ * for line in self._scan_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line) # <<<<<<<<<<<<<<
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ * if match:
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_search); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_2 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_w);
+ PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_9, __pyx_kp_s_w);
+ __Pyx_GIVEREF(__pyx_kp_s_w);
+ __Pyx_INCREF(__pyx_v_line);
+ PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_9, __pyx_v_line);
+ __Pyx_GIVEREF(__pyx_v_line);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_match, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":381
+ * for line in self._scan_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * match_mca = re.search(r"#@(\w+) *(.*)", line) # <<<<<<<<<<<<<<
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip()
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_search); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_4 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (__pyx_t_3) {
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_w_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+__pyx_t_9, __pyx_kp_s_w_2);
+ __Pyx_GIVEREF(__pyx_kp_s_w_2);
+ __Pyx_INCREF(__pyx_v_line);
+ PyTuple_SET_ITEM(__pyx_t_4, 1+__pyx_t_9, __pyx_v_line);
+ __Pyx_GIVEREF(__pyx_v_line);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_match_mca, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":382
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ * if match: # <<<<<<<<<<<<<<
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip()
+ */
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_match); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":383
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_lstrip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hkey, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":384
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca:
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hvalue, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":385
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue) # <<<<<<<<<<<<<<
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_add_or_concatenate); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_dict); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_10 = PyTuple_New(3+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ if (__pyx_t_3) {
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_hkey);
+ PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_v_hkey);
+ __Pyx_GIVEREF(__pyx_v_hkey);
+ __Pyx_INCREF(__pyx_v_hvalue);
+ PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_9, __pyx_v_hvalue);
+ __Pyx_GIVEREF(__pyx_v_hvalue);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L6;
+ }
+
+ /* "specfile.pyx":386
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca: # <<<<<<<<<<<<<<
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ * hvalue = match_mca.group(2).strip()
+ */
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_match_mca); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":387
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match_mca.group(2).strip()
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_match_mca, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_lstrip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_10) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hkey, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":388
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ * hvalue = match_mca.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_match_mca, __pyx_n_s_group); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_10) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hvalue, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":389
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ * hvalue = match_mca.group(2).strip()
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue) # <<<<<<<<<<<<<<
+ * else:
+ * # this shouldn't happen
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_add_or_concatenate); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_mca_header_dict_2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_4 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_3 = PyTuple_New(3+__pyx_t_9); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_9, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __Pyx_INCREF(__pyx_v_hkey);
+ PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_9, __pyx_v_hkey);
+ __Pyx_GIVEREF(__pyx_v_hkey);
+ __Pyx_INCREF(__pyx_v_hvalue);
+ PyTuple_SET_ITEM(__pyx_t_3, 2+__pyx_t_9, __pyx_v_hvalue);
+ __Pyx_GIVEREF(__pyx_v_hvalue);
+ __pyx_t_10 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":392
+ * else:
+ * # this shouldn't happen
+ * _logger.warning("Unable to parse scan header line " + line) # <<<<<<<<<<<<<<
+ *
+ * self._labels = []
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warning); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyNumber_Add(__pyx_kp_s_Unable_to_parse_scan_header_line, __pyx_v_line); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_10) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L6:;
+
+ /* "specfile.pyx":379
+ * self._scan_header_dict = {}
+ * self._mca_header_dict = {}
+ * for line in self._scan_header_lines: # <<<<<<<<<<<<<<
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ */
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "specfile.pyx":394
+ * _logger.warning("Unable to parse scan header line " + line)
+ *
+ * self._labels = [] # <<<<<<<<<<<<<<
+ * if self.record_exists_in_hdr('L'):
+ * try:
+ */
+ __pyx_t_5 = PyList_New(0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_labels, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "specfile.pyx":395
+ *
+ * self._labels = []
+ * if self.record_exists_in_hdr('L'): # <<<<<<<<<<<<<<
+ * try:
+ * self._labels = self._specfile.labels(self._index)
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_record_exists_in_hdr); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":396
+ * self._labels = []
+ * if self.record_exists_in_hdr('L'):
+ * try: # <<<<<<<<<<<<<<
+ * self._labels = self._specfile.labels(self._index)
+ * except SfErrLineNotFound:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_11, &__pyx_t_12, &__pyx_t_13);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __Pyx_XGOTREF(__pyx_t_12);
+ __Pyx_XGOTREF(__pyx_t_13);
+ /*try:*/ {
+
+ /* "specfile.pyx":397
+ * if self.record_exists_in_hdr('L'):
+ * try:
+ * self._labels = self._specfile.labels(self._index) # <<<<<<<<<<<<<<
+ * except SfErrLineNotFound:
+ * # SpecFile.labels raises an IndexError when encountering
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_labels_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_labels, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+ __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+ goto __pyx_L15_try_end;
+ __pyx_L8_error:;
+ __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":398
+ * try:
+ * self._labels = self._specfile.labels(self._index)
+ * except SfErrLineNotFound: # <<<<<<<<<<<<<<
+ * # SpecFile.labels raises an IndexError when encountering
+ * # a Scan with no data, even if the header exists.
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLineNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_14 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_14) {
+ __Pyx_AddTraceback("specfile.Scan.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_3, &__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_t_2);
+
+ /* "specfile.pyx":401
+ * # SpecFile.labels raises an IndexError when encountering
+ * # a Scan with no data, even if the header exists.
+ * L_header = re.sub(r" {2,}", " ", # max. 2 spaces # <<<<<<<<<<<<<<
+ * self._scan_header_dict["L"])
+ * self._labels = L_header.split(" ")
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_sub); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":402
+ * # a Scan with no data, even if the header exists.
+ * L_header = re.sub(r" {2,}", " ", # max. 2 spaces
+ * self._scan_header_dict["L"]) # <<<<<<<<<<<<<<
+ * self._labels = L_header.split(" ")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_dict); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_15 = PyObject_GetItem(__pyx_t_4, __pyx_n_s_L); if (unlikely(__pyx_t_15 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;};
+ __Pyx_GOTREF(__pyx_t_15);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_16 = PyTuple_New(3+__pyx_t_7); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_2);
+ PyTuple_SET_ITEM(__pyx_t_16, 0+__pyx_t_7, __pyx_kp_s_2);
+ __Pyx_GIVEREF(__pyx_kp_s_2);
+ __Pyx_INCREF(__pyx_kp_s__14);
+ PyTuple_SET_ITEM(__pyx_t_16, 1+__pyx_t_7, __pyx_kp_s__14);
+ __Pyx_GIVEREF(__pyx_kp_s__14);
+ PyTuple_SET_ITEM(__pyx_t_16, 2+__pyx_t_7, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ __pyx_t_15 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_16, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_v_L_header = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "specfile.pyx":403
+ * L_header = re.sub(r" {2,}", " ", # max. 2 spaces
+ * self._scan_header_dict["L"])
+ * self._labels = L_header.split(" ") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_L_header, __pyx_n_s_split); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_labels, __pyx_t_10) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L10_except_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9_exception_handled;
+ }
+ goto __pyx_L10_except_error;
+ __pyx_L10_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_XGIVEREF(__pyx_t_12);
+ __Pyx_XGIVEREF(__pyx_t_13);
+ __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
+ goto __pyx_L1_error;
+ __pyx_L9_exception_handled:;
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_XGIVEREF(__pyx_t_12);
+ __Pyx_XGIVEREF(__pyx_t_13);
+ __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
+ __pyx_L15_try_end:;
+ }
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+
+ /* "specfile.pyx":406
+ *
+ *
+ * self._file_header_dict = {} # <<<<<<<<<<<<<<
+ * for line in self._file_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line)
+ */
+ __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_file_header_dict, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":407
+ *
+ * self._file_header_dict = {}
+ * for line in self._file_header_lines: # <<<<<<<<<<<<<<
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * if match:
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (likely(PyList_CheckExact(__pyx_t_2)) || PyTuple_CheckExact(__pyx_t_2)) {
+ __pyx_t_3 = __pyx_t_2; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_2); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_2 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_2 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_2)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_line, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":408
+ * self._file_header_dict = {}
+ * for line in self._file_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line) # <<<<<<<<<<<<<<
+ * if match:
+ * # header type
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_re); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_search); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_5 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (__pyx_t_1) {
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_w);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_9, __pyx_kp_s_w);
+ __Pyx_GIVEREF(__pyx_kp_s_w);
+ __Pyx_INCREF(__pyx_v_line);
+ PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_9, __pyx_v_line);
+ __Pyx_GIVEREF(__pyx_v_line);
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_match, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":409
+ * for line in self._file_header_lines:
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * if match: # <<<<<<<<<<<<<<
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip()
+ */
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_v_match); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":411
+ * if match:
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ */
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_lstrip); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_strip); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hkey, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":412
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ * else:
+ */
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_match, __pyx_n_s_group); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_strip); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_hvalue, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":413
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue) # <<<<<<<<<<<<<<
+ * else:
+ * _logger.warning("Unable to parse file header line " + line)
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_add_or_concatenate); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_dict); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_16 = PyTuple_New(3+__pyx_t_9); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ if (__pyx_t_1) {
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_16, 0+__pyx_t_9, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_hkey);
+ PyTuple_SET_ITEM(__pyx_t_16, 1+__pyx_t_9, __pyx_v_hkey);
+ __Pyx_GIVEREF(__pyx_v_hkey);
+ __Pyx_INCREF(__pyx_v_hvalue);
+ PyTuple_SET_ITEM(__pyx_t_16, 2+__pyx_t_9, __pyx_v_hvalue);
+ __Pyx_GIVEREF(__pyx_v_hvalue);
+ __pyx_t_5 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_16, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":415
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ * else:
+ * _logger.warning("Unable to parse file header line " + line) # <<<<<<<<<<<<<<
+ *
+ * self._motor_names = self._specfile.motor_names(self._index)
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_warning); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyNumber_Add(__pyx_kp_s_Unable_to_parse_file_header_line, __pyx_v_line); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_16))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_16);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_16);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_16, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_16, __pyx_t_10); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_1 = PyTuple_New(1+1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_1, 0+1, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_16, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L20:;
+
+ /* "specfile.pyx":407
+ *
+ * self._file_header_dict = {}
+ * for line in self._file_header_lines: # <<<<<<<<<<<<<<
+ * match = re.search(r"#(\w+) *(.*)", line)
+ * if match:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":417
+ * _logger.warning("Unable to parse file header line " + line)
+ *
+ * self._motor_names = self._specfile.motor_names(self._index) # <<<<<<<<<<<<<<
+ * self._motor_positions = self._specfile.motor_positions(self._index)
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_motor_names); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_16))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_16);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_16);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_16, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_16, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_16, __pyx_t_10, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_motor_names_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":418
+ *
+ * self._motor_names = self._specfile.motor_names(self._index)
+ * self._motor_positions = self._specfile.motor_positions(self._index) # <<<<<<<<<<<<<<
+ *
+ * self._data = None
+ */
+ __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_16, __pyx_n_s_motor_positions); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __pyx_t_16 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_16); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_1 = PyTuple_New(1+1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_1, 0+1, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_16 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_1, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_motor_positions_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":420
+ * self._motor_positions = self._specfile.motor_positions(self._index)
+ *
+ * self._data = None # <<<<<<<<<<<<<<
+ * self._mca = None
+ *
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_data, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":421
+ *
+ * self._data = None
+ * self._mca = None # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_mca, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":363
+ * scan2 = sf["3.1"]
+ * """
+ * def __init__(self, specfile, scan_index): # <<<<<<<<<<<<<<
+ * self._specfile = specfile
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("specfile.Scan.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XDECREF(__pyx_v_match);
+ __Pyx_XDECREF(__pyx_v_match_mca);
+ __Pyx_XDECREF(__pyx_v_hkey);
+ __Pyx_XDECREF(__pyx_v_hvalue);
+ __Pyx_XDECREF(__pyx_v_L_header);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":425
+ * @cython.embedsignature(False)
+ * @property
+ * def index(self): # <<<<<<<<<<<<<<
+ * """Unique scan index 0 - len(specfile)-1
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_3index(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_2index[] = "Unique scan index 0 - len(specfile)-1\n\n This attribute is implemented as a read-only property as changing\n its value may cause nasty side-effects (such as loading data from a\n different scan without updating the header accordingly.";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_3index = {"index", (PyCFunction)__pyx_pw_8specfile_4Scan_3index, METH_O, __pyx_doc_8specfile_4Scan_2index};
+static PyObject *__pyx_pw_8specfile_4Scan_3index(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("index (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_2index(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_2index(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("index", 0);
+
+ /* "specfile.pyx":431
+ * its value may cause nasty side-effects (such as loading data from a
+ * different scan without updating the header accordingly."""
+ * return self._index # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 431; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":425
+ * @cython.embedsignature(False)
+ * @property
+ * def index(self): # <<<<<<<<<<<<<<
+ * """Unique scan index 0 - len(specfile)-1
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":435
+ * @cython.embedsignature(False)
+ * @property
+ * def number(self): # <<<<<<<<<<<<<<
+ * """First value on #S line (as int)"""
+ * return self._number
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_5number(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_4number[] = "First value on #S line (as int)";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_5number = {"number", (PyCFunction)__pyx_pw_8specfile_4Scan_5number, METH_O, __pyx_doc_8specfile_4Scan_4number};
+static PyObject *__pyx_pw_8specfile_4Scan_5number(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("number (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_4number(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_4number(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("number", 0);
+
+ /* "specfile.pyx":437
+ * def number(self):
+ * """First value on #S line (as int)"""
+ * return self._number # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_number_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":435
+ * @cython.embedsignature(False)
+ * @property
+ * def number(self): # <<<<<<<<<<<<<<
+ * """First value on #S line (as int)"""
+ * return self._number
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.number", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":441
+ * @cython.embedsignature(False)
+ * @property
+ * def order(self): # <<<<<<<<<<<<<<
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_7order(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_6order[] = "Order can be > 1 if the same number is repeated in a specfile";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_7order = {"order", (PyCFunction)__pyx_pw_8specfile_4Scan_7order, METH_O, __pyx_doc_8specfile_4Scan_6order};
+static PyObject *__pyx_pw_8specfile_4Scan_7order(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("order (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_6order(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_6order(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("order", 0);
+
+ /* "specfile.pyx":443
+ * def order(self):
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_order_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":441
+ * @cython.embedsignature(False)
+ * @property
+ * def order(self): # <<<<<<<<<<<<<<
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.order", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":447
+ * @cython.embedsignature(False)
+ * @property
+ * def header(self): # <<<<<<<<<<<<<<
+ * """List of raw header lines (as a list of strings).
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_9header(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_8header[] = "List of raw header lines (as a list of strings).\n\n This includes the file header, the scan header and possibly a MCA\n header.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_9header = {"header", (PyCFunction)__pyx_pw_8specfile_4Scan_9header, METH_O, __pyx_doc_8specfile_4Scan_8header};
+static PyObject *__pyx_pw_8specfile_4Scan_9header(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("header (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_8header(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_8header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("header", 0);
+
+ /* "specfile.pyx":453
+ * header.
+ * """
+ * return self._header # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":447
+ * @cython.embedsignature(False)
+ * @property
+ * def header(self): # <<<<<<<<<<<<<<
+ * """List of raw header lines (as a list of strings).
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":457
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header(self): # <<<<<<<<<<<<<<
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_11scan_header(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_10scan_header[] = "List of raw scan header lines (as a list of strings).\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_11scan_header = {"scan_header", (PyCFunction)__pyx_pw_8specfile_4Scan_11scan_header, METH_O, __pyx_doc_8specfile_4Scan_10scan_header};
+static PyObject *__pyx_pw_8specfile_4Scan_11scan_header(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("scan_header (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_10scan_header(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_10scan_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("scan_header", 0);
+
+ /* "specfile.pyx":460
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ * return self._scan_header_lines # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":457
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header(self): # <<<<<<<<<<<<<<
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.scan_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":464
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header(self): # <<<<<<<<<<<<<<
+ * """List of raw file header lines (as a list of strings).
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_13file_header(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_12file_header[] = "List of raw file header lines (as a list of strings).\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_13file_header = {"file_header", (PyCFunction)__pyx_pw_8specfile_4Scan_13file_header, METH_O, __pyx_doc_8specfile_4Scan_12file_header};
+static PyObject *__pyx_pw_8specfile_4Scan_13file_header(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("file_header (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_12file_header(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_12file_header(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("file_header", 0);
+
+ /* "specfile.pyx":467
+ * """List of raw file header lines (as a list of strings).
+ * """
+ * return self._file_header_lines # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_lines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":464
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header(self): # <<<<<<<<<<<<<<
+ * """List of raw file header lines (as a list of strings).
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.file_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":471
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of scan header strings, keys without the leading``#``
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_15scan_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_14scan_header_dict[] = "\n Dictionary of scan header strings, keys without the leading``#``\n (e.g. ``scan_header_dict[\"S\"]``).\n Note: this does not include MCA header lines starting with ``#@``.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_15scan_header_dict = {"scan_header_dict", (PyCFunction)__pyx_pw_8specfile_4Scan_15scan_header_dict, METH_O, __pyx_doc_8specfile_4Scan_14scan_header_dict};
+static PyObject *__pyx_pw_8specfile_4Scan_15scan_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("scan_header_dict (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_14scan_header_dict(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_14scan_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("scan_header_dict", 0);
+
+ /* "specfile.pyx":477
+ * Note: this does not include MCA header lines starting with ``#@``.
+ * """
+ * return self._scan_header_dict # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_scan_header_dict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":471
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of scan header strings, keys without the leading``#``
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.scan_header_dict", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":481
+ * @cython.embedsignature(False)
+ * @property
+ * def mca_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of MCA header strings, keys without the leading ``#@``
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_17mca_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_16mca_header_dict[] = "\n Dictionary of MCA header strings, keys without the leading ``#@``\n (e.g. ``mca_header_dict[\"CALIB\"]``).\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_17mca_header_dict = {"mca_header_dict", (PyCFunction)__pyx_pw_8specfile_4Scan_17mca_header_dict, METH_O, __pyx_doc_8specfile_4Scan_16mca_header_dict};
+static PyObject *__pyx_pw_8specfile_4Scan_17mca_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("mca_header_dict (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_16mca_header_dict(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_16mca_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("mca_header_dict", 0);
+
+ /* "specfile.pyx":486
+ * (e.g. ``mca_header_dict["CALIB"]``).
+ * """
+ * return self._mca_header_dict # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_mca_header_dict_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":481
+ * @cython.embedsignature(False)
+ * @property
+ * def mca_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of MCA header strings, keys without the leading ``#@``
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.mca_header_dict", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":490
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of file header strings, keys without the leading ``#``
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_19file_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_18file_header_dict[] = "\n Dictionary of file header strings, keys without the leading ``#``\n (e.g. ``file_header_dict[\"F\"]``).\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_19file_header_dict = {"file_header_dict", (PyCFunction)__pyx_pw_8specfile_4Scan_19file_header_dict, METH_O, __pyx_doc_8specfile_4Scan_18file_header_dict};
+static PyObject *__pyx_pw_8specfile_4Scan_19file_header_dict(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("file_header_dict (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_18file_header_dict(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_18file_header_dict(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("file_header_dict", 0);
+
+ /* "specfile.pyx":495
+ * (e.g. ``file_header_dict["F"]``).
+ * """
+ * return self._file_header_dict # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_file_header_dict); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":490
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of file header strings, keys without the leading ``#``
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.file_header_dict", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":499
+ * @cython.embedsignature(False)
+ * @property
+ * def labels(self): # <<<<<<<<<<<<<<
+ * """
+ * List of data column headers from ``#L`` scan header
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_21labels(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_20labels[] = "\n List of data column headers from ``#L`` scan header\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_21labels = {"labels", (PyCFunction)__pyx_pw_8specfile_4Scan_21labels, METH_O, __pyx_doc_8specfile_4Scan_20labels};
+static PyObject *__pyx_pw_8specfile_4Scan_21labels(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("labels (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_20labels(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_20labels(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("labels", 0);
+
+ /* "specfile.pyx":503
+ * List of data column headers from ``#L`` scan header
+ * """
+ * return self._labels # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_labels); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":499
+ * @cython.embedsignature(False)
+ * @property
+ * def labels(self): # <<<<<<<<<<<<<<
+ * """
+ * List of data column headers from ``#L`` scan header
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.labels", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":507
+ * @cython.embedsignature(False)
+ * @property
+ * def data(self): # <<<<<<<<<<<<<<
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ * (e.g. data.shape).
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_23data(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_22data[] = "Scan data as a 2D numpy.ndarray with the usual attributes\n (e.g. data.shape).\n\n The first index is the detector, the second index is the sample index.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_23data = {"data", (PyCFunction)__pyx_pw_8specfile_4Scan_23data, METH_O, __pyx_doc_8specfile_4Scan_22data};
+static PyObject *__pyx_pw_8specfile_4Scan_23data(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_22data(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_22data(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data", 0);
+
+ /* "specfile.pyx":513
+ * The first index is the detector, the second index is the sample index.
+ * """
+ * if self._data is None: # <<<<<<<<<<<<<<
+ * self._data = numpy.transpose(self._specfile.data(self._index))
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 513; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = (__pyx_t_1 == Py_None);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":514
+ * """
+ * if self._data is None:
+ * self._data = numpy.transpose(self._specfile.data(self._index)) # <<<<<<<<<<<<<<
+ *
+ * return self._data
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_transpose); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_data_2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_data, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":516
+ * self._data = numpy.transpose(self._specfile.data(self._index))
+ *
+ * return self._data # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 516; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":507
+ * @cython.embedsignature(False)
+ * @property
+ * def data(self): # <<<<<<<<<<<<<<
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ * (e.g. data.shape).
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("specfile.Scan.data", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":520
+ * @cython.embedsignature(False)
+ * @property
+ * def mca(self): # <<<<<<<<<<<<<<
+ * """MCA data in this scan.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_25mca(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_24mca[] = "MCA data in this scan.\n\n Each multichannel analysis is a 1D numpy array. Metadata about\n MCA data is to be found in :py:attr:`mca_header`.\n\n :rtype: :class:`MCA`\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_25mca = {"mca", (PyCFunction)__pyx_pw_8specfile_4Scan_25mca, METH_O, __pyx_doc_8specfile_4Scan_24mca};
+static PyObject *__pyx_pw_8specfile_4Scan_25mca(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("mca (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_24mca(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_24mca(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("mca", 0);
+
+ /* "specfile.pyx":528
+ * :rtype: :class:`MCA`
+ * """
+ * if self._mca is None: # <<<<<<<<<<<<<<
+ * self._mca = MCA(self)
+ * return self._mca
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_mca); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = (__pyx_t_1 == Py_None);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":529
+ * """
+ * if self._mca is None:
+ * self._mca = MCA(self) # <<<<<<<<<<<<<<
+ * return self._mca
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_MCA); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ __Pyx_INCREF(__pyx_v_self);
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_self);
+ __Pyx_GIVEREF(__pyx_v_self);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_mca, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":530
+ * if self._mca is None:
+ * self._mca = MCA(self)
+ * return self._mca # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_mca); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 530; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":520
+ * @cython.embedsignature(False)
+ * @property
+ * def mca(self): # <<<<<<<<<<<<<<
+ * """MCA data in this scan.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("specfile.Scan.mca", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":534
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_names(self): # <<<<<<<<<<<<<<
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_27motor_names(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_26motor_names[] = "List of motor names from the ``#O`` file header line.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_27motor_names = {"motor_names", (PyCFunction)__pyx_pw_8specfile_4Scan_27motor_names, METH_O, __pyx_doc_8specfile_4Scan_26motor_names};
+static PyObject *__pyx_pw_8specfile_4Scan_27motor_names(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_names (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_26motor_names(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_26motor_names(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_names", 0);
+
+ /* "specfile.pyx":537
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ * return self._motor_names # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_motor_names_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 537; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":534
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_names(self): # <<<<<<<<<<<<<<
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.motor_names", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":541
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_positions(self): # <<<<<<<<<<<<<<
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_29motor_positions(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_4Scan_28motor_positions[] = "List of motor positions as floats from the ``#P`` scan header line.\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_29motor_positions = {"motor_positions", (PyCFunction)__pyx_pw_8specfile_4Scan_29motor_positions, METH_O, __pyx_doc_8specfile_4Scan_28motor_positions};
+static PyObject *__pyx_pw_8specfile_4Scan_29motor_positions(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_positions (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4Scan_28motor_positions(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_28motor_positions(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_positions", 0);
+
+ /* "specfile.pyx":544
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ * return self._motor_positions # <<<<<<<<<<<<<<
+ *
+ * def record_exists_in_hdr(self, record):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_motor_positions_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":541
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_positions(self): # <<<<<<<<<<<<<<
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.Scan.motor_positions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":546
+ * return self._motor_positions
+ *
+ * def record_exists_in_hdr(self, record): # <<<<<<<<<<<<<<
+ * """Check whether a scan header line exists.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_31record_exists_in_hdr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan_30record_exists_in_hdr[] = "Scan.record_exists_in_hdr(self, record)\nCheck whether a scan header line exists.\n \n This should be used before attempting to retrieve header information \n using a C function that may crash with a *segmentation fault* if the\n header isn't defined in the SpecFile.\n \n :param record: single upper case letter corresponding to the\n header you want to test (e.g. ``L`` for labels)\n :type record: str\n\n :return: True or False\n :rtype: boolean\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_31record_exists_in_hdr = {"record_exists_in_hdr", (PyCFunction)__pyx_pw_8specfile_4Scan_31record_exists_in_hdr, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan_30record_exists_in_hdr};
+static PyObject *__pyx_pw_8specfile_4Scan_31record_exists_in_hdr(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_record = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("record_exists_in_hdr (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_record,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_record)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("record_exists_in_hdr", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "record_exists_in_hdr") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_record = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("record_exists_in_hdr", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.record_exists_in_hdr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan_30record_exists_in_hdr(__pyx_self, __pyx_v_self, __pyx_v_record);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_30record_exists_in_hdr(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_record) {
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("record_exists_in_hdr", 0);
+
+ /* "specfile.pyx":560
+ * :rtype: boolean
+ * """
+ * for line in self._header: # <<<<<<<<<<<<<<
+ * if line.startswith("#" + record):
+ * return True
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_header); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+ __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_1); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_1 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_1)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_line, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":561
+ * """
+ * for line in self._header:
+ * if line.startswith("#" + record): # <<<<<<<<<<<<<<
+ * return True
+ * return False
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_line, __pyx_n_s_startswith); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyNumber_Add(__pyx_kp_s__7, __pyx_v_record); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_9 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_9) {
+
+ /* "specfile.pyx":562
+ * for line in self._header:
+ * if line.startswith("#" + record):
+ * return True # <<<<<<<<<<<<<<
+ * return False
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_True);
+ __pyx_r = Py_True;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "specfile.pyx":560
+ * :rtype: boolean
+ * """
+ * for line in self._header: # <<<<<<<<<<<<<<
+ * if line.startswith("#" + record):
+ * return True
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":563
+ * if line.startswith("#" + record):
+ * return True
+ * return False # <<<<<<<<<<<<<<
+ *
+ * def data_line(self, line_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_False);
+ __pyx_r = Py_False;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":546
+ * return self._motor_positions
+ *
+ * def record_exists_in_hdr(self, record): # <<<<<<<<<<<<<<
+ * """Check whether a scan header line exists.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.Scan.record_exists_in_hdr", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":565
+ * return False
+ *
+ * def data_line(self, line_index): # <<<<<<<<<<<<<<
+ * """Returns data for a given line of this scan.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_33data_line(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan_32data_line[] = "Scan.data_line(self, line_index)\nReturns data for a given line of this scan.\n\n .. note::\n\n A data line returned by this method, corresponds to a data line\n in the original specfile (a series of data points, one per\n detector). In the :attr:`data` array, this line index corresponds\n to the index in the second dimension (~ column) of the array.\n \n :param line_index: Index of data line to retrieve (starting with 0)\n :type line_index: int\n\n :return: Line data as a 1D array of doubles\n :rtype: numpy.ndarray \n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_33data_line = {"data_line", (PyCFunction)__pyx_pw_8specfile_4Scan_33data_line, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan_32data_line};
+static PyObject *__pyx_pw_8specfile_4Scan_33data_line(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_line_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data_line (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_line_index,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_line_index)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("data_line", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "data_line") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_line_index = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("data_line", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.data_line", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan_32data_line(__pyx_self, __pyx_v_self, __pyx_v_line_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_32data_line(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_line_index) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data_line", 0);
+
+ /* "specfile.pyx":583
+ * # attribute data corresponds to a transposed version of the original
+ * # specfile data (where detectors correspond to columns)
+ * return self.data[:, line_index] # <<<<<<<<<<<<<<
+ *
+ * def data_column_by_name(self, label):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_data_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_slice__19);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_slice__19);
+ __Pyx_GIVEREF(__pyx_slice__19);
+ __Pyx_INCREF(__pyx_v_line_index);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_line_index);
+ __Pyx_GIVEREF(__pyx_v_line_index);
+ __pyx_t_3 = PyObject_GetItem(__pyx_t_1, __pyx_t_2); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":565
+ * return False
+ *
+ * def data_line(self, line_index): # <<<<<<<<<<<<<<
+ * """Returns data for a given line of this scan.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.Scan.data_line", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":585
+ * return self.data[:, line_index]
+ *
+ * def data_column_by_name(self, label): # <<<<<<<<<<<<<<
+ * """Returns a data column
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_35data_column_by_name(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan_34data_column_by_name[] = "Scan.data_column_by_name(self, label)\nReturns a data column\n\n :param label: Label of data column to retrieve, as defined on the\n ``#L`` line of the scan header.\n :type label: str\n\n :return: Line data as a 1D array of doubles\n :rtype: numpy.ndarray\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_35data_column_by_name = {"data_column_by_name", (PyCFunction)__pyx_pw_8specfile_4Scan_35data_column_by_name, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan_34data_column_by_name};
+static PyObject *__pyx_pw_8specfile_4Scan_35data_column_by_name(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_label = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data_column_by_name (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_label,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_label)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("data_column_by_name", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "data_column_by_name") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_label = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("data_column_by_name", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan_34data_column_by_name(__pyx_self, __pyx_v_self, __pyx_v_label);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_34data_column_by_name(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_label) {
+ PyObject *__pyx_v_ret = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data_column_by_name", 0);
+
+ /* "specfile.pyx":595
+ * :rtype: numpy.ndarray
+ * """
+ * try: # <<<<<<<<<<<<<<
+ * ret = self._specfile.data_column_by_name(self._index, label)
+ * except SfErrLineNotFound:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ /*try:*/ {
+
+ /* "specfile.pyx":596
+ * """
+ * try:
+ * ret = self._specfile.data_column_by_name(self._index, label) # <<<<<<<<<<<<<<
+ * except SfErrLineNotFound:
+ * # Could be a "#C Scan aborted after 0 points"
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_data_column_by_name); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_label);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_label);
+ __Pyx_GIVEREF(__pyx_v_label);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_ret = __pyx_t_4;
+ __pyx_t_4 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L10_try_end;
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":597
+ * try:
+ * ret = self._specfile.data_column_by_name(self._index, label)
+ * except SfErrLineNotFound: # <<<<<<<<<<<<<<
+ * # Could be a "#C Scan aborted after 0 points"
+ * _logger.warning("Cannot get data column %s in scan %d.%d",
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLineNotFound); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_10 = PyErr_ExceptionMatches(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_10) {
+ __Pyx_AddTraceback("specfile.Scan.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "specfile.pyx":599
+ * except SfErrLineNotFound:
+ * # Could be a "#C Scan aborted after 0 points"
+ * _logger.warning("Cannot get data column %s in scan %d.%d", # <<<<<<<<<<<<<<
+ * label, self.number, self.order)
+ * ret = numpy.empty((0, ), numpy.double)
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_warning); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "specfile.pyx":600
+ * # Could be a "#C Scan aborted after 0 points"
+ * _logger.warning("Cannot get data column %s in scan %d.%d",
+ * label, self.number, self.order) # <<<<<<<<<<<<<<
+ * ret = numpy.empty((0, ), numpy.double)
+ * return ret
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_number); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_order); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ __pyx_t_13 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_11))) {
+ __pyx_t_13 = PyMethod_GET_SELF(__pyx_t_11);
+ if (likely(__pyx_t_13)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+ __Pyx_INCREF(__pyx_t_13);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_11, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_14 = PyTuple_New(4+__pyx_t_8); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ if (__pyx_t_13) {
+ PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_13); __Pyx_GIVEREF(__pyx_t_13); __pyx_t_13 = NULL;
+ }
+ __Pyx_INCREF(__pyx_kp_s_Cannot_get_data_column_s_in_scan);
+ PyTuple_SET_ITEM(__pyx_t_14, 0+__pyx_t_8, __pyx_kp_s_Cannot_get_data_column_s_in_scan);
+ __Pyx_GIVEREF(__pyx_kp_s_Cannot_get_data_column_s_in_scan);
+ __Pyx_INCREF(__pyx_v_label);
+ PyTuple_SET_ITEM(__pyx_t_14, 1+__pyx_t_8, __pyx_v_label);
+ __Pyx_GIVEREF(__pyx_v_label);
+ PyTuple_SET_ITEM(__pyx_t_14, 2+__pyx_t_8, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_14, 3+__pyx_t_8, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ __pyx_t_7 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_14, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "specfile.pyx":601
+ * _logger.warning("Cannot get data column %s in scan %d.%d",
+ * label, self.number, self.order)
+ * ret = numpy.empty((0, ), numpy.double) # <<<<<<<<<<<<<<
+ * return ret
+ *
+ */
+ __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_empty); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_double); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_11 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_14))) {
+ __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_14);
+ if (likely(__pyx_t_11)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_14);
+ __Pyx_INCREF(__pyx_t_11);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_14, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_7 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ if (__pyx_t_11) {
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_11); __Pyx_GIVEREF(__pyx_t_11); __pyx_t_11 = NULL;
+ }
+ __Pyx_INCREF(__pyx_tuple__20);
+ PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_8, __pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+ PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_8, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ __pyx_t_12 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_14, __pyx_t_7, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_ret, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L4_exception_handled;
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_1);
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
+ goto __pyx_L1_error;
+ __pyx_L4_exception_handled:;
+ __Pyx_XGIVEREF(__pyx_t_1);
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3);
+ __pyx_L10_try_end:;
+ }
+
+ /* "specfile.pyx":602
+ * label, self.number, self.order)
+ * ret = numpy.empty((0, ), numpy.double)
+ * return ret # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_ret);
+ __pyx_r = __pyx_v_ret;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":585
+ * return self.data[:, line_index]
+ *
+ * def data_column_by_name(self, label): # <<<<<<<<<<<<<<
+ * """Returns a data column
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_AddTraceback("specfile.Scan.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_ret);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":605
+ *
+ *
+ * def motor_position_by_name(self, name): # <<<<<<<<<<<<<<
+ * """Returns the position for a given motor
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_4Scan_37motor_position_by_name(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_4Scan_36motor_position_by_name[] = "Scan.motor_position_by_name(self, name)\nReturns the position for a given motor\n\n :param name: Name of motor, as defined on the ``#O`` line of the\n file header.\n :type name: str\n\n :return: Motor position\n :rtype: float\n ";
+static PyMethodDef __pyx_mdef_8specfile_4Scan_37motor_position_by_name = {"motor_position_by_name", (PyCFunction)__pyx_pw_8specfile_4Scan_37motor_position_by_name, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_4Scan_36motor_position_by_name};
+static PyObject *__pyx_pw_8specfile_4Scan_37motor_position_by_name(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_position_by_name (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_name,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("motor_position_by_name", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "motor_position_by_name") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_name = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("motor_position_by_name", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.Scan.motor_position_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_4Scan_36motor_position_by_name(__pyx_self, __pyx_v_self, __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4Scan_36motor_position_by_name(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_name) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_position_by_name", 0);
+
+ /* "specfile.pyx":615
+ * :rtype: float
+ * """
+ * return self._specfile.motor_position_by_name(self._index, name) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_specfile); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_motor_position_by_name); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_index_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = NULL;
+ __pyx_t_5 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ __pyx_t_5 = 1;
+ }
+ }
+ __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_name);
+ PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 615; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":605
+ *
+ *
+ * def motor_position_by_name(self, name): # <<<<<<<<<<<<<<
+ * """Returns the position for a given motor
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("specfile.Scan.motor_position_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":618
+ *
+ *
+ * def _string_to_char_star(string_): # <<<<<<<<<<<<<<
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_3_string_to_char_star(PyObject *__pyx_self, PyObject *__pyx_v_string_); /*proto*/
+static char __pyx_doc_8specfile_2_string_to_char_star[] = "_string_to_char_star(string_)\nConvert a string to ASCII encoded bytes when using python3";
+static PyMethodDef __pyx_mdef_8specfile_3_string_to_char_star = {"_string_to_char_star", (PyCFunction)__pyx_pw_8specfile_3_string_to_char_star, METH_O, __pyx_doc_8specfile_2_string_to_char_star};
+static PyObject *__pyx_pw_8specfile_3_string_to_char_star(PyObject *__pyx_self, PyObject *__pyx_v_string_) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_string_to_char_star (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_2_string_to_char_star(__pyx_self, ((PyObject *)__pyx_v_string_));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_2_string_to_char_star(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_string_) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_string_to_char_star", 0);
+
+ /* "specfile.pyx":620
+ * def _string_to_char_star(string_):
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes): # <<<<<<<<<<<<<<
+ * return bytes(string_, "ascii")
+ * return string_
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_sys); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_version); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_startswith); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_1 = __pyx_t_4;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_4 = PyBytes_Check(__pyx_v_string_);
+ __pyx_t_5 = ((!(__pyx_t_4 != 0)) != 0);
+ __pyx_t_1 = __pyx_t_5;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "specfile.pyx":621
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ * return bytes(string_, "ascii") # <<<<<<<<<<<<<<
+ * return string_
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_string_);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_string_);
+ __Pyx_GIVEREF(__pyx_v_string_);
+ __Pyx_INCREF(__pyx_n_s_ascii);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_n_s_ascii);
+ __Pyx_GIVEREF(__pyx_n_s_ascii);
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyBytes_Type))), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "specfile.pyx":622
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ * return bytes(string_, "ascii")
+ * return string_ # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_string_);
+ __pyx_r = __pyx_v_string_;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":618
+ *
+ *
+ * def _string_to_char_star(string_): # <<<<<<<<<<<<<<
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile._string_to_char_star", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":625
+ *
+ *
+ * def is_specfile(filename): # <<<<<<<<<<<<<<
+ * """Test if a file is a SPEC file, by checking if one of the first two
+ * lines starts with *#F* (SPEC file header) or *#S* (scan header).
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_5is_specfile(PyObject *__pyx_self, PyObject *__pyx_v_filename); /*proto*/
+static char __pyx_doc_8specfile_4is_specfile[] = "is_specfile(filename)\nTest if a file is a SPEC file, by checking if one of the first two\n lines starts with *#F* (SPEC file header) or *#S* (scan header).\n\n :param str filename: File path\n :return: *True* if file is a SPEC file, *False* if it is not a SPEC file\n :rtype: bool\n ";
+static PyMethodDef __pyx_mdef_8specfile_5is_specfile = {"is_specfile", (PyCFunction)__pyx_pw_8specfile_5is_specfile, METH_O, __pyx_doc_8specfile_4is_specfile};
+static PyObject *__pyx_pw_8specfile_5is_specfile(PyObject *__pyx_self, PyObject *__pyx_v_filename) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_specfile (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_4is_specfile(__pyx_self, ((PyObject *)__pyx_v_filename));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_4is_specfile(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_filename) {
+ PyObject *__pyx_v_f = NULL;
+ PyObject *__pyx_v_i = NULL;
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_specfile", 0);
+
+ /* "specfile.pyx":633
+ * :rtype: bool
+ * """
+ * if not os.path.isfile(filename): # <<<<<<<<<<<<<<
+ * return False
+ * # test for presence of #S or #F in first two lines
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_os); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_path); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_isfile); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_filename); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ __Pyx_INCREF(__pyx_v_filename);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_filename);
+ __Pyx_GIVEREF(__pyx_v_filename);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = ((!__pyx_t_5) != 0);
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":634
+ * """
+ * if not os.path.isfile(filename):
+ * return False # <<<<<<<<<<<<<<
+ * # test for presence of #S or #F in first two lines
+ * f = open(filename)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_False);
+ __pyx_r = Py_False;
+ goto __pyx_L0;
+ }
+
+ /* "specfile.pyx":636
+ * return False
+ * # test for presence of #S or #F in first two lines
+ * f = open(filename) # <<<<<<<<<<<<<<
+ * for i, line in enumerate(f):
+ * if line.startswith("#S ") or line.startswith("#F "):
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_filename);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_filename);
+ __Pyx_GIVEREF(__pyx_v_filename);
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_open, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_f = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":637
+ * # test for presence of #S or #F in first two lines
+ * f = open(filename)
+ * for i, line in enumerate(f): # <<<<<<<<<<<<<<
+ * if line.startswith("#S ") or line.startswith("#F "):
+ * f.close()
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_2 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_f)) || PyTuple_CheckExact(__pyx_v_f)) {
+ __pyx_t_1 = __pyx_v_f; __Pyx_INCREF(__pyx_t_1); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_f); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_8 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_1))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_7); __Pyx_INCREF(__pyx_t_4); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_4 = PySequence_ITEM(__pyx_t_1, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_4 = __pyx_t_8(__pyx_t_1);
+ if (unlikely(!__pyx_t_4)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_4);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_line, __pyx_t_4);
+ __pyx_t_4 = 0;
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_2);
+ __pyx_t_4 = PyNumber_Add(__pyx_t_2, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2);
+ __pyx_t_2 = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":638
+ * f = open(filename)
+ * for i, line in enumerate(f):
+ * if line.startswith("#S ") or line.startswith("#F "): # <<<<<<<<<<<<<<
+ * f.close()
+ * return True
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_line, __pyx_n_s_startswith); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (!__pyx_t_5) {
+ } else {
+ __pyx_t_6 = __pyx_t_5;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_line, __pyx_n_s_startswith); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __pyx_t_5;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":639
+ * for i, line in enumerate(f):
+ * if line.startswith("#S ") or line.startswith("#F "):
+ * f.close() # <<<<<<<<<<<<<<
+ * return True
+ * if i >= 10:
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_f, __pyx_n_s_close); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 639; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_9) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 639; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 639; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":640
+ * if line.startswith("#S ") or line.startswith("#F "):
+ * f.close()
+ * return True # <<<<<<<<<<<<<<
+ * if i >= 10:
+ * break
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_True);
+ __pyx_r = Py_True;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "specfile.pyx":641
+ * f.close()
+ * return True
+ * if i >= 10: # <<<<<<<<<<<<<<
+ * break
+ * f.close()
+ */
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_i, __pyx_int_10, Py_GE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":642
+ * return True
+ * if i >= 10:
+ * break # <<<<<<<<<<<<<<
+ * f.close()
+ * return False
+ */
+ goto __pyx_L5_break;
+ }
+
+ /* "specfile.pyx":637
+ * # test for presence of #S or #F in first two lines
+ * f = open(filename)
+ * for i, line in enumerate(f): # <<<<<<<<<<<<<<
+ * if line.startswith("#S ") or line.startswith("#F "):
+ * f.close()
+ */
+ }
+ __pyx_L5_break:;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":643
+ * if i >= 10:
+ * break
+ * f.close() # <<<<<<<<<<<<<<
+ * return False
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_f, __pyx_n_s_close); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":644
+ * break
+ * f.close()
+ * return False # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_False);
+ __pyx_r = Py_False;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":625
+ *
+ *
+ * def is_specfile(filename): # <<<<<<<<<<<<<<
+ * """Test if a file is a SPEC file, by checking if one of the first two
+ * lines starts with *#F* (SPEC file header) or *#S* (scan header).
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("specfile.is_specfile", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_f);
+ __Pyx_XDECREF(__pyx_v_i);
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":661
+ * int __open_failed
+ *
+ * def __cinit__(self, filename): # <<<<<<<<<<<<<<
+ * cdef int error = SF_ERR_NO_ERRORS
+ * self.__open_failed = 0
+ */
+
+/* Python wrapper */
+static int __pyx_pw_8specfile_8SpecFile_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_8specfile_8SpecFile_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_filename = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_filename)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 661; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_filename = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 661; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile___cinit__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_filename);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_8specfile_8SpecFile___cinit__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_filename) {
+ int __pyx_v_error;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_t_6;
+ char *__pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_filename);
+
+ /* "specfile.pyx":662
+ *
+ * def __cinit__(self, filename):
+ * cdef int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ * self.__open_failed = 0
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":663
+ * def __cinit__(self, filename):
+ * cdef int error = SF_ERR_NO_ERRORS
+ * self.__open_failed = 0 # <<<<<<<<<<<<<<
+ *
+ * if is_specfile(filename):
+ */
+ __pyx_v_self->__pyx___open_failed = 0;
+
+ /* "specfile.pyx":665
+ * self.__open_failed = 0
+ *
+ * if is_specfile(filename): # <<<<<<<<<<<<<<
+ * filename = _string_to_char_star(filename)
+ * self.handle = specfile_wrapper.SfOpen(filename, &error)
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_is_specfile); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_filename);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_filename);
+ __Pyx_GIVEREF(__pyx_v_filename);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 665; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":666
+ *
+ * if is_specfile(filename):
+ * filename = _string_to_char_star(filename) # <<<<<<<<<<<<<<
+ * self.handle = specfile_wrapper.SfOpen(filename, &error)
+ * else:
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_string_to_char_star); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 666; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_filename); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 666; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 666; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ __Pyx_INCREF(__pyx_v_filename);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_filename);
+ __Pyx_GIVEREF(__pyx_v_filename);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 666; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_filename, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":667
+ * if is_specfile(filename):
+ * filename = _string_to_char_star(filename)
+ * self.handle = specfile_wrapper.SfOpen(filename, &error) # <<<<<<<<<<<<<<
+ * else:
+ * self.__open_failed = 1
+ */
+ __pyx_t_7 = __Pyx_PyObject_AsString(__pyx_v_filename); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->handle = SfOpen(__pyx_t_7, (&__pyx_v_error));
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":669
+ * self.handle = specfile_wrapper.SfOpen(filename, &error)
+ * else:
+ * self.__open_failed = 1 # <<<<<<<<<<<<<<
+ * self._handle_error(SF_ERR_FILE_OPEN)
+ * if error:
+ */
+ __pyx_v_self->__pyx___open_failed = 1;
+
+ /* "specfile.pyx":670
+ * else:
+ * self.__open_failed = 1
+ * self._handle_error(SF_ERR_FILE_OPEN) # <<<<<<<<<<<<<<
+ * if error:
+ * self.__open_failed = 1
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_FILE_OPEN); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":671
+ * self.__open_failed = 1
+ * self._handle_error(SF_ERR_FILE_OPEN)
+ * if error: # <<<<<<<<<<<<<<
+ * self.__open_failed = 1
+ * self._handle_error(error)
+ */
+ __pyx_t_6 = (__pyx_v_error != 0);
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":672
+ * self._handle_error(SF_ERR_FILE_OPEN)
+ * if error:
+ * self.__open_failed = 1 # <<<<<<<<<<<<<<
+ * self._handle_error(error)
+ *
+ */
+ __pyx_v_self->__pyx___open_failed = 1;
+
+ /* "specfile.pyx":673
+ * if error:
+ * self.__open_failed = 1
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * def __init__(self, filename):
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "specfile.pyx":661
+ * int __open_failed
+ *
+ * def __cinit__(self, filename): # <<<<<<<<<<<<<<
+ * cdef int error = SF_ERR_NO_ERRORS
+ * self.__open_failed = 0
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_filename);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":675
+ * self._handle_error(error)
+ *
+ * def __init__(self, filename): # <<<<<<<<<<<<<<
+ * if not isinstance(filename, str):
+ * # encode unicode to str in python 2
+ */
+
+/* Python wrapper */
+static int __pyx_pw_8specfile_8SpecFile_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_8specfile_8SpecFile_3__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_filename = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_filename,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_filename)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 675; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_filename = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 675; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_2__init__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_filename);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_8specfile_8SpecFile_2__init__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_filename) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "specfile.pyx":676
+ *
+ * def __init__(self, filename):
+ * if not isinstance(filename, str): # <<<<<<<<<<<<<<
+ * # encode unicode to str in python 2
+ * if sys.version_info[0] < 3:
+ */
+ __pyx_t_1 = PyString_Check(__pyx_v_filename);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":678
+ * if not isinstance(filename, str):
+ * # encode unicode to str in python 2
+ * if sys.version_info[0] < 3: # <<<<<<<<<<<<<<
+ * self.filename = filename.encode()
+ * # decode bytes to str in python 3
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_sys); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_version_info); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_4, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_int_3, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 678; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":679
+ * # encode unicode to str in python 2
+ * if sys.version_info[0] < 3:
+ * self.filename = filename.encode() # <<<<<<<<<<<<<<
+ * # decode bytes to str in python 3
+ * elif sys.version_info[0] >= 3:
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_filename, __pyx_n_s_encode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_4 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (!(likely(PyString_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GIVEREF(__pyx_t_4);
+ __Pyx_GOTREF(__pyx_v_self->filename);
+ __Pyx_DECREF(__pyx_v_self->filename);
+ __pyx_v_self->filename = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L4;
+ }
+
+ /* "specfile.pyx":681
+ * self.filename = filename.encode()
+ * # decode bytes to str in python 3
+ * elif sys.version_info[0] >= 3: # <<<<<<<<<<<<<<
+ * self.filename = filename.decode()
+ * else:
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_sys); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_version_info); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyObject_RichCompare(__pyx_t_4, __pyx_int_3, Py_GE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 681; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":682
+ * # decode bytes to str in python 3
+ * elif sys.version_info[0] >= 3:
+ * self.filename = filename.decode() # <<<<<<<<<<<<<<
+ * else:
+ * self.filename = filename
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_filename, __pyx_n_s_decode); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (__pyx_t_5) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ } else {
+ __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (!(likely(PyString_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->filename);
+ __Pyx_DECREF(__pyx_v_self->filename);
+ __pyx_v_self->filename = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":684
+ * self.filename = filename.decode()
+ * else:
+ * self.filename = filename # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(self):
+ */
+ if (!(likely(PyString_CheckExact(__pyx_v_filename))||((__pyx_v_filename) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "str", Py_TYPE(__pyx_v_filename)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 684; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_filename;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->filename);
+ __Pyx_DECREF(__pyx_v_self->filename);
+ __pyx_v_self->filename = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":675
+ * self._handle_error(error)
+ *
+ * def __init__(self, filename): # <<<<<<<<<<<<<<
+ * if not isinstance(filename, str):
+ * # encode unicode to str in python 2
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("specfile.SpecFile.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":686
+ * self.filename = filename
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * """Destructor: Calls SfClose(self.handle)"""
+ * #SfClose makes a segmentation fault if file failed to open
+ */
+
+/* Python wrapper */
+static void __pyx_pw_8specfile_8SpecFile_5__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_8specfile_8SpecFile_5__dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_pf_8specfile_8SpecFile_4__dealloc__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_8specfile_8SpecFile_4__dealloc__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "specfile.pyx":689
+ * """Destructor: Calls SfClose(self.handle)"""
+ * #SfClose makes a segmentation fault if file failed to open
+ * if not self.__open_failed: # <<<<<<<<<<<<<<
+ * if specfile_wrapper.SfClose(self.handle):
+ * _logger.warning("Error while closing SpecFile")
+ */
+ __pyx_t_1 = ((!(__pyx_v_self->__pyx___open_failed != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "specfile.pyx":690
+ * #SfClose makes a segmentation fault if file failed to open
+ * if not self.__open_failed:
+ * if specfile_wrapper.SfClose(self.handle): # <<<<<<<<<<<<<<
+ * _logger.warning("Error while closing SpecFile")
+ *
+ */
+ __pyx_t_1 = (SfClose(__pyx_v_self->handle) != 0);
+ if (__pyx_t_1) {
+
+ /* "specfile.pyx":691
+ * if not self.__open_failed:
+ * if specfile_wrapper.SfClose(self.handle):
+ * _logger.warning("Error while closing SpecFile") # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warning); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":686
+ * self.filename = filename
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * """Destructor: Calls SfClose(self.handle)"""
+ * #SfClose makes a segmentation fault if file failed to open
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("specfile.SpecFile.__dealloc__", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "specfile.pyx":693
+ * _logger.warning("Error while closing SpecFile")
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """Return the number of scans in the SpecFile
+ * """
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_pw_8specfile_8SpecFile_7__len__(PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_6__len__[] = "Return the number of scans in the SpecFile\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_8specfile_8SpecFile_6__len__;
+#endif
+static Py_ssize_t __pyx_pw_8specfile_8SpecFile_7__len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_6__len__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_pf_8specfile_8SpecFile_6__len__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "specfile.pyx":696
+ * """Return the number of scans in the SpecFile
+ * """
+ * return specfile_wrapper.SfScanNo(self.handle) # <<<<<<<<<<<<<<
+ *
+ * def __iter__(self):
+ */
+ __pyx_r = SfScanNo(__pyx_v_self->handle);
+ goto __pyx_L0;
+
+ /* "specfile.pyx":693
+ * _logger.warning("Error while closing SpecFile")
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """Return the number of scans in the SpecFile
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+static PyObject *__pyx_gb_8specfile_8SpecFile_10generator1(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value); /* proto */
+
+/* "specfile.pyx":698
+ * return specfile_wrapper.SfScanNo(self.handle)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next :class:`Scan` in a SpecFile each time this method
+ * is called.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_9__iter__(PyObject *__pyx_v_self); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_8__iter__[] = "Return the next :class:`Scan` in a SpecFile each time this method\n is called.\n\n This usually happens when the python built-in function ``next()`` is\n called with a :class:`SpecFile` instance as a parameter, or when a\n :class:`SpecFile` instance is used as an iterator (e.g. in a ``for``\n loop).\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_8specfile_8SpecFile_8__iter__;
+#endif
+static PyObject *__pyx_pw_8specfile_8SpecFile_9__iter__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__iter__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_8__iter__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_8__iter__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *__pyx_cur_scope;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__iter__", 0);
+ __pyx_cur_scope = (struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)__pyx_tp_new_8specfile___pyx_scope_struct_1___iter__(__pyx_ptype_8specfile___pyx_scope_struct_1___iter__, __pyx_empty_tuple, NULL);
+ if (unlikely(!__pyx_cur_scope)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_cur_scope);
+ __pyx_cur_scope->__pyx_v_self = __pyx_v_self;
+ __Pyx_INCREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+ __Pyx_GIVEREF((PyObject *)__pyx_cur_scope->__pyx_v_self);
+ {
+ __pyx_GeneratorObject *gen = __Pyx_Generator_New((__pyx_generator_body_t) __pyx_gb_8specfile_8SpecFile_10generator1, (PyObject *) __pyx_cur_scope, __pyx_n_s_iter, __pyx_n_s_SpecFile___iter); if (unlikely(!gen)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_cur_scope);
+ __Pyx_RefNannyFinishContext();
+ return (PyObject *) gen;
+ }
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_gb_8specfile_8SpecFile_10generator1(__pyx_GeneratorObject *__pyx_generator, PyObject *__pyx_sent_value) /* generator body */
+{
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *__pyx_cur_scope = ((struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)__pyx_generator->closure);
+ PyObject *__pyx_r = NULL;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("None", 0);
+ switch (__pyx_generator->resume_label) {
+ case 0: goto __pyx_L3_first_run;
+ case 1: goto __pyx_L6_resume_from_yield;
+ default: /* CPython raises the right error here */
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __pyx_L3_first_run:;
+ if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":707
+ * loop).
+ * """
+ * for scan_index in range(len(self)): # <<<<<<<<<<<<<<
+ * yield Scan(self, scan_index)
+ *
+ */
+ __pyx_t_1 = PyObject_Length(((PyObject *)__pyx_cur_scope->__pyx_v_self)); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_cur_scope->__pyx_v_scan_index = __pyx_t_2;
+
+ /* "specfile.pyx":708
+ * """
+ * for scan_index in range(len(self)):
+ * yield Scan(self, scan_index) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, key):
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_Scan); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyInt_FromSsize_t(__pyx_cur_scope->__pyx_v_scan_index); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_6) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ }
+ __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, ((PyObject *)__pyx_cur_scope->__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_cur_scope->__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
+ __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ /* return from generator, yielding value */
+ __pyx_generator->resume_label = 1;
+ return __pyx_r;
+ __pyx_L6_resume_from_yield:;
+ __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
+ __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
+ if (unlikely(!__pyx_sent_value)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":698
+ * return specfile_wrapper.SfScanNo(self.handle)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next :class:`Scan` in a SpecFile each time this method
+ * is called.
+ */
+
+ /* function exit code */
+ PyErr_SetNone(PyExc_StopIteration);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("__iter__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_generator->resume_label = -1;
+ __Pyx_Generator_clear((PyObject*)__pyx_generator);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+}
+
+/* "specfile.pyx":710
+ * yield Scan(self, scan_index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a :class:`Scan` object.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_12__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_11__getitem__[] = "Return a :class:`Scan` object.\n\n This special method is called when a :class:`SpecFile` instance is\n accessed as a dictionary (e.g. ``sf[key]``).\n\n :param key: 0-based scan index or ``\"n.m\"`` key, where ``n`` is the scan\n number defined on the ``#S`` header line and ``m`` is the order\n :type key: int or str\n\n :return: Scan defined by its 0-based index or its ``\"n.m\"`` key\n :rtype: :class:`Scan`\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_8specfile_8SpecFile_11__getitem__;
+#endif
+static PyObject *__pyx_pw_8specfile_8SpecFile_12__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_11__getitem__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_11__getitem__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_key) {
+ PyObject *__pyx_v_msg = NULL;
+ PyObject *__pyx_v_scan_index = NULL;
+ PyObject *__pyx_v_number = NULL;
+ PyObject *__pyx_v_order = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *(*__pyx_t_11)(PyObject *);
+ int __pyx_t_12;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "specfile.pyx":723
+ * :rtype: :class:`Scan`
+ * """
+ * msg = "The scan identification key can be an integer representing " # <<<<<<<<<<<<<<
+ * msg += "the unique scan index or a string 'N.M' with N being the scan"
+ * msg += " number and M the order (eg '2.3')."
+ */
+ __Pyx_INCREF(__pyx_kp_s_The_scan_identification_key_can);
+ __pyx_v_msg = __pyx_kp_s_The_scan_identification_key_can;
+
+ /* "specfile.pyx":724
+ * """
+ * msg = "The scan identification key can be an integer representing "
+ * msg += "the unique scan index or a string 'N.M' with N being the scan" # <<<<<<<<<<<<<<
+ * msg += " number and M the order (eg '2.3')."
+ *
+ */
+ __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_msg, __pyx_kp_s_the_unique_scan_index_or_a_strin); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 724; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":725
+ * msg = "The scan identification key can be an integer representing "
+ * msg += "the unique scan index or a string 'N.M' with N being the scan"
+ * msg += " number and M the order (eg '2.3')." # <<<<<<<<<<<<<<
+ *
+ * if isinstance(key, int):
+ */
+ __pyx_t_1 = PyNumber_InPlaceAdd(__pyx_v_msg, __pyx_kp_s_number_and_M_the_order_eg_2_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":727
+ * msg += " number and M the order (eg '2.3')."
+ *
+ * if isinstance(key, int): # <<<<<<<<<<<<<<
+ * scan_index = key
+ * # allow negative index, like lists
+ */
+ __pyx_t_2 = PyInt_Check(__pyx_v_key);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":728
+ *
+ * if isinstance(key, int):
+ * scan_index = key # <<<<<<<<<<<<<<
+ * # allow negative index, like lists
+ * if scan_index < 0:
+ */
+ __Pyx_INCREF(__pyx_v_key);
+ __pyx_v_scan_index = __pyx_v_key;
+
+ /* "specfile.pyx":730
+ * scan_index = key
+ * # allow negative index, like lists
+ * if scan_index < 0: # <<<<<<<<<<<<<<
+ * scan_index = len(self) + scan_index
+ * else:
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_scan_index, __pyx_int_0, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":731
+ * # allow negative index, like lists
+ * if scan_index < 0:
+ * scan_index = len(self) + scan_index # <<<<<<<<<<<<<<
+ * else:
+ * try:
+ */
+ __pyx_t_4 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = PyNumber_Add(__pyx_t_1, __pyx_v_scan_index); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF_SET(__pyx_v_scan_index, __pyx_t_5);
+ __pyx_t_5 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":733
+ * scan_index = len(self) + scan_index
+ * else:
+ * try: # <<<<<<<<<<<<<<
+ * (number, order) = map(int, key.split("."))
+ * scan_index = self.index(number, order)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ /*try:*/ {
+
+ /* "specfile.pyx":734
+ * else:
+ * try:
+ * (number, order) = map(int, key.split(".")) # <<<<<<<<<<<<<<
+ * scan_index = self.index(number, order)
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_key, __pyx_n_s_split); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+ PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
+ __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_map, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_9 = PyTuple_GET_ITEM(sequence, 1);
+ } else {
+ __pyx_t_5 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_9 = PyList_GET_ITEM(sequence, 1);
+ }
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_9);
+ #else
+ __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ Py_ssize_t index = -1;
+ __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_11 = Py_TYPE(__pyx_t_10)->tp_iternext;
+ index = 0; __pyx_t_5 = __pyx_t_11(__pyx_t_10); if (unlikely(!__pyx_t_5)) goto __pyx_L13_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_5);
+ index = 1; __pyx_t_9 = __pyx_t_11(__pyx_t_10); if (unlikely(!__pyx_t_9)) goto __pyx_L13_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_11(__pyx_t_10), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __pyx_t_11 = NULL;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ goto __pyx_L14_unpacking_done;
+ __pyx_L13_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_11 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __pyx_L14_unpacking_done:;
+ }
+ __pyx_v_number = __pyx_t_5;
+ __pyx_t_5 = 0;
+ __pyx_v_order = __pyx_t_9;
+ __pyx_t_9 = 0;
+
+ /* "specfile.pyx":735
+ * try:
+ * (number, order) = map(int, key.split("."))
+ * scan_index = self.index(number, order) # <<<<<<<<<<<<<<
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ * # int() can raise a value error
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_index); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_5 = NULL;
+ __pyx_t_4 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ __pyx_t_4 = 1;
+ }
+ }
+ __pyx_t_10 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_number);
+ PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_4, __pyx_v_number);
+ __Pyx_GIVEREF(__pyx_v_number);
+ __Pyx_INCREF(__pyx_v_order);
+ PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_4, __pyx_v_order);
+ __Pyx_GIVEREF(__pyx_v_order);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L5_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_scan_index = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L12_try_end;
+ __pyx_L5_error:;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":736
+ * (number, order) = map(int, key.split("."))
+ * scan_index = self.index(number, order)
+ * except (ValueError, SfErrScanNotFound, KeyError): # <<<<<<<<<<<<<<
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" +
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrScanNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_builtin_ValueError) || PyErr_ExceptionMatches(__pyx_t_1) || PyErr_ExceptionMatches(__pyx_builtin_KeyError);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("specfile.SpecFile.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_9, &__pyx_t_10) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_GOTREF(__pyx_t_10);
+
+ /* "specfile.pyx":738
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" + # <<<<<<<<<<<<<<
+ * "', '".join( self.keys()) + "'")
+ * except AttributeError:
+ */
+ __pyx_t_5 = PyNumber_Add(__pyx_v_msg, __pyx_kp_s_Valid_keys); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "specfile.pyx":739
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" +
+ * "', '".join( self.keys()) + "'") # <<<<<<<<<<<<<<
+ * except AttributeError:
+ * # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ */
+ __pyx_t_14 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_keys); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __pyx_t_15 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_14))) {
+ __pyx_t_15 = PyMethod_GET_SELF(__pyx_t_14);
+ if (likely(__pyx_t_15)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_14);
+ __Pyx_INCREF(__pyx_t_15);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_14, function);
+ }
+ }
+ if (__pyx_t_15) {
+ __pyx_t_13 = __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_15); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+ } else {
+ __pyx_t_13 = __Pyx_PyObject_CallNoArg(__pyx_t_14); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_13);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ __pyx_t_14 = __Pyx_PyString_Join(__pyx_kp_s__27, __pyx_t_13); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+
+ /* "specfile.pyx":738
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" + # <<<<<<<<<<<<<<
+ * "', '".join( self.keys()) + "'")
+ * except AttributeError:
+ */
+ __pyx_t_13 = PyNumber_Add(__pyx_t_5, __pyx_t_14); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+
+ /* "specfile.pyx":739
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" +
+ * "', '".join( self.keys()) + "'") # <<<<<<<<<<<<<<
+ * except AttributeError:
+ * # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ */
+ __pyx_t_14 = PyNumber_Add(__pyx_t_13, __pyx_kp_s__28); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+
+ /* "specfile.pyx":738
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ * # int() can raise a value error
+ * raise KeyError(msg + "\nValid keys: '" + # <<<<<<<<<<<<<<
+ * "', '".join( self.keys()) + "'")
+ * except AttributeError:
+ */
+ __pyx_t_13 = PyTuple_New(1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ __pyx_t_14 = 0;
+ __pyx_t_14 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_t_13, NULL); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ __Pyx_Raise(__pyx_t_14, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ }
+
+ /* "specfile.pyx":740
+ * raise KeyError(msg + "\nValid keys: '" +
+ * "', '".join( self.keys()) + "'")
+ * except AttributeError: # <<<<<<<<<<<<<<
+ * # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ * raise TypeError(msg)
+ */
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_builtin_AttributeError);
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("specfile.SpecFile.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_10, &__pyx_t_9, &__pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "specfile.pyx":742
+ * except AttributeError:
+ * # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ * raise TypeError(msg) # <<<<<<<<<<<<<<
+ *
+ * if not 0 <= scan_index < len(self):
+ */
+ __pyx_t_14 = PyTuple_New(1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 742; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __Pyx_INCREF(__pyx_v_msg);
+ PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_v_msg);
+ __Pyx_GIVEREF(__pyx_v_msg);
+ __pyx_t_13 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_14, NULL); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 742; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ __Pyx_Raise(__pyx_t_13, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 742; __pyx_clineno = __LINE__; goto __pyx_L7_except_error;}
+ }
+ goto __pyx_L7_except_error;
+ __pyx_L7_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ goto __pyx_L1_error;
+ __pyx_L12_try_end:;
+ }
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":744
+ * raise TypeError(msg)
+ *
+ * if not 0 <= scan_index < len(self): # <<<<<<<<<<<<<<
+ * msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ * raise IndexError(msg)
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_int_0, __pyx_v_scan_index, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__Pyx_PyObject_IsTrue(__pyx_t_1)) {
+ __Pyx_DECREF(__pyx_t_1);
+ __pyx_t_4 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_scan_index, __pyx_t_9, Py_LT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_2 = ((!__pyx_t_3) != 0);
+ if (__pyx_t_2) {
+
+ /* "specfile.pyx":745
+ *
+ * if not 0 <= scan_index < len(self):
+ * msg = "Scan index must be in range 0-%d" % (len(self) - 1) # <<<<<<<<<<<<<<
+ * raise IndexError(msg)
+ *
+ */
+ __pyx_t_4 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 745; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = PyInt_FromSsize_t((__pyx_t_4 - 1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 745; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Scan_index_must_be_in_range_0_d, __pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 745; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_t_9);
+ __pyx_t_9 = 0;
+
+ /* "specfile.pyx":746
+ * if not 0 <= scan_index < len(self):
+ * msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ * raise IndexError(msg) # <<<<<<<<<<<<<<
+ *
+ * return Scan(self, scan_index)
+ */
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_INCREF(__pyx_v_msg);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_msg);
+ __Pyx_GIVEREF(__pyx_v_msg);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":748
+ * raise IndexError(msg)
+ *
+ * return Scan(self, scan_index) # <<<<<<<<<<<<<<
+ *
+ * def keys(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_Scan); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = NULL;
+ __pyx_t_4 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ __pyx_t_4 = 1;
+ }
+ }
+ __pyx_t_13 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ if (__pyx_t_10) {
+ PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ }
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_13, 0+__pyx_t_4, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_INCREF(__pyx_v_scan_index);
+ PyTuple_SET_ITEM(__pyx_t_13, 1+__pyx_t_4, __pyx_v_scan_index);
+ __Pyx_GIVEREF(__pyx_v_scan_index);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_13, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":710
+ * yield Scan(self, scan_index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a :class:`Scan` object.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_AddTraceback("specfile.SpecFile.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_msg);
+ __Pyx_XDECREF(__pyx_v_scan_index);
+ __Pyx_XDECREF(__pyx_v_number);
+ __Pyx_XDECREF(__pyx_v_order);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":750
+ * return Scan(self, scan_index)
+ *
+ * def keys(self): # <<<<<<<<<<<<<<
+ * """Returns list of scan keys (eg ``['1.1', '2.1',...]``).
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_14keys(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_13keys[] = "SpecFile.keys(self)\nReturns list of scan keys (eg ``['1.1', '2.1',...]``).\n\n :return: list of scan keys\n :rtype: list of strings\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_14keys(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("keys (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_13keys(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_13keys(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ PyObject *__pyx_v_ret_list = NULL;
+ PyObject *__pyx_v_list_of_numbers = NULL;
+ PyObject *__pyx_v_count = NULL;
+ PyObject *__pyx_v_number = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ Py_ssize_t __pyx_t_4;
+ PyObject *(*__pyx_t_5)(PyObject *);
+ int __pyx_t_6;
+ int __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("keys", 0);
+
+ /* "specfile.pyx":756
+ * :rtype: list of strings
+ * """
+ * ret_list = [] # <<<<<<<<<<<<<<
+ * list_of_numbers = self._list()
+ * count = {}
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 756; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_ret_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":757
+ * """
+ * ret_list = []
+ * list_of_numbers = self._list() # <<<<<<<<<<<<<<
+ * count = {}
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_list); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_list_of_numbers = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":758
+ * ret_list = []
+ * list_of_numbers = self._list()
+ * count = {} # <<<<<<<<<<<<<<
+ *
+ * for number in list_of_numbers:
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_count = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":760
+ * count = {}
+ *
+ * for number in list_of_numbers: # <<<<<<<<<<<<<<
+ * if not number in count:
+ * count[number] = 1
+ */
+ if (likely(PyList_CheckExact(__pyx_v_list_of_numbers)) || PyTuple_CheckExact(__pyx_v_list_of_numbers)) {
+ __pyx_t_1 = __pyx_v_list_of_numbers; __Pyx_INCREF(__pyx_t_1); __pyx_t_4 = 0;
+ __pyx_t_5 = NULL;
+ } else {
+ __pyx_t_4 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_list_of_numbers); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_5)) {
+ if (likely(PyList_CheckExact(__pyx_t_1))) {
+ if (__pyx_t_4 >= PyList_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_4 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_4); __Pyx_INCREF(__pyx_t_2); __pyx_t_4++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_4); __pyx_t_4++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_2 = __pyx_t_5(__pyx_t_1);
+ if (unlikely(!__pyx_t_2)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 760; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_number, __pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "specfile.pyx":761
+ *
+ * for number in list_of_numbers:
+ * if not number in count: # <<<<<<<<<<<<<<
+ * count[number] = 1
+ * else:
+ */
+ __pyx_t_6 = (__Pyx_PyDict_Contains(__pyx_v_number, __pyx_v_count, Py_NE)); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 761; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = (__pyx_t_6 != 0);
+ if (__pyx_t_7) {
+
+ /* "specfile.pyx":762
+ * for number in list_of_numbers:
+ * if not number in count:
+ * count[number] = 1 # <<<<<<<<<<<<<<
+ * else:
+ * count[number] += 1
+ */
+ if (unlikely(PyDict_SetItem(__pyx_v_count, __pyx_v_number, __pyx_int_1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":764
+ * count[number] = 1
+ * else:
+ * count[number] += 1 # <<<<<<<<<<<<<<
+ * ret_list.append(u'%d.%d' % (number, count[number]))
+ *
+ */
+ __Pyx_INCREF(__pyx_v_number);
+ __pyx_t_2 = __pyx_v_number;
+ __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_count, __pyx_t_2); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = PyNumber_InPlaceAdd(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (unlikely(PyDict_SetItem(__pyx_v_count, __pyx_t_2, __pyx_t_8) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L5:;
+
+ /* "specfile.pyx":765
+ * else:
+ * count[number] += 1
+ * ret_list.append(u'%d.%d' % (number, count[number])) # <<<<<<<<<<<<<<
+ *
+ * return ret_list
+ */
+ __pyx_t_2 = __Pyx_PyDict_GetItem(__pyx_v_count, __pyx_v_number); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 765; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_number);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_number);
+ __Pyx_GIVEREF(__pyx_v_number);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = PyUnicode_Format(__pyx_kp_u_d_d, __pyx_t_8); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_ret_list, __pyx_t_2); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 765; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":760
+ * count = {}
+ *
+ * for number in list_of_numbers: # <<<<<<<<<<<<<<
+ * if not number in count:
+ * count[number] = 1
+ */
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":767
+ * ret_list.append(u'%d.%d' % (number, count[number]))
+ *
+ * return ret_list # <<<<<<<<<<<<<<
+ *
+ * def __contains__(self, key):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_ret_list);
+ __pyx_r = __pyx_v_ret_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":750
+ * return Scan(self, scan_index)
+ *
+ * def keys(self): # <<<<<<<<<<<<<<
+ * """Returns list of scan keys (eg ``['1.1', '2.1',...]``).
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.keys", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_ret_list);
+ __Pyx_XDECREF(__pyx_v_list_of_numbers);
+ __Pyx_XDECREF(__pyx_v_count);
+ __Pyx_XDECREF(__pyx_v_number);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":769
+ * return ret_list
+ *
+ * def __contains__(self, key): # <<<<<<<<<<<<<<
+ * """Return ``True`` if ``key`` is a valid scan key.
+ * Valid keys can be a string such as ``"1.1"`` or a 0-based scan index.
+ */
+
+/* Python wrapper */
+static int __pyx_pw_8specfile_8SpecFile_16__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_15__contains__[] = "Return ``True`` if ``key`` is a valid scan key.\n Valid keys can be a string such as ``\"1.1\"`` or a 0-based scan index.\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_8specfile_8SpecFile_15__contains__;
+#endif
+static int __pyx_pw_8specfile_8SpecFile_16__contains__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__contains__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_15__contains__(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_8specfile_8SpecFile_15__contains__(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_key) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ Py_ssize_t __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__contains__", 0);
+
+ /* "specfile.pyx":773
+ * Valid keys can be a string such as ``"1.1"`` or a 0-based scan index.
+ * """
+ * return key in (self.keys() + list(range(len(self)))) # <<<<<<<<<<<<<<
+ *
+ * def _get_error_string(self, error_code):
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_keys); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyNumber_Add(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_5 = (__Pyx_PySequence_Contains(__pyx_v_key, __pyx_t_3, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 773; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_5;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":769
+ * return ret_list
+ *
+ * def __contains__(self, key): # <<<<<<<<<<<<<<
+ * """Return ``True`` if ``key`` is a valid scan key.
+ * Valid keys can be a string such as ``"1.1"`` or a 0-based scan index.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.SpecFile.__contains__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":775
+ * return key in (self.keys() + list(range(len(self))))
+ *
+ * def _get_error_string(self, error_code): # <<<<<<<<<<<<<<
+ * """Returns the error message corresponding to the error code.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_18_get_error_string(PyObject *__pyx_v_self, PyObject *__pyx_v_error_code); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_17_get_error_string[] = "SpecFile._get_error_string(self, error_code)\nReturns the error message corresponding to the error code.\n \n :param code: Error code\n :type code: int\n :return: Human readable error message\n :rtype: str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_18_get_error_string(PyObject *__pyx_v_self, PyObject *__pyx_v_error_code) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_get_error_string (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_17_get_error_string(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_error_code));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_17_get_error_string(CYTHON_UNUSED struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_error_code) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_get_error_string", 0);
+
+ /* "specfile.pyx":783
+ * :rtype: str
+ * """
+ * return (<bytes> specfile_wrapper.SfError(error_code)).decode() # <<<<<<<<<<<<<<
+ *
+ * def _handle_error(self, error_code):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_As_int(__pyx_v_error_code); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyBytes_FromString(SfError(__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (unlikely(__pyx_t_2 == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "decode");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = __Pyx_decode_bytes(((PyObject*)__pyx_t_2), 0, PY_SSIZE_T_MAX, NULL, NULL, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":775
+ * return key in (self.keys() + list(range(len(self))))
+ *
+ * def _get_error_string(self, error_code): # <<<<<<<<<<<<<<
+ * """Returns the error message corresponding to the error code.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.SpecFile._get_error_string", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":785
+ * return (<bytes> specfile_wrapper.SfError(error_code)).decode()
+ *
+ * def _handle_error(self, error_code): # <<<<<<<<<<<<<<
+ * """Inspect error code, raise adequate error type if necessary.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_20_handle_error(PyObject *__pyx_v_self, PyObject *__pyx_v_error_code); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_19_handle_error[] = "SpecFile._handle_error(self, error_code)\nInspect error code, raise adequate error type if necessary.\n \n :param code: Error code\n :type code: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_20_handle_error(PyObject *__pyx_v_self, PyObject *__pyx_v_error_code) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_handle_error (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_19_handle_error(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_error_code));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_19_handle_error(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_error_code) {
+ PyObject *__pyx_v_error_message = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_handle_error", 0);
+
+ /* "specfile.pyx":791
+ * :type code: int
+ * """
+ * error_message = self._get_error_string(error_code) # <<<<<<<<<<<<<<
+ * if error_code in ERRORS:
+ * raise ERRORS[error_code](error_message)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_error_string); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_error_code); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ __Pyx_INCREF(__pyx_v_error_code);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_v_error_code);
+ __Pyx_GIVEREF(__pyx_v_error_code);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_error_message = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":792
+ * """
+ * error_message = self._get_error_string(error_code)
+ * if error_code in ERRORS: # <<<<<<<<<<<<<<
+ * raise ERRORS[error_code](error_message)
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = (__Pyx_PySequence_Contains(__pyx_v_error_code, __pyx_t_1, Py_EQ)); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = (__pyx_t_5 != 0);
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":793
+ * error_message = self._get_error_string(error_code)
+ * if error_code in ERRORS:
+ * raise ERRORS[error_code](error_message) # <<<<<<<<<<<<<<
+ *
+ * def index(self, scan_number, scan_order=1):
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_ERRORS); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = PyObject_GetItem(__pyx_t_2, __pyx_v_error_code); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_error_message); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ __Pyx_INCREF(__pyx_v_error_message);
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_error_message);
+ __Pyx_GIVEREF(__pyx_v_error_message);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":785
+ * return (<bytes> specfile_wrapper.SfError(error_code)).decode()
+ *
+ * def _handle_error(self, error_code): # <<<<<<<<<<<<<<
+ * """Inspect error code, raise adequate error type if necessary.
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("specfile.SpecFile._handle_error", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_error_message);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":795
+ * raise ERRORS[error_code](error_message)
+ *
+ * def index(self, scan_number, scan_order=1): # <<<<<<<<<<<<<<
+ * """Returns scan index from scan number and order.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_22index(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_21index[] = "SpecFile.index(self, scan_number, scan_order=1)\nReturns scan index from scan number and order.\n \n :param scan_number: Scan number (possibly non-unique). \n :type scan_number: int\n :param scan_order: Scan order. \n :type scan_order: int default 1\n\n :return: Unique scan index\n :rtype: int\n \n \n Scan indices are increasing from ``0`` to ``len(self)-1`` in the\n order in which they appear in the file.\n Scan numbers are defined by users and are not necessarily unique.\n The scan order for a given scan number increments each time the scan \n number appers in a given file.\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_22index(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_number = 0;
+ PyObject *__pyx_v_scan_order = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("index (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_number,&__pyx_n_s_scan_order,0};
+ PyObject* values[2] = {0,0};
+ values[1] = ((PyObject *)__pyx_int_1);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_number)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_order);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "index") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_scan_number = values[0];
+ __pyx_v_scan_order = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("index", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_21index(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_number, __pyx_v_scan_order);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_21index(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_number, PyObject *__pyx_v_scan_order) {
+ PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ long __pyx_t_1;
+ long __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("index", 0);
+
+ /* "specfile.pyx":813
+ * number appers in a given file.
+ * """
+ * idx = specfile_wrapper.SfIndex(self.handle, scan_number, scan_order) # <<<<<<<<<<<<<<
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ */
+ __pyx_t_1 = __Pyx_PyInt_As_long(__pyx_v_scan_number); if (unlikely((__pyx_t_1 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyInt_As_long(__pyx_v_scan_order); if (unlikely((__pyx_t_2 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __Pyx_PyInt_From_long(SfIndex(__pyx_v_self->handle, __pyx_t_1, __pyx_t_2)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_idx = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "specfile.pyx":814
+ * """
+ * idx = specfile_wrapper.SfIndex(self.handle, scan_number, scan_order)
+ * if idx == -1: # <<<<<<<<<<<<<<
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return idx - 1
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_idx, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":815
+ * idx = specfile_wrapper.SfIndex(self.handle, scan_number, scan_order)
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND) # <<<<<<<<<<<<<<
+ * return idx - 1
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_SCAN_NOT_FOUND); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":816
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return idx - 1 # <<<<<<<<<<<<<<
+ *
+ * def number(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = PyNumber_Subtract(__pyx_v_idx, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":795
+ * raise ERRORS[error_code](error_message)
+ *
+ * def index(self, scan_number, scan_order=1): # <<<<<<<<<<<<<<
+ * """Returns scan index from scan number and order.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":818
+ * return idx - 1
+ *
+ * def number(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns scan number from scan index.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_24number(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_23number[] = "SpecFile.number(self, scan_index)\nReturns scan number from scan index.\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: User defined scan number.\n :rtype: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_24number(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("number (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_23number(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_23number(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ long __pyx_v_idx;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ long __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("number", 0);
+
+ /* "specfile.pyx":828
+ * :rtype: int
+ * """
+ * idx = specfile_wrapper.SfNumber(self.handle, scan_index + 1) # <<<<<<<<<<<<<<
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_2 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_idx = SfNumber(__pyx_v_self->handle, __pyx_t_2);
+
+ /* "specfile.pyx":829
+ * """
+ * idx = specfile_wrapper.SfNumber(self.handle, scan_index + 1)
+ * if idx == -1: # <<<<<<<<<<<<<<
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return idx
+ */
+ __pyx_t_3 = ((__pyx_v_idx == -1) != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":830
+ * idx = specfile_wrapper.SfNumber(self.handle, scan_index + 1)
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND) # <<<<<<<<<<<<<<
+ * return idx
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_SCAN_NOT_FOUND); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":831
+ * if idx == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return idx # <<<<<<<<<<<<<<
+ *
+ * def order(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_idx); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":818
+ * return idx - 1
+ *
+ * def number(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns scan number from scan index.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.number", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":833
+ * return idx
+ *
+ * def order(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns scan order from scan index.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_26order(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_25order[] = "SpecFile.order(self, scan_index)\nReturns scan order from scan index.\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Scan order (sequential number incrementing each time a\n non-unique occurrence of a scan number is encountered).\n :rtype: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_26order(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("order (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_25order(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_25order(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ long __pyx_v_ordr;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ long __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("order", 0);
+
+ /* "specfile.pyx":844
+ * :rtype: int
+ * """
+ * ordr = specfile_wrapper.SfOrder(self.handle, scan_index + 1) # <<<<<<<<<<<<<<
+ * if ordr == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_2 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_ordr = SfOrder(__pyx_v_self->handle, __pyx_t_2);
+
+ /* "specfile.pyx":845
+ * """
+ * ordr = specfile_wrapper.SfOrder(self.handle, scan_index + 1)
+ * if ordr == -1: # <<<<<<<<<<<<<<
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return ordr
+ */
+ __pyx_t_3 = ((__pyx_v_ordr == -1) != 0);
+ if (__pyx_t_3) {
+
+ /* "specfile.pyx":846
+ * ordr = specfile_wrapper.SfOrder(self.handle, scan_index + 1)
+ * if ordr == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND) # <<<<<<<<<<<<<<
+ * return ordr
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_SCAN_NOT_FOUND); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":847
+ * if ordr == -1:
+ * self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ * return ordr # <<<<<<<<<<<<<<
+ *
+ * def _list(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_ordr); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":833
+ * return idx
+ *
+ * def order(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns scan order from scan index.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.order", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":849
+ * return ordr
+ *
+ * def _list(self): # <<<<<<<<<<<<<<
+ * """see documentation of :meth:`list`
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_28_list(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_27_list[] = "SpecFile._list(self)\nsee documentation of :meth:`list`\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_28_list(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_list (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_27_list(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_27_list(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ long *__pyx_v_scan_numbers;
+ int __pyx_v_error;
+ PyObject *__pyx_v_ret_list = NULL;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_list", 0);
+
+ /* "specfile.pyx":854
+ * cdef:
+ * long *scan_numbers
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * scan_numbers = specfile_wrapper.SfList(self.handle, &error)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":856
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * scan_numbers = specfile_wrapper.SfList(self.handle, &error) # <<<<<<<<<<<<<<
+ * self._handle_error(error)
+ *
+ */
+ __pyx_v_scan_numbers = SfList(__pyx_v_self->handle, (&__pyx_v_error));
+
+ /* "specfile.pyx":857
+ *
+ * scan_numbers = specfile_wrapper.SfList(self.handle, &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * ret_list = []
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 857; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":859
+ * self._handle_error(error)
+ *
+ * ret_list = [] # <<<<<<<<<<<<<<
+ * for i in range(len(self)):
+ * ret_list.append(scan_numbers[i])
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 859; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_ret_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":860
+ *
+ * ret_list = []
+ * for i in range(len(self)): # <<<<<<<<<<<<<<
+ * ret_list.append(scan_numbers[i])
+ *
+ */
+ __pyx_t_7 = PyObject_Length(((PyObject *)__pyx_v_self)); if (unlikely(__pyx_t_7 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":861
+ * ret_list = []
+ * for i in range(len(self)):
+ * ret_list.append(scan_numbers[i]) # <<<<<<<<<<<<<<
+ *
+ * free(scan_numbers)
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_long((__pyx_v_scan_numbers[__pyx_v_i])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_ret_list, __pyx_t_1); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":863
+ * ret_list.append(scan_numbers[i])
+ *
+ * free(scan_numbers) # <<<<<<<<<<<<<<
+ * return ret_list
+ *
+ */
+ free(__pyx_v_scan_numbers);
+
+ /* "specfile.pyx":864
+ *
+ * free(scan_numbers)
+ * return ret_list # <<<<<<<<<<<<<<
+ *
+ * def list(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_ret_list);
+ __pyx_r = __pyx_v_ret_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":849
+ * return ordr
+ *
+ * def _list(self): # <<<<<<<<<<<<<<
+ * """see documentation of :meth:`list`
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("specfile.SpecFile._list", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_ret_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":866
+ * return ret_list
+ *
+ * def list(self): # <<<<<<<<<<<<<<
+ * """Returns list (1D numpy array) of scan numbers in SpecFile.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_30list(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_29list[] = "SpecFile.list(self)\nReturns list (1D numpy array) of scan numbers in SpecFile.\n\n :return: list of scan numbers (from `` #S`` lines) in the same order\n as in the original SpecFile (e.g ``[1, 1, 2, 3, \342\200\246]``).\n :rtype: numpy array\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_30list(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("list (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_29list(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_29list(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("list", 0);
+
+ /* "specfile.pyx":875
+ * # this method is overloaded in specfilewrapper to output a string
+ * # representation of the list
+ * return self._list() # <<<<<<<<<<<<<<
+ *
+ * def data(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_list); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":866
+ * return ret_list
+ *
+ * def list(self): # <<<<<<<<<<<<<<
+ * """Returns list (1D numpy array) of scan numbers in SpecFile.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("specfile.SpecFile.list", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":877
+ * return self._list()
+ *
+ * def data(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns data for the specified scan index.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_32data(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_31data[] = "SpecFile.data(self, scan_index)\nReturns data for the specified scan index.\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Complete scan data as a 2D array of doubles\n :rtype: numpy.ndarray\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_32data(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_31data(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_31data(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ double **__pyx_v_mydata;
+ long *__pyx_v_data_info;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_v_error;
+ long __pyx_v_nlines;
+ long __pyx_v_ncolumns;
+ CYTHON_UNUSED long __pyx_v_regular;
+ CYTHON_UNUSED int __pyx_v_sfdata_error;
+ PyArrayObject *__pyx_v_ret_array = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_t_8;
+ long __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data", 0);
+
+ /* "specfile.pyx":891
+ * long* data_info
+ * int i, j
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ * long nlines, ncolumns, regular
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":895
+ *
+ * sfdata_error = specfile_wrapper.SfData(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &mydata,
+ * &data_info,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 895; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":894
+ * long nlines, ncolumns, regular
+ *
+ * sfdata_error = specfile_wrapper.SfData(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &mydata,
+ */
+ __pyx_v_sfdata_error = SfData(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_mydata), (&__pyx_v_data_info), (&__pyx_v_error));
+
+ /* "specfile.pyx":899
+ * &data_info,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * if <long>data_info != 0:
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":901
+ * self._handle_error(error)
+ *
+ * if <long>data_info != 0: # <<<<<<<<<<<<<<
+ * nlines = data_info[0]
+ * ncolumns = data_info[1]
+ */
+ __pyx_t_8 = ((((long)__pyx_v_data_info) != 0) != 0);
+ if (__pyx_t_8) {
+
+ /* "specfile.pyx":902
+ *
+ * if <long>data_info != 0:
+ * nlines = data_info[0] # <<<<<<<<<<<<<<
+ * ncolumns = data_info[1]
+ * regular = data_info[2]
+ */
+ __pyx_v_nlines = (__pyx_v_data_info[0]);
+
+ /* "specfile.pyx":903
+ * if <long>data_info != 0:
+ * nlines = data_info[0]
+ * ncolumns = data_info[1] # <<<<<<<<<<<<<<
+ * regular = data_info[2]
+ * else:
+ */
+ __pyx_v_ncolumns = (__pyx_v_data_info[1]);
+
+ /* "specfile.pyx":904
+ * nlines = data_info[0]
+ * ncolumns = data_info[1]
+ * regular = data_info[2] # <<<<<<<<<<<<<<
+ * else:
+ * nlines = 0
+ */
+ __pyx_v_regular = (__pyx_v_data_info[2]);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "specfile.pyx":906
+ * regular = data_info[2]
+ * else:
+ * nlines = 0 # <<<<<<<<<<<<<<
+ * ncolumns = 0
+ * regular = 0
+ */
+ __pyx_v_nlines = 0;
+
+ /* "specfile.pyx":907
+ * else:
+ * nlines = 0
+ * ncolumns = 0 # <<<<<<<<<<<<<<
+ * regular = 0
+ *
+ */
+ __pyx_v_ncolumns = 0;
+
+ /* "specfile.pyx":908
+ * nlines = 0
+ * ncolumns = 0
+ * regular = 0 # <<<<<<<<<<<<<<
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns),
+ */
+ __pyx_v_regular = 0;
+ }
+ __pyx_L3:;
+
+ /* "specfile.pyx":910
+ * regular = 0
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_nlines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = __Pyx_PyInt_From_long(__pyx_v_ncolumns); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_1 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "specfile.pyx":911
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns),
+ * dtype=numpy.double) # <<<<<<<<<<<<<<
+ * for i in range(nlines):
+ * for j in range(ncolumns):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "specfile.pyx":910
+ * regular = 0
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (!(likely(((__pyx_t_6) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_6, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_ret_array = ((PyArrayObject *)__pyx_t_6);
+ __pyx_t_6 = 0;
+
+ /* "specfile.pyx":912
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns),
+ * dtype=numpy.double)
+ * for i in range(nlines): # <<<<<<<<<<<<<<
+ * for j in range(ncolumns):
+ * ret_array[i, j] = mydata[i][j]
+ */
+ __pyx_t_3 = __pyx_v_nlines;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "specfile.pyx":913
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ * for j in range(ncolumns): # <<<<<<<<<<<<<<
+ * ret_array[i, j] = mydata[i][j]
+ *
+ */
+ __pyx_t_9 = __pyx_v_ncolumns;
+ for (__pyx_t_10 = 0; __pyx_t_10 < __pyx_t_9; __pyx_t_10+=1) {
+ __pyx_v_j = __pyx_t_10;
+
+ /* "specfile.pyx":914
+ * for i in range(nlines):
+ * for j in range(ncolumns):
+ * ret_array[i, j] = mydata[i][j] # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines)
+ */
+ __pyx_t_6 = PyFloat_FromDouble(((__pyx_v_mydata[__pyx_v_i])[__pyx_v_j])); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_j); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_5 = 0;
+ __pyx_t_7 = 0;
+ if (unlikely(PyObject_SetItem(((PyObject *)__pyx_v_ret_array), __pyx_t_4, __pyx_t_6) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ }
+
+ /* "specfile.pyx":916
+ * ret_array[i, j] = mydata[i][j]
+ *
+ * specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines) # <<<<<<<<<<<<<<
+ * free(data_info)
+ * return ret_array
+ */
+ freeArrNZ(((void ***)(&__pyx_v_mydata)), __pyx_v_nlines);
+
+ /* "specfile.pyx":917
+ *
+ * specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines)
+ * free(data_info) # <<<<<<<<<<<<<<
+ * return ret_array
+ *
+ */
+ free(__pyx_v_data_info);
+
+ /* "specfile.pyx":918
+ * specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines)
+ * free(data_info)
+ * return ret_array # <<<<<<<<<<<<<<
+ *
+ * def data_column_by_name(self, scan_index, label):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_ret_array));
+ __pyx_r = ((PyObject *)__pyx_v_ret_array);
+ goto __pyx_L0;
+
+ /* "specfile.pyx":877
+ * return self._list()
+ *
+ * def data(self, scan_index): # <<<<<<<<<<<<<<
+ * """Returns data for the specified scan index.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.data", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_ret_array);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":920
+ * return ret_array
+ *
+ * def data_column_by_name(self, scan_index, label): # <<<<<<<<<<<<<<
+ * """Returns data column for the specified scan index and column label.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_34data_column_by_name(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_33data_column_by_name[] = "SpecFile.data_column_by_name(self, scan_index, label)\nReturns data column for the specified scan index and column label.\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n :param label: Label of data column, as defined in the ``#L`` line\n of the scan header.\n :type label: str\n\n :return: Data column as a 1D array of doubles\n :rtype: numpy.ndarray\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_34data_column_by_name(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ PyObject *__pyx_v_label = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("data_column_by_name (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,&__pyx_n_s_label,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_label)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("data_column_by_name", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "data_column_by_name") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_scan_index = values[0];
+ __pyx_v_label = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("data_column_by_name", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_33data_column_by_name(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index, __pyx_v_label);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_33data_column_by_name(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_label) {
+ double *__pyx_v_data_column;
+ long __pyx_v_i;
+ long __pyx_v_nlines;
+ int __pyx_v_error;
+ PyArrayObject *__pyx_v_ret_array = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ long __pyx_t_6;
+ char *__pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ long __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("data_column_by_name", 0);
+ __Pyx_INCREF(__pyx_v_label);
+
+ /* "specfile.pyx":936
+ * double* data_column
+ * long i, nlines
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * label = _string_to_char_star(label)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":938
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * label = _string_to_char_star(label) # <<<<<<<<<<<<<<
+ *
+ * nlines = specfile_wrapper.SfDataColByName(self.handle,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_string_to_char_star); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_label); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_label);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_label);
+ __Pyx_GIVEREF(__pyx_v_label);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_label, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":941
+ *
+ * nlines = specfile_wrapper.SfDataColByName(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * label,
+ * &data_column,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_6 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 941; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":942
+ * nlines = specfile_wrapper.SfDataColByName(self.handle,
+ * scan_index + 1,
+ * label, # <<<<<<<<<<<<<<
+ * &data_column,
+ * &error)
+ */
+ __pyx_t_7 = __Pyx_PyObject_AsString(__pyx_v_label); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":940
+ * label = _string_to_char_star(label)
+ *
+ * nlines = specfile_wrapper.SfDataColByName(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * label,
+ */
+ __pyx_v_nlines = SfDataColByName(__pyx_v_self->handle, __pyx_t_6, __pyx_t_7, (&__pyx_v_data_column), (&__pyx_v_error));
+
+ /* "specfile.pyx":945
+ * &data_column,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,),
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":947
+ * self._handle_error(error)
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_nlines); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = PyDict_New(); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+
+ /* "specfile.pyx":948
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,),
+ * dtype=numpy.double) # <<<<<<<<<<<<<<
+ * for i in range(nlines):
+ * ret_array[i] = data_column[i]
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 948; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":947
+ * self._handle_error(error)
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_1, __pyx_t_8); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (!(likely(((__pyx_t_4) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_4, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_ret_array = ((PyArrayObject *)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":949
+ * cdef numpy.ndarray ret_array = numpy.empty((nlines,),
+ * dtype=numpy.double)
+ * for i in range(nlines): # <<<<<<<<<<<<<<
+ * ret_array[i] = data_column[i]
+ *
+ */
+ __pyx_t_6 = __pyx_v_nlines;
+ for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_6; __pyx_t_9+=1) {
+ __pyx_v_i = __pyx_t_9;
+
+ /* "specfile.pyx":950
+ * dtype=numpy.double)
+ * for i in range(nlines):
+ * ret_array[i] = data_column[i] # <<<<<<<<<<<<<<
+ *
+ * free(data_column)
+ */
+ __pyx_t_4 = PyFloat_FromDouble((__pyx_v_data_column[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_ret_array), __pyx_v_i, __pyx_t_4, long, 1, __Pyx_PyInt_From_long, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+
+ /* "specfile.pyx":952
+ * ret_array[i] = data_column[i]
+ *
+ * free(data_column) # <<<<<<<<<<<<<<
+ * return ret_array
+ *
+ */
+ free(__pyx_v_data_column);
+
+ /* "specfile.pyx":953
+ *
+ * free(data_column)
+ * return ret_array # <<<<<<<<<<<<<<
+ *
+ * def scan_header(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_ret_array));
+ __pyx_r = ((PyObject *)__pyx_v_ret_array);
+ goto __pyx_L0;
+
+ /* "specfile.pyx":920
+ * return ret_array
+ *
+ * def data_column_by_name(self, scan_index, label): # <<<<<<<<<<<<<<
+ * """Returns data column for the specified scan index and column label.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.data_column_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_ret_array);
+ __Pyx_XDECREF(__pyx_v_label);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":955
+ * return ret_array
+ *
+ * def scan_header(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return list of scan header lines.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_36scan_header(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_35scan_header[] = "SpecFile.scan_header(self, scan_index)\nReturn list of scan header lines.\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: List of raw scan header lines\n :rtype: list of str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_36scan_header(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("scan_header (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_35scan_header(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_35scan_header(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ char **__pyx_v_lines;
+ int __pyx_v_error;
+ long __pyx_v_nlines;
+ PyObject *__pyx_v_lines_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("scan_header", 0);
+
+ /* "specfile.pyx":967
+ * cdef:
+ * char** lines
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nlines = specfile_wrapper.SfHeader(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 967; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":970
+ *
+ * nlines = specfile_wrapper.SfHeader(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * "", # no pattern matching
+ * &lines,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 970; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":969
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nlines = specfile_wrapper.SfHeader(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * "", # no pattern matching
+ */
+ __pyx_v_nlines = SfHeader(__pyx_v_self->handle, __pyx_t_3, __pyx_k__29, (&__pyx_v_lines), (&__pyx_v_error));
+
+ /* "specfile.pyx":975
+ * &error)
+ *
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * lines_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":977
+ * self._handle_error(error)
+ *
+ * lines_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode()
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_lines_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":978
+ *
+ * lines_list = []
+ * for i in range(nlines): # <<<<<<<<<<<<<<
+ * line = <bytes>lines[i].decode()
+ * lines_list.append(line)
+ */
+ __pyx_t_3 = __pyx_v_nlines;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":979
+ * lines_list = []
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode() # <<<<<<<<<<<<<<
+ * lines_list.append(line)
+ *
+ */
+ __pyx_t_9 = (__pyx_v_lines[__pyx_v_i]);
+ __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_9, 0, strlen(__pyx_t_9), NULL, NULL, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __pyx_t_1;
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_line, ((PyObject*)__pyx_t_4));
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":980
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode()
+ * lines_list.append(line) # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ */
+ __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_lines_list, __pyx_v_line); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 980; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":982
+ * lines_list.append(line)
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines) # <<<<<<<<<<<<<<
+ * return lines_list
+ *
+ */
+ freeArrNZ(((void ***)(&__pyx_v_lines)), __pyx_v_nlines);
+
+ /* "specfile.pyx":983
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ * return lines_list # <<<<<<<<<<<<<<
+ *
+ * def file_header(self, scan_index=0):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_lines_list);
+ __pyx_r = __pyx_v_lines_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":955
+ * return ret_array
+ *
+ * def scan_header(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return list of scan header lines.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.scan_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_lines_list);
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":985
+ * return lines_list
+ *
+ * def file_header(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return list of file header lines.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_38file_header(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_37file_header[] = "SpecFile.file_header(self, scan_index=0)\nReturn list of file header lines.\n \n A file header contains all lines between a ``#F`` header line and\n a ``#S`` header line (start of scan). We need to specify a scan\n number because there can be more than one file header in a given file.\n A file header applies to all subsequent scans, until a new file\n header is defined.\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: List of raw file header lines\n :rtype: list of str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_38file_header(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("file_header (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,0};
+ PyObject* values[1] = {0};
+ values[0] = ((PyObject *)__pyx_int_0);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index);
+ if (value) { values[0] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "file_header") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_scan_index = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("file_header", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.file_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_37file_header(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_37file_header(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ char **__pyx_v_lines;
+ int __pyx_v_error;
+ long __pyx_v_nlines;
+ PyObject *__pyx_v_lines_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_v_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("file_header", 0);
+
+ /* "specfile.pyx":1003
+ * cdef:
+ * char** lines
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nlines = specfile_wrapper.SfFileHeader(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1003; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1006
+ *
+ * nlines = specfile_wrapper.SfFileHeader(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * "", # no pattern matching
+ * &lines,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1005
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nlines = specfile_wrapper.SfFileHeader(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * "", # no pattern matching
+ */
+ __pyx_v_nlines = SfFileHeader(__pyx_v_self->handle, __pyx_t_3, __pyx_k__29, (&__pyx_v_lines), (&__pyx_v_error));
+
+ /* "specfile.pyx":1010
+ * &lines,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * lines_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1012
+ * self._handle_error(error)
+ *
+ * lines_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode()
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_lines_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1013
+ *
+ * lines_list = []
+ * for i in range(nlines): # <<<<<<<<<<<<<<
+ * line = <bytes>lines[i].decode()
+ * lines_list.append(line)
+ */
+ __pyx_t_3 = __pyx_v_nlines;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":1014
+ * lines_list = []
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode() # <<<<<<<<<<<<<<
+ * lines_list.append(line)
+ *
+ */
+ __pyx_t_9 = (__pyx_v_lines[__pyx_v_i]);
+ __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_9, 0, strlen(__pyx_t_9), NULL, NULL, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __pyx_t_1;
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_line, ((PyObject*)__pyx_t_4));
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1015
+ * for i in range(nlines):
+ * line = <bytes>lines[i].decode()
+ * lines_list.append(line) # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ */
+ __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_lines_list, __pyx_v_line); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":1017
+ * lines_list.append(line)
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines) # <<<<<<<<<<<<<<
+ * return lines_list
+ *
+ */
+ freeArrNZ(((void ***)(&__pyx_v_lines)), __pyx_v_nlines);
+
+ /* "specfile.pyx":1018
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ * return lines_list # <<<<<<<<<<<<<<
+ *
+ * def columns(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_lines_list);
+ __pyx_r = __pyx_v_lines_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":985
+ * return lines_list
+ *
+ * def file_header(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return list of file header lines.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.file_header", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_lines_list);
+ __Pyx_XDECREF(__pyx_v_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1020
+ * return lines_list
+ *
+ * def columns(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return number of columns in a scan from the ``#N`` header line
+ * (without ``#N`` and scan number)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_40columns(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_39columns[] = "SpecFile.columns(self, scan_index)\nReturn number of columns in a scan from the ``#N`` header line\n (without ``#N`` and scan number)\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Number of columns in scan from ``#N`` line\n :rtype: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_40columns(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("columns (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_39columns(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_39columns(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ long __pyx_v_ncolumns;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("columns", 0);
+
+ /* "specfile.pyx":1032
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * ncolumns = specfile_wrapper.SfNoColumns(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1035
+ *
+ * ncolumns = specfile_wrapper.SfNoColumns(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &error)
+ * self._handle_error(error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1034
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * ncolumns = specfile_wrapper.SfNoColumns(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &error)
+ */
+ __pyx_v_ncolumns = SfNoColumns(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_error));
+
+ /* "specfile.pyx":1037
+ * scan_index + 1,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * return ncolumns
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1039
+ * self._handle_error(error)
+ *
+ * return ncolumns # <<<<<<<<<<<<<<
+ *
+ * def command(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_ncolumns); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1039; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1020
+ * return lines_list
+ *
+ * def columns(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return number of columns in a scan from the ``#N`` header line
+ * (without ``#N`` and scan number)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.columns", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1041
+ * return ncolumns
+ *
+ * def command(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return ``#S`` line (without ``#S`` and scan number)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_42command(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_41command[] = "SpecFile.command(self, scan_index)\nReturn ``#S`` line (without ``#S`` and scan number)\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: S line\n :rtype: str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_42command(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("command (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_41command(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_41command(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ PyObject *__pyx_v_s_record = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("command", 0);
+
+ /* "specfile.pyx":1052
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * s_record = <bytes> specfile_wrapper.SfCommand(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1055
+ *
+ * s_record = <bytes> specfile_wrapper.SfCommand(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &error)
+ * self._handle_error(error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1054
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * s_record = <bytes> specfile_wrapper.SfCommand(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &error)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromString(SfCommand(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_error))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __pyx_t_1;
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_s_record = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1057
+ * scan_index + 1,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * return s_record.decode()
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1059
+ * self._handle_error(error)
+ *
+ * return s_record.decode() # <<<<<<<<<<<<<<
+ *
+ * def date(self, scan_index=0):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (unlikely(__pyx_v_s_record == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "decode");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_4 = __Pyx_decode_bytes(__pyx_v_s_record, 0, PY_SSIZE_T_MAX, NULL, NULL, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1059; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1041
+ * return ncolumns
+ *
+ * def command(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return ``#S`` line (without ``#S`` and scan number)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.command", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_s_record);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1061
+ * return s_record.decode()
+ *
+ * def date(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return date from ``#D`` line
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_44date(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_43date[] = "SpecFile.date(self, scan_index=0)\nReturn date from ``#D`` line\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Date from ``#D`` line\n :rtype: str\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_44date(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("date (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,0};
+ PyObject* values[1] = {0};
+ values[0] = ((PyObject *)__pyx_int_0);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index);
+ if (value) { values[0] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "date") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1061; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_scan_index = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("date", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1061; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.date", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_43date(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_43date(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ PyObject *__pyx_v_d_line = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("date", 0);
+
+ /* "specfile.pyx":1072
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * d_line = <bytes> specfile_wrapper.SfDate(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1072; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1075
+ *
+ * d_line = <bytes> specfile_wrapper.SfDate(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &error)
+ * self._handle_error(error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1074
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * d_line = <bytes> specfile_wrapper.SfDate(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &error)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromString(SfDate(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_error))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __pyx_t_1;
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_d_line = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1077
+ * scan_index + 1,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * return d_line.decode()
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1077; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "specfile.pyx":1079
+ * self._handle_error(error)
+ *
+ * return d_line.decode() # <<<<<<<<<<<<<<
+ *
+ * def labels(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (unlikely(__pyx_v_d_line == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "decode");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_4 = __Pyx_decode_bytes(__pyx_v_d_line, 0, PY_SSIZE_T_MAX, NULL, NULL, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1079; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1061
+ * return s_record.decode()
+ *
+ * def date(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return date from ``#D`` line
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.date", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_d_line);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1081
+ * return d_line.decode()
+ *
+ * def labels(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return all labels from ``#L`` line
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_46labels(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_45labels[] = "SpecFile.labels(self, scan_index)\nReturn all labels from ``#L`` line\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: All labels from ``#L`` line\n :rtype: list of strings\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_46labels(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("labels (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_45labels(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_45labels(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ char **__pyx_v_all_labels;
+ int __pyx_v_error;
+ long __pyx_v_nlabels;
+ PyObject *__pyx_v_labels_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("labels", 0);
+
+ /* "specfile.pyx":1093
+ * cdef:
+ * char** all_labels
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nlabels = specfile_wrapper.SfAllLabels(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1093; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1096
+ *
+ * nlabels = specfile_wrapper.SfAllLabels(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &all_labels,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1096; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1096; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1095
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nlabels = specfile_wrapper.SfAllLabels(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &all_labels,
+ */
+ __pyx_v_nlabels = SfAllLabels(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_all_labels), (&__pyx_v_error));
+
+ /* "specfile.pyx":1099
+ * &all_labels,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * labels_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1101
+ * self._handle_error(error)
+ *
+ * labels_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nlabels):
+ * labels_list.append(<bytes>all_labels[i].decode())
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_labels_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1102
+ *
+ * labels_list = []
+ * for i in range(nlabels): # <<<<<<<<<<<<<<
+ * labels_list.append(<bytes>all_labels[i].decode())
+ *
+ */
+ __pyx_t_3 = __pyx_v_nlabels;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":1103
+ * labels_list = []
+ * for i in range(nlabels):
+ * labels_list.append(<bytes>all_labels[i].decode()) # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_labels, nlabels)
+ */
+ __pyx_t_9 = (__pyx_v_all_labels[__pyx_v_i]);
+ __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_9, 0, strlen(__pyx_t_9), NULL, NULL, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_labels_list, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":1105
+ * labels_list.append(<bytes>all_labels[i].decode())
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_labels, nlabels) # <<<<<<<<<<<<<<
+ * return labels_list
+ *
+ */
+ freeArrNZ(((void ***)(&__pyx_v_all_labels)), __pyx_v_nlabels);
+
+ /* "specfile.pyx":1106
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_labels, nlabels)
+ * return labels_list # <<<<<<<<<<<<<<
+ *
+ * def motor_names(self, scan_index=0):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_labels_list);
+ __pyx_r = __pyx_v_labels_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1081
+ * return d_line.decode()
+ *
+ * def labels(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return all labels from ``#L`` line
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.labels", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_labels_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1108
+ * return labels_list
+ *
+ * def motor_names(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return all motor names from ``#O`` lines
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_48motor_names(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_47motor_names[] = "SpecFile.motor_names(self, scan_index=0)\nReturn all motor names from ``#O`` lines\n \n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.If not specified, defaults to 0 (meaning the\n function returns motors names associated with the first scan).\n This parameter makes a difference only if there are more than\n on file header in the file, in which case the file header applies\n to all following scans until a new file header appears.\n :type scan_index: int\n\n :return: All motor names\n :rtype: list of strings\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_48motor_names(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_names (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,0};
+ PyObject* values[1] = {0};
+ values[0] = ((PyObject *)__pyx_int_0);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index);
+ if (value) { values[0] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "motor_names") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_scan_index = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("motor_names", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.motor_names", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_47motor_names(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_47motor_names(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ char **__pyx_v_all_motors;
+ int __pyx_v_error;
+ long __pyx_v_nmotors;
+ PyObject *__pyx_v_motors_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_names", 0);
+
+ /* "specfile.pyx":1124
+ * cdef:
+ * char** all_motors
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nmotors = specfile_wrapper.SfAllMotors(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1127
+ *
+ * nmotors = specfile_wrapper.SfAllMotors(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &all_motors,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1126
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nmotors = specfile_wrapper.SfAllMotors(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &all_motors,
+ */
+ __pyx_v_nmotors = SfAllMotors(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_all_motors), (&__pyx_v_error));
+
+ /* "specfile.pyx":1130
+ * &all_motors,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * motors_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1132
+ * self._handle_error(error)
+ *
+ * motors_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nmotors):
+ * motors_list.append(<bytes>all_motors[i].decode())
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_motors_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1133
+ *
+ * motors_list = []
+ * for i in range(nmotors): # <<<<<<<<<<<<<<
+ * motors_list.append(<bytes>all_motors[i].decode())
+ *
+ */
+ __pyx_t_3 = __pyx_v_nmotors;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":1134
+ * motors_list = []
+ * for i in range(nmotors):
+ * motors_list.append(<bytes>all_motors[i].decode()) # <<<<<<<<<<<<<<
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_motors, nmotors)
+ */
+ __pyx_t_9 = (__pyx_v_all_motors[__pyx_v_i]);
+ __pyx_t_1 = __Pyx_decode_c_string(__pyx_t_9, 0, strlen(__pyx_t_9), NULL, NULL, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_10 = __Pyx_PyList_Append(__pyx_v_motors_list, __pyx_t_1); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":1136
+ * motors_list.append(<bytes>all_motors[i].decode())
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_motors, nmotors) # <<<<<<<<<<<<<<
+ * return motors_list
+ *
+ */
+ freeArrNZ(((void ***)(&__pyx_v_all_motors)), __pyx_v_nmotors);
+
+ /* "specfile.pyx":1137
+ *
+ * specfile_wrapper.freeArrNZ(<void***>&all_motors, nmotors)
+ * return motors_list # <<<<<<<<<<<<<<
+ *
+ * def motor_positions(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_motors_list);
+ __pyx_r = __pyx_v_motors_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1108
+ * return labels_list
+ *
+ * def motor_names(self, scan_index=0): # <<<<<<<<<<<<<<
+ * """Return all motor names from ``#O`` lines
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.motor_names", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_motors_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1139
+ * return motors_list
+ *
+ * def motor_positions(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return all motor positions
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_50motor_positions(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_49motor_positions[] = "SpecFile.motor_positions(self, scan_index)\nReturn all motor positions\n \n :param scan_index: Unique scan index between ``0``\n and ``len(self)-1``.\n :type scan_index: int\n\n :return: All motor positions\n :rtype: list of double\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_50motor_positions(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_positions (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_49motor_positions(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_49motor_positions(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ double *__pyx_v_motor_positions;
+ int __pyx_v_error;
+ long __pyx_v_nmotors;
+ PyObject *__pyx_v_motor_positions_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ long __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_positions", 0);
+
+ /* "specfile.pyx":1151
+ * cdef:
+ * double* motor_positions
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * nmotors = specfile_wrapper.SfAllMotorPos(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1154
+ *
+ * nmotors = specfile_wrapper.SfAllMotorPos(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &motor_positions,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1153
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * nmotors = specfile_wrapper.SfAllMotorPos(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &motor_positions,
+ */
+ __pyx_v_nmotors = SfAllMotorPos(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_motor_positions), (&__pyx_v_error));
+
+ /* "specfile.pyx":1157
+ * &motor_positions,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * motor_positions_list = []
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1159
+ * self._handle_error(error)
+ *
+ * motor_positions_list = [] # <<<<<<<<<<<<<<
+ * for i in range(nmotors):
+ * motor_positions_list.append(motor_positions[i])
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_motor_positions_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1160
+ *
+ * motor_positions_list = []
+ * for i in range(nmotors): # <<<<<<<<<<<<<<
+ * motor_positions_list.append(motor_positions[i])
+ *
+ */
+ __pyx_t_3 = __pyx_v_nmotors;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_3; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "specfile.pyx":1161
+ * motor_positions_list = []
+ * for i in range(nmotors):
+ * motor_positions_list.append(motor_positions[i]) # <<<<<<<<<<<<<<
+ *
+ * free(motor_positions)
+ */
+ __pyx_t_1 = PyFloat_FromDouble((__pyx_v_motor_positions[__pyx_v_i])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_motor_positions_list, __pyx_t_1); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":1163
+ * motor_positions_list.append(motor_positions[i])
+ *
+ * free(motor_positions) # <<<<<<<<<<<<<<
+ * return motor_positions_list
+ *
+ */
+ free(__pyx_v_motor_positions);
+
+ /* "specfile.pyx":1164
+ *
+ * free(motor_positions)
+ * return motor_positions_list # <<<<<<<<<<<<<<
+ *
+ * def motor_position_by_name(self, scan_index, name):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_motor_positions_list);
+ __pyx_r = __pyx_v_motor_positions_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1139
+ * return motors_list
+ *
+ * def motor_positions(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return all motor positions
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("specfile.SpecFile.motor_positions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_motor_positions_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1166
+ * return motor_positions_list
+ *
+ * def motor_position_by_name(self, scan_index, name): # <<<<<<<<<<<<<<
+ * """Return motor position
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_52motor_position_by_name(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_51motor_position_by_name[] = "SpecFile.motor_position_by_name(self, scan_index, name)\nReturn motor position\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Specified motor position\n :rtype: double\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_52motor_position_by_name(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("motor_position_by_name (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,&__pyx_n_s_name,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("motor_position_by_name", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "motor_position_by_name") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_scan_index = values[0];
+ __pyx_v_name = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("motor_position_by_name", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1166; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.motor_position_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_51motor_position_by_name(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index, __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_51motor_position_by_name(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_name) {
+ int __pyx_v_error;
+ double __pyx_v_motor_position;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ long __pyx_t_6;
+ char *__pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("motor_position_by_name", 0);
+ __Pyx_INCREF(__pyx_v_name);
+
+ /* "specfile.pyx":1177
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * name = _string_to_char_star(name)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1179
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * name = _string_to_char_star(name) # <<<<<<<<<<<<<<
+ *
+ * motor_position = specfile_wrapper.SfMotorPosByName(self.handle,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_string_to_char_star); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_name); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_name);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_name, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1182
+ *
+ * motor_position = specfile_wrapper.SfMotorPosByName(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * name,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_6 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1183
+ * motor_position = specfile_wrapper.SfMotorPosByName(self.handle,
+ * scan_index + 1,
+ * name, # <<<<<<<<<<<<<<
+ * &error)
+ * self._handle_error(error)
+ */
+ __pyx_t_7 = __Pyx_PyObject_AsString(__pyx_v_name); if (unlikely((!__pyx_t_7) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":1181
+ * name = _string_to_char_star(name)
+ *
+ * motor_position = specfile_wrapper.SfMotorPosByName(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * name,
+ */
+ __pyx_v_motor_position = SfMotorPosByName(__pyx_v_self->handle, __pyx_t_6, __pyx_t_7, (&__pyx_v_error));
+
+ /* "specfile.pyx":1185
+ * name,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ * return motor_position
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1187
+ * self._handle_error(error)
+ *
+ * return motor_position # <<<<<<<<<<<<<<
+ *
+ * def number_of_mca(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyFloat_FromDouble(__pyx_v_motor_position); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1166
+ * return motor_positions_list
+ *
+ * def motor_position_by_name(self, scan_index, name): # <<<<<<<<<<<<<<
+ * """Return motor position
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.motor_position_by_name", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_name);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1189
+ * return motor_position
+ *
+ * def number_of_mca(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return number of mca spectra in a scan.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_54number_of_mca(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_53number_of_mca[] = "SpecFile.number_of_mca(self, scan_index)\nReturn number of mca spectra in a scan.\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: Number of mca spectra.\n :rtype: int\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_54number_of_mca(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("number_of_mca (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_53number_of_mca(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_53number_of_mca(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ long __pyx_v_num_mca;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("number_of_mca", 0);
+
+ /* "specfile.pyx":1200
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ *
+ * num_mca = specfile_wrapper.SfNoMca(self.handle,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1203
+ *
+ * num_mca = specfile_wrapper.SfNoMca(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &error)
+ * # error code updating isn't implemented in SfNoMCA
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1202
+ * int error = SF_ERR_NO_ERRORS
+ *
+ * num_mca = specfile_wrapper.SfNoMca(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &error)
+ */
+ __pyx_v_num_mca = SfNoMca(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_error));
+
+ /* "specfile.pyx":1206
+ * &error)
+ * # error code updating isn't implemented in SfNoMCA
+ * if num_mca == -1: # <<<<<<<<<<<<<<
+ * raise SfNoMcaError("Failed to retrieve number of MCA " +
+ * "(SfNoMca returned -1)")
+ */
+ __pyx_t_4 = ((__pyx_v_num_mca == -1) != 0);
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":1207
+ * # error code updating isn't implemented in SfNoMCA
+ * if num_mca == -1:
+ * raise SfNoMcaError("Failed to retrieve number of MCA " + # <<<<<<<<<<<<<<
+ * "(SfNoMca returned -1)")
+ * return num_mca
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfNoMcaError); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyNumber_Add(__pyx_kp_s_Failed_to_retrieve_number_of_MCA, __pyx_kp_s_SfNoMca_returned_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":1209
+ * raise SfNoMcaError("Failed to retrieve number of MCA " +
+ * "(SfNoMca returned -1)")
+ * return num_mca # <<<<<<<<<<<<<<
+ *
+ * def mca_calibration(self, scan_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_num_mca); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1189
+ * return motor_position
+ *
+ * def number_of_mca(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return number of mca spectra in a scan.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.number_of_mca", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1211
+ * return num_mca
+ *
+ * def mca_calibration(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return MCA calibration in the form :math:`a + b x + c x`
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_56mca_calibration(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_55mca_calibration[] = "SpecFile.mca_calibration(self, scan_index)\nReturn MCA calibration in the form :math:`a + b x + c x\302\262`\n\n Raise a KeyError if there is no ``@CALIB`` line in the scan header.\n\n :param scan_index: Unique scan index between ``0`` and\n ``len(self)-1``.\n :type scan_index: int\n\n :return: MCA calibration as a list of 3 values :math:`(a, b, c)`\n :rtype: list of floats\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_56mca_calibration(PyObject *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("mca_calibration (wrapper)", 0);
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_55mca_calibration(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), ((PyObject *)__pyx_v_scan_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_55mca_calibration(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index) {
+ int __pyx_v_error;
+ double *__pyx_v_mca_calib;
+ long __pyx_v_mca_calib_error;
+ PyObject *__pyx_v_mca_calib_list = NULL;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("mca_calibration", 0);
+
+ /* "specfile.pyx":1224
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ * double* mca_calib
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1228
+ *
+ * mca_calib_error = specfile_wrapper.SfMcaCalib(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * &mca_calib,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1227
+ * double* mca_calib
+ *
+ * mca_calib_error = specfile_wrapper.SfMcaCalib(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * &mca_calib,
+ */
+ __pyx_v_mca_calib_error = SfMcaCalib(__pyx_v_self->handle, __pyx_t_3, (&__pyx_v_mca_calib), (&__pyx_v_error));
+
+ /* "specfile.pyx":1233
+ *
+ * # error code updating isn't implemented in SfMcaCalib
+ * if mca_calib_error: # <<<<<<<<<<<<<<
+ * raise KeyError("MCA calibration line (@CALIB) not found")
+ *
+ */
+ __pyx_t_4 = (__pyx_v_mca_calib_error != 0);
+ if (__pyx_t_4) {
+
+ /* "specfile.pyx":1234
+ * # error code updating isn't implemented in SfMcaCalib
+ * if mca_calib_error:
+ * raise KeyError("MCA calibration line (@CALIB) not found") # <<<<<<<<<<<<<<
+ *
+ * mca_calib_list = []
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_KeyError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "specfile.pyx":1236
+ * raise KeyError("MCA calibration line (@CALIB) not found")
+ *
+ * mca_calib_list = [] # <<<<<<<<<<<<<<
+ * for i in range(3):
+ * mca_calib_list.append(mca_calib[i])
+ */
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_mca_calib_list = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1237
+ *
+ * mca_calib_list = []
+ * for i in range(3): # <<<<<<<<<<<<<<
+ * mca_calib_list.append(mca_calib[i])
+ *
+ */
+ for (__pyx_t_3 = 0; __pyx_t_3 < 3; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "specfile.pyx":1238
+ * mca_calib_list = []
+ * for i in range(3):
+ * mca_calib_list.append(mca_calib[i]) # <<<<<<<<<<<<<<
+ *
+ * free(mca_calib)
+ */
+ __pyx_t_1 = PyFloat_FromDouble((__pyx_v_mca_calib[__pyx_v_i])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyList_Append(__pyx_v_mca_calib_list, __pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+
+ /* "specfile.pyx":1240
+ * mca_calib_list.append(mca_calib[i])
+ *
+ * free(mca_calib) # <<<<<<<<<<<<<<
+ * return mca_calib_list
+ *
+ */
+ free(__pyx_v_mca_calib);
+
+ /* "specfile.pyx":1241
+ *
+ * free(mca_calib)
+ * return mca_calib_list # <<<<<<<<<<<<<<
+ *
+ * def get_mca(self, scan_index, mca_index):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_mca_calib_list);
+ __pyx_r = __pyx_v_mca_calib_list;
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1211
+ * return num_mca
+ *
+ * def mca_calibration(self, scan_index): # <<<<<<<<<<<<<<
+ * """Return MCA calibration in the form :math:`a + b x + c x`
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("specfile.SpecFile.mca_calibration", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_mca_calib_list);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "specfile.pyx":1243
+ * return mca_calib_list
+ *
+ * def get_mca(self, scan_index, mca_index): # <<<<<<<<<<<<<<
+ * """Return one MCA spectrum
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_8specfile_8SpecFile_58get_mca(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_8specfile_8SpecFile_57get_mca[] = "SpecFile.get_mca(self, scan_index, mca_index)\nReturn one MCA spectrum\n\n :param scan_index: Unique scan index between ``0`` and ``len(self)-1``.\n :type scan_index: int\n :param mca_index: Index of MCA in the scan\n :type mca_index: int\n\n :return: MCA spectrum\n :rtype: 1D numpy array\n ";
+static PyObject *__pyx_pw_8specfile_8SpecFile_58get_mca(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_scan_index = 0;
+ PyObject *__pyx_v_mca_index = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("get_mca (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_scan_index,&__pyx_n_s_mca_index,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_scan_index)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mca_index)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("get_mca", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1243; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_mca") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1243; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_scan_index = values[0];
+ __pyx_v_mca_index = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("get_mca", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1243; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("specfile.SpecFile.get_mca", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_8specfile_8SpecFile_57get_mca(((struct __pyx_obj_8specfile_SpecFile *)__pyx_v_self), __pyx_v_scan_index, __pyx_v_mca_index);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_8specfile_8SpecFile_57get_mca(struct __pyx_obj_8specfile_SpecFile *__pyx_v_self, PyObject *__pyx_v_scan_index, PyObject *__pyx_v_mca_index) {
+ int __pyx_v_error;
+ double *__pyx_v_mca_data;
+ long __pyx_v_len_mca;
+ PyArrayObject *__pyx_v_ret_array = 0;
+ long __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_mca", 0);
+
+ /* "specfile.pyx":1255
+ * """
+ * cdef:
+ * int error = SF_ERR_NO_ERRORS # <<<<<<<<<<<<<<
+ * double* mca_data
+ * long len_mca
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SF_ERR_NO_ERRORS); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_error = __pyx_t_2;
+
+ /* "specfile.pyx":1260
+ *
+ * len_mca = specfile_wrapper.SfGetMca(self.handle,
+ * scan_index + 1, # <<<<<<<<<<<<<<
+ * mca_index + 1,
+ * &mca_data,
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_scan_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_3 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1261
+ * len_mca = specfile_wrapper.SfGetMca(self.handle,
+ * scan_index + 1,
+ * mca_index + 1, # <<<<<<<<<<<<<<
+ * &mca_data,
+ * &error)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_v_mca_index, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyInt_As_long(__pyx_t_1); if (unlikely((__pyx_t_4 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1259
+ * long len_mca
+ *
+ * len_mca = specfile_wrapper.SfGetMca(self.handle, # <<<<<<<<<<<<<<
+ * scan_index + 1,
+ * mca_index + 1,
+ */
+ __pyx_v_len_mca = SfGetMca(__pyx_v_self->handle, __pyx_t_3, __pyx_t_4, (&__pyx_v_mca_data), (&__pyx_v_error));
+
+ /* "specfile.pyx":1264
+ * &mca_data,
+ * &error)
+ * self._handle_error(error) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_handle_error); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_error); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1267
+ *
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((len_mca,), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(len_mca):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_empty); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyInt_From_long(__pyx_v_len_mca); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = PyDict_New(); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+
+ /* "specfile.pyx":1268
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((len_mca,),
+ * dtype=numpy.double) # <<<<<<<<<<<<<<
+ * for i in range(len_mca):
+ * ret_array[i] = mca_data[i]
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_double); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "specfile.pyx":1267
+ *
+ *
+ * cdef numpy.ndarray ret_array = numpy.empty((len_mca,), # <<<<<<<<<<<<<<
+ * dtype=numpy.double)
+ * for i in range(len_mca):
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_1, __pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (!(likely(((__pyx_t_7) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_7, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_ret_array = ((PyArrayObject *)__pyx_t_7);
+ __pyx_t_7 = 0;
+
+ /* "specfile.pyx":1269
+ * cdef numpy.ndarray ret_array = numpy.empty((len_mca,),
+ * dtype=numpy.double)
+ * for i in range(len_mca): # <<<<<<<<<<<<<<
+ * ret_array[i] = mca_data[i]
+ *
+ */
+ __pyx_t_4 = __pyx_v_len_mca;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_4; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "specfile.pyx":1270
+ * dtype=numpy.double)
+ * for i in range(len_mca):
+ * ret_array[i] = mca_data[i] # <<<<<<<<<<<<<<
+ *
+ * free(mca_data)
+ */
+ __pyx_t_7 = PyFloat_FromDouble((__pyx_v_mca_data[__pyx_v_i])); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ if (unlikely(__Pyx_SetItemInt(((PyObject *)__pyx_v_ret_array), __pyx_v_i, __pyx_t_7, long, 1, __Pyx_PyInt_From_long, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+
+ /* "specfile.pyx":1272
+ * ret_array[i] = mca_data[i]
+ *
+ * free(mca_data) # <<<<<<<<<<<<<<
+ * return ret_array
+ */
+ free(__pyx_v_mca_data);
+
+ /* "specfile.pyx":1273
+ *
+ * free(mca_data)
+ * return ret_array # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_ret_array));
+ __pyx_r = ((PyObject *)__pyx_v_ret_array);
+ goto __pyx_L0;
+
+ /* "specfile.pyx":1243
+ * return mca_calib_list
+ *
+ * def get_mca(self, scan_index, mca_index): # <<<<<<<<<<<<<<
+ * """Return one MCA spectrum
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("specfile.SpecFile.get_mca", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_ret_array);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_copy_shape;
+ int __pyx_v_i;
+ int __pyx_v_ndim;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ int __pyx_v_t;
+ char *__pyx_v_f;
+ PyArray_Descr *__pyx_v_descr = 0;
+ int __pyx_v_offset;
+ int __pyx_v_hasfields;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":200
+ * # of flags
+ *
+ * if info == NULL: return # <<<<<<<<<<<<<<
+ *
+ * cdef int copy_shape, i, ndim
+ */
+ __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+ if (__pyx_t_1) {
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":204
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ *
+ * ndim = PyArray_NDIM(self)
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<<
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":208
+ * ndim = PyArray_NDIM(self)
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * copy_shape = 1
+ * else:
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * copy_shape = 1 # <<<<<<<<<<<<<<
+ * else:
+ * copy_shape = 0
+ */
+ __pyx_v_copy_shape = 1;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ * copy_shape = 1
+ * else:
+ * copy_shape = 0 # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+ __pyx_v_copy_shape = 0;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":213
+ * copy_shape = 0
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L6_bool_binop_done;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L9_bool_binop_done;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<<
+ * info.ndim = ndim
+ * if copy_shape:
+ */
+ __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim # <<<<<<<<<<<<<<
+ * if copy_shape:
+ * # Allocate new buffer for strides and shape info.
+ */
+ __pyx_v_info->ndim = __pyx_v_ndim;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":223
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim
+ * if copy_shape: # <<<<<<<<<<<<<<
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ */
+ __pyx_t_1 = (__pyx_v_copy_shape != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2) # <<<<<<<<<<<<<<
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":227
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+ __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":228
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ */
+ __pyx_t_4 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<<
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ */
+ (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+ (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+ }
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self) # <<<<<<<<<<<<<<
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self) # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ */
+ __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+ }
+ __pyx_L11:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":234
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<<
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ *
+ */
+ __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<<
+ *
+ * cdef int t
+ */
+ __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *
+ * cdef int t
+ * cdef char* f = NULL # <<<<<<<<<<<<<<
+ * cdef dtype descr = self.descr
+ * cdef list stack
+ */
+ __pyx_v_f = NULL;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":240
+ * cdef int t
+ * cdef char* f = NULL
+ * cdef dtype descr = self.descr # <<<<<<<<<<<<<<
+ * cdef list stack
+ * cdef int offset
+ */
+ __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":244
+ * cdef int offset
+ *
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<<
+ *
+ * if not hasfields and not copy_shape:
+ */
+ __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":246
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ *
+ * if not hasfields and not copy_shape: # <<<<<<<<<<<<<<
+ * # do not call releasebuffer
+ * info.obj = None
+ */
+ __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":248
+ * if not hasfields and not copy_shape:
+ * # do not call releasebuffer
+ * info.obj = None # <<<<<<<<<<<<<<
+ * else:
+ * # need to call releasebuffer
+ */
+ __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = Py_None;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":251
+ * else:
+ * # need to call releasebuffer
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * if not hasfields:
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+ }
+ __pyx_L14:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":253
+ * info.obj = self
+ *
+ * if not hasfields: # <<<<<<<<<<<<<<
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":254
+ *
+ * if not hasfields:
+ * t = descr.type_num # <<<<<<<<<<<<<<
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ */
+ __pyx_t_4 = __pyx_v_descr->type_num;
+ __pyx_v_t = __pyx_t_4;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":255
+ * if not hasfields:
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+ if (!__pyx_t_2) {
+ goto __pyx_L20_next_or;
+ } else {
+ }
+ __pyx_t_2 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_L20_next_or:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L19_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ switch (__pyx_v_t) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ */
+ case NPY_BYTE:
+ __pyx_v_f = __pyx_k_b;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ */
+ case NPY_UBYTE:
+ __pyx_v_f = __pyx_k_B;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ */
+ case NPY_SHORT:
+ __pyx_v_f = __pyx_k_h;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ */
+ case NPY_USHORT:
+ __pyx_v_f = __pyx_k_H;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ */
+ case NPY_INT:
+ __pyx_v_f = __pyx_k_i;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ */
+ case NPY_UINT:
+ __pyx_v_f = __pyx_k_I;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ */
+ case NPY_LONG:
+ __pyx_v_f = __pyx_k_l;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ */
+ case NPY_ULONG:
+ __pyx_v_f = __pyx_k_L;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ */
+ case NPY_LONGLONG:
+ __pyx_v_f = __pyx_k_q;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ */
+ case NPY_ULONGLONG:
+ __pyx_v_f = __pyx_k_Q;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ */
+ case NPY_FLOAT:
+ __pyx_v_f = __pyx_k_f;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ */
+ case NPY_DOUBLE:
+ __pyx_v_f = __pyx_k_d;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ */
+ case NPY_LONGDOUBLE:
+ __pyx_v_f = __pyx_k_g;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+ case NPY_CFLOAT:
+ __pyx_v_f = __pyx_k_Zf;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O"
+ */
+ case NPY_CDOUBLE:
+ __pyx_v_f = __pyx_k_Zd;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ */
+ case NPY_CLONGDOUBLE:
+ __pyx_v_f = __pyx_k_Zg;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ case NPY_OBJECT:
+ __pyx_v_f = __pyx_k_O;
+ break;
+ default:
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * info.format = f
+ * return
+ */
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ break;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f # <<<<<<<<<<<<<<
+ * return
+ * else:
+ */
+ __pyx_v_info->format = __pyx_v_f;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":278
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f
+ * return # <<<<<<<<<<<<<<
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ * return
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<<
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ */
+ __pyx_v_info->format = ((char *)malloc(255));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":281
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<<
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1,
+ */
+ (__pyx_v_info->format[0]) = '^';
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":282
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0 # <<<<<<<<<<<<<<
+ * f = _util_dtypestring(descr, info.format + 1,
+ * info.format + _buffer_format_string_len,
+ */
+ __pyx_v_offset = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<<
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ */
+ __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_7;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":286
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<<
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+ (__pyx_v_f[0]) = '\x00';
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+ __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":289
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<<
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":290
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format) # <<<<<<<<<<<<<<
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides)
+ */
+ free(__pyx_v_info->format);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * stdlib.free(info.strides)
+ * # info.shape was stored after info.strides in the same block
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides) # <<<<<<<<<<<<<<
+ * # info.shape was stored after info.strides in the same block
+ *
+ */
+ free(__pyx_v_info->strides);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":769
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ * return PyArray_MultiIterNew(1, <void*>a) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":772
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":775
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":778
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":781
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e) # <<<<<<<<<<<<<<
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+ PyArray_Descr *__pyx_v_child = 0;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ PyObject *__pyx_v_fields = 0;
+ PyObject *__pyx_v_childname = NULL;
+ PyObject *__pyx_v_new_offset = NULL;
+ PyObject *__pyx_v_t = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":790
+ * cdef int delta_offset
+ * cdef tuple i
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * cdef tuple fields
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":791
+ * cdef tuple i
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ * cdef tuple fields
+ *
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ if (unlikely(__pyx_v_descr->names == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+ for (;;) {
+ if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":795
+ *
+ * for childname in descr.names:
+ * fields = descr.fields[childname] # <<<<<<<<<<<<<<
+ * child, new_offset = fields
+ *
+ */
+ __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":796
+ * for childname in descr.names:
+ * fields = descr.fields[childname]
+ * child, new_offset = fields # <<<<<<<<<<<<<<
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+ if (likely(__pyx_v_fields != Py_None)) {
+ PyObject* sequence = __pyx_v_fields;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ #else
+ __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ #endif
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+ __pyx_t_3 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ * child, new_offset = fields
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__34, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+ if (!__pyx_t_7) {
+ goto __pyx_L8_next_or;
+ } else {
+ }
+ __pyx_t_7 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_L8_next_or:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * # One could encode it in the format string and have Cython
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__35, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":813
+ *
+ * # Output padding bytes
+ * while offset[0] < new_offset: # <<<<<<<<<<<<<<
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ */
+ while (1) {
+ __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (!__pyx_t_6) break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":814
+ * # Output padding bytes
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<<
+ * f += 1
+ * offset[0] += 1
+ */
+ (__pyx_v_f[0]) = 120;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":815
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte
+ * f += 1 # <<<<<<<<<<<<<<
+ * offset[0] += 1
+ *
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ * offset[0] += 1 # <<<<<<<<<<<<<<
+ *
+ * offset[0] += child.itemsize
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ * offset[0] += 1
+ *
+ * offset[0] += child.itemsize # <<<<<<<<<<<<<<
+ *
+ * if not PyDataType_HASFIELDS(child):
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":820
+ * offset[0] += child.itemsize
+ *
+ * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<<
+ * t = child.type_num
+ * if end - f < 5:
+ */
+ __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ *
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num # <<<<<<<<<<<<<<
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.")
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":822
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num
+ * if end - f < 5: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short.")
+ *
+ */
+ __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__36, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 98;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":827
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 66;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":828
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 104;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 72;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 105;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 73;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 108;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 76;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 113;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 81;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 102;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 100;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 103;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 102;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 100;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 103;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 79;
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * f += 1
+ * else:
+ */
+ __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L15:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * f += 1 # <<<<<<<<<<<<<<
+ * else:
+ * # Cython ignores struct boundary information ("T{...}"),
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":849
+ * # Cython ignores struct boundary information ("T{...}"),
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<<
+ * return f
+ *
+ */
+ __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_9;
+ }
+ __pyx_L13:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":850
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset)
+ * return f # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_f;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_child);
+ __Pyx_XDECREF(__pyx_v_fields);
+ __Pyx_XDECREF(__pyx_v_childname);
+ __Pyx_XDECREF(__pyx_v_new_offset);
+ __Pyx_XDECREF(__pyx_v_t);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+ PyObject *__pyx_v_baseptr;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("set_array_base", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ * cdef PyObject* baseptr
+ * if base is None: # <<<<<<<<<<<<<<
+ * baseptr = NULL
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_base == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * cdef PyObject* baseptr
+ * if base is None:
+ * baseptr = NULL # <<<<<<<<<<<<<<
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ */
+ __pyx_v_baseptr = NULL;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ * baseptr = NULL
+ * else:
+ * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<<
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ */
+ Py_INCREF(__pyx_v_base);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base # <<<<<<<<<<<<<<
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr
+ */
+ __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":973
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base) # <<<<<<<<<<<<<<
+ * arr.base = baseptr
+ *
+ */
+ Py_XDECREF(__pyx_v_arr->base);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr # <<<<<<<<<<<<<<
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ */
+ __pyx_v_arr->base = __pyx_v_baseptr;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("get_array_base", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL: # <<<<<<<<<<<<<<
+ * return None
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":978
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL:
+ * return None # <<<<<<<<<<<<<<
+ * else:
+ * return <object>arr.base
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ * return None
+ * else:
+ * return <object>arr.base # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+ __pyx_r = ((PyObject *)__pyx_v_arr->base);
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_8specfile_SpecFile(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_obj_8specfile_SpecFile *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_obj_8specfile_SpecFile *)o);
+ p->filename = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_pw_8specfile_8SpecFile_1__cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_8specfile_SpecFile(PyObject *o) {
+ struct __pyx_obj_8specfile_SpecFile *p = (struct __pyx_obj_8specfile_SpecFile *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_pw_8specfile_8SpecFile_5__dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->filename);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_8specfile_SpecFile(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static PyMethodDef __pyx_methods_8specfile_SpecFile[] = {
+ {"keys", (PyCFunction)__pyx_pw_8specfile_8SpecFile_14keys, METH_NOARGS, __pyx_doc_8specfile_8SpecFile_13keys},
+ {"_get_error_string", (PyCFunction)__pyx_pw_8specfile_8SpecFile_18_get_error_string, METH_O, __pyx_doc_8specfile_8SpecFile_17_get_error_string},
+ {"_handle_error", (PyCFunction)__pyx_pw_8specfile_8SpecFile_20_handle_error, METH_O, __pyx_doc_8specfile_8SpecFile_19_handle_error},
+ {"index", (PyCFunction)__pyx_pw_8specfile_8SpecFile_22index, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_21index},
+ {"number", (PyCFunction)__pyx_pw_8specfile_8SpecFile_24number, METH_O, __pyx_doc_8specfile_8SpecFile_23number},
+ {"order", (PyCFunction)__pyx_pw_8specfile_8SpecFile_26order, METH_O, __pyx_doc_8specfile_8SpecFile_25order},
+ {"_list", (PyCFunction)__pyx_pw_8specfile_8SpecFile_28_list, METH_NOARGS, __pyx_doc_8specfile_8SpecFile_27_list},
+ {"list", (PyCFunction)__pyx_pw_8specfile_8SpecFile_30list, METH_NOARGS, __pyx_doc_8specfile_8SpecFile_29list},
+ {"data", (PyCFunction)__pyx_pw_8specfile_8SpecFile_32data, METH_O, __pyx_doc_8specfile_8SpecFile_31data},
+ {"data_column_by_name", (PyCFunction)__pyx_pw_8specfile_8SpecFile_34data_column_by_name, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_33data_column_by_name},
+ {"scan_header", (PyCFunction)__pyx_pw_8specfile_8SpecFile_36scan_header, METH_O, __pyx_doc_8specfile_8SpecFile_35scan_header},
+ {"file_header", (PyCFunction)__pyx_pw_8specfile_8SpecFile_38file_header, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_37file_header},
+ {"columns", (PyCFunction)__pyx_pw_8specfile_8SpecFile_40columns, METH_O, __pyx_doc_8specfile_8SpecFile_39columns},
+ {"command", (PyCFunction)__pyx_pw_8specfile_8SpecFile_42command, METH_O, __pyx_doc_8specfile_8SpecFile_41command},
+ {"date", (PyCFunction)__pyx_pw_8specfile_8SpecFile_44date, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_43date},
+ {"labels", (PyCFunction)__pyx_pw_8specfile_8SpecFile_46labels, METH_O, __pyx_doc_8specfile_8SpecFile_45labels},
+ {"motor_names", (PyCFunction)__pyx_pw_8specfile_8SpecFile_48motor_names, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_47motor_names},
+ {"motor_positions", (PyCFunction)__pyx_pw_8specfile_8SpecFile_50motor_positions, METH_O, __pyx_doc_8specfile_8SpecFile_49motor_positions},
+ {"motor_position_by_name", (PyCFunction)__pyx_pw_8specfile_8SpecFile_52motor_position_by_name, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_51motor_position_by_name},
+ {"number_of_mca", (PyCFunction)__pyx_pw_8specfile_8SpecFile_54number_of_mca, METH_O, __pyx_doc_8specfile_8SpecFile_53number_of_mca},
+ {"mca_calibration", (PyCFunction)__pyx_pw_8specfile_8SpecFile_56mca_calibration, METH_O, __pyx_doc_8specfile_8SpecFile_55mca_calibration},
+ {"get_mca", (PyCFunction)__pyx_pw_8specfile_8SpecFile_58get_mca, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8specfile_8SpecFile_57get_mca},
+ {0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_SpecFile = {
+ __pyx_pw_8specfile_8SpecFile_7__len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_8specfile_SpecFile, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ __pyx_pw_8specfile_8SpecFile_16__contains__, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_SpecFile = {
+ __pyx_pw_8specfile_8SpecFile_7__len__, /*mp_length*/
+ __pyx_pw_8specfile_8SpecFile_12__getitem__, /*mp_subscript*/
+ 0, /*mp_ass_subscript*/
+};
+
+static PyTypeObject __pyx_type_8specfile_SpecFile = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "specfile.SpecFile", /*tp_name*/
+ sizeof(struct __pyx_obj_8specfile_SpecFile), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_8specfile_SpecFile, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_SpecFile, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_SpecFile, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "SpecFile(filename)\n\n\n :param filename: Path of the SpecFile to read\n\n This class wraps the main data and header access functions of the C\n SpecFile library.\n ", /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ __pyx_pw_8specfile_8SpecFile_9__iter__, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_8specfile_SpecFile, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_pw_8specfile_8SpecFile_3__init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_8specfile_SpecFile, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *__pyx_freelist_8specfile___pyx_scope_struct____iter__[8];
+static int __pyx_freecount_8specfile___pyx_scope_struct____iter__ = 0;
+
+static PyObject *__pyx_tp_new_8specfile___pyx_scope_struct____iter__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ PyObject *o;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_8specfile___pyx_scope_struct____iter__ > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_8specfile___pyx_scope_struct____iter__)))) {
+ o = (PyObject*)__pyx_freelist_8specfile___pyx_scope_struct____iter__[--__pyx_freecount_8specfile___pyx_scope_struct____iter__];
+ memset(o, 0, sizeof(struct __pyx_obj_8specfile___pyx_scope_struct____iter__));
+ (void) PyObject_INIT(o, t);
+ PyObject_GC_Track(o);
+ } else {
+ o = (*t->tp_alloc)(t, 0);
+ if (unlikely(!o)) return 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_8specfile___pyx_scope_struct____iter__(PyObject *o) {
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)o;
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->__pyx_v_self);
+ if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_8specfile___pyx_scope_struct____iter__ < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_8specfile___pyx_scope_struct____iter__)))) {
+ __pyx_freelist_8specfile___pyx_scope_struct____iter__[__pyx_freecount_8specfile___pyx_scope_struct____iter__++] = ((struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)o);
+ } else {
+ (*Py_TYPE(o)->tp_free)(o);
+ }
+}
+
+static int __pyx_tp_traverse_8specfile___pyx_scope_struct____iter__(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)o;
+ if (p->__pyx_v_self) {
+ e = (*v)(p->__pyx_v_self, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_8specfile___pyx_scope_struct____iter__(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct____iter__ *)o;
+ tmp = ((PyObject*)p->__pyx_v_self);
+ p->__pyx_v_self = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyTypeObject __pyx_type_8specfile___pyx_scope_struct____iter__ = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "specfile.__pyx_scope_struct____iter__", /*tp_name*/
+ sizeof(struct __pyx_obj_8specfile___pyx_scope_struct____iter__), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_8specfile___pyx_scope_struct____iter__, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_8specfile___pyx_scope_struct____iter__, /*tp_traverse*/
+ __pyx_tp_clear_8specfile___pyx_scope_struct____iter__, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_8specfile___pyx_scope_struct____iter__, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *__pyx_freelist_8specfile___pyx_scope_struct_1___iter__[8];
+static int __pyx_freecount_8specfile___pyx_scope_struct_1___iter__ = 0;
+
+static PyObject *__pyx_tp_new_8specfile___pyx_scope_struct_1___iter__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ PyObject *o;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_8specfile___pyx_scope_struct_1___iter__ > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__)))) {
+ o = (PyObject*)__pyx_freelist_8specfile___pyx_scope_struct_1___iter__[--__pyx_freecount_8specfile___pyx_scope_struct_1___iter__];
+ memset(o, 0, sizeof(struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__));
+ (void) PyObject_INIT(o, t);
+ PyObject_GC_Track(o);
+ } else {
+ o = (*t->tp_alloc)(t, 0);
+ if (unlikely(!o)) return 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_8specfile___pyx_scope_struct_1___iter__(PyObject *o) {
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)o;
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->__pyx_v_self);
+ if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_8specfile___pyx_scope_struct_1___iter__ < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__)))) {
+ __pyx_freelist_8specfile___pyx_scope_struct_1___iter__[__pyx_freecount_8specfile___pyx_scope_struct_1___iter__++] = ((struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)o);
+ } else {
+ (*Py_TYPE(o)->tp_free)(o);
+ }
+}
+
+static int __pyx_tp_traverse_8specfile___pyx_scope_struct_1___iter__(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)o;
+ if (p->__pyx_v_self) {
+ e = (*v)(((PyObject*)p->__pyx_v_self), a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_8specfile___pyx_scope_struct_1___iter__(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *p = (struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__ *)o;
+ tmp = ((PyObject*)p->__pyx_v_self);
+ p->__pyx_v_self = ((struct __pyx_obj_8specfile_SpecFile *)Py_None); Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyTypeObject __pyx_type_8specfile___pyx_scope_struct_1___iter__ = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "specfile.__pyx_scope_struct_1___iter__", /*tp_name*/
+ sizeof(struct __pyx_obj_8specfile___pyx_scope_struct_1___iter__), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_8specfile___pyx_scope_struct_1___iter__, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_8specfile___pyx_scope_struct_1___iter__, /*tp_traverse*/
+ __pyx_tp_clear_8specfile___pyx_scope_struct_1___iter__, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_8specfile___pyx_scope_struct_1___iter__, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "specfile",
+ __pyx_k_This_module_is_a_cython_binding, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_, __pyx_k_, sizeof(__pyx_k_), 0, 0, 1, 0},
+ {&__pyx_kp_s_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 1, 0},
+ {&__pyx_kp_s_27_09_2016, __pyx_k_27_09_2016, sizeof(__pyx_k_27_09_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
+ {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Base_exception_inherited_by_all, __pyx_k_Base_exception_inherited_by_all, sizeof(__pyx_k_Base_exception_inherited_by_all), 0, 0, 1, 0},
+ {&__pyx_n_s_CALIB, __pyx_k_CALIB, sizeof(__pyx_k_CALIB), 0, 0, 1, 1},
+ {&__pyx_n_s_CHANN, __pyx_k_CHANN, sizeof(__pyx_k_CHANN), 0, 0, 1, 1},
+ {&__pyx_kp_s_Cannot_get_data_column_s_in_scan, __pyx_k_Cannot_get_data_column_s_in_scan, sizeof(__pyx_k_Cannot_get_data_column_s_in_scan), 0, 0, 1, 0},
+ {&__pyx_kp_s_Custom_exception_raised_when_SfN, __pyx_k_Custom_exception_raised_when_SfN, sizeof(__pyx_k_Custom_exception_raised_when_SfN), 0, 0, 1, 0},
+ {&__pyx_n_s_ERRORS, __pyx_k_ERRORS, sizeof(__pyx_k_ERRORS), 0, 0, 1, 1},
+ {&__pyx_kp_s_Error_while_closing_SpecFile, __pyx_k_Error_while_closing_SpecFile, sizeof(__pyx_k_Error_while_closing_SpecFile), 0, 0, 1, 0},
+ {&__pyx_n_s_Exception, __pyx_k_Exception, sizeof(__pyx_k_Exception), 0, 0, 1, 1},
+ {&__pyx_kp_s_F, __pyx_k_F, sizeof(__pyx_k_F), 0, 0, 1, 0},
+ {&__pyx_kp_s_Failed_to_retrieve_number_of_MCA, __pyx_k_Failed_to_retrieve_number_of_MCA, sizeof(__pyx_k_Failed_to_retrieve_number_of_MCA), 0, 0, 1, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1},
+ {&__pyx_n_s_L, __pyx_k_L, sizeof(__pyx_k_L), 0, 0, 1, 1},
+ {&__pyx_n_s_L_header, __pyx_k_L_header, sizeof(__pyx_k_L_header), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA, __pyx_k_MCA, sizeof(__pyx_k_MCA), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA___getitem, __pyx_k_MCA___getitem, sizeof(__pyx_k_MCA___getitem), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA___init, __pyx_k_MCA___init, sizeof(__pyx_k_MCA___init), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA___iter, __pyx_k_MCA___iter, sizeof(__pyx_k_MCA___iter), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA___len, __pyx_k_MCA___len, sizeof(__pyx_k_MCA___len), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA__parse_calibration, __pyx_k_MCA__parse_calibration, sizeof(__pyx_k_MCA__parse_calibration), 0, 0, 1, 1},
+ {&__pyx_n_s_MCA__parse_channels, __pyx_k_MCA__parse_channels, sizeof(__pyx_k_MCA__parse_channels), 0, 0, 1, 1},
+ {&__pyx_kp_s_MCA_calibration_line_CALIB_not_f, __pyx_k_MCA_calibration_line_CALIB_not_f, sizeof(__pyx_k_MCA_calibration_line_CALIB_not_f), 0, 0, 1, 0},
+ {&__pyx_kp_s_MCA_index_must_be_in_range_0_d, __pyx_k_MCA_index_must_be_in_range_0_d, sizeof(__pyx_k_MCA_index_must_be_in_range_0_d), 0, 0, 1, 0},
+ {&__pyx_kp_s_MCA_index_should_be_an_integer_s, __pyx_k_MCA_index_should_be_an_integer_s, sizeof(__pyx_k_MCA_index_should_be_an_integer_s), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_kp_s_No_MCA_spectrum_found_in_this_sc, __pyx_k_No_MCA_spectrum_found_in_this_sc, sizeof(__pyx_k_No_MCA_spectrum_found_in_this_sc), 0, 0, 1, 0},
+ {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+ {&__pyx_kp_s_P_Knobel, __pyx_k_P_Knobel, sizeof(__pyx_k_P_Knobel), 0, 0, 1, 0},
+ {&__pyx_kp_s_Parameter_value_must_be_a_string, __pyx_k_Parameter_value_must_be_a_string, sizeof(__pyx_k_Parameter_value_must_be_a_string), 0, 0, 1, 0},
+ {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_S, __pyx_k_S, sizeof(__pyx_k_S), 0, 0, 1, 0},
+ {&__pyx_n_s_SF_ERR_FILE_OPEN, __pyx_k_SF_ERR_FILE_OPEN, sizeof(__pyx_k_SF_ERR_FILE_OPEN), 0, 0, 1, 1},
+ {&__pyx_n_s_SF_ERR_NO_ERRORS, __pyx_k_SF_ERR_NO_ERRORS, sizeof(__pyx_k_SF_ERR_NO_ERRORS), 0, 0, 1, 1},
+ {&__pyx_n_s_SF_ERR_SCAN_NOT_FOUND, __pyx_k_SF_ERR_SCAN_NOT_FOUND, sizeof(__pyx_k_SF_ERR_SCAN_NOT_FOUND), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan, __pyx_k_Scan, sizeof(__pyx_k_Scan), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan___init, __pyx_k_Scan___init, sizeof(__pyx_k_Scan___init), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_data, __pyx_k_Scan_data, sizeof(__pyx_k_Scan_data), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_data_column_by_name, __pyx_k_Scan_data_column_by_name, sizeof(__pyx_k_Scan_data_column_by_name), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_data_line, __pyx_k_Scan_data_line, sizeof(__pyx_k_Scan_data_line), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_file_header, __pyx_k_Scan_file_header, sizeof(__pyx_k_Scan_file_header), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_file_header_dict, __pyx_k_Scan_file_header_dict, sizeof(__pyx_k_Scan_file_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_header, __pyx_k_Scan_header, sizeof(__pyx_k_Scan_header), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_index, __pyx_k_Scan_index, sizeof(__pyx_k_Scan_index), 0, 0, 1, 1},
+ {&__pyx_kp_s_Scan_index_must_be_in_range_0_d, __pyx_k_Scan_index_must_be_in_range_0_d, sizeof(__pyx_k_Scan_index_must_be_in_range_0_d), 0, 0, 1, 0},
+ {&__pyx_n_s_Scan_labels, __pyx_k_Scan_labels, sizeof(__pyx_k_Scan_labels), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_mca, __pyx_k_Scan_mca, sizeof(__pyx_k_Scan_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_mca_header_dict, __pyx_k_Scan_mca_header_dict, sizeof(__pyx_k_Scan_mca_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_motor_names, __pyx_k_Scan_motor_names, sizeof(__pyx_k_Scan_motor_names), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_motor_position_by_name, __pyx_k_Scan_motor_position_by_name, sizeof(__pyx_k_Scan_motor_position_by_name), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_motor_positions, __pyx_k_Scan_motor_positions, sizeof(__pyx_k_Scan_motor_positions), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_number, __pyx_k_Scan_number, sizeof(__pyx_k_Scan_number), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_order, __pyx_k_Scan_order, sizeof(__pyx_k_Scan_order), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_record_exists_in_hdr, __pyx_k_Scan_record_exists_in_hdr, sizeof(__pyx_k_Scan_record_exists_in_hdr), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_scan_header, __pyx_k_Scan_scan_header, sizeof(__pyx_k_Scan_scan_header), 0, 0, 1, 1},
+ {&__pyx_n_s_Scan_scan_header_dict, __pyx_k_Scan_scan_header_dict, sizeof(__pyx_k_Scan_scan_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrColNotFound, __pyx_k_SfErrColNotFound, sizeof(__pyx_k_SfErrColNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrFileClose, __pyx_k_SfErrFileClose, sizeof(__pyx_k_SfErrFileClose), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrFileOpen, __pyx_k_SfErrFileOpen, sizeof(__pyx_k_SfErrFileOpen), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrFileRead, __pyx_k_SfErrFileRead, sizeof(__pyx_k_SfErrFileRead), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrFileWrite, __pyx_k_SfErrFileWrite, sizeof(__pyx_k_SfErrFileWrite), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrHeaderNotFound, __pyx_k_SfErrHeaderNotFound, sizeof(__pyx_k_SfErrHeaderNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrLabelNotFound, __pyx_k_SfErrLabelNotFound, sizeof(__pyx_k_SfErrLabelNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrLineEmpty, __pyx_k_SfErrLineEmpty, sizeof(__pyx_k_SfErrLineEmpty), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrLineNotFound, __pyx_k_SfErrLineNotFound, sizeof(__pyx_k_SfErrLineNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrMcaNotFound, __pyx_k_SfErrMcaNotFound, sizeof(__pyx_k_SfErrMcaNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrMemoryAlloc, __pyx_k_SfErrMemoryAlloc, sizeof(__pyx_k_SfErrMemoryAlloc), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrMotorNotFound, __pyx_k_SfErrMotorNotFound, sizeof(__pyx_k_SfErrMotorNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrPositionNotFound, __pyx_k_SfErrPositionNotFound, sizeof(__pyx_k_SfErrPositionNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrScanNotFound, __pyx_k_SfErrScanNotFound, sizeof(__pyx_k_SfErrScanNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfErrUserNotFound, __pyx_k_SfErrUserNotFound, sizeof(__pyx_k_SfErrUserNotFound), 0, 0, 1, 1},
+ {&__pyx_n_s_SfError, __pyx_k_SfError, sizeof(__pyx_k_SfError), 0, 0, 1, 1},
+ {&__pyx_n_s_SfNoMcaError, __pyx_k_SfNoMcaError, sizeof(__pyx_k_SfNoMcaError), 0, 0, 1, 1},
+ {&__pyx_kp_s_SfNoMca_returned_1, __pyx_k_SfNoMca_returned_1, sizeof(__pyx_k_SfNoMca_returned_1), 0, 0, 1, 0},
+ {&__pyx_n_s_SpecFile___iter, __pyx_k_SpecFile___iter, sizeof(__pyx_k_SpecFile___iter), 0, 0, 1, 1},
+ {&__pyx_kp_s_The_scan_identification_key_can, __pyx_k_The_scan_identification_key_can, sizeof(__pyx_k_The_scan_identification_key_can), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_parse_file_header_line, __pyx_k_Unable_to_parse_file_header_line, sizeof(__pyx_k_Unable_to_parse_file_header_line), 0, 0, 1, 0},
+ {&__pyx_kp_s_Unable_to_parse_scan_header_line, __pyx_k_Unable_to_parse_scan_header_line, sizeof(__pyx_k_Unable_to_parse_scan_header_line), 0, 0, 1, 0},
+ {&__pyx_kp_s_Valid_keys, __pyx_k_Valid_keys, sizeof(__pyx_k_Valid_keys), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_kp_s__14, __pyx_k__14, sizeof(__pyx_k__14), 0, 0, 1, 0},
+ {&__pyx_kp_s__25, __pyx_k__25, sizeof(__pyx_k__25), 0, 0, 1, 0},
+ {&__pyx_kp_s__27, __pyx_k__27, sizeof(__pyx_k__27), 0, 0, 1, 0},
+ {&__pyx_kp_s__28, __pyx_k__28, sizeof(__pyx_k__28), 0, 0, 1, 0},
+ {&__pyx_kp_s__7, __pyx_k__7, sizeof(__pyx_k__7), 0, 0, 1, 0},
+ {&__pyx_n_s_add_or_concatenate, __pyx_k_add_or_concatenate, sizeof(__pyx_k_add_or_concatenate), 0, 0, 1, 1},
+ {&__pyx_n_s_all_calib_values, __pyx_k_all_calib_values, sizeof(__pyx_k_all_calib_values), 0, 0, 1, 1},
+ {&__pyx_n_s_all_chann_values, __pyx_k_all_chann_values, sizeof(__pyx_k_all_chann_values), 0, 0, 1, 1},
+ {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1},
+ {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1},
+ {&__pyx_n_s_ascii, __pyx_k_ascii, sizeof(__pyx_k_ascii), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_basicConfig, __pyx_k_basicConfig, sizeof(__pyx_k_basicConfig), 0, 0, 1, 1},
+ {&__pyx_n_s_calib_line, __pyx_k_calib_line, sizeof(__pyx_k_calib_line), 0, 0, 1, 1},
+ {&__pyx_n_s_calib_lines, __pyx_k_calib_lines, sizeof(__pyx_k_calib_lines), 0, 0, 1, 1},
+ {&__pyx_n_s_calibration, __pyx_k_calibration, sizeof(__pyx_k_calibration), 0, 0, 1, 1},
+ {&__pyx_n_s_chann_line, __pyx_k_chann_line, sizeof(__pyx_k_chann_line), 0, 0, 1, 1},
+ {&__pyx_n_s_chann_lines, __pyx_k_chann_lines, sizeof(__pyx_k_chann_lines), 0, 0, 1, 1},
+ {&__pyx_n_s_channels, __pyx_k_channels, sizeof(__pyx_k_channels), 0, 0, 1, 1},
+ {&__pyx_n_s_close, __pyx_k_close, sizeof(__pyx_k_close), 0, 0, 1, 1},
+ {&__pyx_kp_u_d_d, __pyx_k_d_d, sizeof(__pyx_k_d_d), 0, 1, 0, 0},
+ {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1},
+ {&__pyx_n_s_data_2, __pyx_k_data_2, sizeof(__pyx_k_data_2), 0, 0, 1, 1},
+ {&__pyx_n_s_data_column_by_name, __pyx_k_data_column_by_name, sizeof(__pyx_k_data_column_by_name), 0, 0, 1, 1},
+ {&__pyx_n_s_data_line, __pyx_k_data_line, sizeof(__pyx_k_data_line), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_decode, __pyx_k_decode, sizeof(__pyx_k_decode), 0, 0, 1, 1},
+ {&__pyx_n_s_dictionary, __pyx_k_dictionary, sizeof(__pyx_k_dictionary), 0, 0, 1, 1},
+ {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1},
+ {&__pyx_n_s_double, __pyx_k_double, sizeof(__pyx_k_double), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
+ {&__pyx_n_s_encode, __pyx_k_encode, sizeof(__pyx_k_encode), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_f, __pyx_k_f, sizeof(__pyx_k_f), 0, 0, 1, 1},
+ {&__pyx_n_s_file_header, __pyx_k_file_header, sizeof(__pyx_k_file_header), 0, 0, 1, 1},
+ {&__pyx_n_s_file_header_dict, __pyx_k_file_header_dict, sizeof(__pyx_k_file_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_file_header_dict_2, __pyx_k_file_header_dict_2, sizeof(__pyx_k_file_header_dict_2), 0, 0, 1, 1},
+ {&__pyx_n_s_file_header_lines, __pyx_k_file_header_lines, sizeof(__pyx_k_file_header_lines), 0, 0, 1, 1},
+ {&__pyx_n_s_filename, __pyx_k_filename, sizeof(__pyx_k_filename), 0, 0, 1, 1},
+ {&__pyx_n_s_getLogger, __pyx_k_getLogger, sizeof(__pyx_k_getLogger), 0, 0, 1, 1},
+ {&__pyx_n_s_get_error_string, __pyx_k_get_error_string, sizeof(__pyx_k_get_error_string), 0, 0, 1, 1},
+ {&__pyx_n_s_get_mca, __pyx_k_get_mca, sizeof(__pyx_k_get_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_getitem, __pyx_k_getitem, sizeof(__pyx_k_getitem), 0, 0, 1, 1},
+ {&__pyx_n_s_group, __pyx_k_group, sizeof(__pyx_k_group), 0, 0, 1, 1},
+ {&__pyx_n_s_handle_error, __pyx_k_handle_error, sizeof(__pyx_k_handle_error), 0, 0, 1, 1},
+ {&__pyx_n_s_header, __pyx_k_header, sizeof(__pyx_k_header), 0, 0, 1, 1},
+ {&__pyx_n_s_header_2, __pyx_k_header_2, sizeof(__pyx_k_header_2), 0, 0, 1, 1},
+ {&__pyx_n_s_hkey, __pyx_k_hkey, sizeof(__pyx_k_hkey), 0, 0, 1, 1},
+ {&__pyx_n_s_hvalue, __pyx_k_hvalue, sizeof(__pyx_k_hvalue), 0, 0, 1, 1},
+ {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_increment, __pyx_k_increment, sizeof(__pyx_k_increment), 0, 0, 1, 1},
+ {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1},
+ {&__pyx_n_s_index_2, __pyx_k_index_2, sizeof(__pyx_k_index_2), 0, 0, 1, 1},
+ {&__pyx_n_s_init, __pyx_k_init, sizeof(__pyx_k_init), 0, 0, 1, 1},
+ {&__pyx_n_s_is_specfile, __pyx_k_is_specfile, sizeof(__pyx_k_is_specfile), 0, 0, 1, 1},
+ {&__pyx_n_s_isfile, __pyx_k_isfile, sizeof(__pyx_k_isfile), 0, 0, 1, 1},
+ {&__pyx_n_s_iter, __pyx_k_iter, sizeof(__pyx_k_iter), 0, 0, 1, 1},
+ {&__pyx_n_s_join, __pyx_k_join, sizeof(__pyx_k_join), 0, 0, 1, 1},
+ {&__pyx_n_s_key, __pyx_k_key, sizeof(__pyx_k_key), 0, 0, 1, 1},
+ {&__pyx_n_s_keys, __pyx_k_keys, sizeof(__pyx_k_keys), 0, 0, 1, 1},
+ {&__pyx_n_s_label, __pyx_k_label, sizeof(__pyx_k_label), 0, 0, 1, 1},
+ {&__pyx_n_s_labels, __pyx_k_labels, sizeof(__pyx_k_labels), 0, 0, 1, 1},
+ {&__pyx_n_s_labels_2, __pyx_k_labels_2, sizeof(__pyx_k_labels_2), 0, 0, 1, 1},
+ {&__pyx_n_s_len, __pyx_k_len, sizeof(__pyx_k_len), 0, 0, 1, 1},
+ {&__pyx_n_s_length, __pyx_k_length, sizeof(__pyx_k_length), 0, 0, 1, 1},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_line, __pyx_k_line, sizeof(__pyx_k_line), 0, 0, 1, 1},
+ {&__pyx_n_s_line_index, __pyx_k_line_index, sizeof(__pyx_k_line_index), 0, 0, 1, 1},
+ {&__pyx_n_s_list, __pyx_k_list, sizeof(__pyx_k_list), 0, 0, 1, 1},
+ {&__pyx_n_s_logger, __pyx_k_logger, sizeof(__pyx_k_logger), 0, 0, 1, 1},
+ {&__pyx_n_s_logging, __pyx_k_logging, sizeof(__pyx_k_logging), 0, 0, 1, 1},
+ {&__pyx_n_s_lstrip, __pyx_k_lstrip, sizeof(__pyx_k_lstrip), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_map, __pyx_k_map, sizeof(__pyx_k_map), 0, 0, 1, 1},
+ {&__pyx_n_s_match, __pyx_k_match, sizeof(__pyx_k_match), 0, 0, 1, 1},
+ {&__pyx_n_s_match_mca, __pyx_k_match_mca, sizeof(__pyx_k_match_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_mca, __pyx_k_mca, sizeof(__pyx_k_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_mca_2, __pyx_k_mca_2, sizeof(__pyx_k_mca_2), 0, 0, 1, 1},
+ {&__pyx_n_s_mca_header_dict, __pyx_k_mca_header_dict, sizeof(__pyx_k_mca_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_mca_header_dict_2, __pyx_k_mca_header_dict_2, sizeof(__pyx_k_mca_header_dict_2), 0, 0, 1, 1},
+ {&__pyx_n_s_mca_index, __pyx_k_mca_index, sizeof(__pyx_k_mca_index), 0, 0, 1, 1},
+ {&__pyx_n_s_metaclass, __pyx_k_metaclass, sizeof(__pyx_k_metaclass), 0, 0, 1, 1},
+ {&__pyx_n_s_module, __pyx_k_module, sizeof(__pyx_k_module), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_names, __pyx_k_motor_names, sizeof(__pyx_k_motor_names), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_names_2, __pyx_k_motor_names_2, sizeof(__pyx_k_motor_names_2), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_position_by_name, __pyx_k_motor_position_by_name, sizeof(__pyx_k_motor_position_by_name), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_positions, __pyx_k_motor_positions, sizeof(__pyx_k_motor_positions), 0, 0, 1, 1},
+ {&__pyx_n_s_motor_positions_2, __pyx_k_motor_positions_2, sizeof(__pyx_k_motor_positions_2), 0, 0, 1, 1},
+ {&__pyx_n_s_msg, __pyx_k_msg, sizeof(__pyx_k_msg), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+ {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+ {&__pyx_n_s_number, __pyx_k_number, sizeof(__pyx_k_number), 0, 0, 1, 1},
+ {&__pyx_n_s_number_2, __pyx_k_number_2, sizeof(__pyx_k_number_2), 0, 0, 1, 1},
+ {&__pyx_kp_s_number_and_M_the_order_eg_2_3, __pyx_k_number_and_M_the_order_eg_2_3, sizeof(__pyx_k_number_and_M_the_order_eg_2_3), 0, 0, 1, 0},
+ {&__pyx_n_s_number_of_mca, __pyx_k_number_of_mca, sizeof(__pyx_k_number_of_mca), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_object, __pyx_k_object, sizeof(__pyx_k_object), 0, 0, 1, 1},
+ {&__pyx_n_s_one_line_calib_values, __pyx_k_one_line_calib_values, sizeof(__pyx_k_one_line_calib_values), 0, 0, 1, 1},
+ {&__pyx_n_s_one_line_chann_values, __pyx_k_one_line_chann_values, sizeof(__pyx_k_one_line_chann_values), 0, 0, 1, 1},
+ {&__pyx_n_s_open, __pyx_k_open, sizeof(__pyx_k_open), 0, 0, 1, 1},
+ {&__pyx_n_s_order, __pyx_k_order, sizeof(__pyx_k_order), 0, 0, 1, 1},
+ {&__pyx_n_s_order_2, __pyx_k_order_2, sizeof(__pyx_k_order_2), 0, 0, 1, 1},
+ {&__pyx_n_s_os, __pyx_k_os, sizeof(__pyx_k_os), 0, 0, 1, 1},
+ {&__pyx_n_s_os_path, __pyx_k_os_path, sizeof(__pyx_k_os_path), 0, 0, 1, 1},
+ {&__pyx_kp_s_param_scan_Parent_Scan_instance, __pyx_k_param_scan_Parent_Scan_instance, sizeof(__pyx_k_param_scan_Parent_Scan_instance), 0, 0, 1, 0},
+ {&__pyx_kp_s_param_specfile_Parent_SpecFile, __pyx_k_param_specfile_Parent_SpecFile, sizeof(__pyx_k_param_specfile_Parent_SpecFile), 0, 0, 1, 0},
+ {&__pyx_n_s_parse_calibration, __pyx_k_parse_calibration, sizeof(__pyx_k_parse_calibration), 0, 0, 1, 1},
+ {&__pyx_n_s_parse_channels, __pyx_k_parse_channels, sizeof(__pyx_k_parse_channels), 0, 0, 1, 1},
+ {&__pyx_n_s_path, __pyx_k_path, sizeof(__pyx_k_path), 0, 0, 1, 1},
+ {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1},
+ {&__pyx_n_s_property, __pyx_k_property, sizeof(__pyx_k_property), 0, 0, 1, 1},
+ {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_re, __pyx_k_re, sizeof(__pyx_k_re), 0, 0, 1, 1},
+ {&__pyx_n_s_record, __pyx_k_record, sizeof(__pyx_k_record), 0, 0, 1, 1},
+ {&__pyx_n_s_record_exists_in_hdr, __pyx_k_record_exists_in_hdr, sizeof(__pyx_k_record_exists_in_hdr), 0, 0, 1, 1},
+ {&__pyx_n_s_ret, __pyx_k_ret, sizeof(__pyx_k_ret), 0, 0, 1, 1},
+ {&__pyx_n_s_scan, __pyx_k_scan, sizeof(__pyx_k_scan), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_2, __pyx_k_scan_2, sizeof(__pyx_k_scan_2), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_header, __pyx_k_scan_header, sizeof(__pyx_k_scan_header), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_header_dict, __pyx_k_scan_header_dict, sizeof(__pyx_k_scan_header_dict), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_header_dict_2, __pyx_k_scan_header_dict_2, sizeof(__pyx_k_scan_header_dict_2), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_header_lines, __pyx_k_scan_header_lines, sizeof(__pyx_k_scan_header_lines), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_index, __pyx_k_scan_index, sizeof(__pyx_k_scan_index), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_number, __pyx_k_scan_number, sizeof(__pyx_k_scan_number), 0, 0, 1, 1},
+ {&__pyx_n_s_scan_order, __pyx_k_scan_order, sizeof(__pyx_k_scan_order), 0, 0, 1, 1},
+ {&__pyx_n_s_search, __pyx_k_search, sizeof(__pyx_k_search), 0, 0, 1, 1},
+ {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1},
+ {&__pyx_n_s_send, __pyx_k_send, sizeof(__pyx_k_send), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_specfile, __pyx_k_specfile, sizeof(__pyx_k_specfile), 0, 0, 1, 1},
+ {&__pyx_n_s_specfile_2, __pyx_k_specfile_2, sizeof(__pyx_k_specfile_2), 0, 0, 1, 1},
+ {&__pyx_n_s_split, __pyx_k_split, sizeof(__pyx_k_split), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_startswith, __pyx_k_startswith, sizeof(__pyx_k_startswith), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_n_s_string, __pyx_k_string, sizeof(__pyx_k_string), 0, 0, 1, 1},
+ {&__pyx_n_s_string_to_char_star, __pyx_k_string_to_char_star, sizeof(__pyx_k_string_to_char_star), 0, 0, 1, 1},
+ {&__pyx_n_s_strip, __pyx_k_strip, sizeof(__pyx_k_strip), 0, 0, 1, 1},
+ {&__pyx_n_s_sub, __pyx_k_sub, sizeof(__pyx_k_sub), 0, 0, 1, 1},
+ {&__pyx_n_s_sys, __pyx_k_sys, sizeof(__pyx_k_sys), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_kp_s_the_unique_scan_index_or_a_strin, __pyx_k_the_unique_scan_index_or_a_strin, sizeof(__pyx_k_the_unique_scan_index_or_a_strin), 0, 0, 1, 0},
+ {&__pyx_n_s_throw, __pyx_k_throw, sizeof(__pyx_k_throw), 0, 0, 1, 1},
+ {&__pyx_n_s_transpose, __pyx_k_transpose, sizeof(__pyx_k_transpose), 0, 0, 1, 1},
+ {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+ {&__pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_k_users_payno_Documents_dev_esrf, sizeof(__pyx_k_users_payno_Documents_dev_esrf), 0, 0, 1, 0},
+ {&__pyx_n_s_value, __pyx_k_value, sizeof(__pyx_k_value), 0, 0, 1, 1},
+ {&__pyx_n_s_version, __pyx_k_version, sizeof(__pyx_k_version), 0, 0, 1, 1},
+ {&__pyx_n_s_version_info, __pyx_k_version_info, sizeof(__pyx_k_version_info), 0, 0, 1, 1},
+ {&__pyx_kp_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 0},
+ {&__pyx_kp_s_w_2, __pyx_k_w_2, sizeof(__pyx_k_w_2), 0, 0, 1, 0},
+ {&__pyx_n_s_warning, __pyx_k_warning, sizeof(__pyx_k_warning), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_Exception = __Pyx_GetBuiltinName(__pyx_n_s_Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_property = __Pyx_GetBuiltinName(__pyx_n_s_property); if (!__pyx_builtin_property) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_map = __Pyx_GetBuiltinName(__pyx_n_s_map); if (!__pyx_builtin_map) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_open = __Pyx_GetBuiltinName(__pyx_n_s_open); if (!__pyx_builtin_open) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 637; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "specfile.pyx":256
+ * # Channels list
+ * if "CHANN" in self._header:
+ * chann_lines = self._header["CHANN"].split("\n") # <<<<<<<<<<<<<<
+ * all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ * for one_line_chann_values in all_chann_values:
+ */
+ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "specfile.pyx":271
+ * # Channels list
+ * if "CALIB" in self._header:
+ * calib_lines = self._header["CALIB"].split("\n") # <<<<<<<<<<<<<<
+ * all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ * for one_line_calib_values in all_calib_values:
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "specfile.pyx":297
+ * """
+ * if not len(self):
+ * raise IndexError("No MCA spectrum found in this scan") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(key, int):
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_No_MCA_spectrum_found_in_this_sc); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "specfile.pyx":335
+ * dictionary[key] += "\n" + value
+ * except TypeError:
+ * raise TypeError("Parameter value must be a string.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_Parameter_value_must_be_a_string); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "specfile.pyx":383
+ * match_mca = re.search(r"#@(\w+) *(.*)", line)
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s__7); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "specfile.pyx":384
+ * if match:
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca:
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_int_2); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "specfile.pyx":387
+ * _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match_mca.group(2).strip()
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s__7); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+
+ /* "specfile.pyx":388
+ * elif match_mca:
+ * hkey = match_mca.group(1).lstrip("#").strip()
+ * hvalue = match_mca.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ * else:
+ */
+ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_int_2); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__12);
+ __Pyx_GIVEREF(__pyx_tuple__12);
+
+ /* "specfile.pyx":395
+ *
+ * self._labels = []
+ * if self.record_exists_in_hdr('L'): # <<<<<<<<<<<<<<
+ * try:
+ * self._labels = self._specfile.labels(self._index)
+ */
+ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_n_s_L); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__13);
+ __Pyx_GIVEREF(__pyx_tuple__13);
+
+ /* "specfile.pyx":403
+ * L_header = re.sub(r" {2,}", " ", # max. 2 spaces
+ * self._scan_header_dict["L"])
+ * self._labels = L_header.split(" ") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s__14); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+
+ /* "specfile.pyx":411
+ * if match:
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip() # <<<<<<<<<<<<<<
+ * hvalue = match.group(2).strip()
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ */
+ __pyx_tuple__16 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s__7); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+
+ /* "specfile.pyx":412
+ * # header type
+ * hkey = match.group(1).lstrip("#").strip()
+ * hvalue = match.group(2).strip() # <<<<<<<<<<<<<<
+ * _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ * else:
+ */
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_int_2); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+
+ /* "specfile.pyx":583
+ * # attribute data corresponds to a transposed version of the original
+ * # specfile data (where detectors correspond to columns)
+ * return self.data[:, line_index] # <<<<<<<<<<<<<<
+ *
+ * def data_column_by_name(self, label):
+ */
+ __pyx_slice__19 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 583; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__19);
+ __Pyx_GIVEREF(__pyx_slice__19);
+
+ /* "specfile.pyx":601
+ * _logger.warning("Cannot get data column %s in scan %d.%d",
+ * label, self.number, self.order)
+ * ret = numpy.empty((0, ), numpy.double) # <<<<<<<<<<<<<<
+ * return ret
+ *
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_int_0); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+
+ /* "specfile.pyx":620
+ * def _string_to_char_star(string_):
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes): # <<<<<<<<<<<<<<
+ * return bytes(string_, "ascii")
+ * return string_
+ */
+ __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_3); if (unlikely(!__pyx_tuple__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__21);
+ __Pyx_GIVEREF(__pyx_tuple__21);
+
+ /* "specfile.pyx":638
+ * f = open(filename)
+ * for i, line in enumerate(f):
+ * if line.startswith("#S ") or line.startswith("#F "): # <<<<<<<<<<<<<<
+ * f.close()
+ * return True
+ */
+ __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_S); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__22);
+ __Pyx_GIVEREF(__pyx_tuple__22);
+ __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_F); if (unlikely(!__pyx_tuple__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__23);
+ __Pyx_GIVEREF(__pyx_tuple__23);
+
+ /* "specfile.pyx":691
+ * if not self.__open_failed:
+ * if specfile_wrapper.SfClose(self.handle):
+ * _logger.warning("Error while closing SpecFile") # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_Error_while_closing_SpecFile); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 691; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__24);
+ __Pyx_GIVEREF(__pyx_tuple__24);
+
+ /* "specfile.pyx":734
+ * else:
+ * try:
+ * (number, order) = map(int, key.split(".")) # <<<<<<<<<<<<<<
+ * scan_index = self.index(number, order)
+ * except (ValueError, SfErrScanNotFound, KeyError):
+ */
+ __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s__25); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__26);
+ __Pyx_GIVEREF(__pyx_tuple__26);
+
+ /* "specfile.pyx":1234
+ * # error code updating isn't implemented in SfMcaCalib
+ * if mca_calib_error:
+ * raise KeyError("MCA calibration line (@CALIB) not found") # <<<<<<<<<<<<<<
+ *
+ * mca_calib_list = []
+ */
+ __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_MCA_calibration_line_CALIB_not_f); if (unlikely(!__pyx_tuple__30)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__30);
+ __Pyx_GIVEREF(__pyx_tuple__30);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__31)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__31);
+ __Pyx_GIVEREF(__pyx_tuple__31);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__32)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__32);
+ __Pyx_GIVEREF(__pyx_tuple__32);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_tuple__33 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__33);
+ __Pyx_GIVEREF(__pyx_tuple__33);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_tuple__34 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__34)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__34);
+ __Pyx_GIVEREF(__pyx_tuple__34);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_tuple__35 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__35)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__35);
+ __Pyx_GIVEREF(__pyx_tuple__35);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_tuple__36 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__36)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__36);
+ __Pyx_GIVEREF(__pyx_tuple__36);
+
+ /* "specfile.pyx":234
+ *
+ * """
+ * def __init__(self, scan): # <<<<<<<<<<<<<<
+ * self._scan = scan
+ *
+ */
+ __pyx_tuple__37 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_scan); if (unlikely(!__pyx_tuple__37)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__37);
+ __Pyx_GIVEREF(__pyx_tuple__37);
+ __pyx_codeobj__38 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_init, 234, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__38)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":252
+ * self._parse_channels()
+ *
+ * def _parse_channels(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ */
+ __pyx_tuple__39 = PyTuple_Pack(9, __pyx_n_s_self, __pyx_n_s_chann_lines, __pyx_n_s_all_chann_values, __pyx_n_s_one_line_chann_values, __pyx_n_s_length, __pyx_n_s_start, __pyx_n_s_stop, __pyx_n_s_increment, __pyx_n_s_chann_line); if (unlikely(!__pyx_tuple__39)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__39);
+ __Pyx_GIVEREF(__pyx_tuple__39);
+ __pyx_codeobj__40 = (PyObject*)__Pyx_PyCode_New(1, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__39, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_parse_channels, 252, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__40)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":267
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ * def _parse_calibration(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ */
+ __pyx_tuple__41 = PyTuple_Pack(5, __pyx_n_s_self, __pyx_n_s_calib_lines, __pyx_n_s_all_calib_values, __pyx_n_s_one_line_calib_values, __pyx_n_s_calib_line); if (unlikely(!__pyx_tuple__41)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__41);
+ __Pyx_GIVEREF(__pyx_tuple__41);
+ __pyx_codeobj__42 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__41, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_parse_calibration, 267, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__42)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":279
+ * self.calibration.append([0., 1., 0.])
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_tuple__43 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__43)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__43);
+ __Pyx_GIVEREF(__pyx_tuple__43);
+ __pyx_codeobj__44 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__43, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_len, 279, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":287
+ * return self._scan._specfile.number_of_mca(self._scan.index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a single MCA data line
+ *
+ */
+ __pyx_tuple__45 = PyTuple_Pack(4, __pyx_n_s_self, __pyx_n_s_key, __pyx_n_s_mca_index, __pyx_n_s_msg); if (unlikely(!__pyx_tuple__45)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__45);
+ __Pyx_GIVEREF(__pyx_tuple__45);
+ __pyx_codeobj__46 = (PyObject*)__Pyx_PyCode_New(2, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__45, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_getitem, 287, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+ __pyx_tuple__47 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_mca_index); if (unlikely(!__pyx_tuple__47)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__47);
+ __Pyx_GIVEREF(__pyx_tuple__47);
+ __pyx_codeobj__48 = (PyObject*)__Pyx_PyCode_New(1, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__47, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_iter, 315, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__48)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":325
+ *
+ *
+ * def _add_or_concatenate(dictionary, key, value): # <<<<<<<<<<<<<<
+ * """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ * Else append/concatenate the new value to the existing one
+ */
+ __pyx_tuple__49 = PyTuple_Pack(3, __pyx_n_s_dictionary, __pyx_n_s_key, __pyx_n_s_value); if (unlikely(!__pyx_tuple__49)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__49);
+ __Pyx_GIVEREF(__pyx_tuple__49);
+ __pyx_codeobj__50 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__49, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_add_or_concatenate, 325, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__50)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":363
+ * scan2 = sf["3.1"]
+ * """
+ * def __init__(self, specfile, scan_index): # <<<<<<<<<<<<<<
+ * self._specfile = specfile
+ *
+ */
+ __pyx_tuple__51 = PyTuple_Pack(9, __pyx_n_s_self, __pyx_n_s_specfile_2, __pyx_n_s_scan_index, __pyx_n_s_line, __pyx_n_s_match, __pyx_n_s_match_mca, __pyx_n_s_hkey, __pyx_n_s_hvalue, __pyx_n_s_L_header); if (unlikely(!__pyx_tuple__51)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__51);
+ __Pyx_GIVEREF(__pyx_tuple__51);
+ __pyx_codeobj__52 = (PyObject*)__Pyx_PyCode_New(3, 0, 9, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__51, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_init, 363, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__52)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":425
+ * @cython.embedsignature(False)
+ * @property
+ * def index(self): # <<<<<<<<<<<<<<
+ * """Unique scan index 0 - len(specfile)-1
+ *
+ */
+ __pyx_tuple__53 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__53)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__53);
+ __Pyx_GIVEREF(__pyx_tuple__53);
+ __pyx_codeobj__54 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__53, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_index, 425, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__54)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":435
+ * @cython.embedsignature(False)
+ * @property
+ * def number(self): # <<<<<<<<<<<<<<
+ * """First value on #S line (as int)"""
+ * return self._number
+ */
+ __pyx_tuple__55 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__55)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__55);
+ __Pyx_GIVEREF(__pyx_tuple__55);
+ __pyx_codeobj__56 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__55, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_number, 435, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__56)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":441
+ * @cython.embedsignature(False)
+ * @property
+ * def order(self): # <<<<<<<<<<<<<<
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order
+ */
+ __pyx_tuple__57 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__57)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__57);
+ __Pyx_GIVEREF(__pyx_tuple__57);
+ __pyx_codeobj__58 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__57, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_order, 441, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__58)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":447
+ * @cython.embedsignature(False)
+ * @property
+ * def header(self): # <<<<<<<<<<<<<<
+ * """List of raw header lines (as a list of strings).
+ *
+ */
+ __pyx_tuple__59 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__59)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__59);
+ __Pyx_GIVEREF(__pyx_tuple__59);
+ __pyx_codeobj__60 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__59, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_header_2, 447, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__60)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":457
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header(self): # <<<<<<<<<<<<<<
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ */
+ __pyx_tuple__61 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__61)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__61);
+ __Pyx_GIVEREF(__pyx_tuple__61);
+ __pyx_codeobj__62 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__61, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_scan_header, 457, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__62)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":464
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header(self): # <<<<<<<<<<<<<<
+ * """List of raw file header lines (as a list of strings).
+ * """
+ */
+ __pyx_tuple__63 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__63)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__63);
+ __Pyx_GIVEREF(__pyx_tuple__63);
+ __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_file_header, 464, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":471
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of scan header strings, keys without the leading``#``
+ */
+ __pyx_tuple__65 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__65)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__65);
+ __Pyx_GIVEREF(__pyx_tuple__65);
+ __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_scan_header_dict_2, 471, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":481
+ * @cython.embedsignature(False)
+ * @property
+ * def mca_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of MCA header strings, keys without the leading ``#@``
+ */
+ __pyx_tuple__67 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__67)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__67);
+ __Pyx_GIVEREF(__pyx_tuple__67);
+ __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_mca_header_dict, 481, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":490
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of file header strings, keys without the leading ``#``
+ */
+ __pyx_tuple__69 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__69)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__69);
+ __Pyx_GIVEREF(__pyx_tuple__69);
+ __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_file_header_dict_2, 490, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":499
+ * @cython.embedsignature(False)
+ * @property
+ * def labels(self): # <<<<<<<<<<<<<<
+ * """
+ * List of data column headers from ``#L`` scan header
+ */
+ __pyx_tuple__71 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__71)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__71);
+ __Pyx_GIVEREF(__pyx_tuple__71);
+ __pyx_codeobj__72 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__71, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_labels_2, 499, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__72)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":507
+ * @cython.embedsignature(False)
+ * @property
+ * def data(self): # <<<<<<<<<<<<<<
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ * (e.g. data.shape).
+ */
+ __pyx_tuple__73 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__73)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__73);
+ __Pyx_GIVEREF(__pyx_tuple__73);
+ __pyx_codeobj__74 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__73, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_data_2, 507, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__74)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":520
+ * @cython.embedsignature(False)
+ * @property
+ * def mca(self): # <<<<<<<<<<<<<<
+ * """MCA data in this scan.
+ *
+ */
+ __pyx_tuple__75 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__75)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__75);
+ __Pyx_GIVEREF(__pyx_tuple__75);
+ __pyx_codeobj__76 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__75, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_mca_2, 520, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__76)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":534
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_names(self): # <<<<<<<<<<<<<<
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ */
+ __pyx_tuple__77 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__77)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__77);
+ __Pyx_GIVEREF(__pyx_tuple__77);
+ __pyx_codeobj__78 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__77, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_motor_names, 534, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__78)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":541
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_positions(self): # <<<<<<<<<<<<<<
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ */
+ __pyx_tuple__79 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__79)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__79);
+ __Pyx_GIVEREF(__pyx_tuple__79);
+ __pyx_codeobj__80 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__79, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_motor_positions, 541, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__80)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":546
+ * return self._motor_positions
+ *
+ * def record_exists_in_hdr(self, record): # <<<<<<<<<<<<<<
+ * """Check whether a scan header line exists.
+ *
+ */
+ __pyx_tuple__81 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_record, __pyx_n_s_line); if (unlikely(!__pyx_tuple__81)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__81);
+ __Pyx_GIVEREF(__pyx_tuple__81);
+ __pyx_codeobj__82 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__81, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_record_exists_in_hdr, 546, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__82)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":565
+ * return False
+ *
+ * def data_line(self, line_index): # <<<<<<<<<<<<<<
+ * """Returns data for a given line of this scan.
+ *
+ */
+ __pyx_tuple__83 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_line_index); if (unlikely(!__pyx_tuple__83)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__83);
+ __Pyx_GIVEREF(__pyx_tuple__83);
+ __pyx_codeobj__84 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__83, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_data_line, 565, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__84)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":585
+ * return self.data[:, line_index]
+ *
+ * def data_column_by_name(self, label): # <<<<<<<<<<<<<<
+ * """Returns a data column
+ *
+ */
+ __pyx_tuple__85 = PyTuple_Pack(3, __pyx_n_s_self, __pyx_n_s_label, __pyx_n_s_ret); if (unlikely(!__pyx_tuple__85)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__85);
+ __Pyx_GIVEREF(__pyx_tuple__85);
+ __pyx_codeobj__86 = (PyObject*)__Pyx_PyCode_New(2, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__85, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_data_column_by_name, 585, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__86)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":605
+ *
+ *
+ * def motor_position_by_name(self, name): # <<<<<<<<<<<<<<
+ * """Returns the position for a given motor
+ *
+ */
+ __pyx_tuple__87 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_name); if (unlikely(!__pyx_tuple__87)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__87);
+ __Pyx_GIVEREF(__pyx_tuple__87);
+ __pyx_codeobj__88 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__87, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_motor_position_by_name, 605, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__88)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":618
+ *
+ *
+ * def _string_to_char_star(string_): # <<<<<<<<<<<<<<
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ */
+ __pyx_tuple__89 = PyTuple_Pack(1, __pyx_n_s_string); if (unlikely(!__pyx_tuple__89)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__89);
+ __Pyx_GIVEREF(__pyx_tuple__89);
+ __pyx_codeobj__90 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__89, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_string_to_char_star, 618, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__90)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":625
+ *
+ *
+ * def is_specfile(filename): # <<<<<<<<<<<<<<
+ * """Test if a file is a SPEC file, by checking if one of the first two
+ * lines starts with *#F* (SPEC file header) or *#S* (scan header).
+ */
+ __pyx_tuple__91 = PyTuple_Pack(4, __pyx_n_s_filename, __pyx_n_s_f, __pyx_n_s_i, __pyx_n_s_line); if (unlikely(!__pyx_tuple__91)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__91);
+ __Pyx_GIVEREF(__pyx_tuple__91);
+ __pyx_codeobj__92 = (PyObject*)__Pyx_PyCode_New(1, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__91, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_is_specfile, 625, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__92)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_float_0_ = PyFloat_FromDouble(0.); if (unlikely(!__pyx_float_0_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_float_1_ = PyFloat_FromDouble(1.); if (unlikely(!__pyx_float_1_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_6 = PyInt_FromLong(6); if (unlikely(!__pyx_int_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_7 = PyInt_FromLong(7); if (unlikely(!__pyx_int_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_8 = PyInt_FromLong(8); if (unlikely(!__pyx_int_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_9 = PyInt_FromLong(9); if (unlikely(!__pyx_int_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_10 = PyInt_FromLong(10); if (unlikely(!__pyx_int_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_11 = PyInt_FromLong(11); if (unlikely(!__pyx_int_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_12 = PyInt_FromLong(12); if (unlikely(!__pyx_int_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_13 = PyInt_FromLong(13); if (unlikely(!__pyx_int_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_14 = PyInt_FromLong(14); if (unlikely(!__pyx_int_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_15 = PyInt_FromLong(15); if (unlikely(!__pyx_int_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initspecfile(void); /*proto*/
+PyMODINIT_FUNC initspecfile(void)
+#else
+PyMODINIT_FUNC PyInit_specfile(void); /*proto*/
+PyMODINIT_FUNC PyInit_specfile(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_specfile(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("specfile", __pyx_methods, __pyx_k_This_module_is_a_cython_binding, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_specfile) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "specfile")) {
+ if (unlikely(PyDict_SetItemString(modules, "specfile", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type_8specfile_SpecFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_8specfile_SpecFile.tp_print = 0;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_8specfile_SpecFile, "__len__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_8specfile_8SpecFile_6__len__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_8specfile_8SpecFile_6__len__.doc = __pyx_doc_8specfile_8SpecFile_6__len__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_8specfile_8SpecFile_6__len__;
+ }
+ }
+ #endif
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_8specfile_SpecFile, "__iter__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_8specfile_8SpecFile_8__iter__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_8specfile_8SpecFile_8__iter__.doc = __pyx_doc_8specfile_8SpecFile_8__iter__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_8specfile_8SpecFile_8__iter__;
+ }
+ }
+ #endif
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_8specfile_SpecFile, "__getitem__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_8specfile_8SpecFile_11__getitem__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_8specfile_8SpecFile_11__getitem__.doc = __pyx_doc_8specfile_8SpecFile_11__getitem__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_8specfile_8SpecFile_11__getitem__;
+ }
+ }
+ #endif
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_8specfile_SpecFile, "__contains__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_8specfile_8SpecFile_15__contains__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_8specfile_8SpecFile_15__contains__.doc = __pyx_doc_8specfile_8SpecFile_15__contains__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_8specfile_8SpecFile_15__contains__;
+ }
+ }
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "SpecFile", (PyObject *)&__pyx_type_8specfile_SpecFile) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_8specfile_SpecFile = &__pyx_type_8specfile_SpecFile;
+ if (PyType_Ready(&__pyx_type_8specfile___pyx_scope_struct____iter__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_8specfile___pyx_scope_struct____iter__.tp_print = 0;
+ __pyx_ptype_8specfile___pyx_scope_struct____iter__ = &__pyx_type_8specfile___pyx_scope_struct____iter__;
+ if (PyType_Ready(&__pyx_type_8specfile___pyx_scope_struct_1___iter__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_8specfile___pyx_scope_struct_1___iter__.tp_print = 0;
+ __pyx_ptype_8specfile___pyx_scope_struct_1___iter__ = &__pyx_type_8specfile___pyx_scope_struct_1___iter__;
+ /*--- Type import code ---*/
+ __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type",
+ #if CYTHON_COMPILING_IN_PYPY
+ sizeof(PyTypeObject),
+ #else
+ sizeof(PyHeapTypeObject),
+ #endif
+ 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "specfile.pyx":106
+ * """
+ *
+ * __authors__ = ["P. Knobel"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "27/09/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_P_Knobel);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_P_Knobel);
+ __Pyx_GIVEREF(__pyx_kp_s_P_Knobel);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":107
+ *
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "27/09/2016"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":108
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT"
+ * __date__ = "27/09/2016" # <<<<<<<<<<<<<<
+ *
+ * import os.path
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_27_09_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":110
+ * __date__ = "27/09/2016"
+ *
+ * import os.path # <<<<<<<<<<<<<<
+ * import logging
+ * import numpy
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_os_path, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_os, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":111
+ *
+ * import os.path
+ * import logging # <<<<<<<<<<<<<<
+ * import numpy
+ * import re
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":112
+ * import os.path
+ * import logging
+ * import numpy # <<<<<<<<<<<<<<
+ * import re
+ * import sys
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":113
+ * import logging
+ * import numpy
+ * import re # <<<<<<<<<<<<<<
+ * import sys
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_re, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_re, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":114
+ * import numpy
+ * import re
+ * import sys # <<<<<<<<<<<<<<
+ *
+ * logging.basicConfig()
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_sys, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sys, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":116
+ * import sys
+ *
+ * logging.basicConfig() # <<<<<<<<<<<<<<
+ * _logger = logging.getLogger(__name__)
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_basicConfig); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":117
+ *
+ * logging.basicConfig()
+ * _logger = logging.getLogger(__name__) # <<<<<<<<<<<<<<
+ *
+ * cimport numpy
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_getLogger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_name_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logger, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":132
+ * void import_umath()
+ *
+ * if FALSE: # <<<<<<<<<<<<<<
+ * import_array()
+ * import_umath()
+ */
+ __pyx_t_6 = (0 != 0);
+ if (__pyx_t_6) {
+
+ /* "specfile.pyx":133
+ *
+ * if FALSE:
+ * import_array() # <<<<<<<<<<<<<<
+ * import_umath()
+ *
+ */
+ import_array();
+
+ /* "specfile.pyx":134
+ * if FALSE:
+ * import_array()
+ * import_umath() # <<<<<<<<<<<<<<
+ *
+ * numpy.import_array()
+ */
+ import_umath();
+ goto __pyx_L2;
+ }
+ __pyx_L2:;
+
+ /* "specfile.pyx":136
+ * import_umath()
+ *
+ * numpy.import_array() # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ import_array();
+
+ /* "specfile.pyx":139
+ *
+ *
+ * SF_ERR_NO_ERRORS = 0 # <<<<<<<<<<<<<<
+ * SF_ERR_FILE_OPEN = 2
+ * SF_ERR_SCAN_NOT_FOUND = 7
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SF_ERR_NO_ERRORS, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":140
+ *
+ * SF_ERR_NO_ERRORS = 0
+ * SF_ERR_FILE_OPEN = 2 # <<<<<<<<<<<<<<
+ * SF_ERR_SCAN_NOT_FOUND = 7
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SF_ERR_FILE_OPEN, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":141
+ * SF_ERR_NO_ERRORS = 0
+ * SF_ERR_FILE_OPEN = 2
+ * SF_ERR_SCAN_NOT_FOUND = 7 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SF_ERR_SCAN_NOT_FOUND, __pyx_int_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "specfile.pyx":145
+ *
+ * # custom errors
+ * class SfError(Exception): # <<<<<<<<<<<<<<
+ * """Base exception inherited by all exceptions raised when a
+ * C function from the legacy SpecFile library returns an error
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_builtin_Exception);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_builtin_Exception);
+ __Pyx_GIVEREF(__pyx_builtin_Exception);
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfError, __pyx_n_s_SfError, (PyObject *) NULL, __pyx_n_s_specfile_2, __pyx_kp_s_Base_exception_inherited_by_all); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfError, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfError, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":152
+ * pass
+ *
+ * class SfErrMemoryAlloc(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrFileOpen(SfError): pass
+ * class SfErrFileClose(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrMemoryAlloc, __pyx_n_s_SfErrMemoryAlloc, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrMemoryAlloc, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrMemoryAlloc, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":153
+ *
+ * class SfErrMemoryAlloc(SfError): pass
+ * class SfErrFileOpen(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrFileClose(SfError): pass
+ * class SfErrFileRead(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrFileOpen, __pyx_n_s_SfErrFileOpen, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrFileOpen, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrFileOpen, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":154
+ * class SfErrMemoryAlloc(SfError): pass
+ * class SfErrFileOpen(SfError): pass
+ * class SfErrFileClose(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrFileRead(SfError): pass
+ * class SfErrFileWrite(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrFileClose, __pyx_n_s_SfErrFileClose, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrFileClose, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrFileClose, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":155
+ * class SfErrFileOpen(SfError): pass
+ * class SfErrFileClose(SfError): pass
+ * class SfErrFileRead(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrFileWrite(SfError): pass
+ * class SfErrLineNotFound(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrFileRead, __pyx_n_s_SfErrFileRead, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrFileRead, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrFileRead, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":156
+ * class SfErrFileClose(SfError): pass
+ * class SfErrFileRead(SfError): pass
+ * class SfErrFileWrite(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrLineNotFound(SfError): pass
+ * class SfErrScanNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrFileWrite, __pyx_n_s_SfErrFileWrite, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrFileWrite, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrFileWrite, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":157
+ * class SfErrFileRead(SfError): pass
+ * class SfErrFileWrite(SfError): pass
+ * class SfErrLineNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrScanNotFound(SfError): pass
+ * class SfErrHeaderNotFound(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrLineNotFound, __pyx_n_s_SfErrLineNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrLineNotFound, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrLineNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":158
+ * class SfErrFileWrite(SfError): pass
+ * class SfErrLineNotFound(SfError): pass
+ * class SfErrScanNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrHeaderNotFound(SfError): pass
+ * class SfErrLabelNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrScanNotFound, __pyx_n_s_SfErrScanNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrScanNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrScanNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":159
+ * class SfErrLineNotFound(SfError): pass
+ * class SfErrScanNotFound(SfError): pass
+ * class SfErrHeaderNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrLabelNotFound(SfError): pass
+ * class SfErrMotorNotFound(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrHeaderNotFound, __pyx_n_s_SfErrHeaderNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrHeaderNotFound, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrHeaderNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":160
+ * class SfErrScanNotFound(SfError): pass
+ * class SfErrHeaderNotFound(SfError): pass
+ * class SfErrLabelNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrMotorNotFound(SfError): pass
+ * class SfErrPositionNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrLabelNotFound, __pyx_n_s_SfErrLabelNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrLabelNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrLabelNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":161
+ * class SfErrHeaderNotFound(SfError): pass
+ * class SfErrLabelNotFound(SfError): pass
+ * class SfErrMotorNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrPositionNotFound(SfError): pass
+ * class SfErrLineEmpty(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrMotorNotFound, __pyx_n_s_SfErrMotorNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrMotorNotFound, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrMotorNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":162
+ * class SfErrLabelNotFound(SfError): pass
+ * class SfErrMotorNotFound(SfError): pass
+ * class SfErrPositionNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrLineEmpty(SfError): pass
+ * class SfErrUserNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrPositionNotFound, __pyx_n_s_SfErrPositionNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrPositionNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrPositionNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":163
+ * class SfErrMotorNotFound(SfError): pass
+ * class SfErrPositionNotFound(SfError): pass
+ * class SfErrLineEmpty(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrUserNotFound(SfError): pass
+ * class SfErrColNotFound(SfError): pass
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrLineEmpty, __pyx_n_s_SfErrLineEmpty, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrLineEmpty, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrLineEmpty, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":164
+ * class SfErrPositionNotFound(SfError): pass
+ * class SfErrLineEmpty(SfError): pass
+ * class SfErrUserNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrColNotFound(SfError): pass
+ * class SfErrMcaNotFound(SfError): pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrUserNotFound, __pyx_n_s_SfErrUserNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrUserNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrUserNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":165
+ * class SfErrLineEmpty(SfError): pass
+ * class SfErrUserNotFound(SfError): pass
+ * class SfErrColNotFound(SfError): pass # <<<<<<<<<<<<<<
+ * class SfErrMcaNotFound(SfError): pass
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfErrColNotFound, __pyx_n_s_SfErrColNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfErrColNotFound, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrColNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":166
+ * class SfErrUserNotFound(SfError): pass
+ * class SfErrColNotFound(SfError): pass
+ * class SfErrMcaNotFound(SfError): pass # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_SfErrMcaNotFound, __pyx_n_s_SfErrMcaNotFound, (PyObject *) NULL, __pyx_n_s_specfile_2, (PyObject *) NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_SfErrMcaNotFound, __pyx_t_2, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfErrMcaNotFound, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":169
+ *
+ *
+ * ERRORS = { # <<<<<<<<<<<<<<
+ * 1: SfErrMemoryAlloc,
+ * 2: SfErrFileOpen,
+ */
+ __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+
+ /* "specfile.pyx":170
+ *
+ * ERRORS = {
+ * 1: SfErrMemoryAlloc, # <<<<<<<<<<<<<<
+ * 2: SfErrFileOpen,
+ * 3: SfErrFileClose,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrMemoryAlloc); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_1, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":171
+ * ERRORS = {
+ * 1: SfErrMemoryAlloc,
+ * 2: SfErrFileOpen, # <<<<<<<<<<<<<<
+ * 3: SfErrFileClose,
+ * 4: SfErrFileRead,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrFileOpen); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_2, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":172
+ * 1: SfErrMemoryAlloc,
+ * 2: SfErrFileOpen,
+ * 3: SfErrFileClose, # <<<<<<<<<<<<<<
+ * 4: SfErrFileRead,
+ * 5: SfErrFileWrite,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrFileClose); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_3, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":173
+ * 2: SfErrFileOpen,
+ * 3: SfErrFileClose,
+ * 4: SfErrFileRead, # <<<<<<<<<<<<<<
+ * 5: SfErrFileWrite,
+ * 6: SfErrLineNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrFileRead); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_4, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":174
+ * 3: SfErrFileClose,
+ * 4: SfErrFileRead,
+ * 5: SfErrFileWrite, # <<<<<<<<<<<<<<
+ * 6: SfErrLineNotFound,
+ * 7: SfErrScanNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrFileWrite); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_5, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":175
+ * 4: SfErrFileRead,
+ * 5: SfErrFileWrite,
+ * 6: SfErrLineNotFound, # <<<<<<<<<<<<<<
+ * 7: SfErrScanNotFound,
+ * 8: SfErrHeaderNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLineNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_6, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":176
+ * 5: SfErrFileWrite,
+ * 6: SfErrLineNotFound,
+ * 7: SfErrScanNotFound, # <<<<<<<<<<<<<<
+ * 8: SfErrHeaderNotFound,
+ * 9: SfErrLabelNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrScanNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_7, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":177
+ * 6: SfErrLineNotFound,
+ * 7: SfErrScanNotFound,
+ * 8: SfErrHeaderNotFound, # <<<<<<<<<<<<<<
+ * 9: SfErrLabelNotFound,
+ * 10: SfErrMotorNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrHeaderNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_8, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":178
+ * 7: SfErrScanNotFound,
+ * 8: SfErrHeaderNotFound,
+ * 9: SfErrLabelNotFound, # <<<<<<<<<<<<<<
+ * 10: SfErrMotorNotFound,
+ * 11: SfErrPositionNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLabelNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_9, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":179
+ * 8: SfErrHeaderNotFound,
+ * 9: SfErrLabelNotFound,
+ * 10: SfErrMotorNotFound, # <<<<<<<<<<<<<<
+ * 11: SfErrPositionNotFound,
+ * 12: SfErrLineEmpty,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrMotorNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_10, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":180
+ * 9: SfErrLabelNotFound,
+ * 10: SfErrMotorNotFound,
+ * 11: SfErrPositionNotFound, # <<<<<<<<<<<<<<
+ * 12: SfErrLineEmpty,
+ * 13: SfErrUserNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrPositionNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_11, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":181
+ * 10: SfErrMotorNotFound,
+ * 11: SfErrPositionNotFound,
+ * 12: SfErrLineEmpty, # <<<<<<<<<<<<<<
+ * 13: SfErrUserNotFound,
+ * 14: SfErrColNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrLineEmpty); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_12, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":182
+ * 11: SfErrPositionNotFound,
+ * 12: SfErrLineEmpty,
+ * 13: SfErrUserNotFound, # <<<<<<<<<<<<<<
+ * 14: SfErrColNotFound,
+ * 15: SfErrMcaNotFound,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrUserNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_13, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":183
+ * 12: SfErrLineEmpty,
+ * 13: SfErrUserNotFound,
+ * 14: SfErrColNotFound, # <<<<<<<<<<<<<<
+ * 15: SfErrMcaNotFound,
+ * }
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrColNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_14, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":184
+ * 13: SfErrUserNotFound,
+ * 14: SfErrColNotFound,
+ * 15: SfErrMcaNotFound, # <<<<<<<<<<<<<<
+ * }
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfErrMcaNotFound); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_2, __pyx_int_15, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_ERRORS, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "specfile.pyx":188
+ *
+ *
+ * class SfNoMcaError(SfError): # <<<<<<<<<<<<<<
+ * """Custom exception raised when ``SfNoMca()`` returns ``-1``
+ * """
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_SfError); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_SfNoMcaError, __pyx_n_s_SfNoMcaError, (PyObject *) NULL, __pyx_n_s_specfile_2, __pyx_kp_s_Custom_exception_raised_when_SfN); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_SfNoMcaError, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_SfNoMcaError, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":194
+ *
+ *
+ * class MCA(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_builtin_object);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_builtin_object);
+ __Pyx_GIVEREF(__pyx_builtin_object);
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_MCA, __pyx_n_s_MCA, (PyObject *) NULL, __pyx_n_s_specfile_2, __pyx_kp_s_param_scan_Parent_Scan_instance); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "specfile.pyx":234
+ *
+ * """
+ * def __init__(self, scan): # <<<<<<<<<<<<<<
+ * self._scan = scan
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_1__init__, 0, __pyx_n_s_MCA___init, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__38)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_init, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 234; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":252
+ * self._parse_channels()
+ *
+ * def _parse_channels(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`channels`"""
+ * # Channels list
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_3_parse_channels, 0, __pyx_n_s_MCA__parse_channels, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__40)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_parse_channels, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":267
+ * self.channels.append(list(range(start, stop + 1, increment)))
+ *
+ * def _parse_calibration(self): # <<<<<<<<<<<<<<
+ * """Fill :attr:`calibration`"""
+ * # Channels list
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_5_parse_calibration, 0, __pyx_n_s_MCA__parse_calibration, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__42)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_parse_calibration, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":279
+ * self.calibration.append([0., 1., 0.])
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_7__len__, 0, __pyx_n_s_MCA___len, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__44)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_len, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":287
+ * return self._scan._specfile.number_of_mca(self._scan.index)
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Return a single MCA data line
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_9__getitem__, 0, __pyx_n_s_MCA___getitem, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_getitem, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":315
+ * mca_index)
+ *
+ * def __iter__(self): # <<<<<<<<<<<<<<
+ * """Return the next MCA data line each time this method is called.
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_3MCA_11__iter__, 0, __pyx_n_s_MCA___iter, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_iter, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":194
+ *
+ *
+ * class MCA(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_MCA, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_MCA, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":325
+ *
+ *
+ * def _add_or_concatenate(dictionary, key, value): # <<<<<<<<<<<<<<
+ * """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ * Else append/concatenate the new value to the existing one
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8specfile_1_add_or_concatenate, NULL, __pyx_n_s_specfile_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_add_or_concatenate, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":338
+ *
+ *
+ * class Scan(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_builtin_object);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_builtin_object);
+ __Pyx_GIVEREF(__pyx_builtin_object);
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_Scan, __pyx_n_s_Scan, (PyObject *) NULL, __pyx_n_s_specfile_2, __pyx_kp_s_param_specfile_Parent_SpecFile); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "specfile.pyx":363
+ * scan2 = sf["3.1"]
+ * """
+ * def __init__(self, specfile, scan_index): # <<<<<<<<<<<<<<
+ * self._specfile = specfile
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_1__init__, 0, __pyx_n_s_Scan___init, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__52)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_init, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":425
+ * @cython.embedsignature(False)
+ * @property
+ * def index(self): # <<<<<<<<<<<<<<
+ * """Unique scan index 0 - len(specfile)-1
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_3index, 0, __pyx_n_s_Scan_index, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__54)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":424
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def index(self):
+ * """Unique scan index 0 - len(specfile)-1
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 424; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_index, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":435
+ * @cython.embedsignature(False)
+ * @property
+ * def number(self): # <<<<<<<<<<<<<<
+ * """First value on #S line (as int)"""
+ * return self._number
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_5number, 0, __pyx_n_s_Scan_number, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__56)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":434
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def number(self):
+ * """First value on #S line (as int)"""
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_number, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":441
+ * @cython.embedsignature(False)
+ * @property
+ * def order(self): # <<<<<<<<<<<<<<
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ * return self._order
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_7order, 0, __pyx_n_s_Scan_order, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__58)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":440
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def order(self):
+ * """Order can be > 1 if the same number is repeated in a specfile"""
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":447
+ * @cython.embedsignature(False)
+ * @property
+ * def header(self): # <<<<<<<<<<<<<<
+ * """List of raw header lines (as a list of strings).
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_9header, 0, __pyx_n_s_Scan_header, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__60)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":446
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def header(self):
+ * """List of raw header lines (as a list of strings).
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_header_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":457
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header(self): # <<<<<<<<<<<<<<
+ * """List of raw scan header lines (as a list of strings).
+ * """
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_11scan_header, 0, __pyx_n_s_Scan_scan_header, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__62)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":456
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def scan_header(self):
+ * """List of raw scan header lines (as a list of strings).
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_scan_header, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":464
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header(self): # <<<<<<<<<<<<<<
+ * """List of raw file header lines (as a list of strings).
+ * """
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_13file_header, 0, __pyx_n_s_Scan_file_header, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__64)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":463
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def file_header(self):
+ * """List of raw file header lines (as a list of strings).
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_file_header, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":471
+ * @cython.embedsignature(False)
+ * @property
+ * def scan_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of scan header strings, keys without the leading``#``
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_15scan_header_dict, 0, __pyx_n_s_Scan_scan_header_dict, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__66)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":470
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def scan_header_dict(self):
+ * """
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_scan_header_dict_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":481
+ * @cython.embedsignature(False)
+ * @property
+ * def mca_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of MCA header strings, keys without the leading ``#@``
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_17mca_header_dict, 0, __pyx_n_s_Scan_mca_header_dict, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__68)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":480
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def mca_header_dict(self):
+ * """
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_mca_header_dict, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":490
+ * @cython.embedsignature(False)
+ * @property
+ * def file_header_dict(self): # <<<<<<<<<<<<<<
+ * """
+ * Dictionary of file header strings, keys without the leading ``#``
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_19file_header_dict, 0, __pyx_n_s_Scan_file_header_dict, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__70)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":489
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def file_header_dict(self):
+ * """
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_file_header_dict_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":499
+ * @cython.embedsignature(False)
+ * @property
+ * def labels(self): # <<<<<<<<<<<<<<
+ * """
+ * List of data column headers from ``#L`` scan header
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_21labels, 0, __pyx_n_s_Scan_labels, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__72)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":498
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def labels(self):
+ * """
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_labels_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":507
+ * @cython.embedsignature(False)
+ * @property
+ * def data(self): # <<<<<<<<<<<<<<
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ * (e.g. data.shape).
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_23data, 0, __pyx_n_s_Scan_data, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__74)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":506
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def data(self):
+ * """Scan data as a 2D numpy.ndarray with the usual attributes
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_data_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":520
+ * @cython.embedsignature(False)
+ * @property
+ * def mca(self): # <<<<<<<<<<<<<<
+ * """MCA data in this scan.
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_25mca, 0, __pyx_n_s_Scan_mca, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__76)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":519
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def mca(self):
+ * """MCA data in this scan.
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_mca_2, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":534
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_names(self): # <<<<<<<<<<<<<<
+ * """List of motor names from the ``#O`` file header line.
+ * """
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_27motor_names, 0, __pyx_n_s_Scan_motor_names, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__78)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":533
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def motor_names(self):
+ * """List of motor names from the ``#O`` file header line.
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_motor_names, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":541
+ * @cython.embedsignature(False)
+ * @property
+ * def motor_positions(self): # <<<<<<<<<<<<<<
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ * """
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_29motor_positions, 0, __pyx_n_s_Scan_motor_positions, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__80)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "specfile.pyx":540
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def motor_positions(self):
+ * """List of motor positions as floats from the ``#P`` scan header line.
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_motor_positions, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":546
+ * return self._motor_positions
+ *
+ * def record_exists_in_hdr(self, record): # <<<<<<<<<<<<<<
+ * """Check whether a scan header line exists.
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_31record_exists_in_hdr, 0, __pyx_n_s_Scan_record_exists_in_hdr, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__82)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_record_exists_in_hdr, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":565
+ * return False
+ *
+ * def data_line(self, line_index): # <<<<<<<<<<<<<<
+ * """Returns data for a given line of this scan.
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_33data_line, 0, __pyx_n_s_Scan_data_line, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__84)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_data_line, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":585
+ * return self.data[:, line_index]
+ *
+ * def data_column_by_name(self, label): # <<<<<<<<<<<<<<
+ * """Returns a data column
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_35data_column_by_name, 0, __pyx_n_s_Scan_data_column_by_name, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__86)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_data_column_by_name, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":605
+ *
+ *
+ * def motor_position_by_name(self, name): # <<<<<<<<<<<<<<
+ * """Returns the position for a given motor
+ *
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_8specfile_4Scan_37motor_position_by_name, 0, __pyx_n_s_Scan_motor_position_by_name, NULL, __pyx_n_s_specfile_2, __pyx_d, ((PyObject *)__pyx_codeobj__88)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyObject_SetItem(__pyx_t_5, __pyx_n_s_motor_position_by_name, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "specfile.pyx":338
+ *
+ *
+ * class Scan(object): # <<<<<<<<<<<<<<
+ * """
+ *
+ */
+ __pyx_t_3 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_Scan, __pyx_t_1, __pyx_t_5, NULL, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_Scan, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":618
+ *
+ *
+ * def _string_to_char_star(string_): # <<<<<<<<<<<<<<
+ * """Convert a string to ASCII encoded bytes when using python3"""
+ * if sys.version.startswith("3") and not isinstance(string_, bytes):
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8specfile_3_string_to_char_star, NULL, __pyx_n_s_specfile_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_string_to_char_star, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":625
+ *
+ *
+ * def is_specfile(filename): # <<<<<<<<<<<<<<
+ * """Test if a file is a SPEC file, by checking if one of the first two
+ * lines starts with *#F* (SPEC file header) or *#S* (scan header).
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8specfile_5is_specfile, NULL, __pyx_n_s_specfile_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_is_specfile, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "specfile.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * # /[inserted by cython to avoid comment start]*##########################################################################
+ * # Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init specfile", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init specfile");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* exc_type = tstate->curexc_type;
+ if (unlikely(exc_type)) {
+ if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+ PyObject *exc_value, *exc_tb;
+ exc_value = tstate->curexc_value;
+ exc_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+ Py_DECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#else
+ if (unlikely(PyErr_Occurred())) {
+ if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+ PyErr_Clear();
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#endif
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+ if (unlikely(retval)) {
+ Py_DECREF(retval);
+ __Pyx_RaiseTooManyValuesError(expected);
+ return -1;
+ } else {
+ return __Pyx_IterFinish();
+ }
+ return 0;
+}
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
+ PyObject *method, *result = NULL;
+ method = __Pyx_PyObject_GetAttrStr(obj, method_name);
+ if (unlikely(!method)) goto bad;
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyMethod_Check(method))) {
+ PyObject *self = PyMethod_GET_SELF(method);
+ if (likely(self)) {
+ PyObject *args;
+ PyObject *function = PyMethod_GET_FUNCTION(method);
+ args = PyTuple_New(2);
+ if (unlikely(!args)) goto bad;
+ Py_INCREF(self);
+ PyTuple_SET_ITEM(args, 0, self);
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 1, arg);
+ Py_INCREF(function);
+ Py_DECREF(method); method = NULL;
+ result = __Pyx_PyObject_Call(function, args, NULL);
+ Py_DECREF(args);
+ Py_DECREF(function);
+ return result;
+ }
+ }
+#endif
+ result = __Pyx_PyObject_CallOneArg(method, arg);
+bad:
+ Py_XDECREF(method);
+ return result;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
+ if (likely(PyList_CheckExact(L))) {
+ if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1;
+ } else {
+ PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_n_s_append, x);
+ if (unlikely(!retval))
+ return -1;
+ Py_DECREF(retval);
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+#if !CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values) {
+ return PyObject_CallMethodObjArgs(sep, __pyx_n_s_join, values, NULL);
+}
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
+ const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ if (unlikely((start < 0) | (stop < 0))) {
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ if (stop > length)
+ stop = length;
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+ int r;
+ if (!j) return -1;
+ r = PyObject_SetItem(o, j, v);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o));
+ if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+ PyObject* old = PyList_GET_ITEM(o, n);
+ Py_INCREF(v);
+ PyList_SET_ITEM(o, n, v);
+ Py_DECREF(old);
+ return 1;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_ass_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return -1;
+ }
+ }
+ return m->sq_ass_item(o, i, v);
+ }
+ }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+ if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) {
+#else
+ if (is_list || PySequence_Check(o)) {
+#endif
+ return PySequence_SetItem(o, i, v);
+ }
+#endif
+ return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) {
+ Py_ssize_t i, nbases = PyTuple_GET_SIZE(bases);
+ for (i=0; i < nbases; i++) {
+ PyTypeObject *tmptype;
+ PyObject *tmp = PyTuple_GET_ITEM(bases, i);
+ tmptype = Py_TYPE(tmp);
+#if PY_MAJOR_VERSION < 3
+ if (tmptype == &PyClass_Type)
+ continue;
+#endif
+ if (!metaclass) {
+ metaclass = tmptype;
+ continue;
+ }
+ if (PyType_IsSubtype(metaclass, tmptype))
+ continue;
+ if (PyType_IsSubtype(tmptype, metaclass)) {
+ metaclass = tmptype;
+ continue;
+ }
+ PyErr_SetString(PyExc_TypeError,
+ "metaclass conflict: "
+ "the metaclass of a derived class "
+ "must be a (non-strict) subclass "
+ "of the metaclasses of all its bases");
+ return NULL;
+ }
+ if (!metaclass) {
+#if PY_MAJOR_VERSION < 3
+ metaclass = &PyClass_Type;
+#else
+ metaclass = &PyType_Type;
+#endif
+ }
+ Py_INCREF((PyObject*) metaclass);
+ return (PyObject*) metaclass;
+}
+
+static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name,
+ PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) {
+ PyObject *ns;
+ if (metaclass) {
+ PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, __pyx_n_s_prepare);
+ if (prep) {
+ PyObject *pargs = PyTuple_Pack(2, name, bases);
+ if (unlikely(!pargs)) {
+ Py_DECREF(prep);
+ return NULL;
+ }
+ ns = PyObject_Call(prep, pargs, mkw);
+ Py_DECREF(prep);
+ Py_DECREF(pargs);
+ } else {
+ if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError)))
+ return NULL;
+ PyErr_Clear();
+ ns = PyDict_New();
+ }
+ } else {
+ ns = PyDict_New();
+ }
+ if (unlikely(!ns))
+ return NULL;
+ if (unlikely(PyObject_SetItem(ns, __pyx_n_s_module, modname) < 0)) goto bad;
+ if (unlikely(PyObject_SetItem(ns, __pyx_n_s_qualname, qualname) < 0)) goto bad;
+ if (unlikely(doc && PyObject_SetItem(ns, __pyx_n_s_doc, doc) < 0)) goto bad;
+ return ns;
+bad:
+ Py_DECREF(ns);
+ return NULL;
+}
+static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases,
+ PyObject *dict, PyObject *mkw,
+ int calculate_metaclass, int allow_py2_metaclass) {
+ PyObject *result, *margs;
+ PyObject *owned_metaclass = NULL;
+ if (allow_py2_metaclass) {
+ owned_metaclass = PyObject_GetItem(dict, __pyx_n_s_metaclass);
+ if (owned_metaclass) {
+ metaclass = owned_metaclass;
+ } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) {
+ PyErr_Clear();
+ } else {
+ return NULL;
+ }
+ }
+ if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) {
+ metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases);
+ Py_XDECREF(owned_metaclass);
+ if (unlikely(!metaclass))
+ return NULL;
+ owned_metaclass = metaclass;
+ }
+ margs = PyTuple_Pack(3, name, bases, dict);
+ if (unlikely(!margs)) {
+ result = NULL;
+ } else {
+ result = PyObject_Call(metaclass, margs, mkw);
+ Py_DECREF(margs);
+ }
+ Py_XDECREF(owned_metaclass);
+ return result;
+}
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
+ PyObject* fake_module;
+ PyTypeObject* cached_type = NULL;
+ fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
+ if (!fake_module) return NULL;
+ Py_INCREF(fake_module);
+ cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
+ if (cached_type) {
+ if (!PyType_Check((PyObject*)cached_type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s is not a type object",
+ type->tp_name);
+ goto bad;
+ }
+ if (cached_type->tp_basicsize != type->tp_basicsize) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s has the wrong size, try recompiling",
+ type->tp_name);
+ goto bad;
+ }
+ } else {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+ PyErr_Clear();
+ if (PyType_Ready(type) < 0) goto bad;
+ if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
+ goto bad;
+ Py_INCREF(type);
+ cached_type = type;
+ }
+done:
+ Py_DECREF(fake_module);
+ return cached_type;
+bad:
+ Py_XDECREF(cached_type);
+ cached_type = NULL;
+ goto done;
+}
+
+static PyObject *
+__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure)
+{
+ if (unlikely(op->func_doc == NULL)) {
+ if (op->func.m_ml->ml_doc) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc);
+#else
+ op->func_doc = PyString_FromString(op->func.m_ml->ml_doc);
+#endif
+ if (unlikely(op->func_doc == NULL))
+ return NULL;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+ Py_INCREF(op->func_doc);
+ return op->func_doc;
+}
+static int
+__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp = op->func_doc;
+ if (value == NULL) {
+ value = Py_None;
+ }
+ Py_INCREF(value);
+ op->func_doc = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_name == NULL)) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name);
+#else
+ op->func_name = PyString_InternFromString(op->func.m_ml->ml_name);
+#endif
+ if (unlikely(op->func_name == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_name);
+ return op->func_name;
+}
+static int
+__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__name__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_name;
+ Py_INCREF(value);
+ op->func_name = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_qualname);
+ return op->func_qualname;
+}
+static int
+__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__qualname__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_qualname;
+ Py_INCREF(value);
+ op->func_qualname = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure)
+{
+ PyObject *self;
+ self = m->func_closure;
+ if (self == NULL)
+ self = Py_None;
+ Py_INCREF(self);
+ return self;
+}
+static PyObject *
+__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_dict == NULL)) {
+ op->func_dict = PyDict_New();
+ if (unlikely(op->func_dict == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_dict);
+ return op->func_dict;
+}
+static int
+__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+ if (unlikely(value == NULL)) {
+ PyErr_SetString(PyExc_TypeError,
+ "function's dictionary may not be deleted");
+ return -1;
+ }
+ if (unlikely(!PyDict_Check(value))) {
+ PyErr_SetString(PyExc_TypeError,
+ "setting function's dictionary to a non-dict");
+ return -1;
+ }
+ tmp = op->func_dict;
+ Py_INCREF(value);
+ op->func_dict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_globals);
+ return op->func_globals;
+}
+static PyObject *
+__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op)
+{
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+static PyObject *
+__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op)
+{
+ PyObject* result = (op->func_code) ? op->func_code : Py_None;
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) {
+ PyObject *res = op->defaults_getter((PyObject *) op);
+ if (unlikely(!res))
+ return -1;
+ op->defaults_tuple = PyTuple_GET_ITEM(res, 0);
+ Py_INCREF(op->defaults_tuple);
+ op->defaults_kwdict = PyTuple_GET_ITEM(res, 1);
+ Py_INCREF(op->defaults_kwdict);
+ Py_DECREF(res);
+ return 0;
+}
+static int
+__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyTuple_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__defaults__ must be set to a tuple object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_tuple;
+ op->defaults_tuple = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_tuple;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_tuple;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__kwdefaults__ must be set to a dict object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_kwdict;
+ op->defaults_kwdict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_kwdict;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_kwdict;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value || value == Py_None) {
+ value = NULL;
+ } else if (!PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__annotations__ must be set to a dict object");
+ return -1;
+ }
+ Py_XINCREF(value);
+ tmp = op->func_annotations;
+ op->func_annotations = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->func_annotations;
+ if (unlikely(!result)) {
+ result = PyDict_New();
+ if (unlikely(!result)) return NULL;
+ op->func_annotations = result;
+ }
+ Py_INCREF(result);
+ return result;
+}
+static PyGetSetDef __pyx_CyFunction_getsets[] = {
+ {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0},
+ {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0},
+ {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0},
+ {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+#ifndef PY_WRITE_RESTRICTED
+#define PY_WRITE_RESTRICTED WRITE_RESTRICTED
+#endif
+static PyMemberDef __pyx_CyFunction_members[] = {
+ {(char *) "__module__", T_OBJECT, offsetof(__pyx_CyFunctionObject, func.m_module), PY_WRITE_RESTRICTED, 0},
+ {0, 0, 0, 0, 0}
+};
+static PyObject *
+__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromString(m->func.m_ml->ml_name);
+#else
+ return PyString_FromString(m->func.m_ml->ml_name);
+#endif
+}
+static PyMethodDef __pyx_CyFunction_methods[] = {
+ {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0},
+ {0, 0, 0, 0}
+};
+#if PY_VERSION_HEX < 0x030500A0
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist)
+#else
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
+#endif
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname,
+ PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
+ __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
+ if (op == NULL)
+ return NULL;
+ op->flags = flags;
+ __Pyx_CyFunction_weakreflist(op) = NULL;
+ op->func.m_ml = ml;
+ op->func.m_self = (PyObject *) op;
+ Py_XINCREF(closure);
+ op->func_closure = closure;
+ Py_XINCREF(module);
+ op->func.m_module = module;
+ op->func_dict = NULL;
+ op->func_name = NULL;
+ Py_INCREF(qualname);
+ op->func_qualname = qualname;
+ op->func_doc = NULL;
+ op->func_classobj = NULL;
+ op->func_globals = globals;
+ Py_INCREF(op->func_globals);
+ Py_XINCREF(code);
+ op->func_code = code;
+ op->defaults_pyobjects = 0;
+ op->defaults = NULL;
+ op->defaults_tuple = NULL;
+ op->defaults_kwdict = NULL;
+ op->defaults_getter = NULL;
+ op->func_annotations = NULL;
+ PyObject_GC_Track(op);
+ return (PyObject *) op;
+}
+static int
+__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
+{
+ Py_CLEAR(m->func_closure);
+ Py_CLEAR(m->func.m_module);
+ Py_CLEAR(m->func_dict);
+ Py_CLEAR(m->func_name);
+ Py_CLEAR(m->func_qualname);
+ Py_CLEAR(m->func_doc);
+ Py_CLEAR(m->func_globals);
+ Py_CLEAR(m->func_code);
+ Py_CLEAR(m->func_classobj);
+ Py_CLEAR(m->defaults_tuple);
+ Py_CLEAR(m->defaults_kwdict);
+ Py_CLEAR(m->func_annotations);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_XDECREF(pydefaults[i]);
+ PyMem_Free(m->defaults);
+ m->defaults = NULL;
+ }
+ return 0;
+}
+static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
+{
+ PyObject_GC_UnTrack(m);
+ if (__Pyx_CyFunction_weakreflist(m) != NULL)
+ PyObject_ClearWeakRefs((PyObject *) m);
+ __Pyx_CyFunction_clear(m);
+ PyObject_GC_Del(m);
+}
+static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg)
+{
+ Py_VISIT(m->func_closure);
+ Py_VISIT(m->func.m_module);
+ Py_VISIT(m->func_dict);
+ Py_VISIT(m->func_name);
+ Py_VISIT(m->func_qualname);
+ Py_VISIT(m->func_doc);
+ Py_VISIT(m->func_globals);
+ Py_VISIT(m->func_code);
+ Py_VISIT(m->func_classobj);
+ Py_VISIT(m->defaults_tuple);
+ Py_VISIT(m->defaults_kwdict);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_VISIT(pydefaults[i]);
+ }
+ return 0;
+}
+static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
+ Py_INCREF(func);
+ return func;
+ }
+ if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) {
+ if (type == NULL)
+ type = (PyObject *)(Py_TYPE(obj));
+ return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type)));
+ }
+ if (obj == Py_None)
+ obj = NULL;
+ return __Pyx_PyMethod_New(func, obj, type);
+}
+static PyObject*
+__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromFormat("<cyfunction %U at %p>",
+ op->func_qualname, (void *)op);
+#else
+ return PyString_FromFormat("<cyfunction %s at %p>",
+ PyString_AsString(op->func_qualname), (void *)op);
+#endif
+}
+#if CYTHON_COMPILING_IN_PYPY
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyCFunctionObject* f = (PyCFunctionObject*)func;
+ PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ PyObject *self = PyCFunction_GET_SELF(func);
+ Py_ssize_t size;
+ switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+ case METH_VARARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0)
+ return (*meth)(self, arg);
+ break;
+ case METH_VARARGS | METH_KEYWORDS:
+ return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+ case METH_NOARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 0)
+ return (*meth)(self, NULL);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes no arguments (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ case METH_O:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 1)
+ return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes exactly one argument (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError, "Bad call flags in "
+ "__Pyx_CyFunction_Call. METH_OLDARGS is no "
+ "longer supported!");
+ return NULL;
+ }
+ PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+ f->m_ml->ml_name);
+ return NULL;
+}
+#else
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ return PyCFunction_Call(func, arg, kw);
+}
+#endif
+static PyTypeObject __pyx_CyFunctionType_type = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "cython_function_or_method",
+ sizeof(__pyx_CyFunctionObject),
+ 0,
+ (destructor) __Pyx_CyFunction_dealloc,
+ 0,
+ 0,
+ 0,
+#if PY_MAJOR_VERSION < 3
+ 0,
+#else
+ 0,
+#endif
+ (reprfunc) __Pyx_CyFunction_repr,
+ 0,
+ 0,
+ 0,
+ 0,
+ __Pyx_CyFunction_Call,
+ 0,
+ 0,
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ 0,
+ (traverseproc) __Pyx_CyFunction_traverse,
+ (inquiry) __Pyx_CyFunction_clear,
+ 0,
+#if PY_VERSION_HEX < 0x030500A0
+ offsetof(__pyx_CyFunctionObject, func_weakreflist),
+#else
+ offsetof(PyCFunctionObject, m_weakreflist),
+#endif
+ 0,
+ 0,
+ __pyx_CyFunction_methods,
+ __pyx_CyFunction_members,
+ __pyx_CyFunction_getsets,
+ 0,
+ 0,
+ __Pyx_CyFunction_descr_get,
+ 0,
+ offsetof(__pyx_CyFunctionObject, func_dict),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ 0,
+#endif
+};
+static int __Pyx_CyFunction_init(void) {
+#if !CYTHON_COMPILING_IN_PYPY
+ __pyx_CyFunctionType_type.tp_call = PyCFunction_Call;
+#endif
+ __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
+ if (__pyx_CyFunctionType == NULL) {
+ return -1;
+ }
+ return 0;
+}
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults = PyMem_Malloc(size);
+ if (!m->defaults)
+ return PyErr_NoMemory();
+ memset(m->defaults, 0, size);
+ m->defaults_pyobjects = pyobjects;
+ return m->defaults;
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_tuple = tuple;
+ Py_INCREF(tuple);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_kwdict = dict;
+ Py_INCREF(dict);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->func_annotations = dict;
+ Py_INCREF(dict);
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return ::std::complex< float >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return x + y*(__pyx_t_float_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ __pyx_t_float_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrtf(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypotf(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ float denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(a, a);
+ case 3:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, a);
+ case 4:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_absf(a);
+ theta = atan2f(a.imag, a.real);
+ }
+ lnr = logf(r);
+ z_r = expf(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cosf(z_theta);
+ z.imag = z_r * sinf(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return ::std::complex< double >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return x + y*(__pyx_t_double_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ __pyx_t_double_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrt(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypot(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ double denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(a, a);
+ case 3:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, a);
+ case 4:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_abs(a);
+ theta = atan2(a.imag, a.real);
+ }
+ lnr = log(r);
+ z_r = exp(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cos(z_theta);
+ z.imag = z_r * sin(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static PyObject *__Pyx_Generator_Next(PyObject *self);
+static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value);
+static PyObject *__Pyx_Generator_Close(PyObject *self);
+static PyObject *__Pyx_Generator_Throw(PyObject *gen, PyObject *args);
+static PyTypeObject *__pyx_GeneratorType = 0;
+#define __Pyx_Generator_CheckExact(obj) (Py_TYPE(obj) == __pyx_GeneratorType)
+#define __Pyx_Generator_Undelegate(gen) Py_CLEAR((gen)->yieldfrom)
+#if 1 || PY_VERSION_HEX < 0x030300B0
+static int __Pyx_PyGen_FetchStopIterationValue(PyObject **pvalue) {
+ PyObject *et, *ev, *tb;
+ PyObject *value = NULL;
+ __Pyx_ErrFetch(&et, &ev, &tb);
+ if (!et) {
+ Py_XDECREF(tb);
+ Py_XDECREF(ev);
+ Py_INCREF(Py_None);
+ *pvalue = Py_None;
+ return 0;
+ }
+ if (unlikely(et != PyExc_StopIteration) &&
+ unlikely(!PyErr_GivenExceptionMatches(et, PyExc_StopIteration))) {
+ __Pyx_ErrRestore(et, ev, tb);
+ return -1;
+ }
+ if (likely(et == PyExc_StopIteration)) {
+ if (likely(!ev) || !PyObject_IsInstance(ev, PyExc_StopIteration)) {
+ if (!ev) {
+ Py_INCREF(Py_None);
+ ev = Py_None;
+ }
+ Py_XDECREF(tb);
+ Py_DECREF(et);
+ *pvalue = ev;
+ return 0;
+ }
+ }
+ PyErr_NormalizeException(&et, &ev, &tb);
+ if (unlikely(!PyObject_IsInstance(ev, PyExc_StopIteration))) {
+ __Pyx_ErrRestore(et, ev, tb);
+ return -1;
+ }
+ Py_XDECREF(tb);
+ Py_DECREF(et);
+#if PY_VERSION_HEX >= 0x030300A0
+ value = ((PyStopIterationObject *)ev)->value;
+ Py_INCREF(value);
+ Py_DECREF(ev);
+#else
+ {
+ PyObject* args = PyObject_GetAttr(ev, __pyx_n_s_args);
+ Py_DECREF(ev);
+ if (likely(args)) {
+ value = PyObject_GetItem(args, 0);
+ Py_DECREF(args);
+ }
+ if (unlikely(!value)) {
+ __Pyx_ErrRestore(NULL, NULL, NULL);
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+ }
+#endif
+ *pvalue = value;
+ return 0;
+}
+#endif
+static CYTHON_INLINE
+void __Pyx_Generator_ExceptionClear(__pyx_GeneratorObject *self) {
+ PyObject *exc_type = self->exc_type;
+ PyObject *exc_value = self->exc_value;
+ PyObject *exc_traceback = self->exc_traceback;
+ self->exc_type = NULL;
+ self->exc_value = NULL;
+ self->exc_traceback = NULL;
+ Py_XDECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_traceback);
+}
+static CYTHON_INLINE
+int __Pyx_Generator_CheckRunning(__pyx_GeneratorObject *gen) {
+ if (unlikely(gen->is_running)) {
+ PyErr_SetString(PyExc_ValueError,
+ "generator already executing");
+ return 1;
+ }
+ return 0;
+}
+static CYTHON_INLINE
+PyObject *__Pyx_Generator_SendEx(__pyx_GeneratorObject *self, PyObject *value) {
+ PyObject *retval;
+ assert(!self->is_running);
+ if (unlikely(self->resume_label == 0)) {
+ if (unlikely(value && value != Py_None)) {
+ PyErr_SetString(PyExc_TypeError,
+ "can't send non-None value to a "
+ "just-started generator");
+ return NULL;
+ }
+ }
+ if (unlikely(self->resume_label == -1)) {
+ PyErr_SetNone(PyExc_StopIteration);
+ return NULL;
+ }
+ if (value) {
+#if CYTHON_COMPILING_IN_PYPY
+#else
+ if (self->exc_traceback) {
+ PyThreadState *tstate = PyThreadState_GET();
+ PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
+ PyFrameObject *f = tb->tb_frame;
+ Py_XINCREF(tstate->frame);
+ assert(f->f_back == NULL);
+ f->f_back = tstate->frame;
+ }
+#endif
+ __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
+ &self->exc_traceback);
+ } else {
+ __Pyx_Generator_ExceptionClear(self);
+ }
+ self->is_running = 1;
+ retval = self->body((PyObject *) self, value);
+ self->is_running = 0;
+ if (retval) {
+ __Pyx_ExceptionSwap(&self->exc_type, &self->exc_value,
+ &self->exc_traceback);
+#if CYTHON_COMPILING_IN_PYPY
+#else
+ if (self->exc_traceback) {
+ PyTracebackObject *tb = (PyTracebackObject *) self->exc_traceback;
+ PyFrameObject *f = tb->tb_frame;
+ Py_CLEAR(f->f_back);
+ }
+#endif
+ } else {
+ __Pyx_Generator_ExceptionClear(self);
+ }
+ return retval;
+}
+static CYTHON_INLINE
+PyObject *__Pyx_Generator_FinishDelegation(__pyx_GeneratorObject *gen) {
+ PyObject *ret;
+ PyObject *val = NULL;
+ __Pyx_Generator_Undelegate(gen);
+ __Pyx_PyGen_FetchStopIterationValue(&val);
+ ret = __Pyx_Generator_SendEx(gen, val);
+ Py_XDECREF(val);
+ return ret;
+}
+static PyObject *__Pyx_Generator_Next(PyObject *self) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
+ PyObject *yf = gen->yieldfrom;
+ if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+ return NULL;
+ if (yf) {
+ PyObject *ret;
+ gen->is_running = 1;
+ ret = Py_TYPE(yf)->tp_iternext(yf);
+ gen->is_running = 0;
+ if (likely(ret)) {
+ return ret;
+ }
+ return __Pyx_Generator_FinishDelegation(gen);
+ }
+ return __Pyx_Generator_SendEx(gen, Py_None);
+}
+static PyObject *__Pyx_Generator_Send(PyObject *self, PyObject *value) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject*) self;
+ PyObject *yf = gen->yieldfrom;
+ if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+ return NULL;
+ if (yf) {
+ PyObject *ret;
+ gen->is_running = 1;
+ if (__Pyx_Generator_CheckExact(yf)) {
+ ret = __Pyx_Generator_Send(yf, value);
+ } else {
+ if (value == Py_None)
+ ret = PyIter_Next(yf);
+ else
+ ret = __Pyx_PyObject_CallMethod1(yf, __pyx_n_s_send, value);
+ }
+ gen->is_running = 0;
+ if (likely(ret)) {
+ return ret;
+ }
+ return __Pyx_Generator_FinishDelegation(gen);
+ }
+ return __Pyx_Generator_SendEx(gen, value);
+}
+static int __Pyx_Generator_CloseIter(__pyx_GeneratorObject *gen, PyObject *yf) {
+ PyObject *retval = NULL;
+ int err = 0;
+ if (__Pyx_Generator_CheckExact(yf)) {
+ retval = __Pyx_Generator_Close(yf);
+ if (!retval)
+ return -1;
+ } else {
+ PyObject *meth;
+ gen->is_running = 1;
+ meth = PyObject_GetAttr(yf, __pyx_n_s_close);
+ if (unlikely(!meth)) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_WriteUnraisable(yf);
+ }
+ PyErr_Clear();
+ } else {
+ retval = PyObject_CallFunction(meth, NULL);
+ Py_DECREF(meth);
+ if (!retval)
+ err = -1;
+ }
+ gen->is_running = 0;
+ }
+ Py_XDECREF(retval);
+ return err;
+}
+static PyObject *__Pyx_Generator_Close(PyObject *self) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ PyObject *retval, *raised_exception;
+ PyObject *yf = gen->yieldfrom;
+ int err = 0;
+ if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+ return NULL;
+ if (yf) {
+ Py_INCREF(yf);
+ err = __Pyx_Generator_CloseIter(gen, yf);
+ __Pyx_Generator_Undelegate(gen);
+ Py_DECREF(yf);
+ }
+ if (err == 0)
+ PyErr_SetNone(PyExc_GeneratorExit);
+ retval = __Pyx_Generator_SendEx(gen, NULL);
+ if (retval) {
+ Py_DECREF(retval);
+ PyErr_SetString(PyExc_RuntimeError,
+ "generator ignored GeneratorExit");
+ return NULL;
+ }
+ raised_exception = PyErr_Occurred();
+ if (!raised_exception
+ || raised_exception == PyExc_StopIteration
+ || raised_exception == PyExc_GeneratorExit
+ || PyErr_GivenExceptionMatches(raised_exception, PyExc_GeneratorExit)
+ || PyErr_GivenExceptionMatches(raised_exception, PyExc_StopIteration))
+ {
+ if (raised_exception) PyErr_Clear();
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return NULL;
+}
+static PyObject *__Pyx_Generator_Throw(PyObject *self, PyObject *args) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ PyObject *typ;
+ PyObject *tb = NULL;
+ PyObject *val = NULL;
+ PyObject *yf = gen->yieldfrom;
+ if (!PyArg_UnpackTuple(args, (char *)"throw", 1, 3, &typ, &val, &tb))
+ return NULL;
+ if (unlikely(__Pyx_Generator_CheckRunning(gen)))
+ return NULL;
+ if (yf) {
+ PyObject *ret;
+ Py_INCREF(yf);
+ if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit)) {
+ int err = __Pyx_Generator_CloseIter(gen, yf);
+ Py_DECREF(yf);
+ __Pyx_Generator_Undelegate(gen);
+ if (err < 0)
+ return __Pyx_Generator_SendEx(gen, NULL);
+ goto throw_here;
+ }
+ gen->is_running = 1;
+ if (__Pyx_Generator_CheckExact(yf)) {
+ ret = __Pyx_Generator_Throw(yf, args);
+ } else {
+ PyObject *meth = PyObject_GetAttr(yf, __pyx_n_s_throw);
+ if (unlikely(!meth)) {
+ Py_DECREF(yf);
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ gen->is_running = 0;
+ return NULL;
+ }
+ PyErr_Clear();
+ __Pyx_Generator_Undelegate(gen);
+ gen->is_running = 0;
+ goto throw_here;
+ }
+ ret = PyObject_CallObject(meth, args);
+ Py_DECREF(meth);
+ }
+ gen->is_running = 0;
+ Py_DECREF(yf);
+ if (!ret) {
+ ret = __Pyx_Generator_FinishDelegation(gen);
+ }
+ return ret;
+ }
+throw_here:
+ __Pyx_Raise(typ, val, tb, NULL);
+ return __Pyx_Generator_SendEx(gen, NULL);
+}
+static int __Pyx_Generator_traverse(PyObject *self, visitproc visit, void *arg) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ Py_VISIT(gen->closure);
+ Py_VISIT(gen->classobj);
+ Py_VISIT(gen->yieldfrom);
+ Py_VISIT(gen->exc_type);
+ Py_VISIT(gen->exc_value);
+ Py_VISIT(gen->exc_traceback);
+ return 0;
+}
+static int __Pyx_Generator_clear(PyObject *self) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ Py_CLEAR(gen->closure);
+ Py_CLEAR(gen->classobj);
+ Py_CLEAR(gen->yieldfrom);
+ Py_CLEAR(gen->exc_type);
+ Py_CLEAR(gen->exc_value);
+ Py_CLEAR(gen->exc_traceback);
+ Py_CLEAR(gen->gi_name);
+ Py_CLEAR(gen->gi_qualname);
+ return 0;
+}
+static void __Pyx_Generator_dealloc(PyObject *self) {
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ PyObject_GC_UnTrack(gen);
+ if (gen->gi_weakreflist != NULL)
+ PyObject_ClearWeakRefs(self);
+ if (gen->resume_label > 0) {
+ PyObject_GC_Track(self);
+#if PY_VERSION_HEX >= 0x030400a1
+ if (PyObject_CallFinalizerFromDealloc(self))
+#else
+ Py_TYPE(gen)->tp_del(self);
+ if (self->ob_refcnt > 0)
+#endif
+ {
+ return;
+ }
+ PyObject_GC_UnTrack(self);
+ }
+ __Pyx_Generator_clear(self);
+ PyObject_GC_Del(gen);
+}
+static void __Pyx_Generator_del(PyObject *self) {
+ PyObject *res;
+ PyObject *error_type, *error_value, *error_traceback;
+ __pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
+ if (gen->resume_label <= 0)
+ return ;
+#if PY_VERSION_HEX < 0x030400a1
+ assert(self->ob_refcnt == 0);
+ self->ob_refcnt = 1;
+#endif
+ __Pyx_ErrFetch(&error_type, &error_value, &error_traceback);
+ res = __Pyx_Generator_Close(self);
+ if (res == NULL)
+ PyErr_WriteUnraisable(self);
+ else
+ Py_DECREF(res);
+ __Pyx_ErrRestore(error_type, error_value, error_traceback);
+#if PY_VERSION_HEX < 0x030400a1
+ assert(self->ob_refcnt > 0);
+ if (--self->ob_refcnt == 0) {
+ return;
+ }
+ {
+ Py_ssize_t refcnt = self->ob_refcnt;
+ _Py_NewReference(self);
+ self->ob_refcnt = refcnt;
+ }
+#if CYTHON_COMPILING_IN_CPYTHON
+ assert(PyType_IS_GC(self->ob_type) &&
+ _Py_AS_GC(self)->gc.gc_refs != _PyGC_REFS_UNTRACKED);
+ _Py_DEC_REFTOTAL;
+#endif
+#ifdef COUNT_ALLOCS
+ --Py_TYPE(self)->tp_frees;
+ --Py_TYPE(self)->tp_allocs;
+#endif
+#endif
+}
+static PyObject *
+__Pyx_Generator_get_name(__pyx_GeneratorObject *self)
+{
+ Py_INCREF(self->gi_name);
+ return self->gi_name;
+}
+static int
+__Pyx_Generator_set_name(__pyx_GeneratorObject *self, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__name__ must be set to a string object");
+ return -1;
+ }
+ tmp = self->gi_name;
+ Py_INCREF(value);
+ self->gi_name = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_Generator_get_qualname(__pyx_GeneratorObject *self)
+{
+ Py_INCREF(self->gi_qualname);
+ return self->gi_qualname;
+}
+static int
+__Pyx_Generator_set_qualname(__pyx_GeneratorObject *self, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__qualname__ must be set to a string object");
+ return -1;
+ }
+ tmp = self->gi_qualname;
+ Py_INCREF(value);
+ self->gi_qualname = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyGetSetDef __pyx_Generator_getsets[] = {
+ {(char *) "__name__", (getter)__Pyx_Generator_get_name, (setter)__Pyx_Generator_set_name,
+ (char*) PyDoc_STR("name of the generator"), 0},
+ {(char *) "__qualname__", (getter)__Pyx_Generator_get_qualname, (setter)__Pyx_Generator_set_qualname,
+ (char*) PyDoc_STR("qualified name of the generator"), 0},
+ {0, 0, 0, 0, 0}
+};
+static PyMemberDef __pyx_Generator_memberlist[] = {
+ {(char *) "gi_running", T_BOOL, offsetof(__pyx_GeneratorObject, is_running), READONLY, NULL},
+ {0, 0, 0, 0, 0}
+};
+static PyMethodDef __pyx_Generator_methods[] = {
+ {"send", (PyCFunction) __Pyx_Generator_Send, METH_O, 0},
+ {"throw", (PyCFunction) __Pyx_Generator_Throw, METH_VARARGS, 0},
+ {"close", (PyCFunction) __Pyx_Generator_Close, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+static PyTypeObject __pyx_GeneratorType_type = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "generator",
+ sizeof(__pyx_GeneratorObject),
+ 0,
+ (destructor) __Pyx_Generator_dealloc,
+ 0,
+ 0,
+ 0,
+#if PY_MAJOR_VERSION < 3
+ 0,
+#else
+ 0,
+#endif
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
+ 0,
+ (traverseproc) __Pyx_Generator_traverse,
+ 0,
+ 0,
+ offsetof(__pyx_GeneratorObject, gi_weakreflist),
+ 0,
+ (iternextfunc) __Pyx_Generator_Next,
+ __pyx_Generator_methods,
+ __pyx_Generator_memberlist,
+ __pyx_Generator_getsets,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ 0,
+#else
+ __Pyx_Generator_del,
+#endif
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ __Pyx_Generator_del,
+#endif
+};
+static __pyx_GeneratorObject *__Pyx_Generator_New(__pyx_generator_body_t body,
+ PyObject *closure, PyObject *name, PyObject *qualname) {
+ __pyx_GeneratorObject *gen =
+ PyObject_GC_New(__pyx_GeneratorObject, &__pyx_GeneratorType_type);
+ if (gen == NULL)
+ return NULL;
+ gen->body = body;
+ gen->closure = closure;
+ Py_XINCREF(closure);
+ gen->is_running = 0;
+ gen->resume_label = 0;
+ gen->classobj = NULL;
+ gen->yieldfrom = NULL;
+ gen->exc_type = NULL;
+ gen->exc_value = NULL;
+ gen->exc_traceback = NULL;
+ gen->gi_weakreflist = NULL;
+ Py_XINCREF(qualname);
+ gen->gi_qualname = qualname;
+ Py_XINCREF(name);
+ gen->gi_name = name;
+ PyObject_GC_Track(gen);
+ return gen;
+}
+static int __pyx_Generator_init(void) {
+ __pyx_GeneratorType_type.tp_getattro = PyObject_GenericGetAttr;
+ __pyx_GeneratorType_type.tp_iter = PyObject_SelfIter;
+ __pyx_GeneratorType = __Pyx_FetchCommonType(&__pyx_GeneratorType_type);
+ if (__pyx_GeneratorType == NULL) {
+ return -1;
+ }
+ return 0;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+ PyObject *py_name = 0;
+ PyObject *py_module = 0;
+ py_name = __Pyx_PyIdentifier_FromString(name);
+ if (!py_name)
+ goto bad;
+ py_module = PyImport_Import(py_name);
+ Py_DECREF(py_name);
+ return py_module;
+bad:
+ Py_XDECREF(py_name);
+ return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+ size_t size, int strict)
+{
+ PyObject *py_module = 0;
+ PyObject *result = 0;
+ PyObject *py_name = 0;
+ char warning[200];
+ Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+ PyObject *py_basicsize;
+#endif
+ py_module = __Pyx_ImportModule(module_name);
+ if (!py_module)
+ goto bad;
+ py_name = __Pyx_PyIdentifier_FromString(class_name);
+ if (!py_name)
+ goto bad;
+ result = PyObject_GetAttr(py_module, py_name);
+ Py_DECREF(py_name);
+ py_name = 0;
+ Py_DECREF(py_module);
+ py_module = 0;
+ if (!result)
+ goto bad;
+ if (!PyType_Check(result)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.%.200s is not a type object",
+ module_name, class_name);
+ goto bad;
+ }
+#ifndef Py_LIMITED_API
+ basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+ py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+ if (!py_basicsize)
+ goto bad;
+ basicsize = PyLong_AsSsize_t(py_basicsize);
+ Py_DECREF(py_basicsize);
+ py_basicsize = 0;
+ if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+ goto bad;
+#endif
+ if (!strict && (size_t)basicsize > size) {
+ PyOS_snprintf(warning, sizeof(warning),
+ "%s.%s size changed, may indicate binary incompatibility",
+ module_name, class_name);
+ if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+ }
+ else if ((size_t)basicsize != size) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s.%.200s has the wrong size, try recompiling",
+ module_name, class_name);
+ goto bad;
+ }
+ return (PyTypeObject *)result;
+bad:
+ Py_XDECREF(py_module);
+ Py_XDECREF(result);
+ return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/io/specfile/specfile.pyx b/silx/io/specfile/specfile.pyx
new file mode 100644
index 0000000..a465aa6
--- /dev/null
+++ b/silx/io/specfile/specfile.pyx
@@ -0,0 +1,1273 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""
+This module is a cython binding to wrap the C SpecFile library, to access
+SpecFile data within a python program.
+
+Documentation for the original C library SpecFile can be found on the ESRF
+website:
+`The manual for the SpecFile Library <http://www.esrf.eu/files/live/sites/www/files/Instrumentation/software/beamline-control/BLISS/documentation/SpecFileManual.pdf>`_
+
+Examples
+========
+
+Start by importing :class:`SpecFile` and instantiate it:
+
+.. code-block:: python
+
+ from silx.io.specfile import SpecFile
+
+ sf = SpecFile("test.dat")
+
+A :class:`SpecFile` instance can be accessed like a dictionary to obtain a
+:class:`Scan` instance.
+
+If the key is a string representing two values
+separated by a dot (e.g. ``"1.2"``), they will be treated as the scan number
+(``#S`` header line) and the scan order::
+
+ # get second occurrence of scan "#S 1"
+ myscan = sf["1.2"]
+
+ # access scan data as a numpy array
+ nlines, ncolumns = myscan.data.shape
+
+If the key is an integer, it will be treated as a 0-based index::
+
+ first_scan = sf[0]
+ second_scan = sf[1]
+
+It is also possible to browse through all scans using :class:`SpecFile` as
+an iterator::
+
+ for scan in sf:
+ print(scan.scan_header_dict['S'])
+
+MCA spectra can be selectively loaded using an instance of :class:`MCA`
+provided by :class:`Scan`::
+
+ # Only one MCA spectrum is loaded in memory
+ second_mca = first_scan.mca[1]
+
+ # Iterating trough all MCA spectra in a scan:
+ for mca_data in first_scan.mca:
+ print(sum(mca_data))
+
+Classes
+=======
+
+- :class:`SpecFile`
+- :class:`Scan`
+- :class:`MCA`
+
+Exceptions
+==========
+
+- :class:`SfError`
+- :class:`SfErrMemoryAlloc`
+- :class:`SfErrFileOpen`
+- :class:`SfErrFileClose`
+- :class:`SfErrFileRead`
+- :class:`SfErrFileWrite`
+- :class:`SfErrLineNotFound`
+- :class:`SfErrScanNotFound`
+- :class:`SfErrHeaderNotFound`
+- :class:`SfErrLabelNotFound`
+- :class:`SfErrMotorNotFound`
+- :class:`SfErrPositionNotFound`
+- :class:`SfErrLineEmpty`
+- :class:`SfErrUserNotFound`
+- :class:`SfErrColNotFound`
+- :class:`SfErrMcaNotFound`
+
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "27/09/2016"
+
+import os.path
+import logging
+import numpy
+import re
+import sys
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+cimport numpy
+cimport cython
+from libc.stdlib cimport free
+
+cimport specfile_wrapper
+
+# hack to avoid C compiler warnings about unused functions in the NumPy header files
+# Sources: Cython test suite.
+cdef extern from *:
+ bint FALSE "0"
+ void import_array()
+ void import_umath()
+
+if FALSE:
+ import_array()
+ import_umath()
+
+numpy.import_array()
+
+
+SF_ERR_NO_ERRORS = 0
+SF_ERR_FILE_OPEN = 2
+SF_ERR_SCAN_NOT_FOUND = 7
+
+
+# custom errors
+class SfError(Exception):
+ """Base exception inherited by all exceptions raised when a
+ C function from the legacy SpecFile library returns an error
+ code.
+ """
+ pass
+
+class SfErrMemoryAlloc(SfError): pass
+class SfErrFileOpen(SfError): pass
+class SfErrFileClose(SfError): pass
+class SfErrFileRead(SfError): pass
+class SfErrFileWrite(SfError): pass
+class SfErrLineNotFound(SfError): pass
+class SfErrScanNotFound(SfError): pass
+class SfErrHeaderNotFound(SfError): pass
+class SfErrLabelNotFound(SfError): pass
+class SfErrMotorNotFound(SfError): pass
+class SfErrPositionNotFound(SfError): pass
+class SfErrLineEmpty(SfError): pass
+class SfErrUserNotFound(SfError): pass
+class SfErrColNotFound(SfError): pass
+class SfErrMcaNotFound(SfError): pass
+
+
+ERRORS = {
+ 1: SfErrMemoryAlloc,
+ 2: SfErrFileOpen,
+ 3: SfErrFileClose,
+ 4: SfErrFileRead,
+ 5: SfErrFileWrite,
+ 6: SfErrLineNotFound,
+ 7: SfErrScanNotFound,
+ 8: SfErrHeaderNotFound,
+ 9: SfErrLabelNotFound,
+ 10: SfErrMotorNotFound,
+ 11: SfErrPositionNotFound,
+ 12: SfErrLineEmpty,
+ 13: SfErrUserNotFound,
+ 14: SfErrColNotFound,
+ 15: SfErrMcaNotFound,
+}
+
+
+class SfNoMcaError(SfError):
+ """Custom exception raised when ``SfNoMca()`` returns ``-1``
+ """
+ pass
+
+
+class MCA(object):
+ """
+
+ :param scan: Parent Scan instance
+ :type scan: :class:`Scan`
+
+ :var calibration: MCA calibration :math:`(a, b, c)` (as in
+ :math:`a + b x + c x²`) from ``#@CALIB`` scan header.
+ :type calibration: list of 3 floats, default ``[0., 1., 0.]``
+ :var channels: MCA channels list from ``#@CHANN`` scan header.
+ In the absence of a ``#@CHANN`` header, this attribute is a list
+ ``[0, …, N-1]`` where ``N`` is the length of the first spectrum.
+ In the absence of MCA spectra, this attribute defaults to ``None``.
+ :type channels: list of int
+
+ This class provides access to Multi-Channel Analysis data. A :class:`MCA`
+ instance can be indexed to access 1D numpy arrays representing single
+ MCA spectra.
+
+ To create a :class:`MCA` instance, you must provide a parent :class:`Scan`
+ instance, which in turn will provide a reference to the original
+ :class:`SpecFile` instance::
+
+ sf = SpecFile("/path/to/specfile.dat")
+ scan2 = Scan(sf, scan_index=2)
+ mcas_in_scan2 = MCA(scan2)
+ for i in len(mcas_in_scan2):
+ mca_data = mcas_in_scan2[i]
+ ... # do some something with mca_data (1D numpy array)
+
+ A more pythonic way to do the same work, without having to explicitly
+ instantiate ``scan`` and ``mcas_in_scan``, would be::
+
+ sf = SpecFile("specfilename.dat")
+ # scan2 from previous example can be referred to as sf[2]
+ # mcas_in_scan2 from previous example can be referred to as scan2.mca
+ for mca_data in sf[2].mca:
+ ... # do some something with mca_data (1D numpy array)
+
+ """
+ def __init__(self, scan):
+ self._scan = scan
+
+ # Header dict
+ self._header = scan.mca_header_dict
+
+ self.calibration = []
+ """List of lists of calibration values,
+ one list of 3 floats per MCA device or a single list applying to
+ all devices """
+ self._parse_calibration()
+
+ self.channels = []
+ """List of lists of channels,
+ one list of integers per MCA device or a single list applying to
+ all devices"""
+ self._parse_channels()
+
+ def _parse_channels(self):
+ """Fill :attr:`channels`"""
+ # Channels list
+ if "CHANN" in self._header:
+ chann_lines = self._header["CHANN"].split("\n")
+ all_chann_values = [chann_line.split() for chann_line in chann_lines]
+ for one_line_chann_values in all_chann_values:
+ length, start, stop, increment = map(int, one_line_chann_values)
+ self.channels.append(list(range(start, stop + 1, increment)))
+ elif len(self):
+ # in the absence of #@CHANN, use shape of first MCA
+ length = self[0].shape[0]
+ start, stop, increment = (0, length - 1, 1)
+ self.channels.append(list(range(start, stop + 1, increment)))
+
+ def _parse_calibration(self):
+ """Fill :attr:`calibration`"""
+ # Channels list
+ if "CALIB" in self._header:
+ calib_lines = self._header["CALIB"].split("\n")
+ all_calib_values = [calib_line.split() for calib_line in calib_lines]
+ for one_line_calib_values in all_calib_values:
+ self.calibration.append(list(map(float, one_line_calib_values)))
+ else:
+ # in the absence of #@calib, use default
+ self.calibration.append([0., 1., 0.])
+
+ def __len__(self):
+ """
+
+ :return: Number of mca in Scan
+ :rtype: int
+ """
+ return self._scan._specfile.number_of_mca(self._scan.index)
+
+ def __getitem__(self, key):
+ """Return a single MCA data line
+
+ :param key: 0-based index of MCA within Scan
+ :type key: int
+
+ :return: Single MCA
+ :rtype: 1D numpy array
+ """
+ if not len(self):
+ raise IndexError("No MCA spectrum found in this scan")
+
+ if isinstance(key, int):
+ mca_index = key
+ # allow negative index, like lists
+ if mca_index < 0:
+ mca_index = len(self) + mca_index
+ else:
+ raise TypeError("MCA index should be an integer (%s provided)" %
+ (type(key)))
+
+ if not 0 <= mca_index < len(self):
+ msg = "MCA index must be in range 0-%d" % (len(self) - 1)
+ raise IndexError(msg)
+
+ return self._scan._specfile.get_mca(self._scan.index,
+ mca_index)
+
+ def __iter__(self):
+ """Return the next MCA data line each time this method is called.
+
+ :return: Single MCA
+ :rtype: 1D numpy array
+ """
+ for mca_index in range(len(self)):
+ yield self._scan._specfile.get_mca(self._scan.index, mca_index)
+
+
+def _add_or_concatenate(dictionary, key, value):
+ """If key doesn't exist in dictionary, create a new ``key: value`` pair.
+ Else append/concatenate the new value to the existing one
+ """
+ try:
+ if not key in dictionary:
+ dictionary[key] = value
+ else:
+ dictionary[key] += "\n" + value
+ except TypeError:
+ raise TypeError("Parameter value must be a string.")
+
+
+class Scan(object):
+ """
+
+ :param specfile: Parent SpecFile from which this scan is extracted.
+ :type specfile: :class:`SpecFile`
+ :param scan_index: Unique index defining the scan in the SpecFile
+ :type scan_index: int
+
+ Interface to access a SpecFile scan
+
+ A scan is a block of descriptive header lines followed by a 2D data array.
+
+ Following three ways of accessing a scan are equivalent::
+
+ sf = SpecFile("/path/to/specfile.dat")
+
+ # Explicit class instantiation
+ scan2 = Scan(sf, scan_index=2)
+
+ # 0-based index on a SpecFile object
+ scan2 = sf[2]
+
+ # Using a "n.m" key (scan number starting with 1, scan order)
+ scan2 = sf["3.1"]
+ """
+ def __init__(self, specfile, scan_index):
+ self._specfile = specfile
+
+ self._index = scan_index
+ self._number = specfile.number(scan_index)
+ self._order = specfile.order(scan_index)
+
+ self._scan_header_lines = self._specfile.scan_header(self._index)
+ self._file_header_lines = self._specfile.file_header(self._index)
+
+ if self._file_header_lines == self._scan_header_lines:
+ self._file_header_lines = []
+ self._header = self._file_header_lines + self._scan_header_lines
+
+ self._scan_header_dict = {}
+ self._mca_header_dict = {}
+ for line in self._scan_header_lines:
+ match = re.search(r"#(\w+) *(.*)", line)
+ match_mca = re.search(r"#@(\w+) *(.*)", line)
+ if match:
+ hkey = match.group(1).lstrip("#").strip()
+ hvalue = match.group(2).strip()
+ _add_or_concatenate(self._scan_header_dict, hkey, hvalue)
+ elif match_mca:
+ hkey = match_mca.group(1).lstrip("#").strip()
+ hvalue = match_mca.group(2).strip()
+ _add_or_concatenate(self._mca_header_dict, hkey, hvalue)
+ else:
+ # this shouldn't happen
+ _logger.warning("Unable to parse scan header line " + line)
+
+ self._labels = []
+ if self.record_exists_in_hdr('L'):
+ try:
+ self._labels = self._specfile.labels(self._index)
+ except SfErrLineNotFound:
+ # SpecFile.labels raises an IndexError when encountering
+ # a Scan with no data, even if the header exists.
+ L_header = re.sub(r" {2,}", " ", # max. 2 spaces
+ self._scan_header_dict["L"])
+ self._labels = L_header.split(" ")
+
+
+ self._file_header_dict = {}
+ for line in self._file_header_lines:
+ match = re.search(r"#(\w+) *(.*)", line)
+ if match:
+ # header type
+ hkey = match.group(1).lstrip("#").strip()
+ hvalue = match.group(2).strip()
+ _add_or_concatenate(self._file_header_dict, hkey, hvalue)
+ else:
+ _logger.warning("Unable to parse file header line " + line)
+
+ self._motor_names = self._specfile.motor_names(self._index)
+ self._motor_positions = self._specfile.motor_positions(self._index)
+
+ self._data = None
+ self._mca = None
+
+ @cython.embedsignature(False)
+ @property
+ def index(self):
+ """Unique scan index 0 - len(specfile)-1
+
+ This attribute is implemented as a read-only property as changing
+ its value may cause nasty side-effects (such as loading data from a
+ different scan without updating the header accordingly."""
+ return self._index
+
+ @cython.embedsignature(False)
+ @property
+ def number(self):
+ """First value on #S line (as int)"""
+ return self._number
+
+ @cython.embedsignature(False)
+ @property
+ def order(self):
+ """Order can be > 1 if the same number is repeated in a specfile"""
+ return self._order
+
+ @cython.embedsignature(False)
+ @property
+ def header(self):
+ """List of raw header lines (as a list of strings).
+
+ This includes the file header, the scan header and possibly a MCA
+ header.
+ """
+ return self._header
+
+ @cython.embedsignature(False)
+ @property
+ def scan_header(self):
+ """List of raw scan header lines (as a list of strings).
+ """
+ return self._scan_header_lines
+
+ @cython.embedsignature(False)
+ @property
+ def file_header(self):
+ """List of raw file header lines (as a list of strings).
+ """
+ return self._file_header_lines
+
+ @cython.embedsignature(False)
+ @property
+ def scan_header_dict(self):
+ """
+ Dictionary of scan header strings, keys without the leading``#``
+ (e.g. ``scan_header_dict["S"]``).
+ Note: this does not include MCA header lines starting with ``#@``.
+ """
+ return self._scan_header_dict
+
+ @cython.embedsignature(False)
+ @property
+ def mca_header_dict(self):
+ """
+ Dictionary of MCA header strings, keys without the leading ``#@``
+ (e.g. ``mca_header_dict["CALIB"]``).
+ """
+ return self._mca_header_dict
+
+ @cython.embedsignature(False)
+ @property
+ def file_header_dict(self):
+ """
+ Dictionary of file header strings, keys without the leading ``#``
+ (e.g. ``file_header_dict["F"]``).
+ """
+ return self._file_header_dict
+
+ @cython.embedsignature(False)
+ @property
+ def labels(self):
+ """
+ List of data column headers from ``#L`` scan header
+ """
+ return self._labels
+
+ @cython.embedsignature(False)
+ @property
+ def data(self):
+ """Scan data as a 2D numpy.ndarray with the usual attributes
+ (e.g. data.shape).
+
+ The first index is the detector, the second index is the sample index.
+ """
+ if self._data is None:
+ self._data = numpy.transpose(self._specfile.data(self._index))
+
+ return self._data
+
+ @cython.embedsignature(False)
+ @property
+ def mca(self):
+ """MCA data in this scan.
+
+ Each multichannel analysis is a 1D numpy array. Metadata about
+ MCA data is to be found in :py:attr:`mca_header`.
+
+ :rtype: :class:`MCA`
+ """
+ if self._mca is None:
+ self._mca = MCA(self)
+ return self._mca
+
+ @cython.embedsignature(False)
+ @property
+ def motor_names(self):
+ """List of motor names from the ``#O`` file header line.
+ """
+ return self._motor_names
+
+ @cython.embedsignature(False)
+ @property
+ def motor_positions(self):
+ """List of motor positions as floats from the ``#P`` scan header line.
+ """
+ return self._motor_positions
+
+ def record_exists_in_hdr(self, record):
+ """Check whether a scan header line exists.
+
+ This should be used before attempting to retrieve header information
+ using a C function that may crash with a *segmentation fault* if the
+ header isn't defined in the SpecFile.
+
+ :param record: single upper case letter corresponding to the
+ header you want to test (e.g. ``L`` for labels)
+ :type record: str
+
+ :return: True or False
+ :rtype: boolean
+ """
+ for line in self._header:
+ if line.startswith("#" + record):
+ return True
+ return False
+
+ def data_line(self, line_index):
+ """Returns data for a given line of this scan.
+
+ .. note::
+
+ A data line returned by this method, corresponds to a data line
+ in the original specfile (a series of data points, one per
+ detector). In the :attr:`data` array, this line index corresponds
+ to the index in the second dimension (~ column) of the array.
+
+ :param line_index: Index of data line to retrieve (starting with 0)
+ :type line_index: int
+
+ :return: Line data as a 1D array of doubles
+ :rtype: numpy.ndarray
+ """
+ # attribute data corresponds to a transposed version of the original
+ # specfile data (where detectors correspond to columns)
+ return self.data[:, line_index]
+
+ def data_column_by_name(self, label):
+ """Returns a data column
+
+ :param label: Label of data column to retrieve, as defined on the
+ ``#L`` line of the scan header.
+ :type label: str
+
+ :return: Line data as a 1D array of doubles
+ :rtype: numpy.ndarray
+ """
+ try:
+ ret = self._specfile.data_column_by_name(self._index, label)
+ except SfErrLineNotFound:
+ # Could be a "#C Scan aborted after 0 points"
+ _logger.warning("Cannot get data column %s in scan %d.%d",
+ label, self.number, self.order)
+ ret = numpy.empty((0, ), numpy.double)
+ return ret
+
+
+ def motor_position_by_name(self, name):
+ """Returns the position for a given motor
+
+ :param name: Name of motor, as defined on the ``#O`` line of the
+ file header.
+ :type name: str
+
+ :return: Motor position
+ :rtype: float
+ """
+ return self._specfile.motor_position_by_name(self._index, name)
+
+
+def _string_to_char_star(string_):
+ """Convert a string to ASCII encoded bytes when using python3"""
+ if sys.version.startswith("3") and not isinstance(string_, bytes):
+ return bytes(string_, "ascii")
+ return string_
+
+
+def is_specfile(filename):
+ """Test if a file is a SPEC file, by checking if one of the first two
+ lines starts with *#F* (SPEC file header) or *#S* (scan header).
+
+ :param str filename: File path
+ :return: *True* if file is a SPEC file, *False* if it is not a SPEC file
+ :rtype: bool
+ """
+ if not os.path.isfile(filename):
+ return False
+ # test for presence of #S or #F in first two lines
+ f = open(filename)
+ for i, line in enumerate(f):
+ if line.startswith("#S ") or line.startswith("#F "):
+ f.close()
+ return True
+ if i >= 10:
+ break
+ f.close()
+ return False
+
+
+cdef class SpecFile(object):
+ """
+
+ :param filename: Path of the SpecFile to read
+
+ This class wraps the main data and header access functions of the C
+ SpecFile library.
+ """
+
+ cdef:
+ specfile_wrapper.SpecFileHandle *handle
+ str filename
+ int __open_failed
+
+ def __cinit__(self, filename):
+ cdef int error = SF_ERR_NO_ERRORS
+ self.__open_failed = 0
+
+ if is_specfile(filename):
+ filename = _string_to_char_star(filename)
+ self.handle = specfile_wrapper.SfOpen(filename, &error)
+ else:
+ self.__open_failed = 1
+ self._handle_error(SF_ERR_FILE_OPEN)
+ if error:
+ self.__open_failed = 1
+ self._handle_error(error)
+
+ def __init__(self, filename):
+ if not isinstance(filename, str):
+ # encode unicode to str in python 2
+ if sys.version_info[0] < 3:
+ self.filename = filename.encode()
+ # decode bytes to str in python 3
+ elif sys.version_info[0] >= 3:
+ self.filename = filename.decode()
+ else:
+ self.filename = filename
+
+ def __dealloc__(self):
+ """Destructor: Calls SfClose(self.handle)"""
+ #SfClose makes a segmentation fault if file failed to open
+ if not self.__open_failed:
+ if specfile_wrapper.SfClose(self.handle):
+ _logger.warning("Error while closing SpecFile")
+
+ def __len__(self):
+ """Return the number of scans in the SpecFile
+ """
+ return specfile_wrapper.SfScanNo(self.handle)
+
+ def __iter__(self):
+ """Return the next :class:`Scan` in a SpecFile each time this method
+ is called.
+
+ This usually happens when the python built-in function ``next()`` is
+ called with a :class:`SpecFile` instance as a parameter, or when a
+ :class:`SpecFile` instance is used as an iterator (e.g. in a ``for``
+ loop).
+ """
+ for scan_index in range(len(self)):
+ yield Scan(self, scan_index)
+
+ def __getitem__(self, key):
+ """Return a :class:`Scan` object.
+
+ This special method is called when a :class:`SpecFile` instance is
+ accessed as a dictionary (e.g. ``sf[key]``).
+
+ :param key: 0-based scan index or ``"n.m"`` key, where ``n`` is the scan
+ number defined on the ``#S`` header line and ``m`` is the order
+ :type key: int or str
+
+ :return: Scan defined by its 0-based index or its ``"n.m"`` key
+ :rtype: :class:`Scan`
+ """
+ msg = "The scan identification key can be an integer representing "
+ msg += "the unique scan index or a string 'N.M' with N being the scan"
+ msg += " number and M the order (eg '2.3')."
+
+ if isinstance(key, int):
+ scan_index = key
+ # allow negative index, like lists
+ if scan_index < 0:
+ scan_index = len(self) + scan_index
+ else:
+ try:
+ (number, order) = map(int, key.split("."))
+ scan_index = self.index(number, order)
+ except (ValueError, SfErrScanNotFound, KeyError):
+ # int() can raise a value error
+ raise KeyError(msg + "\nValid keys: '" +
+ "', '".join( self.keys()) + "'")
+ except AttributeError:
+ # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ raise TypeError(msg)
+
+ if not 0 <= scan_index < len(self):
+ msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ raise IndexError(msg)
+
+ return Scan(self, scan_index)
+
+ def keys(self):
+ """Returns list of scan keys (eg ``['1.1', '2.1',...]``).
+
+ :return: list of scan keys
+ :rtype: list of strings
+ """
+ ret_list = []
+ list_of_numbers = self._list()
+ count = {}
+
+ for number in list_of_numbers:
+ if not number in count:
+ count[number] = 1
+ else:
+ count[number] += 1
+ ret_list.append(u'%d.%d' % (number, count[number]))
+
+ return ret_list
+
+ def __contains__(self, key):
+ """Return ``True`` if ``key`` is a valid scan key.
+ Valid keys can be a string such as ``"1.1"`` or a 0-based scan index.
+ """
+ return key in (self.keys() + list(range(len(self))))
+
+ def _get_error_string(self, error_code):
+ """Returns the error message corresponding to the error code.
+
+ :param code: Error code
+ :type code: int
+ :return: Human readable error message
+ :rtype: str
+ """
+ return (<bytes> specfile_wrapper.SfError(error_code)).decode()
+
+ def _handle_error(self, error_code):
+ """Inspect error code, raise adequate error type if necessary.
+
+ :param code: Error code
+ :type code: int
+ """
+ error_message = self._get_error_string(error_code)
+ if error_code in ERRORS:
+ raise ERRORS[error_code](error_message)
+
+ def index(self, scan_number, scan_order=1):
+ """Returns scan index from scan number and order.
+
+ :param scan_number: Scan number (possibly non-unique).
+ :type scan_number: int
+ :param scan_order: Scan order.
+ :type scan_order: int default 1
+
+ :return: Unique scan index
+ :rtype: int
+
+
+ Scan indices are increasing from ``0`` to ``len(self)-1`` in the
+ order in which they appear in the file.
+ Scan numbers are defined by users and are not necessarily unique.
+ The scan order for a given scan number increments each time the scan
+ number appers in a given file.
+ """
+ idx = specfile_wrapper.SfIndex(self.handle, scan_number, scan_order)
+ if idx == -1:
+ self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ return idx - 1
+
+ def number(self, scan_index):
+ """Returns scan number from scan index.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: User defined scan number.
+ :rtype: int
+ """
+ idx = specfile_wrapper.SfNumber(self.handle, scan_index + 1)
+ if idx == -1:
+ self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ return idx
+
+ def order(self, scan_index):
+ """Returns scan order from scan index.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Scan order (sequential number incrementing each time a
+ non-unique occurrence of a scan number is encountered).
+ :rtype: int
+ """
+ ordr = specfile_wrapper.SfOrder(self.handle, scan_index + 1)
+ if ordr == -1:
+ self._handle_error(SF_ERR_SCAN_NOT_FOUND)
+ return ordr
+
+ def _list(self):
+ """see documentation of :meth:`list`
+ """
+ cdef:
+ long *scan_numbers
+ int error = SF_ERR_NO_ERRORS
+
+ scan_numbers = specfile_wrapper.SfList(self.handle, &error)
+ self._handle_error(error)
+
+ ret_list = []
+ for i in range(len(self)):
+ ret_list.append(scan_numbers[i])
+
+ free(scan_numbers)
+ return ret_list
+
+ def list(self):
+ """Returns list (1D numpy array) of scan numbers in SpecFile.
+
+ :return: list of scan numbers (from `` #S`` lines) in the same order
+ as in the original SpecFile (e.g ``[1, 1, 2, 3, …]``).
+ :rtype: numpy array
+ """
+ # this method is overloaded in specfilewrapper to output a string
+ # representation of the list
+ return self._list()
+
+ def data(self, scan_index):
+ """Returns data for the specified scan index.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Complete scan data as a 2D array of doubles
+ :rtype: numpy.ndarray
+ """
+ cdef:
+ double** mydata
+ long* data_info
+ int i, j
+ int error = SF_ERR_NO_ERRORS
+ long nlines, ncolumns, regular
+
+ sfdata_error = specfile_wrapper.SfData(self.handle,
+ scan_index + 1,
+ &mydata,
+ &data_info,
+ &error)
+ self._handle_error(error)
+
+ if <long>data_info != 0:
+ nlines = data_info[0]
+ ncolumns = data_info[1]
+ regular = data_info[2]
+ else:
+ nlines = 0
+ ncolumns = 0
+ regular = 0
+
+ cdef numpy.ndarray ret_array = numpy.empty((nlines, ncolumns),
+ dtype=numpy.double)
+ for i in range(nlines):
+ for j in range(ncolumns):
+ ret_array[i, j] = mydata[i][j]
+
+ specfile_wrapper.freeArrNZ(<void ***>&mydata, nlines)
+ free(data_info)
+ return ret_array
+
+ def data_column_by_name(self, scan_index, label):
+ """Returns data column for the specified scan index and column label.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+ :param label: Label of data column, as defined in the ``#L`` line
+ of the scan header.
+ :type label: str
+
+ :return: Data column as a 1D array of doubles
+ :rtype: numpy.ndarray
+ """
+ cdef:
+ double* data_column
+ long i, nlines
+ int error = SF_ERR_NO_ERRORS
+
+ label = _string_to_char_star(label)
+
+ nlines = specfile_wrapper.SfDataColByName(self.handle,
+ scan_index + 1,
+ label,
+ &data_column,
+ &error)
+ self._handle_error(error)
+
+ cdef numpy.ndarray ret_array = numpy.empty((nlines,),
+ dtype=numpy.double)
+ for i in range(nlines):
+ ret_array[i] = data_column[i]
+
+ free(data_column)
+ return ret_array
+
+ def scan_header(self, scan_index):
+ """Return list of scan header lines.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: List of raw scan header lines
+ :rtype: list of str
+ """
+ cdef:
+ char** lines
+ int error = SF_ERR_NO_ERRORS
+
+ nlines = specfile_wrapper.SfHeader(self.handle,
+ scan_index + 1,
+ "", # no pattern matching
+ &lines,
+ &error)
+
+ self._handle_error(error)
+
+ lines_list = []
+ for i in range(nlines):
+ line = <bytes>lines[i].decode()
+ lines_list.append(line)
+
+ specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ return lines_list
+
+ def file_header(self, scan_index=0):
+ """Return list of file header lines.
+
+ A file header contains all lines between a ``#F`` header line and
+ a ``#S`` header line (start of scan). We need to specify a scan
+ number because there can be more than one file header in a given file.
+ A file header applies to all subsequent scans, until a new file
+ header is defined.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: List of raw file header lines
+ :rtype: list of str
+ """
+ cdef:
+ char** lines
+ int error = SF_ERR_NO_ERRORS
+
+ nlines = specfile_wrapper.SfFileHeader(self.handle,
+ scan_index + 1,
+ "", # no pattern matching
+ &lines,
+ &error)
+ self._handle_error(error)
+
+ lines_list = []
+ for i in range(nlines):
+ line = <bytes>lines[i].decode()
+ lines_list.append(line)
+
+ specfile_wrapper.freeArrNZ(<void***>&lines, nlines)
+ return lines_list
+
+ def columns(self, scan_index):
+ """Return number of columns in a scan from the ``#N`` header line
+ (without ``#N`` and scan number)
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Number of columns in scan from ``#N`` line
+ :rtype: int
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ ncolumns = specfile_wrapper.SfNoColumns(self.handle,
+ scan_index + 1,
+ &error)
+ self._handle_error(error)
+
+ return ncolumns
+
+ def command(self, scan_index):
+ """Return ``#S`` line (without ``#S`` and scan number)
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: S line
+ :rtype: str
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ s_record = <bytes> specfile_wrapper.SfCommand(self.handle,
+ scan_index + 1,
+ &error)
+ self._handle_error(error)
+
+ return s_record.decode()
+
+ def date(self, scan_index=0):
+ """Return date from ``#D`` line
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Date from ``#D`` line
+ :rtype: str
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ d_line = <bytes> specfile_wrapper.SfDate(self.handle,
+ scan_index + 1,
+ &error)
+ self._handle_error(error)
+
+ return d_line.decode()
+
+ def labels(self, scan_index):
+ """Return all labels from ``#L`` line
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: All labels from ``#L`` line
+ :rtype: list of strings
+ """
+ cdef:
+ char** all_labels
+ int error = SF_ERR_NO_ERRORS
+
+ nlabels = specfile_wrapper.SfAllLabels(self.handle,
+ scan_index + 1,
+ &all_labels,
+ &error)
+ self._handle_error(error)
+
+ labels_list = []
+ for i in range(nlabels):
+ labels_list.append(<bytes>all_labels[i].decode())
+
+ specfile_wrapper.freeArrNZ(<void***>&all_labels, nlabels)
+ return labels_list
+
+ def motor_names(self, scan_index=0):
+ """Return all motor names from ``#O`` lines
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.If not specified, defaults to 0 (meaning the
+ function returns motors names associated with the first scan).
+ This parameter makes a difference only if there are more than
+ on file header in the file, in which case the file header applies
+ to all following scans until a new file header appears.
+ :type scan_index: int
+
+ :return: All motor names
+ :rtype: list of strings
+ """
+ cdef:
+ char** all_motors
+ int error = SF_ERR_NO_ERRORS
+
+ nmotors = specfile_wrapper.SfAllMotors(self.handle,
+ scan_index + 1,
+ &all_motors,
+ &error)
+ self._handle_error(error)
+
+ motors_list = []
+ for i in range(nmotors):
+ motors_list.append(<bytes>all_motors[i].decode())
+
+ specfile_wrapper.freeArrNZ(<void***>&all_motors, nmotors)
+ return motors_list
+
+ def motor_positions(self, scan_index):
+ """Return all motor positions
+
+ :param scan_index: Unique scan index between ``0``
+ and ``len(self)-1``.
+ :type scan_index: int
+
+ :return: All motor positions
+ :rtype: list of double
+ """
+ cdef:
+ double* motor_positions
+ int error = SF_ERR_NO_ERRORS
+
+ nmotors = specfile_wrapper.SfAllMotorPos(self.handle,
+ scan_index + 1,
+ &motor_positions,
+ &error)
+ self._handle_error(error)
+
+ motor_positions_list = []
+ for i in range(nmotors):
+ motor_positions_list.append(motor_positions[i])
+
+ free(motor_positions)
+ return motor_positions_list
+
+ def motor_position_by_name(self, scan_index, name):
+ """Return motor position
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Specified motor position
+ :rtype: double
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ name = _string_to_char_star(name)
+
+ motor_position = specfile_wrapper.SfMotorPosByName(self.handle,
+ scan_index + 1,
+ name,
+ &error)
+ self._handle_error(error)
+
+ return motor_position
+
+ def number_of_mca(self, scan_index):
+ """Return number of mca spectra in a scan.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: Number of mca spectra.
+ :rtype: int
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+
+ num_mca = specfile_wrapper.SfNoMca(self.handle,
+ scan_index + 1,
+ &error)
+ # error code updating isn't implemented in SfNoMCA
+ if num_mca == -1:
+ raise SfNoMcaError("Failed to retrieve number of MCA " +
+ "(SfNoMca returned -1)")
+ return num_mca
+
+ def mca_calibration(self, scan_index):
+ """Return MCA calibration in the form :math:`a + b x + c x²`
+
+ Raise a KeyError if there is no ``@CALIB`` line in the scan header.
+
+ :param scan_index: Unique scan index between ``0`` and
+ ``len(self)-1``.
+ :type scan_index: int
+
+ :return: MCA calibration as a list of 3 values :math:`(a, b, c)`
+ :rtype: list of floats
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+ double* mca_calib
+
+ mca_calib_error = specfile_wrapper.SfMcaCalib(self.handle,
+ scan_index + 1,
+ &mca_calib,
+ &error)
+
+ # error code updating isn't implemented in SfMcaCalib
+ if mca_calib_error:
+ raise KeyError("MCA calibration line (@CALIB) not found")
+
+ mca_calib_list = []
+ for i in range(3):
+ mca_calib_list.append(mca_calib[i])
+
+ free(mca_calib)
+ return mca_calib_list
+
+ def get_mca(self, scan_index, mca_index):
+ """Return one MCA spectrum
+
+ :param scan_index: Unique scan index between ``0`` and ``len(self)-1``.
+ :type scan_index: int
+ :param mca_index: Index of MCA in the scan
+ :type mca_index: int
+
+ :return: MCA spectrum
+ :rtype: 1D numpy array
+ """
+ cdef:
+ int error = SF_ERR_NO_ERRORS
+ double* mca_data
+ long len_mca
+
+ len_mca = specfile_wrapper.SfGetMca(self.handle,
+ scan_index + 1,
+ mca_index + 1,
+ &mca_data,
+ &error)
+ self._handle_error(error)
+
+
+ cdef numpy.ndarray ret_array = numpy.empty((len_mca,),
+ dtype=numpy.double)
+ for i in range(len_mca):
+ ret_array[i] = mca_data[i]
+
+ free(mca_data)
+ return ret_array
diff --git a/silx/io/specfile/specfile_wrapper.pxd b/silx/io/specfile/specfile_wrapper.pxd
new file mode 100644
index 0000000..6770f7e
--- /dev/null
+++ b/silx/io/specfile/specfile_wrapper.pxd
@@ -0,0 +1,77 @@
+# 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.
+#
+# ############################################################################*/
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "17/03/2016"
+
+cimport cython
+
+cdef extern from "SpecFileCython.h":
+ struct _SpecFile:
+ pass
+# Renaming struct because we have too many SpecFile items (files, classes…)
+ctypedef _SpecFile SpecFileHandle
+
+cdef extern from "SpecFileCython.h":
+ # sfinit
+ SpecFileHandle* SfOpen(char*, int*)
+ int SfClose(SpecFileHandle*)
+ char* SfError(int)
+
+ # sfindex
+ long* SfList(SpecFileHandle*, int*)
+ long SfScanNo(SpecFileHandle*)
+ long SfIndex(SpecFileHandle*, long, long)
+ long SfNumber(SpecFileHandle*, long)
+ long SfOrder(SpecFileHandle*, long)
+
+ # sfdata
+ int SfData(SpecFileHandle*, long, double***, long**, int*)
+ long SfDataLine(SpecFileHandle*, long, long, double**, int*)
+ long SfDataColByName(SpecFileHandle*, long, char*, double**, int*)
+
+ # sfheader
+ #char* SfTitle(SpecFileHandle*, long, int*)
+ long SfHeader(SpecFileHandle*, long, char*, char***, int*)
+ long SfFileHeader(SpecFileHandle*, long, char*, char***, int*)
+ char* SfCommand(SpecFileHandle*, long, int*)
+ long SfNoColumns(SpecFileHandle*, long, int*)
+ char* SfDate(SpecFileHandle*, long, int*)
+
+ # sflabel
+ long SfAllLabels(SpecFileHandle*, long, char***, int*)
+ char* SfLabel(SpecFileHandle*, long, long, int *)
+ long SfAllMotors(SpecFileHandle*, long, char***, int*)
+ long SfAllMotorPos(SpecFileHandle*, long, double**, int*)
+ double SfMotorPosByName(SpecFileHandle*, long, char*, int*)
+
+ # sftools
+ void freeArrNZ(void***, long)
+
+ # sfmca
+ long SfNoMca(SpecFileHandle*, long, int*)
+ int SfGetMca(SpecFileHandle*, long, long , double**, int*)
+ long SfMcaCalib(SpecFileHandle*, long, double**, int*)
+
diff --git a/silx/io/specfile/src/locale_management.c b/silx/io/specfile/src/locale_management.c
new file mode 100644
index 0000000..1e6a196
--- /dev/null
+++ b/silx/io/specfile/src/locale_management.c
@@ -0,0 +1,64 @@
+#/*##########################################################################
+# Copyright (C) 2012-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+#include <locale_management.h>
+#include <stdlib.h>
+
+#ifdef _GNU_SOURCE
+#include <xlocale.h>
+#include <locale.h>
+#else
+#ifdef PYMCA_POSIX
+#else
+#ifdef SPECFILE_POSIX
+#include <locale.h>
+#endif
+#endif
+#endif
+
+#include <string.h>
+
+double PyMcaAtof(const char * inputString)
+{
+#ifdef _GNU_SOURCE
+ double result;
+ locale_t newLocale;
+ newLocale = newlocale(LC_NUMERIC_MASK, "C", NULL);
+ result = strtod_l(inputString, NULL, newLocale);
+ freelocale(newLocale);
+ return result;
+#else
+#ifdef PYMCA_POSIX
+ return atof(inputString);
+#else
+#ifdef SPECFILE_POSIX
+ char *currentLocaleBuffer;
+ char *restoredLocaleBuffer;
+ char localeBuffer[21];
+ double result;
+ currentLocaleBuffer = setlocale(LC_NUMERIC, NULL);
+ strcpy(localeBuffer, currentLocaleBuffer);
+ setlocale(LC_NUMERIC, "C\0");
+ result = atof(inputString);
+ restoredLocaleBuffer = setlocale(LC_NUMERIC, localeBuffer);
+ return(result);
+#else
+ return atof(inputString);
+#endif
+#endif
+#endif
+}
diff --git a/silx/io/specfile/src/sfdata.c b/silx/io/specfile/src/sfdata.c
new file mode 100644
index 0000000..229f4e6
--- /dev/null
+++ b/silx/io/specfile/src/sfdata.c
@@ -0,0 +1,775 @@
+#/*##########################################################################
+# Copyright (C) 2004-2014 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfdata.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Functions for getting data
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2005/07/04 15:02:38 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfdata.c,v $
+ * Log: Revision 1.8 2005/07/04 15:02:38 ahoms
+ * Log: Fixed memory leak in SfNoDataLines
+ * Log:
+ * Log: Revision 1.7 2004/01/20 09:23:50 sole
+ * Log: Small change in sfdata (ptr < (to-1)) changed to (ptr <= (to-1))
+ * Log:
+ * Log: Revision 1.6 2003/03/06 16:56:40 sole
+ * Log: Check if to is beyond the scan size in SfData (still not finished but it seems to solve a crash)
+ * Log:
+ * Log: Revision 1.5 2002/12/09 13:04:05 sole
+ * Log: Added a check in SfNoDataLines
+ * Log:
+ * Log: Revision 1.4 2002/11/13 15:02:38 sole
+ * Log: Removed some printing in SfData
+ * Log:
+ * Log: Revision 1.3 2002/11/12 16:22:07 sole
+ * Log: WARNING: Developing version - Improved MCA reading and reading properly the end of the file.
+ * Log:
+ * Log: Revision 1.2 2002/11/12 13:15:52 sole
+ * Log: 1st version from Armando. The idea behind is to take the last line only if it ends with \n
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:11 19:05:11 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ *
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#include <locale_management.h>
+
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+#include <locale.h>
+#endif
+#endif
+
+#include <ctype.h>
+/*
+ * Define macro
+ */
+#define isnumber(this) ( isdigit(this) || this == '-' || this == '+' || this == '.' || this == 'E' || this == 'e')
+
+/*
+ * Mca continuation character
+ */
+#define MCA_CONT '\\'
+#define D_INFO 3
+
+/*
+ * Declarations
+ */
+DllExport long SfNoDataLines ( SpecFile *sf, long index, int *error );
+DllExport int SfData ( SpecFile *sf, long index, double ***retdata,
+ long **retinfo, int *error );
+DllExport long SfDataAsString ( SpecFile *sf, long index,
+ char ***data, int *error );
+DllExport long SfDataLine ( SpecFile *sf, long index, long line,
+ double **data_line, int *error );
+DllExport long SfDataCol ( SpecFile *sf, long index, long col,
+ double **data_col, int *error );
+DllExport long SfDataColByName( SpecFile *sf, long index,
+ char *label, double **data_col, int *error );
+
+
+/*********************************************************************
+ * Function: long SfNoDataLines( sf, index, error )
+ *
+ * Description: Gets number of data lines in a scan
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of data lines ,
+ * ( -1 ) => errors.
+ * Possible errors:
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfNoDataLines( SpecFile *sf, long index, int *error )
+{
+ long *dinfo = NULL;
+ double **data = NULL;
+ long nrlines = 0;
+ int ret, i;
+
+ ret = SfData(sf,index,&data,&dinfo,error);
+
+ if (ret == -1) {
+ return(-1);
+ }
+ if (dinfo == (long *) NULL){
+ return(-1);
+ }
+ if (dinfo[ROW] < 0){
+ printf("Negative number of points!\n");
+ /*free(dinfo);*/
+ return(-1);
+ }
+
+ nrlines = dinfo[ROW];
+
+ /* now free all stuff that SfData allocated */
+ for (i = 0; i < nrlines; i++)
+ free(data[i]);
+ free(data);
+ free(dinfo);
+
+ return nrlines;
+}
+
+
+
+/*********************************************************************
+ * Function: int SfData(sf, index, data, data_info, error)
+ *
+ * Description: Gets data.
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) Data array
+ * (4) Data info : [0] => no_lines
+ * [1] => no_columns
+ * [2] = ( 0 ) => regular
+ * ( 1 ) => not regular !
+ * (5) error number
+ * Returns:
+ * ( 0 ) => OK
+ * ( -1 ) => errors occured
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport int
+SfData( SpecFile *sf, long index, double ***retdata, long **retinfo, int *error )
+{
+ long *dinfo = NULL;
+ double **data = NULL;
+ double *dataline = NULL;
+ long headersize;
+
+ char *ptr,
+ *from,
+ *to;
+
+ char strval[100];
+ double val;
+ double valline[512];
+ long cols,
+ maxcol=512;
+ long rows;
+ int i;
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ char *currentLocaleBuffer;
+ char localeBuffer[21];
+#endif
+#endif
+
+ if (index <= 0 ){
+ return(-1);
+ }
+
+ if (sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+
+ /*
+ * Copy if already there
+ */
+ if (sf->data_info != (long *)NULL) {
+ dinfo = ( long * ) malloc ( sizeof(long) * D_INFO);
+ dinfo[ROW] = sf->data_info[ROW];
+ dinfo[COL] = sf->data_info[COL];
+ dinfo[REG] = sf->data_info[REG];
+ data = ( double **) malloc ( sizeof(double *) * dinfo[ROW]);
+ for (i=0;i<dinfo[ROW];i++) {
+ data[i] = (double *)malloc (sizeof(double) * dinfo[COL]);
+ memcpy(data[i],sf->data[i],sizeof(double) * dinfo[COL]);
+ }
+ *retdata = data;
+ *retinfo = dinfo;
+ return(0);
+ }
+ /*
+ * else do the job
+ */
+
+ if ( ((SpecScan *)sf->current->contents)->data_offset == -1 ) {
+ *retdata = data;
+ *retinfo = dinfo;
+ return(-1);
+ }
+
+ headersize = ((SpecScan *)sf->current->contents)->data_offset
+ - ((SpecScan *)sf->current->contents)->offset;
+
+ from = sf->scanbuffer + headersize;
+ to = sf->scanbuffer + ((SpecScan *)sf->current->contents)->size;
+ if (to > sf->scanbuffer+sf->scansize){
+ /* the -32 found "experimentaly" */
+ ptr = sf->scanbuffer+sf->scansize - 32;
+ while (*ptr != '\n') ptr--;
+ to=ptr;
+ /*printf("I let it crash ...\n");*/
+ }
+ i=0;
+ ptr = from;
+ rows = -1;
+ cols = -1;
+ /*
+ * Alloc memory
+ */
+ if ( (data = (double **) malloc (sizeof(double *)) ) == (double **)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ if ( (dinfo = (long *) malloc(sizeof(long) * D_INFO) ) == (long *)NULL) {
+ free(data);
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+ ptr = from;
+ dinfo[ROW] = dinfo[COL] = dinfo[REG] = 0;
+if(0){
+ /*
+ * first characters of buffer
+ */
+ while (*ptr == ' ') ptr++; /* get rid of empty spaces */
+
+ if (*ptr == '@') {
+ /*
+ * read all mca block: go while in buffer ( ptr < to - 1 )
+ * and while a newline is preceded by a slash
+ */
+ for ( ptr = ptr + 2;
+ (*ptr != '\n' || (*(ptr-1) == MCA_CONT)) && ptr < to ;
+ ptr++);
+ }
+ if ( *ptr == '#') { /* Comment --> pass one line */
+ for (ptr = ptr + 1; *ptr != '\n';ptr++);
+ }
+
+ /*
+ * continue
+ */
+ ptr++;
+}
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ currentLocaleBuffer = setlocale(LC_NUMERIC, NULL);
+ strcpy(localeBuffer, currentLocaleBuffer);
+ setlocale(LC_NUMERIC, "C\0");
+#endif
+#endif
+ for ( ; ptr < to; ptr++) {
+ /* get a complete line */
+ i=0;
+ cols=0;
+ /*I should be at the start of a line */
+ while(*(ptr) != '\n'){
+ if (*(ptr-1) == '\n'){
+ /*I am at the start of a line */
+ while(*ptr == '#'){
+ if (ptr >= to)
+ break;
+ for (ptr = ptr; ptr < to;ptr++){
+ if (*ptr == '\n'){
+ break;
+ }
+ };
+ /* on exit is equal to newline */
+ if (ptr < to) {
+ ptr++;
+ }
+ }
+ if (*ptr == '@') {
+ /*
+ * read all mca block: go while in buffer ( ptr < to - 1 )
+ * and while a newline is preceded by a slash
+ */
+ for ( ptr = ptr + 2;
+ (*ptr != '\n' || (*(ptr-1) == MCA_CONT)) && ptr < to ;
+ ptr++);
+ if (ptr >= to){
+ break;
+ }
+ }
+ while(*ptr == '#'){
+ if (ptr >= to)
+ break;
+ for (ptr = ptr; ptr < to;ptr++){
+ if (*ptr == '\n'){
+ break;
+ }
+ };
+ /* on exit is equal to newline */
+ if (ptr < to) {
+ ptr++;
+ }
+ }
+ /* first characters of buffer
+ */
+ while (*ptr == ' ' && ptr < to) ptr++; /* get rid of empty spaces */
+ }
+ /*
+ * in the middle of a line
+ */
+ if (*ptr == ' ' || *ptr == '\t' ) {
+ strval[i] = '\0';
+ i = 0;
+ val = PyMcaAtof(strval);
+ valline[cols] = val;
+ cols++;
+ if (cols >= maxcol) return(-1);
+ while(*(ptr+1) == ' ' || *(ptr+1) == '\t') ptr++;
+ } else {
+ if isnumber(*ptr){
+ strval[i] = *ptr;
+ i++;
+ }
+ }
+ if (ptr >= (to-1)){
+ break;
+ }
+ ptr++;
+ }
+ if ((*(ptr)== '\n') && (i != 0)){
+ strval[i] = '\0';
+ val = PyMcaAtof(strval);
+ valline[cols] = val;
+ cols++;
+ if (cols >= maxcol) return(-1);
+ /*while(*(ptr+1) == ' ' || *(ptr+1) == '\t') ptr++;*/
+ }
+ /*printf("%c",*ptr);*/
+ /* diffract31 crash -> changed from i!=0 to i==0 */
+ /*cols>0 necessary scan 59 of 31oct98 */
+ if ((ptr < to) && (cols >0)) {
+ rows++;
+ /*cols++;*/
+ if (cols >= maxcol) return(-1);
+ /* printf("Adding a new row, nrows = %ld, ncols= %ld\n",rows,cols);*/
+ /*printf("info col = %d cols = %d\n", dinfo[COL], cols);*/
+ if (dinfo[COL] != 0 && cols != dinfo[COL]) {
+ ;
+ /*diffract31 crash -> nextline uncommented */
+ dinfo[REG] = 1;
+ } else {
+ dinfo[COL] = cols;
+ }
+ if(dinfo[COL]==cols){
+ dataline = (double *)malloc(sizeof(double) * cols);
+ memcpy(dataline,valline,sizeof(double) * cols);
+ data = (double **) realloc ( data, sizeof(double) * (rows+1));
+ data[rows] = dataline;
+ dinfo[ROW]=rows+1;
+ }else{
+ printf("Error on scan %d line %d\n", (int) index, (int) (rows+1));
+ /* just ignore the line instead of stopping there with a
+ break; */
+ rows--;
+ }
+ }
+ }
+
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ setlocale(LC_NUMERIC, localeBuffer);
+#endif
+#endif
+ /*
+ * make a copy in specfile structure
+ */
+ if ( dinfo[ROW] != 0 && dinfo[REG] == 0) {
+ if (sf->data_info != (long *)NULL){
+ printf("I should not be here!/n");
+ sf->data_info[ROW] = dinfo[ROW];
+ sf->data_info[COL] = dinfo[COL];
+ sf->data_info[REG] = dinfo[REG];
+ for (i=0;i<dinfo[ROW];i++) {
+ sf->data[i]= (double *)realloc (sf->data[i],sizeof(double) * dinfo[COL]);
+ if (sf->data[i] == (double *) NULL){
+ printf("Realloc problem");
+ return (-1);
+ }
+ memcpy(sf->data[i],data[i],sizeof(double) * dinfo[COL]);
+ }
+ *retdata = data;
+ *retinfo = dinfo;
+ return(0);
+ }else{
+ sf->data_info = ( long * ) malloc ( sizeof(long) * D_INFO);
+ sf->data_info[ROW] = dinfo[ROW];
+ sf->data_info[COL] = dinfo[COL];
+ sf->data_info[REG] = dinfo[REG];
+ sf->data = ( double **) malloc ( sizeof(double *) * dinfo[ROW]);
+ if (sf->data == (double **) NULL){
+ printf("malloc1 problem");
+ return (-1);
+ }
+ for (i=0;i<dinfo[ROW];i++) {
+ sf->data[i] = (double *)malloc (sizeof(double) * dinfo[COL]);
+ if (sf->data[i] == (double *) NULL){
+ printf("malloc2 problem");
+ return (-1);
+ }
+ memcpy(sf->data[i],data[i],sizeof(double) * dinfo[COL]);
+ }
+ }
+ } else {
+ if (dinfo[REG] == 0) {
+ ;
+ /*printf("Not Freeing data:!\n");*/
+ /* I can be in the case of an mca without scan points */
+ /*free(data);
+ return(-1);*/
+ }
+ }
+ *retinfo = dinfo;
+ *retdata = data;
+ return( 0 );
+}
+
+
+DllExport long
+SfDataCol ( SpecFile *sf, long index, long col, double **retdata, int *error )
+{
+ double *datacol=NULL;
+
+ long *dinfo = NULL;
+ double **data = NULL;
+
+ long selection;
+ int i,ret;
+
+ ret = SfData(sf,index,&data,&dinfo,error);
+
+ if (ret == -1) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ *retdata = datacol;
+ return(-1);
+ }
+
+ if (col < 0) {
+ selection = dinfo[COL] + col;
+ } else {
+ selection = col - 1;
+ }
+if (selection > dinfo[COL] - 1) {
+selection=dinfo[COL] - 1;
+}
+ if ( selection < 0 || selection > dinfo[COL] - 1) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ if ( dinfo != (long *)NULL) {
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ }
+ free(dinfo);
+ return(-1);
+ }
+
+ datacol = (double *) malloc( sizeof(double) * dinfo[ROW]);
+ if (datacol == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+ return(-1);
+ }
+
+ for (i=0;i<dinfo[ROW];i++) {
+ datacol[i] = data[i][selection];
+ }
+
+ ret = dinfo[ROW];
+
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+
+ *retdata = datacol;
+ return(ret);
+}
+
+
+DllExport long
+SfDataLine( SpecFile *sf, long index, long line, double **retdata, int *error )
+{
+ double *datarow=NULL;
+
+ long *dinfo = NULL;
+ double **data = NULL;
+
+ long selection;
+ int ret;
+
+ ret = SfData(sf,index,&data,&dinfo,error);
+
+ if (ret == -1) {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ *retdata = datarow;
+ return(-1);
+ }
+
+ if (line < 0) {
+ selection = dinfo[ROW] + line;
+ } else {
+ selection = line - 1;
+ }
+
+ if ( selection < 0 || selection > dinfo[ROW] - 1) {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ if ( dinfo != (long *)NULL) {
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ }
+ free(dinfo);
+ return(-1);
+ }
+
+ datarow = (double *) malloc( sizeof(double) * dinfo[COL]);
+ if (datarow == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+ return(-1);
+ }
+
+
+ memcpy(datarow,data[selection],sizeof(double) * dinfo[COL]);
+
+ ret = dinfo[COL];
+
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+
+ *retdata = datarow;
+ return(ret);
+}
+
+
+DllExport long
+SfDataColByName( SpecFile *sf, long index, char *label, double **retdata, int *error )
+{
+
+ double *datacol;
+
+ long *dinfo = NULL;
+ double **data = NULL;
+
+ int i,ret;
+
+ char **labels = NULL;
+
+ long nb_lab,
+ idx;
+
+ short tofree=0;
+
+ if ( sfSetCurrent(sf,index,error) == -1) {
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ if ( sf->no_labels != -1 ) {
+ nb_lab = sf->no_labels;
+ labels = sf->labels;
+ } else {
+ nb_lab = SfAllLabels(sf,index,&labels,error);
+ tofree = 1;
+ }
+
+ if ( nb_lab == 0 || nb_lab == -1) {
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ for (idx=0;idx<nb_lab;idx++)
+ if (!strcmp(label,labels[idx])) break;
+
+ if ( idx == nb_lab ) {
+ if (tofree) freeArrNZ((void ***)&labels,nb_lab);
+ *error = SF_ERR_COL_NOT_FOUND;
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ ret = SfData(sf,index,&data,&dinfo,error);
+
+ if (ret == -1) {
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ datacol = (double *) malloc( sizeof(double) * dinfo[ROW]);
+ if (datacol == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ for (i=0;i<dinfo[ROW];i++) {
+ datacol[i] = data[i][idx];
+ }
+
+ ret = dinfo[ROW];
+
+ if ( dinfo != (long *)NULL)
+ freeArrNZ((void ***)&data,dinfo[ROW]);
+ free(dinfo);
+
+ *retdata = datacol;
+
+ return(ret);
+}
+
+
+DllExport long
+SfDataAsString( SpecFile *sf, long index, char ***retdata, int *error )
+{
+ char **data=NULL;
+ char oneline[300];
+
+ char *from,
+ *to,
+ *ptr,
+ *dataline;
+
+ long headersize,rows;
+ int i;
+
+ if (sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+ if ( ((SpecScan *)sf->current->contents)->data_offset == -1 ) {
+ *retdata = data;
+ return(-1);
+ }
+
+ data = (char **) malloc (sizeof(char *));
+
+ headersize = ((SpecScan *)sf->current->contents)->data_offset
+ - ((SpecScan *)sf->current->contents)->offset;
+
+ from = sf->scanbuffer + headersize;
+ to = sf->scanbuffer + ((SpecScan *)sf->current->contents)->size;
+
+ rows = -1;
+ i = 0;
+
+ /*
+ * first characters of buffer
+ */
+
+ ptr = from;
+
+ if (isnumber(*ptr)) {
+ rows++;
+ oneline[i] = *ptr;
+ i++;
+ } else if (*ptr == '@') {
+ /*
+ * read all mca block: go while in buffer ( ptr < to - 1 )
+ * and while a newline is preceded by a slash
+ */
+ for ( ptr = ptr + 2;
+ (*(ptr+1) != '\n' || (*ptr == MCA_CONT)) && ptr < to - 1 ;
+ ptr++);
+ }
+
+ /*
+ * continue
+ */
+ ptr++;
+
+ for ( ; ptr < to - 1; ptr++) {
+ /*
+ * check for lines and for mca
+ */
+ if ( *(ptr-1) == '\n' ) {
+
+ if ( i != 0 ) {
+ oneline[i-1] = '\0';
+ i = 0;
+
+ dataline = (char *)strdup(oneline);
+ data = (char **) realloc ( data, sizeof(char *) * (rows +1));
+ data[rows] = dataline;
+ }
+
+ if ( *ptr == '@') { /* Mca --> pass it all */
+ for ( ptr = ptr + 2;
+ (*ptr != '\n' || (*(ptr-1) == MCA_CONT)) && ptr < to ;
+ ptr++);
+ } else if ( *ptr == '#') { /* Comment --> pass one line */
+ for (ptr = ptr + 1; *ptr != '\n';ptr++);
+ } else if ( isnumber(*ptr) ) {
+ rows++;
+ oneline[i] = *ptr;
+ i++;
+ }
+ } else {
+ if (rows == -1) continue;
+
+ oneline[i] = *ptr;
+ i++;
+ }
+ }
+
+ /*
+ * last line
+ */
+
+ if (rows != -1 && i) {
+ oneline[i-1] = '\0';
+ dataline = (char *)strdup(oneline);
+ data = (char **) realloc ( data, sizeof(char *) * (rows+1));
+ data[rows] = dataline;
+ }
+
+ *retdata = data;
+ return(rows+1);
+}
diff --git a/silx/io/specfile/src/sfheader.c b/silx/io/specfile/src/sfheader.c
new file mode 100644
index 0000000..424eb08
--- /dev/null
+++ b/silx/io/specfile/src/sfheader.c
@@ -0,0 +1,787 @@
+#/*##########################################################################
+# Copyright (C) 2004-2016 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfheader.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Functions to access file and scan headers
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2002/11/20 09:01:29 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfheader.c,v $
+ * Log: Revision 1.3 2002/11/20 09:01:29 sole
+ * Log: Added free(line); in SfTitle
+ * Log:
+ * Log: Revision 1.2 2002/11/14 16:18:48 sole
+ * Log: stupid bug removed
+ * Log:
+ * Log: Revision 1.1 2002/11/14 15:25:39 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:09 19:05:09 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+
+/*
+ * Function Declaration
+ */
+DllExport char * SfCommand ( SpecFile *sf, long index, int *error );
+DllExport long SfNoColumns ( SpecFile *sf, long index, int *error );
+DllExport char * SfDate ( SpecFile *sf, long index, int *error );
+DllExport double * SfHKL ( SpecFile *sf, long index, int *error );
+
+DllExport long SfEpoch ( SpecFile *sf, long index, int *error );
+DllExport char * SfUser ( SpecFile *sf, long index, int *error );
+DllExport char * SfTitle ( SpecFile *sf, long index, int *error );
+DllExport char * SfFileDate ( SpecFile *sf, long index, int *error );
+DllExport long SfNoHeaderBefore ( SpecFile *sf, long index, int *error );
+DllExport long SfGeometry ( SpecFile *sf, long index,
+ char ***lines, int *error);
+DllExport long SfHeader ( SpecFile *sf, long index, char *string,
+ char ***lines, int *error);
+DllExport long SfFileHeader ( SpecFile *sf, long index, char *string,
+ char ***lines, int *error);
+
+int sfGetHeaderLine ( SpecFile *sf, int from, char character,
+ char **buf,int *error);
+/*
+ * Internal functions
+ */
+static char *sfFindWord ( char *line, char *word, int *error );
+static long sfFindLines ( char *from, char *to,char *string,
+ char ***lines,int *error);
+static char *sfOneLine ( char *from, char *end, int *error);
+
+
+/*********************************************************************
+ * Function: char *SfCommand( sf, index, error )
+ *
+ * Description: Reads '#S' line ( without #S and scan number ).
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * String pointer,
+ * NULL => errors.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport char *
+SfCommand( SpecFile *sf, long index, int *error )
+{
+ char *ret_line=NULL;
+ long cnt,start,length;
+ char *ptr;
+
+ /*
+ * Choose scan
+ */
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(ret_line);
+
+ cnt = 3;
+ for ( ptr = sf->scanbuffer + cnt; *ptr != ' ' ; ptr++,cnt++);
+ for ( ptr = sf->scanbuffer + cnt; *ptr == ' ' || *ptr == '\t'; ptr++,cnt++);
+
+ start = cnt;
+ for ( ptr = sf->scanbuffer + cnt; *ptr != '\n' ; ptr++,cnt++);
+
+ length = cnt - start;
+
+ /*
+ * Return the rest .
+ */
+ ret_line = (char *) malloc ( sizeof(char) * ( length + 1) );
+ if (ret_line == (char *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(ret_line);
+ }
+
+ ptr = sf->scanbuffer + start;
+ memcpy(ret_line,ptr,sizeof(char) * length );
+ ret_line[length] = '\0';
+
+ return( ret_line );
+}
+
+
+/*********************************************************************
+ * Function: long SfNoColumns( sf, index, error )
+ *
+ * Description: Gets number of columns in a scan
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of scan columns.(From #N line !)
+ * ( -1 ) if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfNoColumns( SpecFile *sf, long index, int *error )
+{
+ long col = -1;
+ char *buf=NULL;
+
+ if ( sfSetCurrent(sf,index,error) == -1)
+ return(-1);
+
+ if ( sfGetHeaderLine( sf, FROM_SCAN, SF_COLUMNS, &buf, error) == -1)
+ return(-1);
+ col = atol( buf );
+ free(buf);
+ return( col );
+}
+
+
+/*********************************************************************
+ * Function: char *SfDate( sf, index, error )
+ *
+ * Description: Gets date from scan header
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Date.(From #D line !),
+ * NULL => errors.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport char *
+SfDate(SpecFile *sf, long index, int *error )
+{
+ char *line=NULL;
+
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return(line);
+
+ if ( sfGetHeaderLine( sf, FROM_SCAN, SF_DATE, &line, error))
+ return((char *)NULL);
+
+ return( line );
+}
+
+
+/*********************************************************************
+ * Function: double *SfHKL( sf, index, error )
+ *
+ * Description: Reads '#Q' line.
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Poiter to a 3x1 dbl. array( HKL[0]=HKL[H]=H_value,
+ * HKL[1]=HKL[K]=K_value,
+ * HKL[2]=HKL[L]=L_value.
+ * NULL => errors.
+ *
+ * Possible errors:
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_MEMORY_ALLOC | => mulstrtod()
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport double *
+SfHKL( SpecFile *sf, long index, int *error )
+{
+ char *line=NULL;
+ double *HKL = NULL;
+ long i;
+
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return((double *)NULL);
+
+ if ( sfGetHeaderLine( sf, FROM_SCAN, SF_RECIP_SPACE, &line, error) == -1 )
+ return((double *)NULL);
+
+ /*
+ * Convert into double .
+ */
+ i = mulstrtod( line, &HKL, error );
+ free(line);
+
+ if ( i < 0)
+ return( (double *)NULL );
+
+ if ( i != 3 ) {
+ *error = SF_ERR_LINE_EMPTY;
+ free( HKL );
+ return( (double *)NULL );
+ }
+
+ return( HKL );
+}
+
+
+/*********************************************************************
+ * Function: long SfEpoch( sf, index, error )
+ *
+ * Description: Gets epoch from the last file header.
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Epoch.(From #E line !)
+ * ( -1 ) if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_FILE_READ
+ * SF_ERR_HEADER_NOT_FOUND
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfEpoch( SpecFile *sf, long index, int *error )
+{
+ char *buf=NULL;
+ long epoch = -1;
+
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+ if ( sfGetHeaderLine(sf,FROM_FILE,SF_EPOCH,&buf,error) == -1 )
+ return(-1);
+
+ epoch = atol( buf );
+ free(buf);
+
+ return( epoch );
+}
+
+
+/*********************************************************************
+ * Function: char SfFileDate( sf, index, error )
+ *
+ * Description: Gets date from the last file header
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Date.(From #D line !)
+ * NULL => errors.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_FILE_READ
+ * SF_ERR_HEADER_NOT_FOUND
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport char *
+SfFileDate( SpecFile *sf, long index, int *error )
+{
+ char *date = NULL;
+
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return((char *)NULL);
+
+ if ( sfGetHeaderLine(sf,FROM_FILE,SF_DATE,&date,error) == -1 )
+ return((char *)NULL);
+
+ return( date );
+}
+
+
+/*********************************************************************
+ * Function: long SfNoHeaderBefore( sf, index, error )
+ *
+ * Description: Gets number of scan header lines before data.
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Scan index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of scan header lines before data ,
+ * ( -1 ) => errors.
+ * Possible errors:
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfNoHeaderBefore( SpecFile *sf, long index, int *error )
+{
+ if ( sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+ /*
+ * Obsolete... give some reasonable!
+ */
+ return(-1);
+}
+
+
+/*********************************************************************
+ * Function: char *SfUser( sf, index, error )
+ *
+ * Description: Gets spec user information from the last file header
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * User.(From 1st #C line !)
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC ||=> findWordInLine()
+ * SF_ERR_LINE_NOT_FOUND |
+ * SF_ERR_FILE_READ |
+ * SF_ERR_SCAN_NOT_FOUND | => getFirstFileC()
+ * SF_ERR_HEADER_NOT_FOUND |
+ * SF_ERR_USER_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport char *
+SfUser( SpecFile *sf, long index, int *error )
+{
+
+ char *line=NULL;
+ char *user;
+ char word[] = "User =";
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return((char *)NULL);
+
+ if (sfGetHeaderLine( sf, FROM_FILE, SF_COMMENT, &line, error) == -1)
+ return((char *)NULL);
+
+ /*
+ * Find user.
+ */
+ user = sfFindWord( line, word, error );
+
+ if ( user == (char *) NULL) {
+ *error = SF_ERR_USER_NOT_FOUND;
+ return((char *)NULL);
+ }
+
+ free(line);
+ return( user );
+}
+
+
+/*********************************************************************
+ * Function: long SfTitle( sf, index, error )
+ *
+ * Description: Gets spec title information from the last file header
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Title.(From 1st #C line !)
+ * NULL => errors.
+ * Possible errors:
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_LINE_NOT_FOUND |
+ * SF_ERR_FILE_READ |
+ * SF_ERR_SCAN_NOT_FOUND | => getFirstFileC()
+ * SF_ERR_HEADER_NOT_FOUND |
+ *
+ *********************************************************************/
+DllExport char *
+SfTitle( SpecFile *sf, long index, int *error )
+{
+ char *line=NULL;
+ char *title;
+ char *ptr;
+ long i;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return((char *)NULL);
+
+ if (sfGetHeaderLine( sf, FROM_FILE, SF_COMMENT, &line, error) == -1)
+ return((char *)NULL);
+
+ /*
+ * Get title.( first word )
+ */
+ ptr = line;
+
+ for ( i=0,ptr=line ; *ptr!='\t' && *ptr!='\n' && *ptr!='\0' ; i++ ) {
+ if ( *ptr==' ' ) {
+ if ( *(++ptr)==' ' ) {
+ break;
+ } else ptr--;
+ }
+ ptr++;
+ }
+
+ if ( i==0 ) {
+ *error = SF_ERR_LINE_EMPTY;
+ return( (char *)NULL );
+ }
+
+ title = (char *)malloc( sizeof(char) * ( i+1 ) );
+
+ if ( title == (char *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( title );
+ }
+
+ memcpy( title, line, sizeof(char) * i );
+ /* Next line added by Armando, it may be wrong */
+ free(line);
+ title[i] = '\0';
+
+ return( title );
+}
+
+
+DllExport long
+SfGeometry ( SpecFile *sf, long index, char ***lines, int *error)
+{
+ char string[] = " \0";
+
+ string[0] = SF_GEOMETRY;
+
+ return(SfHeader(sf,index,string,lines,error));
+}
+
+
+DllExport long
+SfHeader ( SpecFile *sf, long index, char *string, char ***lines, int *error)
+{
+ char *headbuf,
+ *endheader;
+
+ long nb_found;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(-1);
+
+ headbuf = sf->scanbuffer;
+ endheader = sf->scanbuffer + sf->scansize;
+
+ nb_found = sfFindLines(headbuf, endheader,string, lines,error);
+
+ if (nb_found == 0) {
+ return SfFileHeader(sf,index,string,lines,error);
+ } else {
+ return nb_found;
+ }
+}
+
+
+
+DllExport long
+SfFileHeader ( SpecFile *sf, long index, char *string, char ***lines, int *error)
+{
+ char *headbuf,
+ *endheader;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(-1);
+ if (sf->filebuffersize > 0)
+ {
+ headbuf = sf->filebuffer;
+ endheader = sf->filebuffer + sf->filebuffersize;
+
+ return(sfFindLines(headbuf,endheader,string,lines,error));
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+static long
+sfFindLines(char *from,char *to,char *string,char ***ret,int *error)
+{
+ char **lines;
+ long found;
+ unsigned long j;
+ char *ptr;
+ short all=0;
+
+ found = 0;
+ ptr = from;
+
+ if ( string == (char *) NULL || strlen(string) == 0)
+ all = 1;
+
+ /*
+ * Allocate memory for an array of strings
+ */
+ if ( (lines = (char **)malloc( sizeof(char *) )) == (char **)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return ( -1 );
+ }
+
+ /*
+ * First line
+ */
+ if ( ptr[0] == '#' ) {
+ if ( all ) {
+ lines = (char **) realloc ( lines, (found+1) * sizeof(char *) );
+ lines[found] = sfOneLine(ptr,to,error);
+ found++;
+ } else if ( ptr[1] == string[0]) {
+ for ( j=0; j < strlen(string) && ptr+j< to;j++)
+ if ( ptr[j+1] != string[j]) break;
+ if ( j == strlen(string)) {
+ lines = (char **) realloc ( lines, (found+1) * sizeof(char *) );
+ lines[found] = sfOneLine(ptr,to,error);
+ found++;
+ }
+ }
+ }
+
+ /*
+ * The rest
+ */
+ for ( ptr = from + 1;ptr < to - 1;ptr++) {
+ if ( *(ptr - 1) == '\n' && *ptr == '#' ) {
+ if ( all ) {
+ lines = (char **) realloc ( lines, (found+1) * sizeof(char *) );
+ lines[found] = sfOneLine(ptr,to,error);
+ found++;
+ } else if ( *(ptr+1) == string[0]) {
+ for ( j=0; j < strlen(string) && (ptr + j) < to;j++)
+ if ( ptr[j+1] != string[j]) break;
+ if ( j == strlen(string)) {
+ lines = (char **) realloc ( lines, (found+1) * sizeof(char *) );
+ lines[found] = sfOneLine(ptr,to,error);
+ found++;
+ }
+ }
+ }
+ }
+
+ if (found) *ret = lines;
+ else free(lines);
+
+ return(found);
+}
+
+
+/*********************************************************************
+ * Function: char *sfGetHeaderLine( SpecFile *sf, sf_char, end, error )
+ *
+ * Description: Gets one '#sf_char' line.
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) sf_character
+ * (3) end ( where to stop the search )
+ * Output:
+ * (4) error number
+ * Returns:
+ * Pointer to the line ,
+ * NULL in case of errors.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_FILE_READ | => findLine()
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+int
+sfGetHeaderLine( SpecFile *sf, int from , char sf_char, char **buf, int *error)
+{
+
+ char *ptr,*headbuf;
+ char *endheader;
+ int found;
+
+ found = 0;
+
+ if ( from == FROM_SCAN ) {
+ headbuf = sf->scanbuffer;
+ endheader = sf->scanbuffer + sf->scanheadersize;
+ } else if ( from == FROM_FILE ) {
+ if ( sf->filebuffersize == 0 ) {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ return(-1);
+ }
+ headbuf = sf->filebuffer;
+ endheader = sf->filebuffer + sf->filebuffersize;
+ } else {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ return(-1);
+ }
+
+ if ( headbuf[0] == '#' && headbuf[1] == sf_char) {
+ found = 1;
+ ptr = headbuf;
+ } else {
+ for ( ptr = headbuf + 1;ptr < endheader - 1;ptr++) {
+ if ( *(ptr - 1) == '\n' && *ptr == '#' && *(ptr+1) == sf_char) {
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ *error = SF_ERR_LINE_NOT_FOUND;
+ return(-1);
+ }
+
+ /*
+ * Beginning of the thing after '#X '
+ */
+ ptr = ptr + 3;
+
+ *buf = sfOneLine(ptr,endheader,error);
+
+ return( 0 );
+}
+
+static char *
+sfOneLine(char *from,char *end,int *error)
+{
+ static char linebuf[5000];
+
+ char *ptr,*buf;
+ long i;
+
+ ptr = from;
+
+ for(i=0;*ptr != '\n' && ptr < end;ptr++,i++) {
+ linebuf[i] = *ptr;
+ }
+
+ linebuf[i]='\0';
+
+ buf = (char *) malloc ( i+1 );
+
+ if (buf == ( char * ) NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return((char *)NULL);
+ }
+ strcpy(buf,(char *)linebuf);
+
+ return(buf);
+}
+
+
+/*********************************************************************
+ * Function: char *sfFindWord( line, word, error )
+ *
+ * Description: Looks for 'word' in given line and returns a
+ * copy of the rest of the line after the found word .
+ *
+ * Parameters:
+ * Input : (1) Line pointer
+ * (2) Word pointer
+ * Output:
+ * (3) error number
+ * Returns:
+ * Rest of the line after word.
+ * NULL => not found.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+static char *
+sfFindWord( char *line, char *word, int *error )
+{
+ char *ret;
+
+ line = strstr( line, word );
+
+ if ( line == (char *)NULL ) {
+ return( line );
+ }
+
+ line += strlen( word );
+
+ /*
+ * Delete blanks.
+ */
+ while ( *line == ' ' || *line == '\t' ) line++;
+
+ /*
+ * Copy the rest.
+ */
+ ret = (char *)malloc( sizeof(char) * ( 1 + strlen( line )) );
+
+ if ( ret == (char *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(ret);
+ }
+
+ memcpy( ret, line, sizeof(char) * ( 1 + strlen( line )) );
+
+ return( ret );
+}
+
diff --git a/silx/io/specfile/src/sfindex.c b/silx/io/specfile/src/sfindex.c
new file mode 100644
index 0000000..fd0c7c3
--- /dev/null
+++ b/silx/io/specfile/src/sfindex.c
@@ -0,0 +1,551 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfindex.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: functions for scan numbering
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2004/05/12 16:56:47 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfindex.c,v $
+ * Log: Revision 1.2 2004/05/12 16:56:47 sole
+ * Log: Support for windows
+ * Log:
+ * Log: Revision 1.1 2003/03/06 16:59:05 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:15 19:05:15 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+/*
+ * File: sfindex.c
+ *
+ * Description:
+ *
+ * Project:
+ *
+ * Author: Vicente Rey Bakaikoa
+ *
+ * Date: March 2000
+ */
+/*
+ * $Log: sfindex.c,v $
+ * Revision 1.2 2004/05/12 16:56:47 sole
+ * Support for windows
+ *
+ * Revision 1.1 2003/03/06 16:59:05 sole
+ * Initial revision
+ *
+ * Revision 3.0 2000/12/20 14:17:19 rey
+ * Python version available
+ *
+ * Revision 2.1 2000/07/31 19:05:15 19:05:15 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:26:55 13:26:55 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ *
+ */
+
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#ifdef WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#else
+#include <unistd.h>
+#endif
+#include <ctype.h>
+
+#define ON_COMMENT 0
+#define ON_ABO 1
+#define ON_RES 2
+/*
+ * Declarations
+ */
+DllExport long * SfList ( SpecFile *sf, int *error );
+DllExport long SfIndexes ( SpecFile *sf, long number, long **idxlist );
+DllExport long SfIndex ( SpecFile *sf, long number, long order );
+DllExport long SfCondList ( SpecFile *sf, long cond, long **scan_list,
+ int *error );
+DllExport long SfScanNo ( SpecFile *sf );
+DllExport int SfNumberOrder ( SpecFile *sf, long index, long *number,
+ long *order );
+DllExport long SfNumber ( SpecFile *sf, long index );
+DllExport long SfOrder ( SpecFile *sf, long index );
+
+/*
+ * Internal Functions
+ */
+static int checkAborted( SpecFile *sf, ObjectList *ptr, int *error );
+
+
+/*********************************************************************
+ * Function: long *SfList( sf, error )
+ *
+ * Description: Creates an array with all scan numbers.
+ *
+ * Parameters:
+ * Input : SpecFile pointer
+ * Returns:
+ * Array with scan numbers.
+ * NULL if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long *
+SfList( SpecFile *sf, int *error )
+{
+ register ObjectList *ptr;
+ long *scan_list;
+ long i = 0;
+
+ scan_list = (long *)malloc( sizeof(long) * (sf->no_scans) );
+
+ if ( scan_list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( scan_list );
+ }
+
+ for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ,i++) {
+ scan_list[i] = ( ((SpecScan *)(ptr->contents))->scan_no );
+ }
+ /*printf("scanlist[%li] = %li\n",i-1,scan_list[i-1]);*/
+ return( scan_list );
+}
+
+
+/*********************************************************************
+ * Function: long SfIndexes( sf, number , idxlist)
+ *
+ * Description: Creates an array with all indexes with the same scan
+ * number.
+ *
+ * Parameters:
+ * Input : SpecFile pointer
+ * scan number
+ * Output : array with scan indexes
+ * Returns:
+ * Number of indexes found
+ * Possible errors:
+ * None possible
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfIndexes( SpecFile *sf, long number, long **idxlist )
+{
+ ObjectList *ptr;
+ long i;
+ long *indexes;
+ long *arr;
+
+ i = 0;
+ indexes = (long *)malloc(sf->no_scans * sizeof(long));
+
+ for (ptr = sf->list.first; ptr; ptr=ptr->next ) {
+ if ( number == ((SpecScan *)(ptr->contents))->scan_no) {
+ indexes[i] = ((SpecScan *)(ptr->contents))->index;
+ i++;
+ }
+ }
+
+ if (i == 0)
+ arr = (long *) NULL;
+ else {
+ arr = (long *)malloc(sizeof(long) * i);
+ memcpy(arr,indexes,sizeof(long) * i);
+ }
+
+ *idxlist = arr;
+ free(indexes);
+ return( i );
+}
+
+
+/*********************************************************************
+ * Function: long SfIndex( sf, number, order )
+ *
+ * Description: Gets scan index from scan number and order.
+ *
+ * Parameters:
+ * Input : (1) Scan number
+ * (2) Scan order
+ * Returns:
+ * Index number.
+ * (-1) if not found.
+ *
+ *********************************************************************/
+DllExport long
+SfIndex( SpecFile *sf, long number, long order )
+{
+ ObjectList *ptr;
+
+ ptr = findScanByNo( &(sf->list), number, order );
+ if ( ptr != (ObjectList *)NULL )
+ return( ((SpecScan *)(ptr->contents))->index );
+
+ return( -1 );
+}
+
+
+/*********************************************************************
+ * Function: long SfCondList( sf, cond, scan_list, error )
+ *
+ * Description: Creates an array with all scan numbers.
+ *
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) Condition : 0 => not aborted scans ( NOT_ABORTED )
+ * -1 => aborted scans ( ABORTED )
+ * nn => more than 'nn' data lines
+ * Output: (3) Scan list
+ * (4) error code
+ * Returns:
+ * Number of found scans.
+ * ( -1 ) if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfCondList( SpecFile *sf, long cond, long **scan_list, int *error )
+{
+ register ObjectList *ptr;
+ long *list;
+ long i = 0;
+ int retcheck;
+ long index;
+
+ *scan_list = (long *)NULL;
+
+ list = (long *)malloc( sizeof(long) * (sf->no_scans) );
+
+ if ( list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+
+ /*
+ * Aborted scans .
+ */
+ if ( cond < 0 ) { /* aborted scans */
+ for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ) {
+
+ retcheck = checkAborted( sf, ptr, error );
+
+ if ( retcheck < 0 ) {
+ free( list );
+ return( -1 );
+ } else if ( retcheck > 0) {
+ list[i] = ( ((SpecScan *)(ptr->contents))->scan_no );
+ i++;
+ }
+ }
+ } else if ( cond == 0 ) { /* not aborted scans */
+ for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ) {
+
+ retcheck = checkAborted( sf, ptr, error );
+
+ if ( retcheck < 0 ) {
+ free( list );
+ return( -1 );
+ } else if ( retcheck == 0 ) {
+ list[i] = ( ((SpecScan *)(ptr->contents))->scan_no );
+ i++;
+ }
+ }
+ } else { /* cond > 0 - more than n data_lines */
+ for ( ptr=sf->list.first ; ptr ; ptr=ptr->next ) {
+
+ index = ( ((SpecScan *)(ptr->contents))->index );
+ if ( SfNoDataLines(sf,index,error) <= cond ) continue;
+
+ list[i] = ( ((SpecScan *)(ptr->contents))->scan_no );
+ i++;
+ }
+ }
+
+ *scan_list = ( long * ) malloc ( i * sizeof(long));
+
+ if ( *scan_list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+
+ memcpy(*scan_list,list, i * sizeof(long));
+ free(list);
+
+ return( i );
+}
+
+
+/*********************************************************************
+ * Function: long SfScanNo( sf )
+ *
+ * Description: Gets number of scans.
+ *
+ * Parameters:
+ * Input :(1) SpecFile pointer
+ * Returns:
+ * Number of scans.
+ *
+ *********************************************************************/
+DllExport long
+SfScanNo( SpecFile *sf )
+{
+ return( sf->no_scans );
+}
+
+
+/*********************************************************************
+ * Function: int SfNumberOrder( sf, index, number, order )
+ *
+ * Description: Gets scan number and order from index.
+ *
+ * Parameters:
+ * Input :
+ * (1) SpecFile pointer
+ * (2) Scan index
+ * Output:
+ * (3) Scan number
+ * (4) Scan order
+ * Returns:
+ * ( -1 ) => not found
+ * ( 0 ) => found
+ *
+ *********************************************************************/
+DllExport int
+SfNumberOrder( SpecFile *sf, long index, long *number, long *order )
+{
+ register ObjectList *list;
+
+ *number = -1;
+ *order = -1;
+
+ /*
+ * Find scan .
+ */
+ list = findScanByIndex( &(sf->list), index );
+ if ( list == (ObjectList *)NULL ) return( -1 );
+
+ *number = ((SpecScan *)list->contents)->scan_no;
+ *order = ((SpecScan *)list->contents)->order;
+
+ return( 0 );
+}
+
+
+/*********************************************************************
+ * Function: long SfNumber( sf, index )
+ *
+ * Description: Gets scan number from index.
+ *
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) Scan index
+ * Returns:
+ * Scan number.
+ * ( -1 ) => not found
+ *
+ *********************************************************************/
+DllExport long
+SfNumber( SpecFile *sf, long index )
+{
+ register ObjectList *list;
+
+ /*
+ * Find scan .
+ */
+ list = findScanByIndex( &(sf->list), index );
+ if ( list == (ObjectList *)NULL ) return( -1 );
+
+ return( ((SpecScan *)list->contents)->scan_no );
+}
+
+
+/*********************************************************************
+ * Function: long SfOrder( sf, index )
+ *
+ * Description: Gets scan order from index.
+ *
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) Scan index
+ * Returns:
+ * Scan order.
+ * ( -1 ) => not found
+ *
+ *********************************************************************/
+DllExport long
+SfOrder( SpecFile *sf, long index )
+{
+ register ObjectList *list;
+
+
+ /*
+ * Find scan .
+ */
+ list = findScanByIndex( &(sf->list), index );
+ if ( list == (ObjectList *)NULL ) return( -1 );
+
+ return( ((SpecScan *)list->contents)->order );
+}
+
+/*********************************************************************
+ * Function: int checkAborted( sf, ptr, error )
+ *
+ * Description: Checks if scan was aborted or not .
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) Pointer to the scan
+ * Output: (3) Error number
+ * Returns:
+ * (-1 ) : error
+ * ( 0 ) : not aborted
+ * ( 1 ) : aborted
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => readHeader()
+ * SF_ERR_FILE_READ
+ *
+ *********************************************************************/
+static int
+checkAborted( SpecFile *sf, ObjectList *ptr, int *error )
+{
+ long nbytes;
+ long data_lines,size,from;
+ SpecScan *scan;
+ char *buffer,*cptr,next;
+ int state=ON_COMMENT;
+ int aborted=0;
+ long index;
+
+ scan = ptr->contents;
+ index = scan->index;
+
+ data_lines = SfNoDataLines(sf,index,error);
+
+ if ( scan->hdafter_offset == -1 && data_lines > 0) {
+ return(0);
+ } else if ( data_lines <= 0 ) {
+ /*
+ * maybe aborted on first point
+ * we have to all to know ( but no data anyway )
+ */
+ size = scan->size;
+ from = scan->offset;
+ } else {
+ size = scan->last - scan->hdafter_offset;
+ from = scan->hdafter_offset;
+ }
+
+ lseek(sf->fd,from,SEEK_SET);
+ buffer = ( char * ) malloc (size);
+ nbytes = read(sf->fd,buffer,size);
+
+ if (nbytes == -1 ) {
+ *error = SF_ERR_FILE_READ;
+ return(-1);
+ }
+
+ if (buffer[0] == '#' && buffer[1] == 'C') {
+ state = ON_COMMENT;
+ }
+
+ for ( cptr = buffer + 1; cptr < buffer + nbytes - 1; cptr++) {
+ /*
+ * Comment line
+ */
+ if ( *cptr == '#' && *(cptr+1) == 'C' && *(cptr-1) == '\n') {
+ state = ON_COMMENT;
+ }
+ /*
+ * Check aborted
+ */
+ if ( *(cptr-1) == 'a' && *cptr == 'b' && *(cptr+1) == 'o') {
+ if ( state == ON_COMMENT ) {
+ state = ON_ABO;
+ }
+ }
+ if ( *(cptr-1) == 'r' && *cptr == 't' && *(cptr+1) == 'e') {
+ if ( state == ON_ABO) {
+ aborted = 1;
+ }
+ }
+ /*
+ * Check resume line
+ */
+ if ( *(cptr-1) == 'r' && *cptr == 'e' && *(cptr+1) == 's') {
+ if ( state == ON_COMMENT ) {
+ state = ON_RES;
+ }
+ }
+ if ( *(cptr-1) == 'u' && *cptr == 'm' && *(cptr+1) == 'e') {
+ if ( state == ON_RES) {
+ aborted = 0;
+ }
+ }
+
+ /*
+ * If data line... aborted is aborted
+ */
+ if ( *cptr == '\n' ) {
+ next = *(cptr+1);
+ if (isdigit(next) || next == '+' || next == '-' || next == '@') {
+ aborted = 0;
+ }
+ }
+ }
+ free(buffer);
+ return(aborted);
+
+/*
+ * To be implemented
+ * - return 0 = not aborted
+ * - return 1 = aborted
+ * - return -1 = error
+ *
+ * implementation: read whole scan
+ * - go to header after offset
+ * - read all till end of scan with size
+ * - search for a line with a) #C ( comment ) then "aborted"
+ */
+ return( 0 );
+}
diff --git a/silx/io/specfile/src/sfinit.c b/silx/io/specfile/src/sfinit.c
new file mode 100644
index 0000000..6f88078
--- /dev/null
+++ b/silx/io/specfile/src/sfinit.c
@@ -0,0 +1,827 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfinit.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Initialization routines ( open/update/close )
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2005/05/25 13:01:32 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfinit.c,v $
+ * Log: Revision 1.5 2005/05/25 13:01:32 sole
+ * Log: Back to revision 1.3
+ * Log:
+ * Log: Revision 1.3 2004/05/12 16:57:32 sole
+ * Log: windows support
+ * Log:
+ * Log: Revision 1.2 2002/11/12 13:23:43 sole
+ * Log: Version with added support for the new sf->updating flag
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Log: Revision 2.2 2000/12/20 12:12:08 rey
+ * Log: bug corrected with SfAllMotors
+ * Log:
+ * Revision 2.1 2000/07/31 19:04:42 19:04:42 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+/*
+ * File: sfinit.c
+ *
+ * Description: This file implements basic routines on SPEC datafiles
+ * SfOpen / SfClose / SfError
+ *
+ * SfUpdate is kept but it is obsolete
+ *
+ * Version: 2.0
+ *
+ * Date: March 2000
+ *
+ * Author: Vicente REY
+ *
+ * Copyright: E.S.R.F. European Synchrotron Radiation Facility (c) 2000
+ */
+/*
+ * $Log: sfinit.c,v $
+ * Revision 1.5 2005/05/25 13:01:32 sole
+ * Back to revision 1.3
+ *
+ * Revision 1.3 2004/05/12 16:57:32 sole
+ * windows support
+ *
+ * Revision 1.2 2002/11/12 13:23:43 sole
+ * Version with added support for the new sf->updating flag
+ *
+ * Revision 3.0 2000/12/20 14:17:19 rey
+ * Python version available
+ *
+ * Revision 2.2 2000/12/20 12:12:08 rey
+ * bug corrected with SfAllMotors
+ *
+ * Revision 2.1 2000/07/31 19:04:42 19:04:42 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:27:19 13:27:19 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ *
+ *
+ *********************************************************************/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#ifdef WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <SpecFile.h>
+#include <SpecFileP.h>
+
+/*
+ * Defines
+ */
+
+#define ANY 0
+#define NEWLINE 1
+#define COMMENT 2
+
+#define SF_ISFX ".sfI"
+
+#define SF_INIT 0
+#define SF_READY 1
+#define SF_MODIFIED 2
+
+/*
+ * Function declaration
+ */
+
+DllExport SpecFile * SfOpen ( char *name,int *error);
+DllExport SpecFile * SfOpen2 ( int fd, char *name,int *error);
+DllExport int SfClose ( SpecFile *sf);
+DllExport short SfUpdate ( SpecFile *sf, int *error);
+DllExport char * SfError ( int error);
+
+
+#ifdef linux
+char SF_SIGNATURE[] = "Linux 2ruru Sf2.0";
+#else
+char SF_SIGNATURE[] = "2ruru Sf2.0";
+#endif
+
+/*
+ * Internal functions
+ */
+static short statusEnd ( char c2, char c1);
+static void sfStartBuffer ( SpecFile *sf, SfCursor *cursor, short status,char c0, char c1,int *error);
+static void sfNewLine ( SpecFile *sf, SfCursor *cursor, char c0,char c1,int *error);
+static void sfHeaderLine ( SpecFile *sf, SfCursor *cursor, char c,int *error);
+static void sfNewBlock ( SpecFile *sf, SfCursor *cursor, short how,int *error);
+static void sfSaveScan ( SpecFile *sf, SfCursor *cursor, int *error);
+static void sfAssignScanNumbers (SpecFile *sf);
+static void sfReadFile ( SpecFile *sf, SfCursor *cursor, int *error);
+static void sfResumeRead ( SpecFile *sf, SfCursor *cursor, int *error);
+#ifdef SPECFILE_USE_INDEX_FILE
+static short sfOpenIndex ( SpecFile *sf, SfCursor *cursor, int *error);
+static short sfReadIndex ( int sfi, SpecFile *sf, SfCursor *cursor, int *error);
+static void sfWriteIndex ( SpecFile *sf, SfCursor *cursor, int *error);
+#endif
+
+/*
+ * errors
+ */
+typedef struct _errors {
+ int code;
+ char *message;
+} sf_errors ;
+
+static
+sf_errors errors[]={
+{ SF_ERR_MEMORY_ALLOC , "Memory allocation error ( SpecFile )" },
+{ SF_ERR_FILE_OPEN , "File open error ( SpecFile )" },
+{ SF_ERR_FILE_CLOSE , "File close error ( SpecFile )" },
+{ SF_ERR_FILE_READ , "File read error ( SpecFile )" },
+{ SF_ERR_FILE_WRITE , "File write error ( SpecFile )" },
+{ SF_ERR_LINE_NOT_FOUND , "Line not found error ( SpecFile )" },
+{ SF_ERR_SCAN_NOT_FOUND , "Scan not found error ( SpecFile )" },
+{ SF_ERR_HEADER_NOT_FOUND , "Header not found error ( SpecFile )" },
+{ SF_ERR_LABEL_NOT_FOUND , "Label not found error ( SpecFile )" },
+{ SF_ERR_MOTOR_NOT_FOUND , "Motor not found error ( SpecFile )" },
+{ SF_ERR_POSITION_NOT_FOUND , "Position not found error ( SpecFile )" },
+{ SF_ERR_LINE_EMPTY , "Line empty or wrong data error ( SpecFile )"},
+{ SF_ERR_USER_NOT_FOUND , "User not found error ( SpecFile )" },
+{ SF_ERR_COL_NOT_FOUND , "Column not found error ( SpecFile )" },
+{ SF_ERR_MCA_NOT_FOUND , "Mca not found ( SpecFile )" },
+/* MUST be always the last one : */
+{ SF_ERR_NO_ERRORS , "OK ( SpecFile )" },
+};
+
+
+
+
+
+/*********************************************************************
+ * Function: SpecFile *SfOpen( name, error)
+ *
+ * Description: Opens connection to Spec data file.
+ * Creates index list in memory.
+ *
+ * Parameters:
+ * Input :
+ * (1) Filename
+ * Output:
+ * (2) error number
+ * Returns:
+ * SpecFile pointer.
+ * NULL if not successful.
+ *
+ * Possible errors:
+ * SF_ERR_FILE_OPEN
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+
+DllExport SpecFile *
+SfOpen(char *name, int *error) {
+
+ int fd;
+ fd = open(name,SF_OPENFLAG);
+ return (SfOpen2(fd, name, error));
+}
+
+
+
+/*********************************************************************
+ * Function: SpecFile *SfOpen2( fd, name, error)
+ *
+ * Description: Opens connection to Spec data file.
+ * Creates index list in memory.
+ *
+ * Parameters:
+ * Input :
+ * (1) Integer file handle
+ * (2) Filename
+ * Output:
+ * (3) error number
+ * Returns:
+ * SpecFile pointer.
+ * NULL if not successful.
+ *
+ * Possible errors:
+ * SF_ERR_FILE_OPEN
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+
+DllExport SpecFile *
+SfOpen2(int fd, char *name,int *error) {
+ SpecFile *sf;
+ short idxret;
+ SfCursor cursor;
+ struct stat mystat;
+
+ if ( fd == -1 ) {
+ *error = SF_ERR_FILE_OPEN;
+ return ( (SpecFile *) NULL );
+ }
+
+ /*
+ * Init specfile strucure
+ */
+#ifdef _WINDOWS
+ static HANDLE hglb;
+ hglb = GlobalAlloc(GPTR,sizeof(SpecFile));
+ sf = (SpecFile * ) GlobalLock(hglb);
+#else
+ sf = (SpecFile *) malloc ( sizeof(SpecFile ));
+#endif
+ stat(name,&mystat);
+
+ sf->fd = fd;
+ sf->m_time = mystat.st_mtime;
+ sf->sfname = (char *)strdup(name);
+
+ sf->list.first = (ObjectList *)NULL;
+ sf->list.last = (ObjectList *)NULL;
+ sf->no_scans = 0;
+ sf->current = (ObjectList *)NULL;
+ sf->scanbuffer = (char *)NULL;
+ sf->scanheadersize = 0;
+ sf->filebuffer = (char *)NULL;
+ sf->filebuffersize = 0;
+
+ sf->no_labels = -1;
+ sf->labels = (char **)NULL;
+ sf->no_motor_names = -1;
+ sf->motor_names = (char **)NULL;
+ sf->no_motor_pos = -1;
+ sf->motor_pos = (double *)NULL;
+ sf->data = (double **)NULL;
+ sf->data_info = (long *)NULL;
+ sf->updating = 0;
+
+ /*
+ * Init cursor
+ */
+ cursor.bytecnt = 0;
+ cursor.cursor = 0;
+ cursor.scanno = 0;
+ cursor.hdafoffset = -1;
+ cursor.dataoffset = -1;
+ cursor.mcaspectra = 0;
+ cursor.what = 0;
+ cursor.data = 0;
+ cursor.file_header = 0;
+
+
+#ifdef SPECFILE_USE_INDEX_FILE
+ /*
+ * Check if index file
+ * open it and continue from there
+ */
+ idxret = sfOpenIndex(sf,&cursor,error);
+#else
+ idxret = SF_INIT;
+#endif
+
+ switch(idxret) {
+ case SF_MODIFIED:
+ sfResumeRead(sf,&cursor,error);
+ sfReadFile(sf,&cursor,error);
+ break;
+
+ case SF_INIT:
+ sfReadFile(sf,&cursor,error);
+ break;
+
+ case SF_READY:
+ break;
+
+ default:
+ break;
+ }
+
+ sf->cursor = cursor;
+
+ /*
+ * Once is all done assign scan numbers and orders
+ */
+ sfAssignScanNumbers(sf);
+
+#ifdef SPECFILE_USE_INDEX_FILE
+ if (idxret != SF_READY) sfWriteIndex(sf,&cursor,error);
+#endif
+ return(sf);
+}
+
+
+
+
+/*********************************************************************
+ *
+ * Function: int SfClose( sf )
+ *
+ * Description: Closes a file previously opened with SfOpen()
+ * and frees all memory .
+ * Parameters:
+ * Input:
+ * File pointer
+ * Returns:
+ * 0 : close successful
+ * -1 : errors occured
+ *
+ *********************************************************************/
+DllExport int
+SfClose( SpecFile *sf )
+{
+ register ObjectList *ptr;
+ register ObjectList *prevptr;
+
+ freeAllData(sf);
+
+ for( ptr=sf->list.last ; ptr ; ptr=prevptr ) {
+ free( (SpecScan *)ptr->contents );
+ prevptr = ptr->prev;
+ free( (ObjectList *)ptr );
+ }
+
+ free ((char *)sf->sfname);
+ if (sf->scanbuffer != NULL)
+ free ((char *)sf->scanbuffer);
+
+ if (sf->filebuffer != NULL)
+ free ((char *)sf->filebuffer);
+
+ if( close(sf->fd) ) {
+ return( -1 ) ;
+ }
+
+ free ( sf );
+ sf = (SpecFile *)NULL;
+
+ return ( 0 );
+}
+
+
+/*********************************************************************
+ *
+ * Function: short SfUpdate( sf, error )
+ *
+ * Description: Updates connection to Spec data file .
+ * Appends to index list in memory.
+ *
+ * Parameters:
+ * Input :
+ * (1) sf (pointer to the index list in memory)
+ * Output:
+ * (2) error number
+ * Returns:
+ * ( 0 ) => Nothing done.
+ * ( 1 ) => File was updated
+ *
+ * Possible errors:
+ * SF_ERR_FILE_OPEN
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport short
+SfUpdate ( SpecFile *sf, int *error )
+{
+ struct stat mystat;
+ long mtime;
+ /*printf("In SfUpdate\n");
+ __asm("int3");*/
+ stat(sf->sfname,&mystat);
+
+ mtime = mystat.st_mtime;
+
+ if (sf->m_time != mtime) {
+ sfResumeRead (sf,&(sf->cursor),error);
+ sfReadFile (sf,&(sf->cursor),error);
+
+ sf->m_time = mtime;
+ sfAssignScanNumbers(sf);
+#ifdef SPECFILE_USE_INDEX_FILE
+ sfWriteIndex (sf,&(sf->cursor),error);
+#endif
+ return(1);
+ }else{
+ return(0);
+ }
+}
+
+
+/*********************************************************************
+ *
+ * Function: char *SfError( code )
+ *
+ * Description: Returns the message associated with error 'code'.
+ *
+ * Parameters:
+ * Input : error code
+ *
+ *********************************************************************/
+DllExport char *
+SfError(int code ) {
+ int i;
+
+ for ( i=0 ; errors[i].code!=0 ; i++ ) {
+ if ( errors[i].code == code ) break;
+ }
+ return( errors[i].message );
+}
+
+
+static void
+sfReadFile(SpecFile *sf,SfCursor *cursor,int *error) {
+
+ int fd;
+
+ char *buffer,*ptr;
+
+ long size,bytesread;
+
+ short status;
+
+ fd = sf->fd;
+
+ size = 1024*1024;
+
+
+ if ( (buffer = (char *) malloc(size)) == NULL ) {
+ /*
+ * Try smaller buffer
+ */
+ size = 128 * 128;
+ if ( (buffer = (char *) malloc(size)) == NULL ) {
+ /*
+ * Uhmmm
+ */
+ *error = SF_ERR_MEMORY_ALLOC;
+ free(sf->sfname);
+ free(sf);
+ sf = (SpecFile *)NULL;
+ return;
+ }
+ }
+
+ status = NEWLINE;
+ while ((bytesread = read(fd,buffer,size)) > 0 ) {
+
+ sfStartBuffer(sf,cursor,status,buffer[0],buffer[1],error);
+
+ cursor->bytecnt++;
+ for (ptr=buffer+1;ptr < buffer + bytesread -1; ptr++,cursor->bytecnt++) {
+ if (*(ptr-1) == '\n' ) {
+ sfNewLine(sf,cursor,*ptr,*(ptr+1),error);
+ }
+ }
+
+ cursor->bytecnt++;
+ status = statusEnd(buffer[bytesread-2],buffer[bytesread-1]);
+ }
+
+ free(buffer);
+
+ sf->no_scans = cursor->scanno;
+ /*
+ * Save last
+ */
+ sfSaveScan(sf,cursor,error);
+
+ return;
+
+}
+
+
+static void
+sfResumeRead ( SpecFile *sf, SfCursor *cursor, int *error) {
+ cursor->bytecnt = cursor->cursor;
+ cursor->what = 0;
+ cursor->hdafoffset = -1;
+ cursor->dataoffset = -1;
+ cursor->mcaspectra = 0;
+ cursor->data = 0;
+ cursor->scanno--;
+ sf->updating = 1;
+ lseek(sf->fd,cursor->bytecnt,SEEK_SET);
+ return;
+}
+
+
+#ifdef SPECFILE_USE_INDEX_FILE
+static short
+sfOpenIndex ( SpecFile *sf, SfCursor *cursor, int *error) {
+ char *idxname;
+ short namelength;
+ int sfi;
+
+ namelength = strlen(sf->sfname) + strlen(SF_ISFX) + 1;
+
+ idxname = (char *)malloc(sizeof(char) * namelength);
+
+ sprintf(idxname,"%s%s",sf->sfname,SF_ISFX);
+
+ if ((sfi = open(idxname,SF_OPENFLAG)) == -1) {
+ free(idxname);
+ return(SF_INIT);
+ } else {
+ free(idxname);
+ return(sfReadIndex(sfi,sf,cursor,error));
+ }
+}
+
+
+static short
+sfReadIndex ( int sfi, SpecFile *sf, SfCursor *cursor, int *error) {
+ SfCursor filecurs;
+ char buffer[200];
+ long bytesread,i=0;
+ SpecScan scan;
+ short modif = 0;
+ long mtime;
+
+ /*
+ * read signature
+ */
+ bytesread = read(sfi,buffer,sizeof(SF_SIGNATURE));
+ if (strcmp(buffer,SF_SIGNATURE) || bytesread == 0 ) {
+ return(SF_INIT);
+ }
+
+ /*
+ * read cursor and specfile structure
+ */
+ if ( read(sfi,&mtime, sizeof(long)) == 0) return(SF_INIT);
+ if ( read(sfi,&filecurs, sizeof(SfCursor)) == 0) return(SF_INIT);
+
+ if (sf->m_time != mtime) modif = 1;
+
+ while(read(sfi,&scan, sizeof(SpecScan))) {
+ addToList(&(sf->list), (void *)&scan, (long)sizeof(SpecScan));
+ i++;
+ }
+ sf->no_scans = i;
+
+ memcpy(cursor,&filecurs,sizeof(SfCursor));
+
+ if (modif) return(SF_MODIFIED);
+
+ return(SF_READY);
+}
+
+
+static void
+sfWriteIndex ( SpecFile *sf, SfCursor *cursor, int *error) {
+
+ int fdi;
+ char *idxname;
+ short namelength;
+ ObjectList *obj;
+ long mtime;
+
+ namelength = strlen(sf->sfname) + strlen(SF_ISFX) + 1;
+
+ idxname = (char *)malloc(sizeof(char) * namelength);
+
+ sprintf(idxname,"%s%s",sf->sfname,SF_ISFX);
+
+ /* if ((fdi = open(idxname,SF_WRITEFLAG,SF_UMASK)) == -1) { */
+ if ((fdi = open(idxname,O_CREAT | O_WRONLY,SF_UMASK)) == -1) {
+ printf(" - cannot open. Error: (%d)\n",errno);
+ free(idxname);
+ return;
+ } else {
+ mtime = sf->m_time;
+ write(fdi,SF_SIGNATURE,sizeof(SF_SIGNATURE));
+ /*
+ * Swap bytes for linux
+ */
+ write(fdi, (void *) &mtime, sizeof(long));
+ write(fdi, (void *) cursor, sizeof(SfCursor));
+ for( obj = sf->list.first; obj ; obj = obj->next)
+ write(fdi,(void *) obj->contents, sizeof(SpecScan));
+ close(fdi);
+ free(idxname);
+ return;
+ }
+}
+#endif
+
+
+/*****************************************************************************
+ *
+ * Function: static void sfStartBuffer()
+ *
+ * Description: start analyzing file buffer and takes into account the last
+ * bytes of previous reading as defined in variable status
+ *
+ *****************************************************************************/
+static void
+sfStartBuffer(SpecFile *sf,SfCursor *cursor,short status,char c0,char c1,int *error) {
+
+ if ( status == ANY ) {
+ return;
+ } else if ( status == NEWLINE ) {
+ sfNewLine(sf,cursor,c0,c1,error);
+ } else if ( status == COMMENT ) {
+ cursor->bytecnt--;
+ sfHeaderLine(sf,cursor,c0,error);
+ cursor->bytecnt++;
+ }
+
+}
+
+
+/*******************************************************************************
+ *
+ * Function: static void statusEnd()
+ *
+ * Description: ends analysis of file buffer and returns a variable
+ * indicating staus ( last character is COMMENT,NEWLINE of ANY )
+ *
+ *******************************************************************************/
+static short
+statusEnd(char c2,char c1) {
+
+ if (c2=='\n' && c1=='#') {
+ return(COMMENT);
+ } else if (c1=='\n') {
+ return(NEWLINE);
+ } else {
+ return(ANY);
+ }
+}
+
+
+static void
+sfNewLine(SpecFile *sf,SfCursor *cursor,char c0,char c1,int *error) {
+ if (c0 == '#') {
+ sfHeaderLine(sf,cursor,c1,error);
+ } else if (c0 == '@') {
+ if ( cursor->data == 0 ) {
+ cursor->dataoffset = cursor->bytecnt;
+ cursor->data = 1;
+ }
+ cursor->mcaspectra++;
+ } else if ( isdigit(c0) || c0 == '-' || c0 == '+' || c0 == ' ' || c0 == '\t') {
+ if ( cursor->data == 0 ) {
+ cursor->dataoffset = cursor->bytecnt;
+ cursor->data = 1;
+ }
+ }
+}
+
+
+static void
+sfHeaderLine(SpecFile *sf,SfCursor *cursor,char c,int *error) {
+ if ( c == 'S') {
+ sfNewBlock(sf,cursor,SCAN,error);
+ } else if ( c == 'F') {
+ sfNewBlock(sf,cursor,FILE_HEADER,error);
+ } else {
+ if (cursor->data && cursor->hdafoffset == -1 )
+ cursor->hdafoffset = cursor->bytecnt;
+ }
+}
+
+
+static void
+sfNewBlock(SpecFile *sf,SfCursor *cursor,short newblock,int *error) {
+
+ /*
+ * Dispatch opened block
+ */
+ if (cursor->what == SCAN) {
+ sfSaveScan(sf,cursor,error);
+ } else if ( cursor->what == FILE_HEADER) {
+ cursor->fileh_size = cursor->bytecnt - cursor->cursor + 1;
+ }
+
+ /*
+ * Open new block
+ */
+ if (newblock == SCAN) {
+ cursor->scanno++;
+ cursor->what = SCAN;
+ } else {
+ cursor->file_header = cursor->bytecnt;
+ }
+ cursor->what = newblock;
+ cursor->hdafoffset = -1;
+ cursor->dataoffset = -1;
+ cursor->mcaspectra = 0;
+ cursor->data = 0;
+ cursor->cursor = cursor->bytecnt;
+}
+
+
+static void
+sfSaveScan(SpecFile *sf, SfCursor *cursor,int *error) {
+ SpecScan scan;
+ SpecScan *oldscan;
+ register ObjectList *ptr;
+
+
+ scan.index = cursor->scanno;
+ scan.offset = cursor->cursor;
+ scan.size = cursor->bytecnt - cursor->cursor;
+ scan.last = cursor->bytecnt - 1;
+ scan.data_offset = cursor->dataoffset;
+ scan.hdafter_offset = cursor->hdafoffset;
+ scan.mcaspectra = cursor->mcaspectra;
+ scan.file_header = cursor->file_header;
+
+ if(sf->updating == 1){
+ ptr = sf->list.last;
+ oldscan=(SpecScan *)(ptr->contents);
+ oldscan->index=scan.index;
+ oldscan->offset=scan.offset;
+ oldscan->size=scan.size;
+ oldscan->last=scan.last;
+ oldscan->data_offset=scan.data_offset;
+ oldscan->hdafter_offset=scan.hdafter_offset;
+ oldscan->mcaspectra=scan.mcaspectra;
+ oldscan->file_header=scan.file_header;
+ sf->updating=0;
+ }else{
+ addToList( &(sf->list), (void *)&scan, (long) sizeof(SpecScan));
+ }
+}
+
+
+static void
+sfAssignScanNumbers(SpecFile *sf) {
+
+ int size,i;
+ char *buffer,*ptr;
+
+ char buffer2[50];
+
+ register ObjectList *object,
+ *object2;
+ SpecScan *scan,
+ *scan2;
+
+ size = 50;
+ buffer = (char *) malloc(size);
+
+ for ( object = (sf->list).first; object; object=object->next) {
+ scan = (SpecScan *) object->contents;
+
+ lseek(sf->fd,scan->offset,SEEK_SET);
+ read(sf->fd,buffer,size);
+ buffer[49] = '\0';
+
+ for ( ptr = buffer+3,i=0; *ptr != ' ';ptr++,i++) buffer2[i] = *ptr;
+
+ buffer2[i] = '\0';
+
+ scan->scan_no = atol(buffer2);
+ scan->order = 1;
+ for ( object2 = (sf->list).first; object2 != object; object2=object2->next) {
+ scan2 = (SpecScan *) object2->contents;
+ if (scan2->scan_no == scan->scan_no) scan->order++;
+ }
+ }
+}
+
+void
+printCursor(SfCursor *cursor) {
+ printf("<Cursor>\n");
+ printf(" - Bytecnt: %ld\n",cursor->bytecnt);
+ printf(" - Cursor: %ld\n",cursor->cursor);
+ printf(" - Scanno: %ld\n",cursor->scanno);
+}
diff --git a/silx/io/specfile/src/sflabel.c b/silx/io/specfile/src/sflabel.c
new file mode 100644
index 0000000..70af965
--- /dev/null
+++ b/silx/io/specfile/src/sflabel.c
@@ -0,0 +1,649 @@
+#/*##########################################################################
+# Copyright (C) 2004-2014 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sflabel.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Access to labels and motors
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2003/02/03 13:15:35 $
+ *
+ ************************************************************************/
+/*
+ * Log:
+ * $Log: sflabel.c,v $
+ * Revision 1.3 2003/02/03 13:15:35 rey
+ * Small change in handling of empty spaces at the beginning of the label buffer
+ *
+ * Revision 1.2 2002/11/20 09:56:31 sole
+ * Some macros leave more than 1 space between #L and the first label.
+ * Routine modified to be able to deal with already collected data.
+ * The offending macro(s) should be re-written.
+ *
+ * Revision 1.1 2002/11/20 08:21:34 sole
+ * Initial revision
+ *
+ * Revision 3.0 2000/12/20 14:17:19 rey
+ * Python version available
+ *
+ * Revision 2.2 2000/12/20 12:12:08 rey
+ * bug corrected with SfAllMotors
+ *
+ * Revision 2.1 2000/07/31 19:05:10 19:05:10 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#include <locale_management.h>
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+#include <locale.h>
+#endif
+#endif
+
+/*
+ * Declarations
+ */
+DllExport char * SfLabel ( SpecFile *sf, long index, long column,
+ int *error );
+DllExport long SfAllLabels ( SpecFile *sf, long index, char ***labels,
+ int *error );
+DllExport char * SfMotor ( SpecFile *sf, long index, long number,
+ int *error );
+DllExport long SfAllMotors ( SpecFile *sf, long index, char ***names,
+ int *error );
+DllExport double SfMotorPos ( SpecFile *sf, long index, long number,
+ int *error );
+DllExport double SfMotorPosByName( SpecFile *sf, long index, char *name,
+ int *error );
+DllExport long SfAllMotorPos ( SpecFile *sf, long index, double **pos,
+ int *error );
+
+
+/*********************************************************************
+ * Function: char *SfLabel( sf, index, column, error )
+ *
+ * Description: Reads one label.
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) Scan index
+ * (3) Column number
+ * Output: (4) Error number
+ * Returns:
+ * Pointer to the label ,
+ * or NULL if errors occured.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => getStrFromArr()
+ * SF_ERR_LABEL_NOT_FOUND
+ * SF_ERR_LINE_EMPTY |
+ * SF_ERR_LINE_NOT_FOUND |
+ * SF_ERR_SCAN_NOT_FOUND | => SfAllLabels()
+ * SF_ERR_FILE_READ |
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport char *
+SfLabel( SpecFile *sf, long index, long column, int *error )
+{
+
+ char **labels=NULL;
+ long no_labels;
+ char *label=NULL;
+ long selection;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return((char *)NULL);
+
+ if (sf->no_labels != -1 ) {
+ no_labels = sf->no_labels;
+ } else {
+ no_labels = SfAllLabels(sf,index,&labels,error);
+ }
+
+ if (no_labels == 0 || no_labels == -1) return((char *)NULL);
+
+ if ( column < 0 ) {
+ selection = no_labels + column;
+ } else {
+ selection = column - 1;
+ }
+
+ if (selection < 0 || selection > no_labels - 1 ) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ if (labels != (char **) NULL )
+ freeArrNZ((void ***)&labels,no_labels);
+ return((char *)NULL);
+ }
+
+ if (labels != (char **)NULL) {
+ label = (char *)strdup(labels[selection]);
+ freeArrNZ((void ***)&labels,no_labels);
+ } else {
+ label = (char *) strdup(sf->labels[selection]);
+ }
+ return( label );
+}
+
+
+/*********************************************************************
+ * Function: long SfAllLabels( sf, index, labels, error )
+ *
+ * Description: Reads all labels in #L lines
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) Scan index
+ * Output: (3) Labels
+ * (4) Error number
+ * Returns:
+ * Number of labels
+ * ( -1 ) if error.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC ||=> cpyStrArr(),lines2words()
+ * SF_ERR_SCAN_NOT_FOUND | => SfHeader()
+ * SF_ERR_FILE_READ |
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_LINE_NOT_FOUND
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfAllLabels( SpecFile *sf, long index, char ***labels, int *error )
+{
+ static char tmplab[40];
+
+ char **labarr;
+ char *onelabel;
+
+ char *ptr,
+ *buf=NULL;
+
+ long no_labels = 0;
+ short i;
+
+ /*
+ * select scan
+ */
+ if (sfSetCurrent(sf,index,error) == -1) {
+ *labels = NULL;
+ return(0);
+ }
+
+ /*
+ * Do not do it if already done
+ */
+ if (sf->labels != (char **)NULL ) {
+ labarr = (char **)malloc(sizeof(char *) * sf->no_labels);
+ for ( i=0;i<sf->no_labels;i++)
+ labarr[i] = (char *)strdup(sf->labels[i]);
+ *labels = labarr;
+ return(sf->no_labels);
+ }
+
+ /*
+ * else..
+ */
+ if (sfGetHeaderLine(sf,FROM_SCAN,SF_LABEL,&buf,error) == -1) {
+ *labels = NULL;
+ return(0);
+ }
+
+ if ( buf[0] == '\0') {
+ *labels = NULL;
+ return(0);
+ }
+
+ if ( (labarr = (char **)malloc( sizeof(char *))) == (char **)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ no_labels = 0;
+ i = 0;
+
+ /*
+ * avoid problem of having too many spaces at the beginning
+ * with bad written macros -> added check for empty string
+ *
+ * get rid of spaces at the beginning of the string buffer
+ */
+
+ ptr = buf;
+ while((ptr < buf + strlen(buf) -1) && (*ptr == ' ')) ptr++;
+
+ for (i=0;ptr < buf + strlen(buf) -1;ptr++,i++) {
+ if (*ptr==' ' && *(ptr+1) == ' ') { /* two spaces delimits one label */
+ tmplab[i] = '\0';
+
+ labarr = (char **)realloc( labarr, (no_labels+1) * sizeof(char *));
+ onelabel = (char *) malloc (i+2);
+ strcpy(onelabel,tmplab);
+ labarr[no_labels] = onelabel;
+
+ no_labels++;
+ i=-1;
+ for(;*(ptr+1) == ' ' && ptr < buf+strlen(buf)-1;ptr++);
+ } else {
+ tmplab[i] = *ptr;
+ }
+ }
+
+ if (*ptr != ' ') {
+ tmplab[i] = *ptr;
+ i++;
+ }
+ tmplab[i] = '\0';
+
+ labarr = (char **)realloc( labarr, (no_labels+1) * sizeof(char *));
+ onelabel = (char *) malloc (i+2);
+ strcpy(onelabel,tmplab);
+ labarr[no_labels] = onelabel;
+
+ no_labels++;
+
+ /*
+ * Save in specfile structure
+ */
+ sf->no_labels = no_labels;
+ sf->labels = (char **) malloc( sizeof(char *) * no_labels);
+ for (i=0;i<no_labels;i++)
+ sf->labels[i] = (char *) strdup(labarr[i]);
+
+ *labels = labarr;
+ return( no_labels );
+}
+
+
+/*********************************************************************
+ * Function: long SfAllMotors( sf, index, names, error )
+ *
+ * Description: Reads all motor names in #O lines (in file header)
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) Scan index
+ * Output: (3) Names
+ * (4) Error number
+ * Returns:
+ * Number of found names
+ * ( -1 ) if errors.
+ * Possible errors:
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ * SF_ERR_LINE_EMPTY
+ * SF_ERR_MEMORY_ALLOC || => cpyStrArr(),lines2words()
+ * SF_ERR_FILE_READ |
+ * SF_ERR_HEADER_NOT_FOUND | => SfFileHeader()
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfAllMotors( SpecFile *sf, long index, char ***names, int *error )
+{
+ char **lines;
+ char *thisline,
+ *endline;
+
+ char **motarr;
+ char *onemot;
+
+ static char tmpmot[40];
+
+ char *ptr;
+
+ long motct = 0;
+ long no_lines;
+ short i,j;
+
+ /*
+ * go to scan
+ */
+ if (sfSetCurrent(sf,index,error) == -1) {
+ *names = NULL;
+ return(0);
+ }
+
+ /*
+ * if motor names for this scan have already been read
+ */
+ if (sf->motor_names != (char **)NULL) {
+ motarr = (char **)malloc(sizeof(char *) * sf->no_motor_names);
+ for (i=0;i<sf->no_motor_names;i++) {
+ motarr[i] = (char *) strdup (sf->motor_names[i]);
+ }
+ *names = motarr;
+ return(sf->no_motor_names);
+ }
+
+ /*
+ * else
+ */
+ no_lines = SfHeader(sf, index,"O",&lines,error);
+ if (no_lines == -1 || no_lines == 0 ) {
+ *names = (char **) NULL;
+ return(-1);
+ }
+
+ if ( (motarr = (char **)malloc( sizeof(char *))) == (char **)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ motct = 0;
+
+ for (j=0;j<no_lines;j++) {
+ thisline = lines[j] + 4;
+ endline = thisline + strlen(thisline);
+ for(ptr=thisline;*ptr == ' ';ptr++);
+ for (i=0;ptr < endline -2;ptr++,i++) {
+ if (*ptr==' ' && *(ptr+1) == ' ') {
+ tmpmot[i] = '\0';
+
+ motarr = (char **)realloc( motarr, (motct+1) * sizeof(char *));
+ onemot = (char *) malloc (i+2);
+ strcpy(onemot,tmpmot);
+ motarr[motct] = onemot;
+
+ motct++;
+ i=-1;
+ for(;*(ptr+1) == ' ' && ptr < endline -1;ptr++);
+ } else {
+ tmpmot[i] = *ptr;
+ }
+ }
+ if (*ptr != ' ') { tmpmot[i] = *ptr; i++; }
+ ptr++;
+ if (*ptr != ' ') { tmpmot[i] = *ptr; i++; }
+
+ tmpmot[i] = '\0';
+ motarr = (char **)realloc( motarr, (motct+1) * sizeof(char *));
+
+ onemot = (char *) malloc (i+2);
+ strcpy(onemot,tmpmot);
+ motarr[motct] = onemot;
+
+ motct++;
+
+ }
+
+ /*
+ * Save in specfile structure
+ */
+ sf->no_motor_names = motct;
+ sf->motor_names = (char **)malloc(sizeof(char *) * motct);
+ for (i=0;i<motct;i++) {
+ sf->motor_names[i] = (char *)strdup(motarr[i]);
+ }
+
+ *names = motarr;
+ return( motct );
+
+}
+
+
+DllExport char *
+SfMotor( SpecFile *sf, long index, long motnum, int *error )
+{
+
+ char **motors=NULL;
+ long nb_mot;
+ char *motor=NULL;
+ long selection;
+
+ /*
+ * go to scan
+ */
+ if (sfSetCurrent(sf,index,error) == -1) {
+ return((char *)NULL);
+ }
+
+ if ( sf->no_motor_names != -1 ) {
+ nb_mot = sf->no_motor_names;
+ } else {
+ nb_mot = SfAllMotors(sf,index,&motors,error);
+ }
+
+ if (nb_mot == 0 || nb_mot == -1) return((char *)NULL);
+
+ if ( motnum < 0 ) {
+ selection = nb_mot + motnum;
+ } else {
+ selection = motnum - 1;
+ }
+
+ if (selection < 0 || selection > nb_mot - 1 ) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ if (motors != (char **) NULL)
+ freeArrNZ((void ***)&motors,nb_mot);
+ return((char *)NULL);
+ }
+
+ if (motors != (char **) NULL) {
+ motor = (char *)strdup(motors[selection]);
+ freeArrNZ((void ***)&motors,nb_mot);
+ } else {
+ motor = (char *)strdup(sf->motor_names[selection]);
+ }
+ return( motor );
+}
+
+
+DllExport long
+SfAllMotorPos ( SpecFile *sf, long index, double **retpos, int *error )
+{
+ char **lines;
+ char *thisline,
+ *endline;
+
+ double *posarr;
+
+ static double pos[200];
+ static char posstr[40];
+
+ char *ptr;
+
+ long motct = 0;
+ long no_lines;
+ short i,j;
+
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ char *currentLocaleBuffer;
+ char localeBuffer[21];
+#endif
+#endif
+
+ if (sfSetCurrent(sf,index,error) == -1) {
+ *retpos = (double *) NULL;
+ return(0);
+ }
+
+ /*
+ * if motors position for this scan have already been read
+ */
+ if (sf->motor_pos != (double *)NULL) {
+ posarr = (double *)malloc(sizeof(double) * sf->no_motor_pos);
+ for (i=0;i<sf->no_motor_pos;i++) {
+ posarr[i] = sf->motor_pos[i];
+ }
+ *retpos = posarr;
+ return(sf->no_motor_pos);
+ }
+
+ /*
+ * else
+ */
+ no_lines = SfHeader(sf, index,"P",&lines,error);
+
+ if (no_lines == -1 || no_lines == 0 ) {
+ *retpos = (double *) NULL;
+ return(-1);
+ }
+
+ motct = 0;
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ currentLocaleBuffer = setlocale(LC_NUMERIC, NULL);
+ strcpy(localeBuffer, currentLocaleBuffer);
+ setlocale(LC_NUMERIC, "C\0");
+#endif
+#endif
+ for (j=0;j<no_lines;j++) {
+ thisline = lines[j] + 4;
+ endline = thisline + strlen(thisline);
+ for(ptr=thisline;*ptr == ' ';ptr++);
+ for (i=0;ptr < endline -1;ptr++,i++) {
+ if (*ptr==' ') {
+ posstr[i] = '\0';
+
+ pos[motct] = PyMcaAtof(posstr);
+
+ motct++;
+ i=-1;
+ for(;*(ptr+1) == ' ' && ptr < endline -1;ptr++);
+ } else {
+ posstr[i] = *ptr;
+ }
+ }
+ if (*ptr != ' ') {
+ posstr[i] = *ptr;
+ i++;
+ }
+ posstr[i] = '\0';
+ pos[motct] = PyMcaAtof(posstr);
+
+ motct++;
+
+ }
+
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ setlocale(LC_NUMERIC, localeBuffer);
+#endif
+#endif
+
+ /*
+ * Save in specfile structure
+ */
+ sf->no_motor_pos = motct;
+ sf->motor_pos = (double *)malloc(sizeof(double) * motct);
+ memcpy(sf->motor_pos,pos,motct * sizeof(double));
+
+ /*
+ * and return
+ */
+ posarr = (double *) malloc ( sizeof(double) * motct ) ;
+ memcpy(posarr,pos,motct * sizeof(double));
+
+ *retpos = posarr;
+
+ return( motct );
+}
+
+
+DllExport double
+SfMotorPos( SpecFile *sf, long index, long motnum, int *error )
+{
+
+ double *motorpos=NULL;
+ long nb_mot;
+ double retpos;
+ long selection;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(HUGE_VAL);
+
+ if (sf->no_motor_pos != -1 ) {
+ nb_mot = sf->no_motor_pos;
+ } else {
+ nb_mot = SfAllMotorPos(sf,index,&motorpos,error);
+ }
+
+ if (nb_mot == 0 || nb_mot == -1) return(HUGE_VAL);
+
+ if ( motnum < 0 ) {
+ selection = nb_mot + motnum;
+ } else {
+ selection = motnum - 1;
+ }
+
+ if (selection < 0 || selection > nb_mot - 1 ) {
+ *error = SF_ERR_COL_NOT_FOUND;
+ if (motorpos != (double *)NULL)
+ free(motorpos);
+ return(HUGE_VAL);
+ }
+
+ if (motorpos != (double *)NULL) {
+ retpos = motorpos[selection];
+ free(motorpos);
+ } else {
+ retpos = sf->motor_pos[selection];
+ }
+ return( retpos );
+}
+
+
+DllExport double
+SfMotorPosByName( SpecFile *sf, long index, char *name, int *error )
+{
+ char **motors=NULL;
+
+ long nb_mot,
+ idx,
+ selection;
+ short tofree=0;
+
+ if (sfSetCurrent(sf,index,error) == -1)
+ return(HUGE_VAL);
+
+ if ( sf->no_motor_names != -1 ) {
+ nb_mot = sf->no_motor_names;
+ motors = sf->motor_names;
+ } else {
+ nb_mot = SfAllMotors(sf,index,&motors,error);
+ tofree=1;
+ }
+
+ if (nb_mot == 0 || nb_mot == -1) return(HUGE_VAL);
+
+ for (idx = 0;idx<nb_mot;idx++) {
+ if (!strcmp(name,motors[idx])) break;
+ }
+
+ if (idx == nb_mot) {
+ if (tofree) freeArrNZ((void ***)&motors,nb_mot);
+ *error = SF_ERR_MOTOR_NOT_FOUND;
+ return(HUGE_VAL);
+ }
+
+ selection = idx+1;
+
+ return(SfMotorPos(sf,index,selection,error));
+}
diff --git a/silx/io/specfile/src/sflists.c b/silx/io/specfile/src/sflists.c
new file mode 100644
index 0000000..3fcb9a7
--- /dev/null
+++ b/silx/io/specfile/src/sflists.c
@@ -0,0 +1,184 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sflists.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Functions to handle lists
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2003/03/06 17:00:42 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sflists.c,v $
+ * Log: Revision 1.1 2003/03/06 17:00:42 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:03:25 19:03:25 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <Lists.h>
+
+/*
+ * Function declaration
+ */
+ObjectList * findInList ( ListHeader *list, int (*proc)(void *,void *), void *value );
+long addToList ( ListHeader *list, void *object, long size );
+void unlinkFromList ( ListHeader *list, ObjectList *element );
+
+static long linkToList ( ListHeader *list, void *object );
+
+
+/*********************************************************************
+ * Function: ObjectList *findInList( list, proc, value )
+ *
+ * Description: Looks for an list element.
+ *
+ * Parameters:
+ * Input : (1) ListHeader pointer
+ * (2) Comp. procedure
+ * (3) value
+ * Returns:
+ * Pointer to the found element ,
+ * NULL if not found .
+ *
+ *********************************************************************/
+ObjectList *
+findInList( ListHeader *list, int (*proc)(void * , void *), void *value )
+{
+ register ObjectList *ptr;
+
+ for ( ptr=list->first ; ptr ; ptr=ptr->next ) {
+ if ( (*proc)(ptr->contents, value) ) {
+ return( ptr );
+ }
+ }
+ return (ObjectList *)NULL;
+}
+
+
+/*********************************************************************
+ * Function: int addToList( list, object, size )
+ *
+ * Description: Adds an element to the list.
+ *
+ * Parameters:
+ * Input : (1) List pointer
+ * (2) Pointer to the new element
+ * (3) Size of the new element
+ * Returns:
+ * ( 0 ) => OK
+ * ( -1 ) => error
+ *
+ *********************************************************************/
+long
+addToList( ListHeader *list, void *object, long size )
+{
+ void *newobj;
+
+ if ( (newobj = (void *)malloc(size)) == (void *)NULL ) return( -1 );
+ memcpy(newobj, object, size);
+
+ return( linkToList( list, newobj ) );
+
+}
+
+
+/*********************************************************************
+ * Function: int linkToList( list, object )
+ *
+ * Description: Adds an element to the list.
+ *
+ * Parameters:
+ * Input: (1) ListHeader pointer
+ * (2) pointer to the new element
+ * Returns:
+ * ( 0 ) => OK
+ * ( -1 ) => error
+ *
+ *********************************************************************/
+static long
+linkToList( ListHeader *list, void *object )
+{
+ ObjectList *newobj;
+
+
+ if ((newobj = (ObjectList *) malloc(sizeof(ObjectList))) ==
+ (ObjectList *) NULL) return( -1 );
+
+ newobj->contents = object;
+ newobj->prev = list->last;
+ newobj->next = NULL;
+
+ if (list->first == (ObjectList *)NULL) {
+ list->first = newobj;
+ } else {
+ (list->last)->next = newobj;
+ }
+
+ list->last = newobj;
+ return( 0 );
+}
+
+
+/*********************************************************************
+ * Function: int unlinkFromList( list, element )
+ *
+ * Description: Removes an element from the list.
+ *
+ * Parameters:
+ * Input : (1) List pointer
+ * (2) Pointer to the element
+ *
+ *********************************************************************/
+void
+unlinkFromList( ListHeader *list, ObjectList *element )
+{
+
+ if ( element != (ObjectList *)NULL ) {
+ if ( element->next != (ObjectList *)NULL ) {
+ element->next->prev = element->prev;
+ }
+ else {
+ list->last = element->prev ;
+ }
+ if ( element->prev != (ObjectList *)NULL ) {
+ element->prev->next = element->next;
+ }
+ else {
+ list->first = element->next;
+ }
+ free( element->contents );
+ free( element );
+ }
+}
+
diff --git a/silx/io/specfile/src/sfmca.c b/silx/io/specfile/src/sfmca.c
new file mode 100644
index 0000000..22d1958
--- /dev/null
+++ b/silx/io/specfile/src/sfmca.c
@@ -0,0 +1,336 @@
+#/*##########################################################################
+# Copyright (C) 2004-2014 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfmca.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Access to MCA spectra
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2002/11/15 16:25:44 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfmca.c,v $
+ * Log: Revision 1.3 2002/11/15 16:25:44 sole
+ * Log: free(retline) replaced by freeArrNZ((void ***) &retline,nb_lines); to eliminate the memory leak when reading mca
+ * Log:
+ * Log: Revision 1.2 2002/11/15 10:44:36 sole
+ * Log: added free(retline) after call to SfHeader
+ * Log:
+ * Log: Revision 1.1 2002/11/15 10:17:38 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:12 19:05:12 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#include <locale_management.h>
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+#include <locale.h>
+#endif
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+/*
+ * Define macro
+ */
+#define isnumber(this) ( isdigit(this) || this == '-' || this == '+' || this =='e' || this == 'E' || this == '.' )
+
+/*
+ * Mca continuation character
+ */
+#define MCA_CONT '\\'
+#define D_INFO 3
+
+/*
+ * Declarations
+ */
+DllExport long SfNoMca ( SpecFile *sf, long index, int *error );
+DllExport int SfGetMca ( SpecFile *sf, long index, long mcano,
+ double **retdata, int *error );
+DllExport long SfMcaCalib ( SpecFile *sf, long index, double **calib,
+ int *error );
+
+
+/*********************************************************************
+ * Function: long SfNoMca( sf, index, error )
+ *
+ * Description: Gets number of mca spectra in a scan
+ *
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of data lines ,
+ * ( -1 ) => errors.
+ * Possible errors:
+ * SF_ERR_SCAN_NOT_FOUND
+ *
+ *********************************************************************/
+DllExport long
+SfNoMca( SpecFile *sf, long index, int *error )
+{
+
+ if (sfSetCurrent(sf,index,error) == -1 )
+ return(-1);
+
+ return( ((SpecScan *)sf->current->contents)->mcaspectra );
+
+}
+
+
+/*********************************************************************
+ * Function: int SfGetMca(sf, index, number, data, error)
+ *
+ * Description: Gets data.
+ * Parameters:
+ * Input : (1) File pointer
+ * (2) Index
+ * Output:
+ * (3) Data array
+ * (4) Data info : [0] => no_lines
+ * [1] => no_columns
+ * [2] = ( 0 ) => regular
+ * ( 1 ) => not regular !
+ * (5) error number
+ * Returns:
+ * ( 0 ) => OK
+ * ( -1 ) => errors occured
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ * SF_ERR_FILE_READ
+ * SF_ERR_SCAN_NOT_FOUND
+ * SF_ERR_LINE_NOT_FOUND
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport int
+SfGetMca( SpecFile *sf, long index, long number, double **retdata, int *error )
+{
+ double *data = NULL;
+ long headersize;
+ int old_fashion;
+ static char* last_from = NULL;
+ static char* last_pos = NULL;
+ static long last_number = 0;
+ long int scanno = 0;
+ static long int last_scanno = 0;
+ char *ptr,
+ *from,
+ *to;
+
+ char strval[100];
+ double val;
+
+ int i,spect_no=0;
+ long vals;
+
+ long blocks=1,
+ initsize=1024;
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ char *currentLocaleBuffer;
+ char localeBuffer[21];
+#endif
+#endif
+
+ headersize = ((SpecScan *)sf->current->contents)->data_offset
+ - ((SpecScan *)sf->current->contents)->offset;
+
+ scanno = ((SpecScan *)sf->current->contents)->scan_no;
+
+ /*
+ * check that mca number is available
+ */
+ if (number < 1) {
+ *error = SF_ERR_MCA_NOT_FOUND;
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+
+ /*
+ * Get MCA info from header
+ */
+
+ from = sf->scanbuffer + headersize;
+ to = sf->scanbuffer + ((SpecScan *)sf->current->contents)->size;
+
+ old_fashion = 1;
+ if (last_scanno == scanno)
+ {
+ if (last_from == from)
+ {
+ /* same scan as before */
+ if (number > last_number)
+ {
+ spect_no = last_number;
+ old_fashion = 0;
+ }
+ }
+ }
+ if (old_fashion)
+ {
+ last_scanno = scanno;
+ last_from = from;
+ spect_no = 0;
+ last_pos = from;
+ }
+ /*
+ * go and find the beginning of spectrum
+ */
+ ptr = last_pos;
+
+ if ( *ptr == '@' ) {
+ spect_no++;
+ ptr++;
+ last_pos = ptr;
+ }
+
+ while ( spect_no != number && ptr < to ) {
+ if (*ptr == '@') spect_no++;
+ ptr++;
+ last_pos = ptr;
+ }
+ ptr++;
+
+ if ( spect_no != number ) {
+ *error = SF_ERR_MCA_NOT_FOUND;
+ *retdata = (double *)NULL;
+ return(-1);
+ }
+ last_number = spect_no;
+ /*
+ * Calculate size and book memory
+ */
+ initsize = 2048;
+
+ i = 0;
+ vals = 0;
+
+ /*
+ * Alloc memory
+ */
+ if ((data = (double *)malloc (sizeof(double) * initsize)) == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ /*
+ * continue
+ */
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ currentLocaleBuffer = setlocale(LC_NUMERIC, NULL);
+ strcpy(localeBuffer, currentLocaleBuffer);
+ setlocale(LC_NUMERIC, "C\0");
+#endif
+#endif
+ for ( ;(*(ptr+1) != '\n' || (*ptr == MCA_CONT)) && ptr < to - 1 ; ptr++)
+ {
+ if (*ptr == ' ' || *ptr == '\t' || *ptr == '\\' || *ptr == '\n') {
+ if ( i ) {
+ if ( vals%initsize == 0 ) {
+ blocks++;
+ if ((data = (double *)realloc (data, sizeof(double) * blocks * initsize))
+ == (double *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ setlocale(LC_NUMERIC, localeBuffer);
+#endif
+#endif
+ return(-1);
+ }
+
+ }
+ strval[i] = '\0';
+ i = 0;
+ val = PyMcaAtof(strval);
+ data[vals] = val;
+ vals++;
+ }
+ } else if (isnumber(*ptr)) {
+ strval[i] = *ptr;
+ i++;
+ }
+ }
+
+ if (isnumber(*ptr)) {
+ strval[i] = *ptr;
+ strval[i+1] = '\0';
+ val = PyMcaAtof(strval);
+ data[vals] = val;
+ vals++;
+ }
+#ifndef _GNU_SOURCE
+#ifdef PYMCA_POSIX
+ setlocale(LC_NUMERIC, localeBuffer);
+#endif
+#endif
+
+ *retdata = data;
+
+ return( vals );
+}
+
+
+DllExport long
+SfMcaCalib ( SpecFile *sf, long index, double **calib, int *error )
+{
+
+ long nb_lines;
+ char **retline;
+ char *strptr;
+
+ double val1,val2,val3;
+
+ double *retdata;
+
+ nb_lines = SfHeader(sf,index,"@CALIB",&retline,error);
+
+ if (nb_lines > 0) {
+ strptr = retline[0] + 8;
+ sscanf(strptr,"%lf %lf %lf",&val1,&val2,&val3);
+ } else {
+ *calib = (double *)NULL;
+ return(-1);
+ }
+
+ retdata = (double *) malloc(sizeof(double) * 3 );
+ retdata[0] = val1; retdata[1] = val2; retdata[2] = val3;
+
+ *calib = retdata;
+ return(0);
+}
diff --git a/silx/io/specfile/src/sftools.c b/silx/io/specfile/src/sftools.c
new file mode 100644
index 0000000..74ae311
--- /dev/null
+++ b/silx/io/specfile/src/sftools.c
@@ -0,0 +1,550 @@
+#/*##########################################################################
+# Copyright (C) 2004-2016 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sftools.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: General library tools
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2004/05/12 16:57:02 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sftools.c,v $
+ * Log: Revision 1.2 2004/05/12 16:57:02 sole
+ * Log: Windows support
+ * Log:
+ * Log: Revision 1.1 2003/09/12 10:34:11 sole
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Log: Revision 2.2 2000/12/20 12:12:08 rey
+ * Log: bug corrected with SfAllMotors
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:07 19:05:07 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+
+#ifdef WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#else
+#include <unistd.h>
+#endif
+
+/*
+ * Library Functions
+ */
+DllExport void freePtr ( void *ptr );
+DllExport void freeArrNZ ( void ***ptr, long lines );
+DllExport void SfShow (SpecFile *sf);
+DllExport void SfShowScan (SpecFile *sf, long index);
+
+/*
+ * Function declaration
+ */
+void freeArr ( void ***ptr, long lines );
+
+int sfSetCurrent ( SpecFile *sf, long index, int *error );
+int sfSameFile ( SpecFile *sf, ObjectList *list );
+int sfSameScan ( SpecFile *sf, long index );
+
+int findIndex ( void *scan, void *number );
+int findNoAndOr ( void *scan, void *number );
+int findFirst ( void *scan, void *file_offset );
+ObjectList *findScanByIndex ( ListHeader *list, long index );
+ObjectList *findFirstInFile ( ListHeader *list, long file_offset );
+ObjectList *findScanByNo ( ListHeader *list, long scan_no, long order );
+
+long mulstrtod ( char *str, double **arr, int *error );
+void freeAllData ( SpecFile *sf );
+
+/*
+ * Globals
+ */
+
+
+/*********************************************************************
+ * Function: void sfSetCurrent( sf, list )
+ *
+ * Description: Sets 'list' to current scan.
+ * Updates SpecFile structure.
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) New scan
+ *
+ *********************************************************************/
+int
+sfSetCurrent( SpecFile *sf, long index,int *error )
+{
+ ObjectList *list,
+ *flist;
+ SpecScan *scan,
+ *fscan;
+ long nbytes;
+ long fileheadsize,start;
+
+ /*
+ * If same scan nothing to do
+ */
+ if (sfSameScan(sf,index)) return(0);
+
+ /*
+ * It is a new scan. Free memory allocated for previous one.
+ */
+ freeAllData(sf);
+
+ /*
+ * Find scan
+ */
+ list = findScanByIndex(&(sf->list),index);
+
+ if (list == (ObjectList *)NULL) {
+ *error = SF_ERR_SCAN_NOT_FOUND;
+ return(-1);
+ }
+
+ /*
+ * Read full scan into buffer
+ */
+ scan = list->contents;
+
+ if (sf->scanbuffer != ( char * ) NULL) free(sf->scanbuffer);
+
+ sf->scanbuffer = ( char *) malloc(scan->size);
+
+ if (sf->scanbuffer == (char *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+
+ lseek(sf->fd,scan->offset,SEEK_SET);
+
+ nbytes = read(sf->fd,sf->scanbuffer,scan->size);
+ if ( nbytes == -1) {
+ *error = SF_ERR_FILE_READ;
+ return(-1);
+ }
+ if ( sf->scanbuffer[0] != '#' || sf->scanbuffer[1] != 'S') {
+ *error = SF_ERR_FILE_READ;
+ return(-1);
+ }
+ sf->scanheadersize = scan->data_offset - scan->offset;
+
+ /*
+ * if different file read fileheader also
+ */
+ if (!sfSameFile(sf,list)) {
+ if (sf->filebuffer != ( char * ) NULL) free(sf->filebuffer);
+
+ start = scan->file_header;
+ flist = findFirstInFile(&(sf->list),scan->file_header);
+ if (flist == (ObjectList *) NULL) {
+ fileheadsize = 0;
+ sf->filebuffersize = fileheadsize;
+ }
+ else
+ {
+ fscan = flist->contents;
+ fileheadsize = fscan->offset - start;
+ }
+
+ if (fileheadsize > 0) {
+ sf->filebuffer = ( char *) malloc(fileheadsize);
+ if (sf->filebuffer == (char *)NULL) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return(-1);
+ }
+ lseek(sf->fd,start,SEEK_SET);
+ read(sf->fd,sf->filebuffer,fileheadsize);
+ if ( nbytes == -1) {
+ *error = SF_ERR_FILE_READ;
+ return(-1);
+ }
+ sf->filebuffersize = fileheadsize;
+ }
+ }
+ sf->scansize = scan->size;
+ sf->current = list;
+
+ return(1);
+}
+
+
+/*********************************************************************
+ * Function: int sfSameFile( sf, list )
+ *
+ * Description: Checks if the current scan file header and
+ * the new scan file header are the same.
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) New scan
+ * Returns:
+ * 1 - the same
+ * 0 - not the same
+ *
+ *********************************************************************/
+int
+sfSameFile( SpecFile *sf, ObjectList *list )
+{
+ if (sf->current) {
+ return ( ((SpecScan *)sf->current->contents)->file_header ==
+ ((SpecScan *)list->contents)->file_header );
+ } else return(0);
+}
+
+
+/*********************************************************************
+ * Function: int sfSameScan( sf, index )
+ *
+ * Description: Checks if the current scan and
+ * the new scan are the same.
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ * (2) New scan index
+ * Returns:
+ * 1 - the same
+ * 0 - not the same
+ *
+ *********************************************************************/
+int
+sfSameScan( SpecFile *sf, long index )
+{
+ if ( sf->current == (ObjectList *)NULL) return(0);
+
+ return ( ((SpecScan *)sf->current->contents)->index == index );
+}
+
+
+/*********************************************************************
+ * Function: freePtr( ptr );
+ *
+ * Description: Frees memory pointed to by 'ptr'.
+ *
+ * Parameters:
+ * Input : (1) Pointer
+ *
+ *********************************************************************/
+void
+freePtr( void *ptr )
+{
+ free( ptr );
+}
+
+
+/*********************************************************************
+ * Function: freeArrNZ( ptr, lines );
+ *
+ * Description: Frees an array if 'lines' > zero.
+ *
+ * Parameters:
+ * Input : (1) Array pointer
+ * (2) No. of lines
+ *
+ *********************************************************************/
+void
+freeArrNZ( void ***ptr, long lines )
+{
+ if ( *ptr != (void **)NULL && lines > 0 ) {
+ for ( ; lines ; lines-- ) {
+ free( (*ptr)[lines-1] );
+ }
+ free( *ptr );
+ *ptr = ( void **)NULL ;
+ }
+}
+
+
+/*********************************************************************
+ * Function: freeArr( ptr, lines );
+ *
+ * Description: Frees an array.
+ * 'ptr' will be always freed !!!
+ *
+ * Parameters:
+ * Input : (1) Array pointer
+ * (2) No. of lines
+ *
+ *********************************************************************/
+void
+freeArr( void ***ptr, long lines )
+{
+ if ( *ptr != (void **)NULL ) {
+ if ( lines > 0 ) {
+ for ( ; lines ; lines-- ) {
+ free( (*ptr)[lines-1] );
+ }
+ }
+ free( *ptr );
+ *ptr = ( void **)NULL ;
+ }
+}
+
+
+/*********************************************************************
+ * Function: int findIndex( scan, number )
+ *
+ * Description: Compares if number == scan index .
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) number
+ * Returns:
+ * 0 : not found
+ * 1 : found
+ *
+ *********************************************************************/
+int
+findIndex( void *scan, void *number )
+{
+ return( ((SpecScan *)scan)->index == *(long *)number );
+}
+
+
+/*********************************************************************
+ * Function: int findFirst( scan, file_offset )
+ *
+ * Description: Compares if scan offset > file_offset
+ *
+ * Parameters:
+ * Input : (1) SpecScan pointer
+ * (2) number
+ * Returns:
+ * 0 : not found
+ * 1 : found
+ *
+ *********************************************************************/
+int
+findFirst( void *scan, void *file_offset )
+{
+ return( ((SpecScan *)scan)->offset > *(long *)file_offset );
+}
+
+
+/*********************************************************************
+ * Function: int findNoAndOr( scan, number )
+ * ( Number
+ * Order )
+ *
+ * Description: Compares if number1 = scan number and
+ * number2 = scan order
+ * Parameters:
+ * Input: (1) SpecScan pointer
+ * (2) number[1]
+ * Returns:
+ * 0 : not found
+ * 1 : found
+ *
+ *********************************************************************/
+int
+findNoAndOr( void *scan, void *number )
+{
+
+ long *n = (long *)number;
+
+ return( ( ((SpecScan *)scan)->scan_no == *n++ ) && ( ((SpecScan *)scan)->order == *n ));
+}
+
+
+/*********************************************************************
+ * Function: ObjectList *findScanByIndex( list, index )
+ *
+ * Description: Looks for a scan .
+ *
+ * Parameters:
+ * Input: (1) List pointer
+ * (2) scan index
+ * Returns:
+ * ObjectList pointer if found ,
+ * NULL if not.
+ *
+ *********************************************************************/
+ObjectList *
+findScanByIndex( ListHeader *list, long index )
+{
+ return findInList( list, findIndex, (void *)&index );
+}
+
+
+/*********************************************************************
+ * Function: ObjectList findScanByNo( list, scan_no, order )
+ *
+ * Description: Looks for a scan .
+ *
+ * Parameters:
+ * Input: (1) List pointer
+ * (2) scan number
+ * (3) scan order
+ * Returns:
+ * ObjectList pointer if found ,
+ * NULL if not.
+ *
+ *********************************************************************/
+ObjectList *
+findScanByNo( ListHeader *list, long scan_no, long order )
+{
+ long value[2];
+
+ value[0] = scan_no;
+ value[1] = order;
+
+ return( findInList( (void *)list, findNoAndOr, (void *)value) );
+}
+
+
+
+/*********************************************************************
+ * Function: ObjectList *findFirstInFile( list, file_offset )
+ *
+ * Description: Looks for a scan .
+ *
+ * Parameters:
+ * Input: (1) List pointer
+ * (2) scan index
+ * Returns:
+ * ObjectList pointer if found ,
+ * NULL if not.
+ *
+ *********************************************************************/
+ObjectList *
+findFirstInFile( ListHeader *list, long file_offset )
+{
+ return findInList( list, findFirst, (void *)&file_offset );
+}
+
+
+/*********************************************************************
+ * Function: long mulstrtod( str, arr, error )
+ *
+ * Description: Converts string to data array.( double array )
+ *
+ * Parameters:
+ * Input : (1) String
+ *
+ * Output:
+ * (2) Data array
+ * (3) error number
+ * Returns:
+ * Number of values.
+ * ( -1 ) in case of errors.
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+long
+mulstrtod( char *str, double **arr, int *error )
+{
+ int count,q,i=0;
+ double *ret;
+ char *str2;
+ static double tmpret[200];
+
+ *arr = (double *)NULL;
+
+ str2 = str;
+
+ while( (q = sscanf(str2, "%lf%n", &(tmpret[i]), &count)) > 0 ) {
+ i++;
+ str2 += count;
+ }
+ str2++;
+
+ if ( !i ) {
+ return( i );
+ }
+
+ ret = (double *)malloc( sizeof(double) * i );
+
+ if ( ret == (double *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ memcpy(ret, tmpret, i * sizeof(double) );
+
+ *arr = ret;
+ return( i );
+}
+
+void
+freeAllData(SpecFile *sf)
+{
+ if (sf->motor_pos != (double *)NULL) {
+ free(sf->motor_pos);
+ sf->motor_pos = (double *)NULL;
+ sf->no_motor_pos = -1;
+ }
+ if (sf->motor_names != (char **)NULL) {
+ freeArrNZ((void ***)&(sf->motor_names),sf->no_motor_names);
+ sf->motor_names = (char **)NULL;
+ sf->no_motor_names = -1;
+ }
+ if (sf->labels != (char **)NULL) {
+ freeArrNZ((void ***)&(sf->labels),sf->no_labels);
+ sf->labels = (char **)NULL;
+ sf->no_labels = -1;
+ }
+ if (sf->data_info != (long *)NULL) {
+ freeArrNZ((void ***)&(sf->data),sf->data_info[ROW]);
+ free(sf->data_info);
+ sf->data = (double **)NULL;
+ sf->data_info = (long *)NULL;
+ }
+}
+
+DllExport void
+SfShow (SpecFile *sf) {
+ printf("<Showing Info> - specfile: %s\n",sf->sfname);
+ printf(" - no_scans: %ld\n",sf->no_scans);
+ printf(" - current: %ld\n",((SpecScan*)sf->current->contents)->scan_no);
+ printf(" Cursor:\n");
+ printf(" - no_scans: %ld\n",sf->cursor.scanno);
+ printf(" - bytecnt: %ld\n",sf->cursor.bytecnt);
+}
+
+DllExport void
+SfShowScan (SpecFile *sf, long index) {
+ int error;
+ SpecScan *scan;
+
+ printf("<Showing Info> - specfile: %s / idx %ld\n",sf->sfname,index);
+
+ if (sfSetCurrent(sf,index,&error) == -1) {
+ printf("Cannot get scan index %ld\n",index);
+ }
+
+ scan = (SpecScan *) sf->current->contents;
+
+ printf(" - index: %ld\n",scan->index);
+ printf(" - scan_no: %ld\n",scan->scan_no);
+ printf(" - offset: %ld\n",scan->offset);
+ printf(" - data_offset: %ld\n",scan->data_offset);
+}
diff --git a/silx/io/specfile/src/sfwrite.c b/silx/io/specfile/src/sfwrite.c
new file mode 100644
index 0000000..4422ae0
--- /dev/null
+++ b/silx/io/specfile/src/sfwrite.c
@@ -0,0 +1,587 @@
+#/*##########################################################################
+# Copyright (C) 2004-2013 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This file is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+#############################################################################*/
+/************************************************************************
+ *
+ * File: sfwrite.c
+ *
+ * Project: SpecFile library
+ *
+ * Description: Functions for scan output
+ *
+ * Author: V.Rey
+ *
+ * Date: $Date: 2003/09/12 13:20:35 $
+ *
+ ************************************************************************/
+/*
+ * Log: $Log: sfwrite.c,v $
+ * Log: Revision 1.1 2003/09/12 13:20:35 rey
+ * Log: Initial revision
+ * Log:
+ * Log: Revision 3.0 2000/12/20 14:17:19 rey
+ * Log: Python version available
+ * Log:
+ * Revision 2.1 2000/07/31 19:05:14 19:05:14 rey (Vicente Rey-Bakaikoa)
+ * SfUpdate and bug corrected in ReadIndex
+ *
+ * Revision 2.0 2000/04/13 13:28:54 13:28:54 rey (Vicente Rey-Bakaikoa)
+ * New version of the library. Complete rewrite
+ * Adds support for MCA
+ */
+#include <SpecFile.h>
+#include <SpecFileP.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+/*
+ * Declarations
+ */
+DllExport SpecFileOut *SfoInit ( SpecFile *sf, int *error );
+DllExport void SfoClose ( SpecFileOut *sfo );
+DllExport long SfoSelectAll ( SpecFileOut *sfo, int *error );
+DllExport long SfoSelectOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport long SfoSelect ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport long SfoSelectRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport long SfoRemoveOne ( SpecFileOut *sfo, long index,
+ int *error );
+DllExport long SfoRemove ( SpecFileOut *sfo, long *list,
+ int *error );
+DllExport long SfoRemoveRange ( SpecFileOut *sfo, long begin,
+ long end, int *error );
+DllExport long SfoRemoveAll ( SpecFileOut *sfo, int *error );
+DllExport long SfoWrite ( SpecFileOut *sfo, char *name,
+ int *error );
+DllExport long SfoGetList ( SpecFileOut *sfo, long **list,
+ int *error );
+
+/*
+ * Internal functions
+ */
+static int sfoWriteOne(SpecFileOut *sfo,int output, long index,int *error);
+
+
+/*********************************************************************
+ * Function: SpecFileOut *SfoInit( sf, error )
+ *
+ * Description: Initializes a SpecFileOut structure:
+ * - pointer to SpecFile
+ * - list of scans to be copied
+ * - size of this list
+ * - last written file header
+ * Parameters:
+ * Input : (1) SpecFile pointer
+ *
+ * Output:
+ * (2) error number
+ * Returns:
+ * Pointer to the initialized SpecFileOut structure.
+ * NULL in case of an error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMOREY_ALLOC
+ *
+ * Remark: This function MUST be the FIRST called before
+ * any other WRITE function is called !
+ *
+ *********************************************************************/
+DllExport SpecFileOut *
+SfoInit( SpecFile *sf, int *error )
+{
+ SpecFileOut *sfo;
+
+ /*
+ * Alloc memory
+ */
+ sfo = (SpecFileOut *) malloc ( sizeof(SpecFileOut) );
+
+ if ( sfo == (SpecFileOut *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( (SpecFileOut *)NULL );
+ }
+
+ /*
+ * Initialize
+ */
+ sfo->sf = sf;
+ sfo->list = (long *)NULL;
+ sfo->list_size = 0;
+ sfo->file_header = -1;
+
+ return( sfo );
+}
+
+
+/*********************************************************************
+ * Function: long SfoGetList( sfo, list, error )
+ *
+ * Description: Makes a copy of the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ *
+ * Output: (2) Copy of the output list of spec scan indices.
+ * (3) error code
+ * Returns:
+ * Number of scan indices in the output list ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) in case of an error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMOREY_ALLOC
+ *
+ * Remark: The memory allocated should be freed by the application
+ *
+ *********************************************************************/
+DllExport long
+SfoGetList( SpecFileOut *sfo, long **list, int *error )
+{
+ long i;
+
+ *list = (long *)NULL;
+
+ if ( sfo->list_size > 0 ) {
+ *list = (long *)malloc( sfo->list_size * sizeof(long) );
+ if ( *list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ for ( i=0 ; i < sfo->list_size ; i++ ) {
+ (*list)[i] = sfo->list[i];
+ }
+ } else *list = (long *)NULL;
+
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelectOne( sfo, index, error )
+ *
+ * Description: Adds one scan index to the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) Scan index
+ * Output:
+ * (3) error code
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport long
+SfoSelectOne( SpecFileOut *sfo, long index, int *error )
+{
+ long i;
+
+ /*
+ * Check if index exists or if it's out of range.
+ */
+ if ( index > sfo->sf->no_scans || index < 1 ) {
+ return( sfo->list_size );
+ }
+
+ /*
+ * Alloc memory for the new index and add it to the list.
+ */
+ if ( sfo->list == (long *)NULL ) {
+ sfo->list = (long *)malloc( sizeof(long) );
+ if ( sfo->list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ sfo->list_size = 1;
+ } else {
+ /*
+ * Is the new index already in list ?
+ */
+ for ( i=0 ; i<sfo->list_size ; i++ )
+ if ( index == sfo->list[i] ) return( sfo->list_size );
+ sfo->list = realloc( sfo->list, ++(sfo->list_size) * sizeof(long) );
+ if ( sfo->list == (long *)NULL ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ sfo->list_size = 0;
+ return( -1 );
+ }
+ }
+ sfo->list[sfo->list_size-1] = index;
+ printf("Adding scan %ld\n",index);
+
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelect( sfo, list, error )
+ *
+ * Description: Adds several scan indices to the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) List scan indices (!The last element
+ * MUST be a '0' !)
+ * Output:
+ * (3) error code
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoSelectOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoSelect( SpecFileOut *sfo, long *list, int *error )
+{
+ for ( ; *list != 0 ; list++ ) {
+ if ( SfoSelectOne( sfo, *list , error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelectRange( sfo, begin, end, error )
+ *
+ * Description: Adds scan indices between 'begin' and 'end'
+ * to the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) First ...
+ * (3) Last index to be added
+ * Output:
+ * (4) error code
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoSelectOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoSelectRange( SpecFileOut *sfo, long begin, long end, int *error )
+{
+ long i;
+
+ if ( begin > end ) {
+ i=begin;
+ begin = end;
+ end = i;
+ }
+ if ( begin < 1 || end > sfo->sf->no_scans ) {
+ return( sfo->list_size );
+ }
+ for ( i=begin ; i<=end ; i++ ) {
+ if ( SfoSelectOne( sfo, i , error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoSelectAll( sfo, error )
+ *
+ * Description: Writes all scan indices in the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOutput pointer
+ * Output: (2) error number
+ * Returns:
+ * ( -1 ) => error
+ * Number of scan indices in the SpecFileOut list.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport long
+SfoSelectAll( SpecFileOut *sfo, int *error )
+{
+ long i;
+
+ if ( sfo->sf->no_scans > 0 ) {
+ for ( i=1 ; i<=sfo->sf->no_scans ; i++ ) {
+ if ( SfoSelectOne( sfo, i , error ) < 0 ) return( -1 );
+ }
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemoveOne( sfo, index, error )
+ *
+ * Description: Removes one scan index from the SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) Scan index to be removed
+ * Output:
+ * (3) error code
+ * Returns:
+ * Number of scans left ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) => error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC
+ *
+ *********************************************************************/
+DllExport long
+SfoRemoveOne( SpecFileOut *sfo, long index, int *error )
+{
+ long i;
+ int found = 0;
+
+ /*
+ * Look for scan index and delete.
+ */
+ for ( i=0 ; i < (sfo->list_size - found) ; i++ ) {
+ if ( sfo->list[i] == index ) found = 1;
+ if ( found ) sfo->list[i]=sfo->list[i+1];
+ }
+
+ /*
+ * Free unused memory
+ */
+ if ( found ) {
+ (sfo->list_size)--;
+ sfo->list = realloc( sfo->list, sfo->list_size * sizeof(long) );
+ if ( sfo->list == (long *)NULL && sfo->list_size != 0 ) {
+ *error = SF_ERR_MEMORY_ALLOC;
+ return( -1 );
+ }
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemove( sfo, list, error )
+ *
+ * Description: Removes several scans indices from the
+ * SpecFileOut list.
+ *
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) List of scan indices to be removed
+ * ( !!! The last element MUST be a '0' !!! )
+ * Output:
+ * (3) error code
+ * Returns:
+ * Number of scan indices left ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) => error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoRemoveOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoRemove( SpecFileOut *sfo, long *list, int *error )
+{
+ for ( ; *list != 0 ; list++ ) {
+ if ( SfoRemoveOne( sfo, *list , error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemoveRange( sfo, begin, end, error )
+ *
+ * Description: Removes scans indices from 'begin' to 'end'
+ * from the SpecFileOut list.
+ *
+ * Parameters:
+ * Input :
+ * (1) SpecFileOut pointer
+ * (2) First ...
+ * (3) Last index to be removed
+ * Output:
+ * (4) error code
+ * Returns:
+ * Number of scan indices left ,
+ * ( 0 ) => list empty( (long *)NULL ) ), no errors
+ * ( -1 ) => error.
+ *
+ * Possible errors:
+ * SF_ERR_MEMORY_ALLOC | => SfoRemoveOne()
+ *
+ *********************************************************************/
+DllExport long
+SfoRemoveRange( SpecFileOut *sfo, long begin, long end, int *error )
+{
+ long i;
+
+ if ( begin > end ) {
+ i=begin;
+ begin = end;
+ end = i;
+ }
+ if ( begin < 1 || end > sfo->sf->no_scans ) {
+ return( sfo->list_size );
+ }
+ for ( i=begin ; i <= end ; i++ ) {
+ if ( SfoRemoveOne( sfo, i, error ) < 0 ) return( -1 );
+ }
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: long SfoRemoveAll( sfo, error )
+ *
+ * Description: Removes all scans indices
+ * from the SpecFileOut list.
+ *
+ * Parameters:
+ * Input :
+ * (1) SpecFileOut pointer
+ * Output:
+ * (2) error code
+ * Returns:
+ * ( 0 ) => OK
+ *
+ *********************************************************************/
+DllExport long
+SfoRemoveAll( SpecFileOut *sfo, int *error )
+{
+ free( sfo->list );
+ sfo->list = (long *)NULL;
+ sfo->list_size = 0;
+ sfo->file_header = -1;
+ return( 0 );
+}
+
+
+/*********************************************************************
+ * Function: int SfoWrite( sfo, name, error )
+ *
+ * Description: Writes (appends) SpecScans specified in the sfo->list
+ * in the file 'name'. Related file headers are copied
+ * too.
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ * (2) Output file name
+ * Output:
+ * (3) error number
+ * Returns:
+ * Number of written scans,
+ * (-1 ) => Errors occured
+ * Possible errors:
+ * SF_ERR_FILE_WRITE | => cpyBlock()
+ * SF_ERR_FILE_READ
+ * SF_ERR_FILE_OPEN
+ * SF_ERR_FILE_CLOSE
+ *
+ *********************************************************************/
+DllExport long
+SfoWrite( SpecFileOut *sfo, char *name, int *error )
+{
+ int output;
+ long i;
+
+ if ( sfo == (SpecFileOut *)NULL || sfo->list_size<1 ) return( 0 );
+
+ /*
+ * Open file
+ */
+ if ( (output = open(name, O_CREAT | O_RDWR | O_APPEND, SF_UMASK )) == (int)NULL ) {
+ *error = SF_ERR_FILE_OPEN;
+ return( -1 );
+ }
+
+ for ( i=0 ; i < sfo->list_size ; i++ )
+ sfoWriteOne(sfo,output,sfo->list[i],error);
+
+ if ( close( output ) ) {
+ *error = SF_ERR_FILE_CLOSE;
+ return( -1 );
+ }
+
+ return( sfo->list_size );
+}
+
+
+/*********************************************************************
+ * Function: int SfoClose( sfo )
+ *
+ * Description: Frees all memory used by
+ * SpecFileOut structure.
+ * Parameters:
+ * Input : (1) SpecFileOut pointer
+ *
+ * Remark: This function should be called after all
+ * writing operations.
+ *
+ *********************************************************************/
+DllExport void
+SfoClose( SpecFileOut *sfo )
+{
+ /*
+ * Free memory.
+ */
+ free( sfo->list );
+ free( sfo );
+}
+
+
+static int
+sfoWriteOne(SpecFileOut *sfo,int output,long index,int *error)
+{
+ long file_header,size;
+ SpecFile *sf;
+
+ if ( sfSetCurrent(sfo->sf,index,error) == -1 ) {
+ *error = SF_ERR_SCAN_NOT_FOUND;
+ return(-1);
+ }
+
+ /*
+ * File header
+ */
+ sf = sfo->sf;
+
+ file_header = ((SpecScan *)sf->current->contents)->size;
+
+ if (file_header != -1 && file_header != sfo->file_header ) {
+ printf("Writing %ld bytes\n",sf->filebuffersize);
+ write(output, (void *) sf->filebuffer, sf->filebuffersize);
+ sfo->file_header = file_header;
+ }
+
+ /*
+ * write scan
+ */
+ size = ((SpecScan *)sf->current->contents)->size;
+
+ if ( write(output,(void *) sf->scanbuffer,size) == -1 ) {
+ *error = SF_ERR_FILE_WRITE;
+ return(-1);
+ }
+ return(0);
+}
diff --git a/silx/io/specfilewrapper.py b/silx/io/specfilewrapper.py
new file mode 100644
index 0000000..005e54e
--- /dev/null
+++ b/silx/io/specfilewrapper.py
@@ -0,0 +1,371 @@
+# 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.
+#
+# ############################################################################*/
+"""This module provides a backward compatibility layer with the legacy
+specfile wrapper.
+
+If you are starting a new project, please consider using :mod:`silx.io.specfile`
+instead of this module.
+
+If you want to use this module for an existing project that used the old
+wrapper through PyMca, you can try replacing::
+
+ from PyMca5.PyMcaIO import specfilewrapper
+
+with::
+
+ from silx.io import specfilewrapper
+
+There might still be differences between this module and the old
+wrapper, due to differences in the underlying implementation.
+Any of these differences that break your code should be reported on
+https://github.com/silx-kit/silx/issues
+
+The documentation mentions only the methods and attributes that are different
+from the ones in :class:`silx.io.specfile.SpecFile` and
+:class:`silx.io.specfile.Scan`. You should refer to the documentation of these
+base classes for more information.
+"""
+from silx.io.specfile import SpecFile, Scan
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "15/09/2016"
+
+
+def _format_number_list(number_list):
+ """Return string representation of a list of integers,
+ using ``,`` as a separator and ``:`` as a range separator.
+ """
+ ret = ""
+ first_in_range = number_list[0]
+ last_in_range = number_list[0]
+ previous = number_list[0]
+ for number in number_list[1:]:
+ if number - previous != 1:
+ # reached end of range
+ if last_in_range > first_in_range:
+ ret += "%d:%d," % (first_in_range, last_in_range)
+ # passed isolated number
+ else:
+ ret += "%d," % previous
+ # reinitialize range
+ first_in_range = number
+ last_in_range = number
+ else:
+ # still inside a continuous range
+ last_in_range = number
+
+ previous = number
+
+ # last number
+ if last_in_range > first_in_range:
+ ret += "%d:%d" % (first_in_range, last_in_range)
+ else:
+ ret += "%d" % previous
+
+ return ret
+
+
+class Specfile(SpecFile):
+ """
+ This class is a subclass of :class:`silx.io.specfile.SpecFile`.
+
+ It redefines following methods:
+
+ - :meth:`__getitem__`: returns a :class:`scandata` object instead of
+ a :class:`silx.io.specfile.Scan` object
+ - :meth:`list`: returns a string representation of a list instead of a
+ list of integers
+
+ Following methods are added:
+
+ - :meth:`select`
+ - :meth:`scanno`
+ - :meth:`allmotors`
+ - :meth:`epoch`
+ - :meth:`title`
+ """
+ def __init__(self, filename):
+ SpecFile.__init__(self, filename)
+
+ def __getitem__(self, key):
+ """Get scan by 0-based index
+
+ :param key: 0-based scan index
+ :type key: int
+
+ :return: Scan
+ :rtype: :class:`scandata`
+ """
+ if not isinstance(key, int):
+ raise TypeError("Scan index must be an integer")
+
+ scan_index = key
+ # allow negative index, like lists
+ if scan_index < 0:
+ scan_index += len(self)
+
+ if not 0 <= scan_index < len(self):
+ msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ raise IndexError(msg)
+
+ return scandata(self, scan_index)
+
+ def list(self):
+ """Return a string representation of a list of scan numbers.
+
+ The scans numbers are listed in the order in which they appear
+ in the file. Continuous ranges of scan numbers are represented
+ as ``first:last``.
+
+ For instance, let's assume our specfile contains following scans:
+ *1, 2, 3, 4, 5, 684, 685, 687, 688, 689, 700, 688, 688*.
+ This method will then return::
+
+ "1:5,684:685,687:689,700,688,688"
+ """
+ number_list = SpecFile.list(self)
+ return _format_number_list(number_list)
+
+ def select(self, key):
+ """Get scan by ``n.m`` key
+
+ :param key: ``"s.o"`` (scan number, scan order)
+ :type key: str
+ :return: Scan
+ :rtype: :class:`scandata`
+ """
+ msg = "Key must be a string 'N.M' with N being the scan"
+ msg += " number and M the order (eg '2.3')."
+
+ if not hasattr(key, "lower") or "." not in key:
+ raise TypeError(msg)
+
+ try:
+ (number, order) = map(int, key.split("."))
+ scan_index = self.index(number, order)
+ except (ValueError, IndexError):
+ # self.index can raise an index error
+ # int() can raise a value error
+ raise KeyError(msg + "\nValid keys: '" +
+ "', '".join(self.keys()) + "'")
+ except AttributeError:
+ # e.g. "AttrErr: 'float' object has no attribute 'split'"
+ raise TypeError(msg)
+
+ if not 0 <= scan_index < len(self):
+ msg = "Scan index must be in range 0-%d" % (len(self) - 1)
+ raise IndexError(msg)
+
+ return scandata(self, scan_index)
+
+ def scanno(self):
+ """Return the number of scans in the SpecFile
+
+ This is an alias for :meth:`__len__`, for compatibility with the old
+ specfile wrapper API.
+ """
+ return len(self)
+
+ def allmotors(self, scan_index=0):
+ """
+ This is an alias for :meth:`motor_names`, for compatibility with
+ the old specfile wrapper API.
+ """
+ return self.motor_names(scan_index)
+
+ def epoch(self):
+ """:return: Epoch, from last word on file header line *#E*
+ :rtype: int
+ :raise: ValueError if *#E* line not found in header or last
+ word on *#E* cannot be converted to type *int*"""
+ fh = self.file_header()
+ for line in fh:
+ if line.startswith("#E "):
+ return int(line.split()[-1])
+ raise ValueError("No #E header found in specfile")
+
+ def title(self):
+ """:return: Title, from second field on *#C* header line (field are
+ strings separated by two spaces)
+ :rtype: str
+ :raise: ValueError if *#C* line not found in header or line is empty"""
+ fh = self.file_header()
+ for line in fh:
+ if line.startswith("#C "):
+ line1 = line.lstrip("#C ")
+ return line1.split(" ")[0]
+ raise ValueError("No #C header found in specfile")
+
+ # # these functions exist in the old API but don't seem to be
+ # # used, and are not easy to implement
+ # def show(self):
+ # raise NotImplementedError
+ #
+ # def user(self):
+ # raise NotImplementedError
+ #
+ # def update(self):
+ # raise NotImplementedError
+
+
+# PEP8 violation in class name is to respect old API
+class scandata(Scan): # noqa
+ """
+ This class is a subclass of :class:`silx.io.specfile.Scan`.
+
+ It redefines following methods/attributes:
+
+ - :meth:`data` becomes a method returning an array, instead of just
+ an array
+ - :meth:`mca`: becomes a method returning an array, instead of
+ a :class:`silx.io.specfile.MCA` object
+ - :meth:`header`: becomes a method returning a list of **scan**
+ header lines (or a list of a single header line, if a key is
+ specified), instead of just a list of all header lines
+
+ Following methods are added:
+
+ - :meth:`allmotors`
+ - :meth:`allmotorpos`
+ - :meth:`alllabels`
+ - :meth:`cols`
+ - :meth:`lines`
+ - :meth:`command`
+ - :meth:`date`
+ - :meth:`datacol`
+ - :meth:`dataline`
+ - :meth:`fileheader`
+ - :meth:`nbmca`
+ """
+ def __init__(self, specfile, scan_index):
+ Scan.__init__(self, specfile, scan_index)
+
+ def allmotors(self):
+ """Return a list of all motor names (identical to
+ :attr:`motor_names`).
+ """
+ return self.motor_names
+
+ def allmotorpos(self):
+ """Return a list of all motor positions (identical to
+ :attr:`motor_positions`).
+ """
+ return self.motor_positions
+
+ def alllabels(self):
+ """
+ Return a list of all labels (:attr:`labels`).
+ """
+ return self.labels
+
+ def cols(self):
+ """Return the number of data columns (number of detectors)"""
+ return super(scandata, self).data.shape[1]
+
+ def command(self):
+ """Return the command called for this scan (``#S`` header line)"""
+ return self._specfile.command(self._index)
+
+ def data(self):
+ """Return the data in this scan as a 2D numpy array.
+
+ The first index corresponds to the columns/detectors in the original
+ file, and the second index is the row index from the original file.
+ Indices are 0-based.
+
+ For instance, this is how you access the 18th data sample for the 3rd
+ detector (assuming ``sc`` is your scan object):
+
+ >>> scdata = sc.data()
+ >>> data_sample = scdata[2, 17]"""
+ return super(scandata, self).data
+
+ def datacol(self, col):
+ """Return a data column (all data for one detector)
+
+ :param col: column number (1-based index)"""
+ return super(scandata, self).data[col - 1, :]
+
+ def dataline(self, line):
+ """Return a data line (one sample for all detectors)
+
+ :param line: line number (1-based index)"""
+ return super(scandata, self).data[:, line - 1]
+
+ def date(self):
+ """Return the date from the scan header line ``#D``"""
+ return self._specfile.date(self._index)
+
+ def fileheader(self, key=''): # noqa
+ """Return a list of file header lines"""
+ # key is there for compatibility
+ return self.file_header
+
+ def header(self, key=""):
+ """Return a list of scan header lines if no key is specified.
+ If a valid key is specified, return a list of a single header line.
+
+ :param key: Header key (e.g. ``S, N, L, @CALIB``…)
+ If ``key`` is an empty string, return complete list of scan header
+ lines.
+ If ``key`` does not match any header line, return empty list.
+ :return: List of scan header lines
+ :rtype: list[str]
+ """
+ if key.strip() == "":
+ return self.scan_header
+ if self.record_exists_in_hdr(key):
+ prefix = "#" + key + " "
+ # there is no leading @ in self.mca_header_dict keys
+ key_mca_dict = key.lstrip("@") if key.startswith("@") else None
+ if key_mca_dict in self.mca_header_dict:
+ return [prefix + self.mca_header_dict[key_mca_dict]]
+ elif key in self.scan_header_dict:
+ return [prefix + self.scan_header_dict[key]]
+ elif key in self.file_header_dict:
+ return [prefix + self.file_header_dict[key]]
+ elif self.record_exists_in_hdr("@" + key):
+ # in case key is a mca header key without the @
+ if key in self.mca_header_dict:
+ prefix = "#@" + key + " "
+ return [prefix + self.mca_header_dict[key]]
+ return []
+
+ def lines(self):
+ """Return the number of data lines (number of data points per
+ detector)"""
+ return super(scandata, self).data.shape[0]
+
+ def mca(self, number):
+ """Return one MCA spectrum
+
+ :param number: MCA number (1-based index)
+ :rtype: 1D numpy array"""
+ # in the base class, mca is an object that can be indexed (but 0-based)
+ return super(scandata, self).mca[number - 1]
+
+ def nbmca(self):
+ """Return number of MCAs in this scan"""
+ return len(super(scandata, self).mca)
diff --git a/silx/io/spech5.py b/silx/io/spech5.py
new file mode 100644
index 0000000..58a6c6b
--- /dev/null
+++ b/silx/io/spech5.py
@@ -0,0 +1,1634 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""This module provides a h5py-like API to access SpecFile data.
+
+API description
+===============
+Specfile data structure exposed by this API:
+
+::
+
+ /
+ 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/
+ …
+
+``file_header`` and ``scan_header`` are the raw headers as they
+appear in the original file, as a string of lines separated by newline (``\\n``) characters.
+
+The title is the content of the ``#S`` scan header line without the leading
+``#S`` (e.g ``"1 ascan ss1vo -4.55687 -0.556875 40 0.2"``).
+
+The start time is converted to ISO8601 format (``"2016-02-23T22:49:05Z"``),
+if the original date format is standard.
+
+Numeric datasets are stored in *float32* format, except for scalar integers
+which are stored as *int64*.
+
+Motor positions (e.g. ``/1.1/instrument/positioners/motor_name``) can be
+1D numpy arrays if they are measured as scan data, or else scalars as defined
+on ``#P`` scan header lines. A simple test is done to check if the motor name
+is also a data column header defined in the ``#L`` scan header line.
+
+Scan data (e.g. ``/1.1/measurement/colname0``) is accessed by column,
+the dataset name ``colname0`` being the column label as defined in the ``#L``
+scan header line.
+
+If a ``/`` character is present in a column label or in a motor name in the
+original SPEC file, it will be substituted with a ``%`` character in the
+corresponding dataset name.
+
+MCA data is exposed as a 2D numpy array containing all spectra for a given
+analyser. The number of analysers is calculated as the number of MCA spectra
+per scan data line. Demultiplexing is then performed to assign the correct
+spectra to a given analyser.
+
+MCA calibration is an array of 3 scalars, from the ``#@CALIB`` header line.
+It is identical for all MCA analysers, as there can be only one
+``#@CALIB`` line per scan.
+
+MCA channels is an array containing all channel numbers. This information is
+computed from the ``#@CHANN`` scan header line (if present), or computed from
+the shape of the first spectrum in a scan (``[0, … len(first_spectrum] - 1]``).
+
+Accessing data
+==============
+
+Data and groups are accessed in :mod:`h5py` fashion::
+
+ 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"]
+ 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
+ mca_0_spectra = measurement_group["mca_0/data"]
+
+:class:`SpecH5` and :class:`SpecH5Group` provide a :meth:`SpecH5Group.keys` method::
+
+ >>> sfh5.keys()
+ ['96.1', '97.1', '98.1']
+ >>> sfh5['96.1'].keys()
+ ['title', 'start_time', 'instrument', 'measurement']
+
+They can also be treated as iterators:
+
+.. code-block:: python
+
+ for scan_group in SpecH5("test.dat"):
+ dataset_names = [item.name in scan_group["measurement"] if
+ isinstance(item, SpecH5Dataset)]
+ print("Found data columns in scan " + scan_group.name)
+ print(", ".join(dataset_names))
+
+You can test for existence of data or groups::
+
+ >>> "/1.1/measurement/Pslit HGap" in sfh5
+ True
+ >>> "positioners" in sfh5["/2.1/instrument"]
+ True
+ >>> "spam" in sfh5["1.1"]
+ False
+
+Strings are stored encoded as ``numpy.string_``, as recommended by
+`the h5py documentation <http://docs.h5py.org/en/latest/strings.html>`_.
+This ensures maximum compatibility with third party software libraries,
+when saving a :class:`SpecH5` to a HDF5 file using :mod:`silx.io.spectoh5`.
+
+The type ``numpy.string_`` is a byte-string format. The consequence of this
+is that you should decode strings before using them in **Python 3**::
+
+ >>> from silx.io.spech5 import SpecH5
+ >>> sfh5 = SpecH5("31oct98.dat")
+ >>> sfh5["/68.1/title"]
+ b'68 ascan tx3 -28.5 -24.5 20 0.5'
+ >>> sfh5["/68.1/title"].decode()
+ '68 ascan tx3 -28.5 -24.5 20 0.5'
+
+
+Classes
+=======
+
+- :class:`SpecH5`
+- :class:`SpecH5Group`
+- :class:`SpecH5Dataset`
+- :class:`SpecH5LinkToGroup`
+- :class:`SpecH5LinkToDataset`
+"""
+
+import logging
+import numpy
+import posixpath
+import re
+import sys
+
+from .specfile import SpecFile
+
+__authors__ = ["P. Knobel", "D. Naudet"]
+__license__ = "MIT"
+__date__ = "11/05/2017"
+
+logging.basicConfig()
+logger1 = logging.getLogger(__name__)
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+ logger1.debug("Module h5py optional.", exc_info=True)
+
+
+string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+
+# Static subitems: all groups and datasets that are present in any
+# scan (excludes list of scans, data columns, list of mca devices,
+# optional mca headers, optional sample group)
+static_items = {
+ "scan": [u"title", u"start_time", u"instrument",
+ u"measurement"],
+ "scan/instrument": [u"specfile", u"positioners"],
+ "scan/instrument/specfile": [u"file_header", u"scan_header"],
+ "scan/measurement/mca": [u"data", u"info"],
+ "scan/instrument/mca": [u"data", u"calibration", u"channels"],
+}
+
+# Patterns for group keys
+root_pattern = re.compile(r"/$")
+scan_pattern = re.compile(r"/[0-9]+\.[0-9]+/?$")
+instrument_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/?$")
+sample_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/?$")
+specfile_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/specfile/?$")
+positioners_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/positioners/?$")
+measurement_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/?$")
+measurement_mca_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_[0-9]+/?$")
+instrument_mca_group_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_[0-9]+/?$")
+
+
+# Link to group
+measurement_mca_info_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_([0-9]+)/info/?$")
+
+# Patterns for dataset keys
+header_pattern = re.compile(r"/[0-9]+\.[0-9]+/header$")
+title_pattern = re.compile(r"/[0-9]+\.[0-9]+/title$")
+start_time_pattern = re.compile(r"/[0-9]+\.[0-9]+/start_time$")
+file_header_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/specfile/file_header$")
+scan_header_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/specfile/scan_header$")
+positioners_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/positioners/([^/]+)$")
+measurement_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/([^/]+)$")
+instrument_mca_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_([0-9]+)/data$")
+instrument_mca_calib_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_([0-9]+)/calibration$")
+instrument_mca_chann_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_([0-9])+/channels$")
+instrument_mca_preset_t_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_[0-9]+/preset_time$")
+instrument_mca_elapsed_t_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_[0-9]+/elapsed_time$")
+instrument_mca_live_t_pattern = re.compile(r"/[0-9]+\.[0-9]+/instrument/mca_[0-9]+/live_time$")
+ub_matrix_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/ub_matrix$")
+unit_cell_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/unit_cell$")
+unit_cell_abc_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/unit_cell_abc$")
+unit_cell_alphabetagamma_pattern = re.compile(r"/[0-9]+\.[0-9]+/sample/unit_cell_alphabetagamma$")
+
+# Links to dataset
+measurement_mca_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_([0-9]+)/data$")
+# info/ + calibration, channel, preset_time, live_time, elapsed_time (not data)
+measurement_mca_info_dataset_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_([0-9]+)/info/([^d/][^/]+)$")
+# info/data
+measurement_mca_info_data_pattern = re.compile(r"/[0-9]+\.[0-9]+/measurement/mca_([0-9]+)/info/data$")
+
+
+def _bulk_match(string_, list_of_patterns):
+ """Check whether a string matches any regular expression pattern in a list
+ """
+ for pattern in list_of_patterns:
+ if pattern.match(string_):
+ return True
+ return False
+
+
+def is_group(name):
+ """Check if ``name`` matches a valid group name pattern in a
+ :class:`SpecH5`.
+
+ :param name: Full name of member
+ :type name: str
+
+ For example:
+
+ - ``is_group("/123.456/instrument/")`` returns ``True``.
+ - ``is_group("spam")`` returns ``False`` because :literal:`\"spam\"`
+ is not at all a valid group name.
+ - ``is_group("/1.2/instrument/positioners/xyz")`` returns ``False``
+ because this key would point to a motor position, which is a
+ dataset and not a group.
+ """
+ group_patterns = (
+ root_pattern, scan_pattern, instrument_pattern,
+ specfile_group_pattern, positioners_group_pattern,
+ measurement_group_pattern, measurement_mca_group_pattern,
+ instrument_mca_group_pattern, sample_pattern
+ )
+ return _bulk_match(name, group_patterns)
+
+
+def is_dataset(name):
+ """Check if ``name`` matches a valid dataset name pattern in a
+ :class:`SpecH5`.
+
+ :param name: Full name of member
+ :type name: str
+
+ For example:
+
+ - ``is_dataset("/1.2/instrument/positioners/xyz")`` returns ``True``
+ because this name could be the key to the dataset recording motor
+ positions for motor ``xyz`` in scan ``1.2``.
+ - ``is_dataset("/123.456/instrument/")`` returns ``False`` because
+ this name points to a group.
+ - ``is_dataset("spam")`` returns ``False`` because :literal:`\"spam\"`
+ is not at all a valid dataset name.
+ """
+ # Check groups first because /1.1/measurement/mca_0 could be interpreted
+ # as a data column with label "mca_0"
+ if measurement_mca_group_pattern.match(name):
+ return False
+
+ data_patterns = (
+ header_pattern, title_pattern, start_time_pattern,
+ file_header_data_pattern, scan_header_data_pattern,
+ positioners_data_pattern, measurement_data_pattern,
+ instrument_mca_data_pattern, instrument_mca_calib_pattern,
+ instrument_mca_chann_pattern,
+ instrument_mca_preset_t_pattern, instrument_mca_elapsed_t_pattern,
+ instrument_mca_live_t_pattern,
+ ub_matrix_pattern, unit_cell_pattern, unit_cell_abc_pattern, unit_cell_alphabetagamma_pattern
+ )
+ return _bulk_match(name, data_patterns)
+
+
+def is_link_to_group(name):
+ """Check if ``name`` is a valid link to a group in a :class:`SpecH5`.
+ Return ``True`` or ``False``
+
+ :param name: Full name of member
+ :type name: str
+ """
+ # so far we only have one type of link to a group
+ if measurement_mca_info_pattern.match(name):
+ return True
+ return False
+
+
+def is_link_to_dataset(name):
+ """Check if ``name`` is a valid link to a dataset in a :class:`SpecH5`.
+ Return ``True`` or ``False``
+
+ :param name: Full name of member
+ :type name: str
+ """
+ list_of_link_patterns = (
+ measurement_mca_data_pattern, measurement_mca_info_dataset_pattern,
+ measurement_mca_info_data_pattern
+ )
+ return _bulk_match(name, list_of_link_patterns)
+
+
+def _get_attrs_dict(name):
+ """Return attributes dictionary corresponding to the group or dataset
+ pointed to by name.
+
+ :param name: Full name/path to data or group
+ :return: attributes dictionary
+ """
+ # Associate group and dataset patterns to their attributes
+ pattern_attrs = {
+ root_pattern:
+ {"NX_class": "NXroot",
+ },
+ scan_pattern:
+ {"NX_class": "NXentry", },
+ title_pattern:
+ {},
+ start_time_pattern:
+ {},
+ instrument_pattern:
+ {"NX_class": "NXinstrument", },
+ specfile_group_pattern:
+ {"NX_class": "NXcollection", },
+ file_header_data_pattern:
+ {},
+ scan_header_data_pattern:
+ {},
+ positioners_group_pattern:
+ {"NX_class": "NXcollection", },
+ positioners_data_pattern:
+ {},
+ instrument_mca_group_pattern:
+ {"NX_class": "NXdetector", },
+ instrument_mca_data_pattern:
+ {"interpretation": "spectrum", },
+ instrument_mca_calib_pattern:
+ {},
+ instrument_mca_chann_pattern:
+ {},
+ instrument_mca_preset_t_pattern:
+ {},
+ instrument_mca_elapsed_t_pattern:
+ {},
+ instrument_mca_live_t_pattern:
+ {},
+ measurement_group_pattern:
+ {"NX_class": "NXcollection", },
+ measurement_data_pattern:
+ {},
+ measurement_mca_group_pattern:
+ {},
+ measurement_mca_data_pattern:
+ {"interpretation": "spectrum", },
+ measurement_mca_info_pattern:
+ {"NX_class": "NXdetector", },
+ measurement_mca_info_dataset_pattern:
+ {},
+ measurement_mca_info_data_pattern:
+ {"interpretation": "spectrum"},
+ sample_pattern:
+ {"NX_class": "NXsample", },
+ ub_matrix_pattern:
+ {"interpretation": "scalar"},
+ unit_cell_pattern:
+ {"interpretation": "scalar"},
+ unit_cell_abc_pattern:
+ {"interpretation": "scalar"},
+ unit_cell_alphabetagamma_pattern:
+ {"interpretation": "scalar"},
+ }
+
+ for pattern in pattern_attrs:
+ if pattern.match(name):
+ return pattern_attrs[pattern]
+
+ logger1.warning("%s not a known pattern, assigning empty dict to attrs",
+ name)
+ return {}
+
+
+def _get_scan_key_in_name(item_name):
+ """
+ :param item_name: Name of a group or dataset
+ :return: Scan identification key (e.g. ``"1.1"``)
+ :rtype: str on None
+ """
+ scan_match = re.match(r"/([0-9]+\.[0-9]+)", item_name)
+ if not scan_match:
+ return None
+ return scan_match.group(1)
+
+
+def _get_mca_index_in_name(item_name):
+ """
+ :param item_name: Name of a group or dataset
+ :return: MCA analyser index, ``None`` if item name does not reference
+ a mca dataset
+ :rtype: int or None
+ """
+ mca_match = re.match(r"/.*/mca_([0-9]+)[^0-9]*", item_name)
+ if not mca_match:
+ return None
+ return int(mca_match.group(1))
+
+
+def _get_motor_in_name(item_name):
+ """
+ :param item_name: Name of a group or dataset
+ :return: Motor name or ``None``
+ :rtype: str on None
+ """
+ motor_match = positioners_data_pattern.match(item_name)
+ if not motor_match:
+ return None
+ return motor_match.group(1)
+
+
+def _get_data_column_label_in_name(item_name):
+ """
+ :param item_name: Name of a group or dataset
+ :return: Data column label or ``None``
+ :rtype: str on None
+ """
+ # /1.1/measurement/mca_0 should not be interpreted as the label of a
+ # data column (let's hope no-one ever uses mca_0 as a label)
+ if measurement_mca_group_pattern.match(item_name):
+ return None
+ data_column_match = measurement_data_pattern.match(item_name)
+ if not data_column_match:
+ return None
+ return data_column_match.group(1)
+
+
+def _get_number_of_mca_analysers(scan):
+ """
+ :param SpecFile sf: :class:`SpecFile` instance
+ :param str scan_key: Scan identification key (e.g. ``1.1``)
+ """
+ number_of_MCA_spectra = len(scan.mca)
+ # Scan.data is transposed
+ number_of_data_lines = scan.data.shape[1]
+
+ if not number_of_data_lines == 0:
+ # Number of MCA spectra must be a multiple of number of data lines
+ assert number_of_MCA_spectra % number_of_data_lines == 0
+ return number_of_MCA_spectra // number_of_data_lines
+ elif number_of_MCA_spectra:
+ # Case of a scan without data lines, only MCA.
+ # Our only option is to assume that the number of analysers
+ # is the number of #@CHANN lines
+ return len(scan.mca.channels)
+ else:
+ return 0
+
+
+def _mca_analyser_in_scan(sf, scan_key, mca_analyser_index):
+ """
+ :param sf: :class:`SpecFile` instance
+ :param scan_key: Scan identification key (e.g. ``1.1``)
+ :param mca_analyser_index: 0-based index of MCA analyser
+ :return: ``True`` if MCA analyser exists in Scan, else ``False``
+ :raise: ``KeyError`` if scan_key not found in SpecFile
+ :raise: ``AssertionError`` if number of MCA spectra is not a multiple
+ of the number of data lines
+ """
+ if scan_key not in sf:
+ raise KeyError("Scan key %s " % scan_key +
+ "does not exist in SpecFile %s" % sf.filename)
+
+ number_of_analysers = _get_number_of_mca_analysers(sf[scan_key])
+
+ return 0 <= mca_analyser_index < number_of_analysers
+
+
+def _motor_in_scan(sf, scan_key, motor_name):
+ """
+ :param sf: :class:`SpecFile` instance
+ :param scan_key: Scan identification key (e.g. ``1.1``)
+ :param motor_name: Name of motor as defined in file header lines
+ :return: ``True`` if motor exists in scan, else ``False``
+ :raise: ``KeyError`` if scan_key not found in SpecFile
+ """
+ if scan_key not in sf:
+ raise KeyError("Scan key %s " % scan_key +
+ "does not exist in SpecFile %s" % sf.filename)
+ ret = motor_name in sf[scan_key].motor_names
+ if not ret and "%" in motor_name:
+ motor_name = motor_name.replace("%", "/")
+ ret = motor_name in sf[scan_key].motor_names
+ return ret
+
+
+def _column_label_in_scan(sf, scan_key, column_label):
+ """
+ :param sf: :class:`SpecFile` instance
+ :param scan_key: Scan identification key (e.g. ``1.1``)
+ :param column_label: Column label as defined in scan header
+ :return: ``True`` if data column label exists in scan, else ``False``
+ :raise: ``KeyError`` if scan_key not found in SpecFile
+ """
+ if scan_key not in sf:
+ raise KeyError("Scan key %s " % scan_key +
+ "does not exist in SpecFile %s" % sf.filename)
+ ret = column_label in sf[scan_key].labels
+ if not ret and "%" in column_label:
+ column_label = column_label.replace("%", "/")
+ ret = column_label in sf[scan_key].labels
+ return ret
+
+
+def _parse_ctime(ctime_lines, analyser_index=0):
+ """
+ :param ctime_lines: e.g ``@CTIME %f %f %f``, first word ``@CTIME`` optional
+ When multiple CTIME lines are present in a scan header, this argument
+ is a concatenation of them separated by a ``\n`` character.
+ :param analyser_index: MCA device/analyser index, when multiple devices
+ are in a scan.
+ :return: (preset_time, live_time, elapsed_time)
+ """
+ ctime_lines = ctime_lines.lstrip("@CTIME ")
+ ctimes_lines_list = ctime_lines.split("\n")
+ if len(ctimes_lines_list) == 1:
+ # single @CTIME line for all devices
+ ctime_line = ctimes_lines_list[0]
+ else:
+ ctime_line = ctimes_lines_list[analyser_index]
+ if not len(ctime_line.split()) == 3:
+ raise ValueError("Incorrect format for @CTIME header line " +
+ '(expected "@CTIME %f %f %f").')
+ return list(map(float, ctime_line.split()))
+
+
+def spec_date_to_iso8601(date, zone=None):
+ """Convert SpecFile date to Iso8601.
+
+ :param date: Date (see supported formats below)
+ :type date: str
+ :param zone: Time zone as it appears in a ISO8601 date
+
+ Supported formats:
+
+ * ``DDD MMM dd hh:mm:ss YYYY``
+ * ``DDD YYYY/MM/dd hh:mm:ss YYYY``
+
+ where `DDD` is the abbreviated weekday, `MMM` is the month abbreviated
+ name, `MM` is the month number (zero padded), `dd` is the weekday number
+ (zero padded) `YYYY` is the year, `hh` the hour (zero padded), `mm` the
+ minute (zero padded) and `ss` the second (zero padded).
+ All names are expected to be in english.
+
+ Examples::
+
+ >>> spec_date_to_iso8601("Thu Feb 11 09:54:35 2016")
+ '2016-02-11T09:54:35'
+
+ >>> spec_date_to_iso8601("Sat 2015/03/14 03:53:50")
+ '2015-03-14T03:53:50'
+ """
+ months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
+ 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+ days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+
+ days_rx = '(?P<day>' + '|'.join(days) + ')'
+ months_rx = '(?P<month>' + '|'.join(months) + ')'
+ year_rx = '(?P<year>\d{4})'
+ day_nb_rx = '(?P<day_nb>[0-3 ]\d)'
+ month_nb_rx = '(?P<month_nb>[0-1]\d)'
+ hh_rx = '(?P<hh>[0-2]\d)'
+ mm_rx = '(?P<mm>[0-5]\d)'
+ ss_rx = '(?P<ss>[0-5]\d)'
+ tz_rx = '(?P<tz>[+-]\d\d:\d\d){0,1}'
+
+ # date formats must have either month_nb (1..12) or month (Jan, Feb, ...)
+ re_tpls = ['{days} {months} {day_nb} {hh}:{mm}:{ss}{tz} {year}',
+ '{days} {year}/{month_nb}/{day_nb} {hh}:{mm}:{ss}{tz}']
+
+ grp_d = None
+
+ for rx in re_tpls:
+ full_rx = rx.format(days=days_rx,
+ months=months_rx,
+ year=year_rx,
+ day_nb=day_nb_rx,
+ month_nb=month_nb_rx,
+ hh=hh_rx,
+ mm=mm_rx,
+ ss=ss_rx,
+ tz=tz_rx)
+ m = re.match(full_rx, date)
+
+ if m:
+ grp_d = m.groupdict()
+ break
+
+ if not grp_d:
+ raise ValueError('Date format not recognized : {0}'.format(date))
+
+ year = grp_d['year']
+
+ month = grp_d.get('month_nb')
+
+ if not month:
+ month = '{0:02d}'.format(months.index(grp_d.get('month')) + 1)
+
+ day = grp_d['day_nb']
+
+ tz = grp_d['tz']
+ if not tz:
+ tz = zone
+
+ time = '{0}:{1}:{2}'.format(grp_d['hh'],
+ grp_d['mm'],
+ grp_d['ss'])
+
+ full_date = '{0}-{1}-{2}T{3}{4}'.format(year,
+ month,
+ day,
+ time,
+ tz if tz else '')
+ return full_date
+
+
+def _fixed_length_strings(strings, length=0):
+ """Return list of fixed length strings, left-justified and right-padded
+ with spaces.
+
+ :param strings: List of variable length strings
+ :param length: Length of strings in returned list, defaults to the maximum
+ length in the original list if set to 0.
+ :type length: int or None
+ """
+ if length == 0 and strings:
+ length = max(len(s) for s in strings)
+ return [s.ljust(length) for s in strings]
+
+
+class SpecH5Dataset(object):
+ """Emulate :class:`h5py.Dataset` for a SpecFile object.
+
+ A :class:`SpecH5Dataset` instance is basically a proxy for the numpy
+ array :attr:`value` attribute, with additional attributes for
+ compatibility with *h5py* datasets.
+
+ :param value: Actual dataset value
+ :param name: Dataset full name (posix path format, starting with ``/``)
+ :type name: str
+ :param file_: Parent :class:`SpecH5`
+ :param parent: Parent :class:`SpecH5Group` which contains this dataset
+ """
+ def __init__(self, value, name, file_, parent):
+ object.__init__(self)
+
+ self.value = None
+ """Actual dataset, can be a *numpy array*, a *numpy.string_*,
+ a *numpy.int_* or a *numpy.float32*
+
+ All operations applied to an instance of the class use this."""
+
+ # get proper value types, to inherit from numpy
+ # attributes (dtype, shape, size)
+ if isinstance(value, string_types):
+ # use bytes for maximum compatibility
+ # (see http://docs.h5py.org/en/latest/strings.html)
+ self.value = numpy.string_(value)
+ elif isinstance(value, float):
+ # use 32 bits for float scalars
+ self.value = numpy.float32(value)
+ elif isinstance(value, int):
+ self.value = numpy.int_(value)
+ else:
+ # Enforce numpy array
+ array = numpy.array(value)
+ data_kind = array.dtype.kind
+
+ if data_kind in ["S", "U"]:
+ self.value = numpy.asarray(array, dtype=numpy.string_)
+ elif data_kind in ["f"]:
+ self.value = numpy.asarray(array, dtype=numpy.float32)
+ else:
+ self.value = array
+
+ # numpy array attributes (more attributes handled in __getattribute__)
+ self.shape = self.value.shape
+ """Dataset shape, as a tuple with the length of each dimension
+ of the dataset."""
+
+ self.dtype = self.value.dtype
+ """Dataset dtype"""
+
+ self.size = self.value.size
+ """Dataset size (number of elements)"""
+
+ # h5py dataset specific attributes
+ self.name = name
+ """"Dataset name (posix path format, starting with ``/``)"""
+
+ self.parent = parent
+ """Parent :class:`SpecH5Group` object which contains this dataset"""
+
+ self.file = file_
+ """Parent :class:`SpecH5` object"""
+
+ self.attrs = _get_attrs_dict(name)
+ """Attributes dictionary"""
+
+ self.compression = None
+ """Compression attribute as provided by h5py.Dataset"""
+
+ self.compression_opts = None
+ """Compression options attribute as provided by h5py.Dataset"""
+
+ self.chunks = None
+
+ @property
+ def h5py_class(self):
+ """Return h5py class which is mimicked by this class:
+ :class:`h5py.dataset`.
+
+ Accessing this attribute if :mod:`h5py` is not installed causes
+ an ``ImportError`` to be raised
+ """
+ if h5py is None:
+ raise ImportError("Cannot return h5py.Dataset class, " +
+ "unable to import h5py module")
+ return h5py.Dataset
+
+ def __getattribute__(self, item):
+ if item in ["value", "name", "parent", "file", "attrs",
+ "shape", "dtype", "size", "h5py_class",
+ "chunks", "compression", "compression_opts",
+ "target"]:
+ return object.__getattribute__(self, item)
+
+ if hasattr(self.value, item):
+ return getattr(self.value, item)
+
+ raise AttributeError("SpecH5Dataset has no attribute %s" % item)
+
+ def __len__(self):
+ return len(self.value)
+
+ def __getitem__(self, item):
+ if not isinstance(self.value, numpy.ndarray):
+ if item == Ellipsis:
+ return numpy.array(self.value)
+ elif item == tuple():
+ return self.value
+ else:
+ raise ValueError("Scalar can only be reached with an ellipsis or an empty tuple")
+ return self.value.__getitem__(item)
+
+ def __getslice__(self, i, j):
+ # deprecated but still in use for python 2.7
+ return self.__getitem__(slice(i, j, None))
+
+ def __iter__(self):
+ return self.value.__iter__()
+
+ def __dir__(self):
+ attrs = set(dir(self.value) +
+ ["value", "name", "parent", "file",
+ "attrs", "shape", "dtype", "size",
+ "h5py_class", "chunks", "compression",
+ "compression_opts"])
+ return sorted(attrs)
+
+ # casting
+ def __repr__(self):
+ return '<SpecH5Dataset "%s": shape %s, type "%s">' % \
+ (self.name, self.shape, self.dtype.str)
+
+ def __float__(self):
+ return float(self.value)
+
+ def __int__(self):
+ return int(self.value)
+
+ def __str__(self):
+ basename = self.name.split("/")[-1]
+ return '<SPEC dataset "%s": shape %s, type "%s">' % \
+ (basename, self.shape, self.dtype.str)
+
+ def __bool__(self):
+ if self.value:
+ return True
+ return False
+
+ def __nonzero__(self):
+ # python 2
+ return self.__bool__()
+
+ def __array__(self, dtype=None):
+ if dtype is None:
+ return numpy.array(self.value)
+ else:
+ return numpy.array(self.value, dtype=dtype)
+
+ # comparisons
+ def __eq__(self, other):
+ if hasattr(other, "value"):
+ return self.value == other.value
+ else:
+ return self.value == other
+
+ def __ne__(self, other):
+ if hasattr(other, "value"):
+ return self.value != other.value
+ else:
+ return self.value != other
+
+ def __lt__(self, other):
+ if hasattr(other, "value"):
+ return self.value < other.value
+ else:
+ return self.value < other
+
+ def __le__(self, other):
+ if hasattr(other, "value"):
+ return self.value <= other.value
+ else:
+ return self.value <= other
+
+ def __gt__(self, other):
+ if hasattr(other, "value"):
+ return self.value > other.value
+ else:
+ return self.value > other
+
+ def __ge__(self, other):
+ if hasattr(other, "value"):
+ return self.value >= other.value
+ else:
+ return self.value >= other
+
+ # operations
+ def __add__(self, other):
+ return self.value + other
+
+ def __radd__(self, other):
+ return other + self.value
+
+ def __sub__(self, other):
+ return self.value - other
+
+ def __rsub__(self, other):
+ return other - self.value
+
+ def __mul__(self, other):
+ return self.value * other
+
+ def __rmul__(self, other):
+ return other * self.value
+
+ def __truediv__(self, other):
+ return self.value / other
+
+ def __rtruediv__(self, other):
+ return other / self.value
+
+ def __floordiv__(self, other):
+ return self.value // other
+
+ def __rfloordiv__(self, other):
+ return other // self.value
+
+ # unary operations
+ def __neg__(self):
+ return -self.value
+
+ def __abs__(self):
+ return abs(self.value)
+
+
+class SpecH5LinkToDataset(SpecH5Dataset):
+ """Special :class:`SpecH5Dataset` representing a link to a dataset. It
+ works like a regular dataset, but :meth:`SpecH5Group.visit`
+ and :meth:`SpecH5Group.visititems` methods will recognize that it is
+ a link and will ignore it.
+
+ A special attribute contains the name of the target dataset:
+ :attr:`target`
+ """
+ def __init__(self, value, name, file_, parent, target):
+ """
+ :param value: Actual dataset value
+ :param name: Dataset full name (posix path format, starting with ``/``)
+ :type name: str
+ :param file_: Parent :class:`SpecH5`
+ :param parent: Parent :class:`SpecH5Group` which contains this dataset
+ :param str target: Name of linked dataset
+ """
+ SpecH5Dataset.__init__(self, value, name, file_, parent)
+ self.target = target
+ """Name of the target dataset"""
+
+
+def _dataset_builder(name, specfileh5, parent_group):
+ """Retrieve dataset from :class:`SpecFile`, based on dataset name, as a
+ subclass of :class:`numpy.ndarray`.
+
+ :param name: Datatset full name (posix path format, starting with ``/``)
+ :type name: str
+ :param specfileh5: parent :class:`SpecH5` object
+ :type specfileh5: :class:`SpecH5`
+ :param parent_group: Parent :class:`SpecH5Group`
+
+ :return: Array with the requested data
+ :rtype: :class:`SpecH5Dataset`.
+ """
+ scan_key = _get_scan_key_in_name(name)
+ scan = specfileh5._sf[scan_key]
+
+ # get dataset in an array-like format (ndarray, str, list…)
+ array_like = None
+
+ if title_pattern.match(name):
+ array_like = scan.scan_header_dict["S"]
+
+ elif start_time_pattern.match(name):
+ if "D" in scan.scan_header_dict:
+ try:
+ array_like = spec_date_to_iso8601(scan.scan_header_dict["D"])
+ except (IndexError, ValueError):
+ logger1.warn("Could not parse date format in scan %s header." +
+ " Using original date not converted to ISO-8601",
+ scan_key)
+ array_like = scan.scan_header_dict["D"]
+ elif "D" in scan.file_header_dict:
+ logger1.warn("No #D line in scan %s header. " +
+ "Using file header for start_time.",
+ scan_key)
+ try:
+ array_like = spec_date_to_iso8601(scan.file_header_dict["D"])
+ except (IndexError, ValueError):
+ logger1.warn("Could not parse date format in scan %s header. " +
+ "Using original date not converted to ISO-8601",
+ scan_key)
+ array_like = scan.file_header_dict["D"]
+ else:
+ logger1.warn("No #D line in %s header. Setting date to empty string.",
+ scan_key)
+ array_like = ""
+
+ elif file_header_data_pattern.match(name):
+ # array_like = _fixed_length_strings(scan.file_header)
+ array_like = "\n".join(scan.file_header)
+
+ elif scan_header_data_pattern.match(name):
+ # array_like = _fixed_length_strings(scan.scan_header)
+ array_like = "\n".join(scan.scan_header)
+
+ elif positioners_data_pattern.match(name):
+ m = positioners_data_pattern.match(name)
+ motor_name = m.group(1)
+ if motor_name not in (scan.labels + scan.motor_names):
+ if "%" in motor_name:
+ motor_name = motor_name.replace("%", "/")
+ # if a motor is recorded as a data column, ignore its position in
+ # header and return the data column instead
+ if motor_name in scan.labels and scan.data.shape[0] > 0:
+ array_like = scan.data_column_by_name(motor_name)
+ else:
+ # may return float("inf") if #P line is missing from scan hdr
+ array_like = scan.motor_position_by_name(motor_name)
+
+ elif measurement_data_pattern.match(name):
+ m = measurement_data_pattern.match(name)
+ column_name = m.group(1)
+ if column_name not in scan.labels:
+ if "%" in column_name:
+ column_name = column_name.replace("%", "/")
+ array_like = scan.data_column_by_name(column_name)
+
+ elif instrument_mca_data_pattern.match(name):
+ m = instrument_mca_data_pattern.match(name)
+
+ analyser_index = int(m.group(1))
+ # retrieve 2D array of all MCA spectra from one analyser
+ array_like = _demultiplex_mca(scan, analyser_index)
+
+ elif instrument_mca_calib_pattern.match(name):
+ m = instrument_mca_calib_pattern.match(name)
+ analyser_index = int(m.group(1))
+ if len(scan.mca.channels) == 1:
+ # single @CALIB line applying to multiple devices
+ analyser_index = 0
+ array_like = scan.mca.calibration[analyser_index]
+
+ elif instrument_mca_chann_pattern.match(name):
+ m = instrument_mca_chann_pattern.match(name)
+ analyser_index = int(m.group(1))
+ if len(scan.mca.channels) == 1:
+ # single @CHANN line applying to multiple devices
+ analyser_index = 0
+ array_like = scan.mca.channels[analyser_index]
+
+ elif ub_matrix_pattern.match(name):
+ if not "G3" in scan.scan_header_dict:
+ raise KeyError("No UB matrix in a scan without a #G3 header line")
+ array_like = numpy.array(
+ list(map(float, scan.scan_header_dict["G3"].split()))).reshape((1, 3, 3))
+ elif unit_cell_pattern.match(name):
+ if not "G1" in scan.scan_header_dict:
+ raise KeyError(
+ "No unit_cell matrix in a scan without a #G1 header line")
+ array_like = numpy.array(
+ list(map(float, scan.scan_header_dict["G1"].split()))[0:6]).reshape((1, 6))
+ elif unit_cell_abc_pattern.match(name):
+ if not "G1" in scan.scan_header_dict:
+ raise KeyError(
+ "No unit_cell matrix in a scan without a #G1 header line")
+ array_like = numpy.array(
+ list(map(float, scan.scan_header_dict["G1"].split()))[0:3]).reshape((3,))
+ elif unit_cell_alphabetagamma_pattern.match(name):
+ if not "G1" in scan.scan_header_dict:
+ raise KeyError(
+ "No unit_cell matrix in a scan without a #G1 header line")
+ array_like = numpy.array(
+ list(map(float, scan.scan_header_dict["G1"].split()))[3:6]).reshape((3,))
+ elif "CTIME" in scan.mca_header_dict and "mca_" in name:
+ m = re.compile(r"/.*/mca_([0-9]+)/.*").match(name)
+ analyser_index = int(m.group(1))
+
+ ctime_line = scan.mca_header_dict['CTIME']
+ (preset_time, live_time, elapsed_time) = _parse_ctime(ctime_line, analyser_index)
+ if instrument_mca_preset_t_pattern.match(name):
+ array_like = preset_time
+ elif instrument_mca_live_t_pattern.match(name):
+ array_like = live_time
+ elif instrument_mca_elapsed_t_pattern.match(name):
+ array_like = elapsed_time
+
+ if array_like is None:
+ raise KeyError("Name " + name + " does not match any known dataset.")
+
+ return SpecH5Dataset(array_like, name,
+ file_=specfileh5, parent=parent_group)
+
+
+def _link_to_dataset_builder(name, specfileh5, parent_group):
+ """Same as :func:`_dataset_builder`, but returns a
+ :class:`SpecH5LinkToDataset`
+
+ :param name: Datatset full name (posix path format, starting with ``/``)
+ :type name: str
+ :param specfileh5: parent :class:`SpecH5` object
+ :type specfileh5: :class:`SpecH5`
+ :param parent_group: Parent :class:`SpecH5Group`
+
+ :return: Array with the requested data
+ :rtype: :class:`SpecH5LinkToDataset`.
+ """
+ scan_key = _get_scan_key_in_name(name)
+ scan = specfileh5._sf[scan_key]
+
+ # get dataset in an array-like format (ndarray, str, list…)
+ array_like = None
+
+ # /1.1/measurement/mca_0/data -> /1.1/instrument/mca_0/data
+ if measurement_mca_data_pattern.match(name):
+ m = measurement_mca_data_pattern.match(name)
+ analyser_index = int(m.group(1))
+ array_like = _demultiplex_mca(scan, analyser_index)
+
+ # /1.1/measurement/mca_0/info/X -> /1.1/instrument/mca_0/X
+ # X: calibration, channels, preset_time, live_time, elapsed_time
+ elif measurement_mca_info_dataset_pattern.match(name):
+ m = measurement_mca_info_dataset_pattern.match(name)
+ analyser_index = int(m.group(1))
+ mca_hdr_type = m.group(2)
+
+ if mca_hdr_type == "calibration":
+ if len(scan.mca.calibration) == 1:
+ # single @CALIB line for multiple devices
+ analyser_index = 0
+ array_like = scan.mca.calibration[analyser_index]
+
+ elif mca_hdr_type == "channels":
+ if len(scan.mca.channels) == 1:
+ # single @CHANN line for multiple devices
+ analyser_index = 0
+ array_like = scan.mca.channels[analyser_index]
+
+ elif "CTIME" in scan.mca_header_dict:
+ ctime_line = scan.mca_header_dict['CTIME']
+ (preset_time, live_time, elapsed_time) = _parse_ctime(ctime_line,
+ analyser_index)
+ if mca_hdr_type == "preset_time":
+ array_like = preset_time
+ elif mca_hdr_type == "live_time":
+ array_like = live_time
+ elif mca_hdr_type == "elapsed_time":
+ array_like = elapsed_time
+
+ # /1.1/measurement/mca_0/info/data -> /1.1/instrument/mca_0/data
+ elif measurement_mca_info_data_pattern.match(name):
+ m = measurement_mca_info_data_pattern.match(name)
+ analyser_index = int(m.group(1))
+ array_like = _demultiplex_mca(scan, analyser_index)
+
+ if array_like is None:
+ raise KeyError("Name " + name + " does not match any known dataset.")
+
+ target = name.replace("measurement", "instrument")
+ target = target.replace("info/", "")
+
+ return SpecH5LinkToDataset(array_like, name,
+ file_=specfileh5, parent=parent_group,
+ target=target)
+
+
+def _demultiplex_mca(scan, analyser_index):
+ """Return MCA data for a single analyser.
+
+ Each MCA spectrum is a 1D array. For each analyser, there is one
+ spectrum recorded per scan data line. When there are more than a single
+ MCA analyser in a scan, the data will be multiplexed. For instance if
+ there are 3 analysers, the consecutive spectra for the first analyser must
+ be accessed as ``mca[0], mca[3], mca[6]…``.
+
+ :param scan: :class:`Scan` instance containing the MCA data
+ :param analyser_index: 0-based index referencing the analyser
+ :type analyser_index: int
+ :return: 2D numpy array containing all spectra for one analyser
+ """
+ number_of_analysers = _get_number_of_mca_analysers(scan)
+
+ number_of_MCA_spectra = len(scan.mca)
+
+ list_of_1D_arrays = []
+ for i in range(analyser_index,
+ number_of_MCA_spectra,
+ number_of_analysers):
+ list_of_1D_arrays.append(scan.mca[i])
+ # convert list to 2D array
+ return numpy.array(list_of_1D_arrays)
+
+
+class SpecH5Group(object):
+ """Emulate :class:`h5py.Group` for a SpecFile object
+
+ :param name: Group full name (posix path format, starting with ``/``)
+ :type name: str
+ :param specfileh5: parent :class:`SpecH5` instance
+
+ """
+ def __init__(self, name, specfileh5):
+ self.name = name
+ """Full name/path of group"""
+
+ self.file = specfileh5
+ """Parent SpecH5 object"""
+
+ self.attrs = _get_attrs_dict(name)
+ """Attributes dictionary"""
+
+ if name != "/":
+ if name not in specfileh5:
+ raise KeyError("File %s does not contain group %s" %
+ (specfileh5, name))
+ scan_key = _get_scan_key_in_name(name)
+ self._scan = self.file._sf[scan_key]
+
+ @property
+ def h5py_class(self):
+ """Return h5py class which is mimicked by this class:
+ :class:`h5py.Group`.
+
+ Accessing this attribute if :mod:`h5py` is not installed causes
+ an ``ImportError`` to be raised
+ """
+ if h5py is None:
+ raise ImportError("Cannot return h5py.Group class, " +
+ "unable to import h5py module")
+ return h5py.Group
+
+ @property
+ def parent(self):
+ """Parent group (group that contains this group)"""
+ if not self.name.strip("/"):
+ return None
+
+ parent_name = posixpath.dirname(self.name.rstrip("/"))
+ return SpecH5Group(parent_name, self.file)
+
+ def __contains__(self, key):
+ """
+ :param key: Path to child element (e.g. ``"mca_0/info"``) or full name
+ of group or dataset (e.g. ``"/2.1/instrument/positioners"``)
+ :return: True if key refers to a valid member of this group,
+ else False
+ """
+ # Absolute path to an item outside this group
+ if key.startswith("/"):
+ if not key.startswith(self.name):
+ return False
+ # Make sure key is an absolute path by prepending this group's name
+ else:
+ key = self.name.rstrip("/") + "/" + key
+
+ # key not matching any known pattern
+ if not is_group(key) and not is_dataset(key) and\
+ not is_link_to_group(key) and not is_link_to_dataset(key):
+ return False
+
+ # nonexistent scan in specfile
+ scan_key = _get_scan_key_in_name(key)
+ if scan_key not in self.file._sf:
+ return False
+
+ # nonexistent MCA analyser in scan
+ mca_analyser_index = _get_mca_index_in_name(key)
+ if mca_analyser_index is not None:
+ if not _mca_analyser_in_scan(self.file._sf,
+ scan_key,
+ mca_analyser_index):
+ return False
+
+ # nonexistent motor name
+ motor_name = _get_motor_in_name(key)
+ if motor_name is not None:
+ if not _motor_in_scan(self.file._sf,
+ scan_key,
+ motor_name):
+ return False
+
+ # nonexistent data column
+ column_label = _get_data_column_label_in_name(key)
+ if column_label is not None:
+ if not _column_label_in_scan(self.file._sf,
+ scan_key,
+ column_label):
+ return False
+
+ if key.endswith("preset_time") or\
+ key.endswith("elapsed_time") or\
+ key.endswith("live_time"):
+ return "CTIME" in self.file._sf[scan_key].mca_header_dict
+
+ if sample_pattern.match(key):
+ return ("G3" in self.file._sf[scan_key].scan_header_dict or
+ "G1" in self.file._sf[scan_key].scan_header_dict)
+
+ if key.endswith("sample/ub_matrix"):
+ return "G3" in self.file._sf[scan_key].scan_header_dict
+
+ if key.endswith("sample/unit_cell"):
+ return "G1" in self.file._sf[scan_key].scan_header_dict
+
+ if key.endswith("sample/unit_cell_abc"):
+ return "G1" in self.file._sf[scan_key].scan_header_dict
+
+
+ if key.endswith("sample/unit_cell_alphabetagamma"):
+ return "G1" in self.file._sf[scan_key].scan_header_dict
+
+ # header, title, start_time, existing scan/mca/motor/measurement
+ return True
+
+ def __eq__(self, other):
+ return (isinstance(other, SpecH5Group) and
+ self.name == other.name and
+ self.file.filename == other.file.filename and
+ self.keys() == other.keys())
+
+ def get(self, name, default=None, getclass=False, getlink=False):
+ """Retrieve an item by name, or a default value if name does not
+ point to an existing item.
+
+ :param name str: name of the item
+ :param default: Default value returned if the name is not found
+ :param bool getclass: if *True*, the returned object is the class of
+ the item, instead of the item instance.
+ :param bool getlink: Not implemented. This method always returns
+ an instance of the original class of the requested item (or
+ just the class, if *getclass* is *True*)
+ :return: The requested item, or its class if *getclass* is *True*,
+ or the specified *default* value if the group does not contain
+ an item with the requested name.
+ """
+ if name not in self:
+ return default
+
+ if getlink and getclass:
+ pass
+
+ if getclass:
+ return self[name].h5py_class
+
+ return self[name]
+
+ def __getitem__(self, key):
+ """Return a :class:`SpecH5Group` or a :class:`SpecH5Dataset`
+ if ``key`` is a valid name of a group or dataset.
+
+ ``key`` can be a member of ``self.keys()``, i.e. an immediate child of
+ the group, or a path reaching into subgroups (e.g.
+ ``"instrument/positioners"``)
+
+ In the special case were this group is the root group, ``key`` can
+ start with a ``/`` character.
+
+ :param key: Name of member
+ :type key: str
+ :raise: KeyError if ``key`` is not a known member of this group.
+ """
+ # accept numbers for scan indices
+ if isinstance(key, int):
+ number = self.file._sf.number(key)
+ order = self.file._sf.order(key)
+ full_key = "/%d.%d" % (number, order)
+ # Relative path starting from this group (e.g "mca_0/info")
+ elif not key.startswith("/"):
+ full_key = self.name.rstrip("/") + "/" + key
+ # Absolute path called from the root group or from a parent group
+ elif key.startswith(self.name):
+ full_key = key
+ # Absolute path to an element called from a non-parent group
+ else:
+ raise KeyError(key + " is not a child of " + self.__repr__())
+
+ if is_group(full_key):
+ return SpecH5Group(full_key, self.file)
+ elif is_dataset(full_key):
+ return _dataset_builder(full_key, self.file, self)
+ elif is_link_to_group(full_key):
+ link_target = full_key.replace("measurement", "instrument").rstrip("/")[:-4]
+ return SpecH5LinkToGroup(full_key, self.file, link_target)
+ elif is_link_to_dataset(full_key):
+ return _link_to_dataset_builder(full_key, self.file, self)
+ else:
+ raise KeyError("unrecognized group or dataset: " + full_key)
+
+ def __iter__(self):
+ for key in self.keys():
+ yield key
+
+ def items(self):
+ for key in self.keys():
+ yield key, self[key]
+
+ def __len__(self):
+ """Return number of members, subgroups and datasets, attached to this
+ group.
+ """
+ return len(self.keys())
+
+ def __repr__(self):
+ return '<SpecH5Group "%s" (%d members)>' % (self.name, len(self))
+
+ def keys(self):
+ """:return: List of all names of members attached to this group
+ """
+ # keys in hdf5 are unicode
+ if self.name == "/":
+ return self.file.keys()
+
+ if scan_pattern.match(self.name):
+ ret = static_items["scan"]
+ if "G1" in self._scan.scan_header_dict or "G3" in self._scan.scan_header_dict:
+ return ret + [u"sample"]
+ return ret
+
+ if positioners_group_pattern.match(self.name):
+ motor_names = self._scan.motor_names
+ return [name.replace("/", "%") for name in motor_names]
+
+ if specfile_group_pattern.match(self.name):
+ return static_items["scan/instrument/specfile"]
+
+ if measurement_mca_group_pattern.match(self.name):
+ return static_items["scan/measurement/mca"]
+
+ if instrument_mca_group_pattern.match(self.name):
+ ret = static_items["scan/instrument/mca"]
+ if "CTIME" in self._scan.mca_header_dict:
+ return ret + [u"preset_time", u"elapsed_time", u"live_time"]
+ return ret
+
+ if sample_pattern.match(self.name):
+ ret = []
+ if "G1" in self._scan.scan_header_dict:
+ ret.append(u"unit_cell")
+ ret.append(u"unit_cell_abc")
+ ret.append(u"unit_cell_alphabetagamma")
+ if "G3" in self._scan.scan_header_dict:
+ ret.append(u"ub_matrix")
+ return ret
+
+ number_of_MCA_spectra = len(self._scan.mca)
+ number_of_data_lines = self._scan.data.shape[1]
+
+ if not number_of_data_lines == 0:
+ # Number of MCA spectra must be a multiple of number of data lines
+ assert number_of_MCA_spectra % number_of_data_lines == 0
+ number_of_MCA_analysers = number_of_MCA_spectra // number_of_data_lines
+ elif number_of_MCA_spectra:
+ # Case of a scan without data lines, only MCA.
+ # Our only option is to assume that the number of analysers
+ # is the number of #@CHANN lines
+ number_of_MCA_analysers = len(self._scan.mca.channels)
+ else:
+ number_of_MCA_analysers = 0
+
+ mca_list = ["mca_%d" % i for i in range(number_of_MCA_analysers)]
+
+ if measurement_group_pattern.match(self.name):
+ scan_labels = self._scan.labels
+ return [label.replace("/", "%") for label in scan_labels] + mca_list
+
+ if instrument_pattern.match(self.name):
+ return static_items["scan/instrument"] + mca_list
+
+ def visit(self, func, follow_links=False):
+ """Recursively visit all names in this group and subgroups.
+
+ :param func: Callable (function, method or callable object)
+ :type func: function
+
+ You supply a callable (function, method or callable object); it
+ will be called exactly once for each link in this group and every
+ group below it. Your callable must conform to the signature:
+
+ ``func(<member name>) => <None or return value>``
+
+ Returning ``None`` continues iteration, returning anything else stops
+ and immediately returns that value from the visit method. No
+ particular order of iteration within groups is guaranteed.
+
+ Example:
+
+ .. code-block:: python
+
+ # Get a list of all contents (groups and datasets) in a SpecFile
+ mylist = []
+ f = File('foo.dat')
+ f.visit(mylist.append)
+ """
+ for member_name in self.keys():
+ member = self[member_name]
+ ret = None
+ if (not is_link_to_dataset(member.name) and
+ not is_link_to_group(member.name)) or follow_links:
+ ret = func(member.name)
+ if ret is not None:
+ return ret
+ # recurse into subgroups
+ if isinstance(member, SpecH5Group):
+ if not isinstance(member, SpecH5LinkToGroup) or follow_links:
+ self[member_name].visit(func, follow_links)
+
+ def visititems(self, func, follow_links=False):
+ """Recursively visit names and objects in this group.
+
+ :param func: Callable (function, method or callable object)
+ :type func: function
+
+ You supply a callable (function, method or callable object); it
+ will be called exactly once for each
+ member in this group and every group below it. Your callable must
+ conform to the signature:
+
+ ``func(<member name>, <object>) => <None or return value>``
+
+ Returning ``None`` continues iteration, returning anything else stops
+ and immediately returns that value from the visit method. No
+ particular order of iteration within groups is guaranteed.
+
+ Example:
+
+ .. code-block:: python
+
+ # Get a list of all datasets in a specific scan
+ mylist = []
+ def func(name, obj):
+ if isinstance(obj, SpecH5Dataset):
+ mylist.append(name)
+
+ f = File('foo.dat')
+ f["1.1"].visititems(func)
+ """
+ for member_name in self.keys():
+ member = self[member_name]
+ ret = None
+ if (not is_link_to_dataset(member.name) and
+ not is_link_to_group(member.name)) or follow_links:
+ ret = func(member.name, member)
+ if ret is not None:
+ return ret
+ # recurse into subgroups
+ if isinstance(self[member_name], SpecH5Group):
+ if not isinstance(self[member_name], SpecH5LinkToGroup) or follow_links:
+ self[member_name].visititems(func, follow_links)
+
+
+class SpecH5LinkToGroup(SpecH5Group):
+ """Special :class:`SpecH5Group` representing a link to a group.
+
+ It works like a regular group but :meth:`SpecH5Group.visit`
+ and :meth:`SpecH5Group.visititems` methods will recognize it as a
+ link and will ignore it.
+
+ An additional attribute indicates the name of the target group:
+ :attr:`target`
+ """
+ def __init__(self, name, specfileh5, target):
+ SpecH5Group.__init__(self, name, specfileh5)
+ self.target = target
+ """Name of the target group."""
+
+ def keys(self):
+ """:return: List of all names of members attached to the target group
+ """
+ # we only have a single type of link to a group:
+ # /1.1/measurement/mca_0/info/ -> /1.1/instrument/mca_0/
+ if measurement_mca_info_pattern.match(self.name):
+ # link_target = self.name.replace("measurement", "instrument").rstrip("/")[:-4]
+ # return SpecH5Group(link_target, self.file).keys()
+ return SpecH5Group(self.target, self.file).keys()
+ else:
+ raise NameError("Unknown link to SpecH5Group: "
+ "%s -> %s" % (self.name, self.target))
+
+
+class SpecH5(SpecH5Group):
+ """Special :class:`SpecH5Group` representing the root of a SpecFile.
+
+ :param filename: Path to SpecFile in filesystem
+ :type filename: str
+
+ In addition to all generic :class:`SpecH5Group` attributes, this class
+ also keeps a reference to the original :class:`SpecFile` object and
+ has a :attr:`filename` attribute.
+
+ Its immediate children are scans, but it also gives access to any group
+ or dataset in the entire SpecFile tree by specifying the full path.
+ """
+ def __init__(self, filename):
+ self.filename = filename
+ self.attrs = _get_attrs_dict("/")
+ self._sf = SpecFile(filename)
+
+ SpecH5Group.__init__(self, name="/", specfileh5=self)
+ if len(self) == 0:
+ # SpecFile library do not raise exception for non specfiles
+ raise IOError("Empty specfile. Not a valid spec format.")
+
+ def keys(self):
+ """
+ :return: List of all scan keys in this SpecFile
+ (e.g. ``["1.1", "2.1"…]``)
+ """
+ return self._sf.keys()
+
+ def __enter__(self):
+ """Context manager enter"""
+ return self
+
+ def __exit__(self, type, value, tb): # pylint: disable=W0622
+ """Context manager exit"""
+ self.close()
+
+ def close(self):
+ """Close the object, and free up associated resources.
+
+ After calling this method, attempts to use the object may fail.
+ """
+ self._sf = None
+
+ def __repr__(self):
+ return '<SpecH5 "%s" (%d members)>' % (self.filename, len(self))
+
+ def __eq__(self, other):
+ return (isinstance(other, SpecH5) and
+ self.filename == other.filename and
+ self.keys() == other.keys())
+
+ @property
+ def h5py_class(self):
+ """h5py class which is mimicked by this class"""
+ if h5py is None:
+ raise ImportError("Cannot return h5py.File class, " +
+ "unable to import h5py module")
+ return h5py.File
diff --git a/silx/io/spectoh5.py b/silx/io/spectoh5.py
new file mode 100644
index 0000000..53988f2
--- /dev/null
+++ b/silx/io/spectoh5.py
@@ -0,0 +1,304 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""This module provides functions to convert a SpecFile into a HDF5 file.
+
+Read the documentation of :mod:`silx.io.spech5` for information on the
+structure of the output HDF5 files.
+
+Strings are written to the HDF5 datasets as fixed-length ASCII (NumPy *S* type).
+This is done in order to produce files that have maximum compatibility with
+other HDF5 libraries, as recommended in the
+`h5py documentation <http://docs.h5py.org/en/latest/strings.html#how-to-store-text-strings>`_.
+
+If you read the files back with *h5py* in Python 3, you will recover strings
+as bytes, which you should decode to transform them into python strings::
+
+ >>> import h5py
+ >>> f = h5py.File("myfile.h5")
+ >>> f["/1.1/instrument/specfile/scan_header"][0]
+ b'#S 94 ascan del -0.5 0.5 20 1'
+ >>> f["/1.1/instrument/specfile/scan_header"][0].decode()
+ '#S 94 ascan del -0.5 0.5 20 1'
+
+Arrays of strings, such as file and scan headers, are stored as fixed-length
+strings. The length of all strings in an array is equal to the length of the
+longest string. Shorter strings are right-padded with blank spaces.
+
+.. note:: This module has a dependency on the `h5py <http://www.h5py.org/>`_
+ library, which is not a mandatory dependency for `silx`. You might need
+ to install it if you don't already have it.
+"""
+
+import numpy
+import logging
+
+_logger = logging.getLogger(__name__)
+
+try:
+ import h5py
+except ImportError as e:
+ _logger.error("Module " + __name__ + " requires h5py")
+ raise e
+
+from .spech5 import SpecH5, SpecH5Group, SpecH5Dataset, \
+ SpecH5LinkToGroup, SpecH5LinkToDataset
+
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "07/02/2017"
+
+
+def _create_link(h5f, link_name, target_name,
+ link_type="hard", overwrite_data=False):
+ """Create a link in a HDF5 file
+
+ If member with name ``link_name`` already exists, delete it first or
+ ignore link depending on global param ``overwrite_data``.
+
+ :param h5f: :class:`h5py.File` object
+ :param link_name: Link path
+ :param target_name: Handle for target group or dataset
+ :param str link_type: "hard" (default) or "soft"
+ :param bool overwrite_data: If True, delete existing member (group,
+ dataset or link) with the same name. Default is False.
+ """
+ if link_name not in h5f:
+ _logger.debug("Creating link " + link_name + " -> " + target_name)
+ elif overwrite_data:
+ _logger.warn("Overwriting " + link_name + " with link to" +
+ target_name)
+ del h5f[link_name]
+ else:
+ _logger.warn(link_name + " already exist. Can't create link to " +
+ target_name)
+ return None
+
+ if link_type == "hard":
+ h5f[link_name] = h5f[target_name]
+ elif link_type == "soft":
+ h5f[link_name] = h5py.SoftLink(target_name)
+ else:
+ raise ValueError("link_type must be 'hard' or 'soft'")
+
+
+class SpecToHdf5Writer(object):
+ """Converter class to write a Spec file to a HDF5 file."""
+ def __init__(self,
+ h5path='/',
+ overwrite_data=False,
+ link_type="hard",
+ create_dataset_args=None):
+ """
+
+ :param h5path: Target path where the scan groups will be written
+ in the output HDF5 file.
+ :param bool overwrite_data:
+ See documentation of :func:`write_spec_to_h5`
+ :param str link_type: ``"hard"`` (default) or ``"soft"``
+ :param dict create_dataset_args: Dictionary of args you want to pass to
+ ``h5py.File.create_dataset``.
+ See documentation of :func:`write_spec_to_h5`
+ """
+ self.h5path = h5path
+
+ self._h5f = None
+ """SpecH5 object, assigned in :meth:`write`"""
+
+ if create_dataset_args is None:
+ create_dataset_args = {}
+ self.create_dataset_args = create_dataset_args
+
+ self.overwrite_data = overwrite_data # boolean
+
+ self.link_type = link_type
+ """'soft' or 'hard' """
+
+ self._links = []
+ """List of *(link_path, target_path)* tuples."""
+
+ def _filter_links(self):
+ """Remove all links that are part of the subtree whose
+ root is a link to a group."""
+ filtered_links = []
+ for i, link in enumerate(self._links):
+ link_is_valid = True
+ link_path, target_path = link
+ other_links = self._links[:i] + self._links[i+1:]
+ for link_path2, target_path2 in other_links:
+ if link_path.startswith(link_path2):
+ # parent group is a link to a group
+ link_is_valid = False
+ break
+ if link_is_valid:
+ filtered_links.append(link)
+ self._links = filtered_links
+
+ def write(self, sfh5, h5f):
+ """Do the conversion from :attr:`sfh5` (Spec file) to *h5f* (HDF5)
+
+ All the parameters needed for the conversion have been initialized
+ in the constructor.
+
+ :param sfh5: :class:`SpecH5` object
+ :param h5f: :class:`h5py.File` instance
+ """
+ # Recurse through all groups and datasets to add them to the HDF5
+ sfh5 = sfh5
+ self._h5f = h5f
+ sfh5.visititems(self.append_spec_member_to_h5, follow_links=True)
+
+ # Handle the attributes of the root group
+ root_grp = h5f[self.h5path]
+ for key in sfh5.attrs:
+ if self.overwrite_data or key not in root_grp.attrs:
+ root_grp.attrs.create(key,
+ numpy.string_(sfh5.attrs[key]))
+
+ # Handle links at the end, when their targets are created
+ self._filter_links()
+ for link_name, target_name in self._links:
+ _create_link(self._h5f, link_name, target_name,
+ link_type=self.link_type,
+ overwrite_data=self.overwrite_data)
+
+ def append_spec_member_to_h5(self, spec_h5_name, obj):
+ """Add one group or one dataset to :attr:`h5f`"""
+ h5_name = self.h5path + spec_h5_name.lstrip("/")
+
+ if isinstance(obj, SpecH5LinkToGroup) or\
+ isinstance(obj, SpecH5LinkToDataset):
+ # links to be created after all groups and datasets
+ h5_target = self.h5path + obj.target.lstrip("/")
+ self._links.append((h5_name, h5_target))
+
+ elif isinstance(obj, SpecH5Dataset):
+ _logger.debug("Saving dataset: " + h5_name)
+
+ member_initially_exists = h5_name in self._h5f
+
+ if self.overwrite_data and member_initially_exists:
+ _logger.warn("Overwriting dataset: " + h5_name)
+ del self._h5f[h5_name]
+
+ if self.overwrite_data or not member_initially_exists:
+ # fancy arguments don't apply to scalars (shape==())
+ if obj.shape == ():
+ ds = self._h5f.create_dataset(h5_name, data=obj.value)
+ else:
+ ds = self._h5f.create_dataset(h5_name, data=obj.value,
+ **self.create_dataset_args)
+
+ # add HDF5 attributes
+ for key in obj.attrs:
+ if self.overwrite_data or key not in ds.attrs:
+ ds.attrs.create(key, numpy.string_(obj.attrs[key]))
+
+ if not self.overwrite_data and member_initially_exists:
+ _logger.warn("Ignoring existing dataset: " + h5_name)
+
+ elif isinstance(obj, SpecH5Group):
+ if h5_name not in self._h5f:
+ _logger.debug("Creating group: " + h5_name)
+ grp = self._h5f.create_group(h5_name)
+ else:
+ grp = self._h5f[h5_name]
+
+ # add HDF5 attributes
+ for key in obj.attrs:
+ if self.overwrite_data or key not in grp.attrs:
+ grp.attrs.create(key, numpy.string_(obj.attrs[key]))
+
+
+def write_spec_to_h5(specfile, h5file, h5path='/',
+ mode="a", overwrite_data=False,
+ link_type="hard", create_dataset_args=None):
+ """Write content of a SpecFile in a HDF5 file.
+
+ :param specfile: Path of input SpecFile or :class:`SpecH5` object
+ :param h5file: Path of output HDF5 file or HDF5 file handle
+ (`h5py.File` object)
+ :param h5path: Target path in HDF5 file in which scan groups are created.
+ Default is root (``"/"``)
+ :param mode: Can be ``"r+"`` (read/write, file must exist),
+ ``"w"`` (write, existing file is lost), ``"w-"`` (write, fail
+ if exists) or ``"a"`` (read/write if exists, create otherwise).
+ This parameter is ignored if ``h5file`` is a file handle.
+ :param overwrite_data: If ``True``, existing groups and datasets can be
+ overwritten, if ``False`` they are skipped. This parameter is only
+ relevant if ``file_mode`` is ``"r+"`` or ``"a"``.
+ :param link_type: ``"hard"`` (default) or ``"soft"``
+ :param create_dataset_args: Dictionary of args you want to pass to
+ ``h5py.File.create_dataset``. This allows you to specify filters and
+ compression parameters. Don't specify ``name`` and ``data``.
+ These arguments don't apply to scalar datasets.
+
+ The structure of the spec data in an HDF5 file is described in the
+ documentation of :mod:`silx.io.spech5`.
+ """
+ if not isinstance(specfile, SpecH5):
+ sfh5 = SpecH5(specfile)
+ else:
+ sfh5 = specfile
+
+ if not h5path.endswith("/"):
+ h5path += "/"
+
+ writer = SpecToHdf5Writer(h5path=h5path,
+ overwrite_data=overwrite_data,
+ link_type=link_type,
+ create_dataset_args=create_dataset_args)
+
+ if not isinstance(h5file, h5py.File):
+ # If h5file is a file path, open and close it
+ with h5py.File(h5file, mode) as h5f:
+ writer.write(sfh5, h5f)
+ else:
+ writer.write(sfh5, h5file)
+
+
+def convert(specfile, h5file, mode="w-",
+ create_dataset_args=None):
+ """Convert a SpecFile into an HDF5 file, write scans into the root (``/``)
+ group.
+
+ :param specfile: Path of input SpecFile or :class:`SpecH5` object
+ :param h5file: Path of output HDF5 file, or h5py.File object
+ :param mode: Can be ``"w"`` (write, existing file is
+ lost), ``"w-"`` (write, fail if exists). This is ignored
+ if ``h5file`` is a file handle.
+ :param create_dataset_args: Dictionary of args you want to pass to
+ ``h5py.File.create_dataset``. This allows you to specify filters and
+ compression parameters. Don't specify ``name`` and ``data``.
+
+ This is a convenience shortcut to call::
+
+ write_spec_to_h5(specfile, h5file, h5path='/',
+ mode="w-", link_type="hard")
+ """
+ if mode not in ["w", "w-"]:
+ raise IOError("File mode must be 'w' or 'w-'. Use write_spec_to_h5" +
+ " to append Spec data to an existing HDF5 file.")
+ write_spec_to_h5(specfile, h5file, h5path='/', mode=mode,
+ create_dataset_args=create_dataset_args)
diff --git a/silx/io/test/__init__.py b/silx/io/test/__init__.py
new file mode 100644
index 0000000..72bd8f9
--- /dev/null
+++ b/silx/io/test/__init__.py
@@ -0,0 +1,53 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "31/08/2016"
+
+import unittest
+
+from .test_specfile import suite as test_specfile_suite
+from .test_specfilewrapper import suite as test_specfilewrapper_suite
+from .test_dictdump import suite as test_dictdump_suite
+from .test_spech5 import suite as test_spech5_suite
+from .test_spectoh5 import suite as test_spectoh5_suite
+from .test_octaveh5 import suite as test_octaveh5_suite
+from .test_fabioh5 import suite as test_fabioh5_suite
+from .test_utils import suite as test_utils_suite
+from .test_nxdata import suite as test_nxdata_suite
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(test_dictdump_suite())
+ test_suite.addTest(test_specfile_suite())
+ test_suite.addTest(test_specfilewrapper_suite())
+ test_suite.addTest(test_spech5_suite())
+ test_suite.addTest(test_spectoh5_suite())
+ test_suite.addTest(test_octaveh5_suite())
+ test_suite.addTest(test_utils_suite())
+ test_suite.addTest(test_fabioh5_suite())
+ test_suite.addTest(test_nxdata_suite())
+ return test_suite
diff --git a/silx/io/test/test_dictdump.py b/silx/io/test/test_dictdump.py
new file mode 100644
index 0000000..15d5fdc
--- /dev/null
+++ b/silx/io/test/test_dictdump.py
@@ -0,0 +1,249 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""Tests for dicttoh5 module"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "10/02/2017"
+
+from collections import OrderedDict
+import numpy
+import os
+import tempfile
+import unittest
+
+try:
+ import h5py
+ h5py_missing = False
+except ImportError:
+ h5py_missing = True
+
+from collections import defaultdict
+
+from ..configdict import ConfigDict
+from ..dictdump import dicttoh5, dicttojson, dicttoini, dump
+from ..dictdump import h5todict, load
+
+
+def tree():
+ """Tree data structure as a recursive nested dictionary"""
+ return defaultdict(tree)
+
+
+city_attrs = tree()
+city_attrs["Europe"]["France"]["Grenoble"]["area"] = "18.44 km2"
+city_attrs["Europe"]["France"]["Grenoble"]["inhabitants"] = 160215
+city_attrs["Europe"]["France"]["Grenoble"]["coordinates"] = [45.1830, 5.7196]
+city_attrs["Europe"]["France"]["Tourcoing"]["area"]
+
+
+@unittest.skipIf(h5py_missing, "Could not import h5py")
+class TestDictToH5(unittest.TestCase):
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp()
+ self.h5_fname = os.path.join(self.tempdir, "cityattrs.h5")
+
+ def tearDown(self):
+ os.unlink(self.h5_fname)
+ os.rmdir(self.tempdir)
+
+ def testH5CityAttrs(self):
+ filters = {'shuffle': True,
+ 'fletcher32': True}
+ dicttoh5(city_attrs, self.h5_fname, h5path='/city attributes',
+ mode="w", create_dataset_args=filters)
+
+ h5f = h5py.File(self.h5_fname)
+
+ self.assertIn("Tourcoing/area", h5f["/city attributes/Europe/France"])
+ ds = h5f["/city attributes/Europe/France/Grenoble/inhabitants"]
+ self.assertEqual(ds[...], 160215)
+
+ # filters only apply to datasets that are not scalars (shape != () )
+ ds = h5f["/city attributes/Europe/France/Grenoble/coordinates"]
+ #self.assertEqual(ds.compression, "gzip")
+ self.assertTrue(ds.fletcher32)
+ self.assertTrue(ds.shuffle)
+
+ h5f.close()
+
+ ddict = load(self.h5_fname, fmat="hdf5")
+ self.assertAlmostEqual(
+ min(ddict["city attributes"]["Europe"]["France"]["Grenoble"]["coordinates"]),
+ 5.7196)
+
+
+@unittest.skipIf(h5py_missing, "Could not import h5py")
+class TestH5ToDict(unittest.TestCase):
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp()
+ self.h5_fname = os.path.join(self.tempdir, "cityattrs.h5")
+ dicttoh5(city_attrs, self.h5_fname)
+
+ def tearDown(self):
+ os.unlink(self.h5_fname)
+ os.rmdir(self.tempdir)
+
+ def testExcludeNames(self):
+ ddict = h5todict(self.h5_fname, path="/Europe/France",
+ exclude_names=["ourcoing", "inhab", "toto"])
+ self.assertNotIn("Tourcoing", ddict)
+ self.assertIn("Grenoble", ddict)
+
+ self.assertNotIn("inhabitants", ddict["Grenoble"])
+ self.assertIn("coordinates", ddict["Grenoble"])
+ self.assertIn("area", ddict["Grenoble"])
+
+
+class TestDictToJson(unittest.TestCase):
+ def setUp(self):
+ self.dir_path = tempfile.mkdtemp()
+ self.json_fname = os.path.join(self.dir_path, "cityattrs.json")
+
+ def tearDown(self):
+ os.unlink(self.json_fname)
+ os.rmdir(self.dir_path)
+
+ def testJsonCityAttrs(self):
+ self.json_fname = os.path.join(self.dir_path, "cityattrs.json")
+ dicttojson(city_attrs, self.json_fname, indent=3)
+
+ with open(self.json_fname, "r") as f:
+ json_content = f.read()
+ self.assertIn('"inhabitants": 160215', json_content)
+
+
+class TestDictToIni(unittest.TestCase):
+ def setUp(self):
+ self.dir_path = tempfile.mkdtemp()
+ self.ini_fname = os.path.join(self.dir_path, "test.ini")
+
+ def tearDown(self):
+ os.unlink(self.ini_fname)
+ os.rmdir(self.dir_path)
+
+ def testConfigDictIO(self):
+ """Ensure values and types of data is preserved when dictionary is
+ written to file and read back."""
+ testdict = {
+ 'simple_types': {
+ 'float': 1.0,
+ 'int': 1,
+ 'percent string': '5 % is too much',
+ 'backslash string': 'i can use \\',
+ 'empty_string': '',
+ 'nonestring': 'None',
+ 'nonetype': None,
+ 'interpstring': 'interpolation: %(percent string)s',
+ },
+ 'containers': {
+ 'list': [-1, 'string', 3.0, False, None],
+ 'array': numpy.array([1.0, 2.0, 3.0]),
+ 'dict': {
+ 'key1': 'Hello World',
+ 'key2': 2.0,
+ }
+ }
+ }
+
+ dump(testdict, self.ini_fname)
+
+ #read the data back
+ readdict = load(self.ini_fname)
+
+ testdictkeys = list(testdict.keys())
+ readkeys = list(readdict.keys())
+
+ self.assertTrue(len(readkeys) == len(testdictkeys),
+ "Number of read keys not equal")
+
+ self.assertEqual(readdict['simple_types']["interpstring"],
+ "interpolation: 5 % is too much")
+
+ testdict['simple_types']["interpstring"] = "interpolation: 5 % is too much"
+
+ for key in testdict["simple_types"]:
+ original = testdict['simple_types'][key]
+ read = readdict['simple_types'][key]
+ self.assertEqual(read, original,
+ "Read <%s> instead of <%s>" % (read, original))
+
+ for key in testdict["containers"]:
+ original = testdict["containers"][key]
+ read = readdict["containers"][key]
+ if key == 'array':
+ self.assertEqual(read.all(), original.all(),
+ "Read <%s> instead of <%s>" % (read, original))
+ else:
+ self.assertEqual(read, original,
+ "Read <%s> instead of <%s>" % (read, original))
+
+ def testConfigDictOrder(self):
+ """Ensure order is preserved when dictionary is
+ written to file and read back."""
+ test_dict = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
+ # sort by key
+ test_ordered_dict1 = OrderedDict(sorted(test_dict.items(),
+ key=lambda t: t[0]))
+ # sort by value
+ test_ordered_dict2 = OrderedDict(sorted(test_dict.items(),
+ key=lambda t: t[1]))
+ # add the two ordered dict as sections of a third ordered dict
+ test_ordered_dict3 = OrderedDict()
+ test_ordered_dict3["section1"] = test_ordered_dict1
+ test_ordered_dict3["section2"] = test_ordered_dict2
+
+ # write to ini and read back as a ConfigDict (inherits OrderedDict)
+ dump(test_ordered_dict3,
+ self.ini_fname, fmat="ini")
+ read_instance = ConfigDict()
+ read_instance.read(self.ini_fname)
+
+ # loop through original and read-back dictionaries,
+ # test identical order for key/value pairs
+ for orig_key, section in zip(test_ordered_dict3.keys(),
+ read_instance.keys()):
+ self.assertEqual(orig_key, section)
+ for orig_key2, read_key in zip(test_ordered_dict3[section].keys(),
+ read_instance[section].keys()):
+ self.assertEqual(orig_key2, read_key)
+ self.assertEqual(test_ordered_dict3[section][orig_key2],
+ read_instance[section][read_key])
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestDictToIni))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestDictToH5))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestDictToJson))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestH5ToDict))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_fabioh5.py b/silx/io/test/test_fabioh5.py
new file mode 100644
index 0000000..c1f4a43
--- /dev/null
+++ b/silx/io/test/test_fabioh5.py
@@ -0,0 +1,236 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""Tests for fabioh5 wrapper"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "11/04/2017"
+
+import logging
+import numpy
+import unittest
+
+_logger = logging.getLogger(__name__)
+
+
+try:
+ import fabio
+except ImportError:
+ fabio = None
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+if fabio is not None and h5py is not None:
+ from .. import fabioh5
+
+
+class TestFabioH5(unittest.TestCase):
+
+ def setUp(self):
+ if fabio is None:
+ self.skipTest("fabio is needed")
+ if h5py is None:
+ self.skipTest("h5py is needed")
+
+ header = {
+ "integer": "-100",
+ "float": "1.0",
+ "string": "hi!",
+ "list_integer": "100 50 0",
+ "list_float": "1.0 2.0 3.5",
+ "string_looks_like_list": "2000 hi!",
+ }
+ data = numpy.array([[10, 11], [12, 13], [14, 15]], dtype=numpy.int64)
+ self.fabio_image = fabio.numpyimage.NumpyImage(data, header)
+ self.h5_image = fabioh5.File(fabio_image=self.fabio_image)
+
+ def test_main_groups(self):
+ self.assertEquals(self.h5_image.h5py_class, h5py.File)
+ self.assertEquals(self.h5_image["/"].h5py_class, h5py.File)
+ self.assertEquals(self.h5_image["/scan_0"].h5py_class, h5py.Group)
+ self.assertEquals(self.h5_image["/scan_0/instrument"].h5py_class, h5py.Group)
+ self.assertEquals(self.h5_image["/scan_0/measurement"].h5py_class, h5py.Group)
+
+ def test_wrong_path_syntax(self):
+ # result tested with a default h5py file
+ self.assertRaises(ValueError, lambda: self.h5_image[""])
+
+ def test_wrong_root_name(self):
+ # result tested with a default h5py file
+ self.assertRaises(KeyError, lambda: self.h5_image["/foo"])
+
+ def test_wrong_root_path(self):
+ # result tested with a default h5py file
+ self.assertRaises(KeyError, lambda: self.h5_image["/foo/foo"])
+
+ def test_wrong_name(self):
+ # result tested with a default h5py file
+ self.assertRaises(KeyError, lambda: self.h5_image["foo"])
+
+ def test_wrong_path(self):
+ # result tested with a default h5py file
+ self.assertRaises(KeyError, lambda: self.h5_image["foo/foo"])
+
+ def test_frames(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/data"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertTrue(isinstance(dataset[()], numpy.ndarray))
+ self.assertEquals(dataset.dtype.kind, "i")
+ self.assertEquals(dataset.shape, (1, 3, 2))
+ self.assertEquals(dataset.attrs["interpretation"], "image")
+
+ def test_metadata_int(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/integer"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset[()], -100)
+ self.assertEquals(dataset.dtype.kind, "i")
+ self.assertEquals(dataset.shape, (1,))
+
+ def test_metadata_float(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/float"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset[()], 1.0)
+ self.assertEquals(dataset.dtype.kind, "f")
+ self.assertEquals(dataset.shape, (1,))
+
+ def test_metadata_string(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/string"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset[()], numpy.string_("hi!"))
+ self.assertEquals(dataset.dtype.type, numpy.string_)
+ self.assertEquals(dataset.shape, (1,))
+
+ def test_metadata_list_integer(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/list_integer"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset.dtype.kind, "u")
+ self.assertEquals(dataset.shape, (1, 3))
+ self.assertEquals(dataset[0, 0], 100)
+ self.assertEquals(dataset[0, 1], 50)
+
+ def test_metadata_list_float(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/list_float"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset.dtype.kind, "f")
+ self.assertEquals(dataset.shape, (1, 3))
+ self.assertEquals(dataset[0, 0], 1.0)
+ self.assertEquals(dataset[0, 1], 2.0)
+
+ def test_metadata_list_looks_like_list(self):
+ dataset = self.h5_image["/scan_0/instrument/detector_0/others/string_looks_like_list"]
+ self.assertEquals(dataset.h5py_class, h5py.Dataset)
+ self.assertEquals(dataset[()], numpy.string_("2000 hi!"))
+ self.assertEquals(dataset.dtype.type, numpy.string_)
+ self.assertEquals(dataset.shape, (1,))
+
+ def test_float_32(self):
+ float_list = [u'1.2', u'1.3', u'1.4']
+ data = numpy.array([[0, 0], [0, 0]], dtype=numpy.int8)
+ fabio_image = None
+ for float_item in float_list:
+ header = {"float_item": float_item}
+ if fabio_image is None:
+ fabio_image = fabio.edfimage.EdfImage(data=data, header=header)
+ else:
+ fabio_image.appendFrame(data=data, header=header)
+ h5_image = fabioh5.File(fabio_image=fabio_image)
+ data = h5_image["/scan_0/instrument/detector_0/others/float_item"]
+ # There is no equality between items
+ self.assertEqual(len(data), len(set(data)))
+ # At worst a float32
+ self.assertIn(data.dtype.char, ['d', 'f'])
+ self.assertLessEqual(data.dtype.itemsize, 32 / 8)
+
+ def test_float_64(self):
+ float_list = [
+ u'1469117129.082226',
+ u'1469117136.684986', u'1469117144.312749', u'1469117151.892507',
+ u'1469117159.474265', u'1469117167.100027', u'1469117174.815799',
+ u'1469117182.437561', u'1469117190.094326', u'1469117197.721089']
+ data = numpy.array([[0, 0], [0, 0]], dtype=numpy.int8)
+ fabio_image = None
+ for float_item in float_list:
+ header = {"time_of_day": float_item}
+ if fabio_image is None:
+ fabio_image = fabio.edfimage.EdfImage(data=data, header=header)
+ else:
+ fabio_image.appendFrame(data=data, header=header)
+ h5_image = fabioh5.File(fabio_image=fabio_image)
+ data = h5_image["/scan_0/instrument/detector_0/others/time_of_day"]
+ # There is no equality between items
+ self.assertEqual(len(data), len(set(data)))
+ # At least a float64
+ self.assertIn(data.dtype.char, ['d', 'f'])
+ self.assertGreaterEqual(data.dtype.itemsize, 64 / 8)
+
+ def test_ub_matrix(self):
+ """Data from mediapix.edf"""
+ header = {}
+ header["UB_mne"] = 'UB0 UB1 UB2 UB3 UB4 UB5 UB6 UB7 UB8'
+ header["UB_pos"] = '1.99593e-16 2.73682e-16 -1.54 -1.08894 1.08894 1.6083e-16 1.08894 1.08894 9.28619e-17'
+ header["sample_mne"] = 'U0 U1 U2 U3 U4 U5'
+ header["sample_pos"] = '4.08 4.08 4.08 90 90 90'
+ data = numpy.array([[0, 0], [0, 0]], dtype=numpy.int8)
+ fabio_image = fabio.edfimage.EdfImage(data=data, header=header)
+ h5_image = fabioh5.File(fabio_image=fabio_image)
+ sample = h5_image["/scan_0/sample"]
+ self.assertIsNotNone(sample)
+ self.assertEquals(sample.attrs["NXclass"], "NXsample")
+
+ d = sample['unit_cell_abc']
+ expected = numpy.array([4.08, 4.08, 4.08])
+ self.assertIsNotNone(d)
+ self.assertEquals(d.shape, (3, ))
+ self.assertIn(d.dtype.char, ['d', 'f'])
+ numpy.testing.assert_array_almost_equal(d[...], expected)
+
+ d = sample['unit_cell_alphabetagamma']
+ expected = numpy.array([90.0, 90.0, 90.0])
+ self.assertIsNotNone(d)
+ self.assertEquals(d.shape, (3, ))
+ self.assertIn(d.dtype.char, ['d', 'f'])
+ numpy.testing.assert_array_almost_equal(d[...], expected)
+
+ d = sample['ub_matrix']
+ expected = numpy.array([[[1.99593e-16, 2.73682e-16, -1.54],
+ [-1.08894, 1.08894, 1.6083e-16],
+ [1.08894, 1.08894, 9.28619e-17]]])
+ self.assertIsNotNone(d)
+ self.assertEquals(d.shape, (1, 3, 3))
+ self.assertIn(d.dtype.char, ['d', 'f'])
+ numpy.testing.assert_array_almost_equal(d[...], expected)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestFabioH5))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_nxdata.py b/silx/io/test/test_nxdata.py
new file mode 100644
index 0000000..caa8c1e
--- /dev/null
+++ b/silx/io/test/test_nxdata.py
@@ -0,0 +1,305 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""Tests for NXdata parsing"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "27/09/2016"
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+import numpy
+import tempfile
+import unittest
+from .. import nxdata
+
+
+@unittest.skipIf(h5py is None, "silx.io.nxdata tests depend on h5py")
+class TestNXdata(unittest.TestCase):
+ def setUp(self):
+ tmp = tempfile.NamedTemporaryFile(prefix="nxdata_examples_", suffix=".h5", delete=True)
+ tmp.file.close()
+ self.h5fname = tmp.name
+ self.h5f = h5py.File(tmp.name, "w")
+
+ # SCALARS
+ g0d = self.h5f.create_group("scalars")
+
+ g0d0 = g0d.create_group("0D_scalar")
+ g0d0.attrs["NX_class"] = "NXdata"
+ g0d0.attrs["signal"] = "scalar"
+ g0d0.create_dataset("scalar", data=10)
+
+ g0d1 = g0d.create_group("2D_scalars")
+ g0d1.attrs["NX_class"] = "NXdata"
+ g0d1.attrs["signal"] = "scalars"
+ ds = g0d1.create_dataset("scalars", data=numpy.arange(3 * 10).reshape((3, 10)))
+ ds.attrs["interpretation"] = "scalar"
+
+ g0d1 = g0d.create_group("4D_scalars")
+ g0d1.attrs["NX_class"] = "NXdata"
+ g0d1.attrs["signal"] = "scalars"
+ ds = g0d1.create_dataset("scalars", data=numpy.arange(2 * 2 * 3 * 10).reshape((2, 2, 3, 10)))
+ ds.attrs["interpretation"] = "scalar"
+
+ # SPECTRA
+ g1d = self.h5f.create_group("spectra")
+
+ g1d0 = g1d.create_group("1D_spectrum")
+ g1d0.attrs["NX_class"] = "NXdata"
+ g1d0.attrs["signal"] = "count"
+ g1d0.attrs["axes"] = "energy_calib"
+ g1d0.attrs["uncertainties"] = b"energy_errors",
+ g1d0.create_dataset("count", data=numpy.arange(10))
+ g1d0.create_dataset("energy_calib", data=(10, 5)) # 10 * idx + 5
+ g1d0.create_dataset("energy_errors", data=3.14 * numpy.random.rand(10))
+
+ g1d1 = g1d.create_group("2D_spectra")
+ g1d1.attrs["NX_class"] = "NXdata"
+ g1d1.attrs["signal"] = "counts"
+ ds = g1d1.create_dataset("counts", data=numpy.arange(3 * 10).reshape((3, 10)))
+ ds.attrs["interpretation"] = "spectrum"
+
+ g1d2 = g1d.create_group("4D_spectra")
+ g1d2.attrs["NX_class"] = "NXdata"
+ g1d2.attrs["signal"] = "counts"
+ g1d2.attrs["axes"] = b"energy",
+ ds = g1d2.create_dataset("counts", data=numpy.arange(2 * 2 * 3 * 10).reshape((2, 2, 3, 10)))
+ ds.attrs["interpretation"] = "spectrum"
+ ds = g1d2.create_dataset("errors", data=4.5 * numpy.random.rand(2, 2, 3, 10))
+ ds = g1d2.create_dataset("energy", data=5 + 10 * numpy.arange(15),
+ shuffle=True, compression="gzip")
+ ds.attrs["long_name"] = "Calibrated energy"
+ ds.attrs["first_good"] = 3
+ ds.attrs["last_good"] = 12
+ g1d2.create_dataset("energy_errors", data=10 * numpy.random.rand(15))
+
+ # IMAGES
+ g2d = self.h5f.create_group("images")
+
+ g2d0 = g2d.create_group("2D_regular_image")
+ g2d0.attrs["NX_class"] = "NXdata"
+ g2d0.attrs["signal"] = "image"
+ g2d0.attrs["axes"] = b"rows_calib", b"columns_coordinates"
+ g2d0.create_dataset("image", data=numpy.arange(4 * 6).reshape((4, 6)))
+ ds = g2d0.create_dataset("rows_calib", data=(10, 5))
+ ds.attrs["long_name"] = "Calibrated Y"
+ g2d0.create_dataset("columns_coordinates", data=0.5 + 0.02 * numpy.arange(6))
+
+ g2d1 = g2d.create_group("2D_irregular_data")
+ g2d1.attrs["NX_class"] = "NXdata"
+ g2d1.attrs["signal"] = "data"
+ g2d1.attrs["axes"] = b"rows_coordinates", b"columns_coordinates"
+ g2d1.create_dataset("data", data=numpy.arange(64 * 128).reshape((64, 128)))
+ g2d1.create_dataset("rows_coordinates", data=numpy.arange(64) + numpy.random.rand(64))
+ g2d1.create_dataset("columns_coordinates", data=numpy.arange(128) + 2.5 * numpy.random.rand(128))
+
+ g2d2 = g2d.create_group("3D_images")
+ g2d2.attrs["NX_class"] = "NXdata"
+ g2d2.attrs["signal"] = "images"
+ ds = g2d2.create_dataset("images", data=numpy.arange(2 * 4 * 6).reshape((2, 4, 6)))
+ ds.attrs["interpretation"] = "image"
+
+ g2d3 = g2d.create_group("5D_images")
+ g2d3.attrs["NX_class"] = "NXdata"
+ g2d3.attrs["signal"] = "images"
+ g2d3.attrs["axes"] = b"rows_coordinates", b"columns_coordinates"
+ ds = g2d3.create_dataset("images", data=numpy.arange(2 * 2 * 2 * 4 * 6).reshape((2, 2, 2, 4, 6)))
+ ds.attrs["interpretation"] = "image"
+ g2d3.create_dataset("rows_coordinates", data=5 + 10 * numpy.arange(4))
+ g2d3.create_dataset("columns_coordinates", data=0.5 + 0.02 * numpy.arange(6))
+
+ # SCATTER
+ g = self.h5f.create_group("scatters")
+
+ gd0 = g.create_group("x_y_scatter")
+ gd0.attrs["NX_class"] = "NXdata"
+ gd0.attrs["signal"] = "y"
+ gd0.attrs["axes"] = b"x",
+ gd0.create_dataset("y", data=numpy.random.rand(128) - 0.5)
+ gd0.create_dataset("x", data=2 * numpy.random.rand(128))
+ gd0.create_dataset("x_errors", data=0.05 * numpy.random.rand(128))
+ gd0.create_dataset("errors", data=0.05 * numpy.random.rand(128))
+
+ gd1 = g.create_group("x_y_value_scatter")
+ gd1.attrs["NX_class"] = "NXdata"
+ gd1.attrs["signal"] = "values"
+ gd1.attrs["axes"] = b"x", b"y"
+ gd1.create_dataset("values", data=3.14 * numpy.random.rand(128))
+ gd1.create_dataset("y", data=numpy.random.rand(128))
+ gd1.create_dataset("y_errors", data=0.02 * numpy.random.rand(128))
+ gd1.create_dataset("x", data=numpy.random.rand(128))
+ gd1.create_dataset("x_errors", data=0.02 * numpy.random.rand(128))
+
+ def tearDown(self):
+ self.h5f.close()
+
+ def testValidity(self):
+ for group in self.h5f:
+ for subgroup in self.h5f[group]:
+ self.assertTrue(
+ nxdata.is_valid_nxdata(self.h5f[group][subgroup]),
+ "%s/%s not found to be a valid NXdata group" % (group, subgroup))
+
+ def testScalars(self):
+ nxd = nxdata.NXdata(self.h5f["scalars/0D_scalar"])
+ self.assertTrue(nxd.signal_is_0d)
+ self.assertEqual(nxd.signal[()], 10)
+ self.assertEqual(nxd.axes_names, [])
+ self.assertEqual(nxd.axes_dataset_names, [])
+ self.assertEqual(nxd.axes, [])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["scalars/2D_scalars"])
+ self.assertTrue(nxd.signal_is_2d)
+ self.assertEqual(nxd.signal[1, 2], 12)
+ self.assertEqual(nxd.axes_names, [None, None])
+ self.assertEqual(nxd.axes_dataset_names, [None, None])
+ self.assertEqual(nxd.axes, [None, None])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "scalar")
+
+ nxd = nxdata.NXdata(self.h5f["scalars/4D_scalars"])
+ self.assertFalse(nxd.signal_is_0d or nxd.signal_is_1d or
+ nxd.signal_is_2d or nxd.signal_is_3d)
+ self.assertEqual(nxd.signal[1, 0, 1, 4], 74)
+ self.assertEqual(nxd.axes_names, [None, None, None, None])
+ self.assertEqual(nxd.axes_dataset_names, [None, None, None, None])
+ self.assertEqual(nxd.axes, [None, None, None, None])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "scalar")
+
+ def testSpectra(self):
+ nxd = nxdata.NXdata(self.h5f["spectra/1D_spectrum"])
+ self.assertTrue(nxd.signal_is_1d)
+ self.assertTrue(numpy.array_equal(numpy.array(nxd.signal),
+ numpy.arange(10)))
+ self.assertEqual(nxd.axes_names, ["energy_calib"])
+ self.assertEqual(nxd.axes_dataset_names, ["energy_calib"])
+ self.assertEqual(nxd.axes[0][0], 10)
+ self.assertEqual(nxd.axes[0][1], 5)
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["spectra/2D_spectra"])
+ self.assertTrue(nxd.signal_is_2d)
+ self.assertEqual(nxd.axes_names, [None, None])
+ self.assertEqual(nxd.axes_dataset_names, [None, None])
+ self.assertEqual(nxd.axes, [None, None])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "spectrum")
+
+ nxd = nxdata.NXdata(self.h5f["spectra/4D_spectra"])
+ self.assertFalse(nxd.signal_is_0d or nxd.signal_is_1d or
+ nxd.signal_is_2d or nxd.signal_is_3d)
+ self.assertEqual(nxd.axes_names,
+ [None, None, None, "Calibrated energy"])
+ self.assertEqual(nxd.axes_dataset_names,
+ [None, None, None, "energy"])
+ self.assertEqual(nxd.axes[:3], [None, None, None])
+ self.assertEqual(nxd.axes[3].shape, (10, )) # dataset shape (15, ) sliced [3:12]
+ self.assertIsNotNone(nxd.errors)
+ self.assertEqual(nxd.errors.shape, (2, 2, 3, 10))
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "spectrum")
+
+ def testImages(self):
+ nxd = nxdata.NXdata(self.h5f["images/2D_regular_image"])
+ self.assertTrue(nxd.signal_is_2d)
+ self.assertEqual(nxd.axes_names, ["Calibrated Y", "columns_coordinates"])
+ self.assertEqual(list(nxd.axes_dataset_names),
+ ["rows_calib", "columns_coordinates"])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["images/2D_irregular_data"])
+ self.assertTrue(nxd.signal_is_2d)
+
+ self.assertEqual(nxd.axes_dataset_names, nxd.axes_names)
+ self.assertEqual(list(nxd.axes_dataset_names),
+ ["rows_coordinates", "columns_coordinates"])
+ self.assertEqual(len(nxd.axes), 2)
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["images/5D_images"])
+ self.assertFalse(nxd.signal_is_0d or nxd.signal_is_1d or
+ nxd.signal_is_2d or nxd.signal_is_3d)
+ self.assertEqual(nxd.axes_names,
+ [None, None, None, 'rows_coordinates', 'columns_coordinates'])
+ self.assertEqual(nxd.axes_dataset_names,
+ [None, None, None, 'rows_coordinates', 'columns_coordinates'])
+ self.assertIsNone(nxd.errors)
+ self.assertFalse(nxd.is_scatter or nxd.is_x_y_value_scatter)
+ self.assertEqual(nxd.interpretation, "image")
+
+ def testScatters(self):
+ nxd = nxdata.NXdata(self.h5f["scatters/x_y_scatter"])
+ self.assertTrue(nxd.signal_is_1d)
+ self.assertEqual(nxd.axes_names, ["x"])
+ self.assertEqual(nxd.axes_dataset_names,
+ ["x"])
+ self.assertIsNotNone(nxd.errors)
+ self.assertEqual(nxd.get_axis_errors("x").shape,
+ (128, ))
+ self.assertTrue(nxd.is_scatter)
+ self.assertFalse(nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+ nxd = nxdata.NXdata(self.h5f["scatters/x_y_value_scatter"])
+ self.assertFalse(nxd.signal_is_1d)
+ self.assertTrue(nxd.axes_dataset_names,
+ nxd.axes_names)
+ self.assertEqual(nxd.axes_dataset_names,
+ ["x", "y"])
+ self.assertEqual(nxd.get_axis_errors("x").shape,
+ (128, ))
+ self.assertEqual(nxd.get_axis_errors("y").shape,
+ (128, ))
+ self.assertEqual(len(nxd.axes), 2)
+ self.assertIsNone(nxd.errors)
+ self.assertTrue(nxd.is_scatter)
+ self.assertTrue(nxd.is_x_y_value_scatter)
+ self.assertIsNone(nxd.interpretation)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestNXdata))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_octaveh5.py b/silx/io/test/test_octaveh5.py
new file mode 100644
index 0000000..2e65820
--- /dev/null
+++ b/silx/io/test/test_octaveh5.py
@@ -0,0 +1,165 @@
+# 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.
+#
+# ############################################################################*/
+"""
+Tests for the octaveh5 module
+"""
+
+__authors__ = ["C. Nemoz", "H. Payno"]
+__license__ = "MIT"
+__date__ = "12/07/2016"
+
+import unittest
+import os
+import tempfile
+
+try:
+ from ..octaveh5 import Octaveh5
+except ImportError:
+ Octaveh5 = None
+
+
+@unittest.skipIf(Octaveh5 is None, "Could not import h5py")
+class TestOctaveH5(unittest.TestCase):
+ @staticmethod
+ def _get_struct_FT():
+ return {
+ 'NO_CHECK': 0.0, 'SHOWSLICE': 1.0, 'DOTOMO': 1.0, 'DATABASE': 0.0, 'ANGLE_OFFSET': 0.0,
+ 'VOLSELECTION_REMEMBER': 0.0, 'NUM_PART': 4.0, 'VOLOUTFILE': 0.0, 'RINGSCORRECTION': 0.0,
+ 'DO_TEST_SLICE': 1.0, 'ZEROOFFMASK': 1.0, 'VERSION': 'fastomo3 version 2.0',
+ 'CORRECT_SPIKES_THRESHOLD': 0.040000000000000001, 'SHOWPROJ': 0.0, 'HALF_ACQ': 0.0,
+ 'ANGLE_OFFSET_VALUE': 0.0, 'FIXEDSLICE': 'middle', 'VOLSELECT': 'total' }
+ @staticmethod
+ def _get_struct_PYHSTEXE():
+ return {
+ 'EXE': 'PyHST2_2015d', 'VERBOSE': 0.0, 'OFFV': 'PyHST2_2015d', 'TOMO': 0.0,
+ 'VERBOSE_FILE': 'pyhst_out.txt', 'DIR': '/usr/bin/', 'OFFN': 'pyhst2'}
+
+ @staticmethod
+ def _get_struct_FTAXIS():
+ return {
+ 'POSITION_VALUE': 12345.0, 'COR_ERROR': 0.0, 'FILESDURINGSCAN': 0.0, 'PLOTFIGURE': 1.0,
+ 'DIM1': 0.0, 'OVERSAMPLING': 5.0, 'TO_THE_CENTER': 1.0, 'POSITION': 'fixed',
+ 'COR_POSITION': 0.0, 'HA': 0.0 }
+
+ @staticmethod
+ def _get_struct_PAGANIN():
+ return {
+ 'MKEEP_MASK': 0.0, 'UNSHARP_SIGMA': 0.80000000000000004, 'DILATE': 2.0, 'UNSHARP_COEFF': 3.0,
+ 'MEDIANR': 4.0, 'DB': 500.0, 'MKEEP_ABS': 0.0, 'MODE': 0.0, 'THRESHOLD': 0.5,
+ 'MKEEP_BONE': 0.0, 'DB2': 100.0, 'MKEEP_CORR': 0.0, 'MKEEP_SOFT': 0.0 }
+
+ @staticmethod
+ def _get_struct_BEAMGEO():
+ return {'DIST': 55.0, 'SY': 0.0, 'SX': 0.0, 'TYPE': 'p'}
+
+
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp()
+ self.test_3_6_fname = os.path.join(self.tempdir, "silx_tmp_t00_octaveTest_3_6.h5")
+ self.test_3_8_fname = os.path.join(self.tempdir, "silx_tmp_t00_octaveTest_3_8.h5")
+
+ def tearDown(self):
+ if os.path.isfile(self.test_3_6_fname):
+ os.unlink(self.test_3_6_fname)
+ if os.path.isfile(self.test_3_8_fname):
+ os.unlink(self.test_3_8_fname)
+
+ def testWritedIsReaded(self):
+ """
+ Simple test to write and reaf the structure compatible with the octave h5 using structure.
+ This test is for # test for octave version > 3.8
+ """
+ writer = Octaveh5()
+
+ writer.open(self.test_3_8_fname, 'a')
+ # step 1 writing the file
+ writer.write('FT', self._get_struct_FT())
+ writer.write('PYHSTEXE', self._get_struct_PYHSTEXE())
+ writer.write('FTAXIS', self._get_struct_FTAXIS())
+ writer.write('PAGANIN', self._get_struct_PAGANIN())
+ writer.write('BEAMGEO', self._get_struct_BEAMGEO())
+ writer.close()
+
+ # step 2 reading the file
+ reader = Octaveh5().open(self.test_3_8_fname)
+ # 2.1 check FT
+ data_readed = reader.get('FT')
+ self.assertEqual(data_readed, self._get_struct_FT() )
+ # 2.2 check PYHSTEXE
+ data_readed = reader.get('PYHSTEXE')
+ self.assertEqual(data_readed, self._get_struct_PYHSTEXE() )
+ # 2.3 check FTAXIS
+ data_readed = reader.get('FTAXIS')
+ self.assertEqual(data_readed, self._get_struct_FTAXIS() )
+ # 2.4 check PAGANIN
+ data_readed = reader.get('PAGANIN')
+ self.assertEqual(data_readed, self._get_struct_PAGANIN() )
+ # 2.5 check BEAMGEO
+ data_readed = reader.get('BEAMGEO')
+ self.assertEqual(data_readed, self._get_struct_BEAMGEO() )
+ reader.close()
+
+ def testWritedIsReadedOldOctaveVersion(self):
+ """The same test as testWritedIsReaded but for octave version < 3.8
+ """
+ # test for octave version < 3.8
+ writer = Octaveh5(3.6)
+
+ writer.open(self.test_3_6_fname, 'a')
+
+ # step 1 writing the file
+ writer.write('FT', self._get_struct_FT())
+ writer.write('PYHSTEXE', self._get_struct_PYHSTEXE())
+ writer.write('FTAXIS', self._get_struct_FTAXIS())
+ writer.write('PAGANIN', self._get_struct_PAGANIN())
+ writer.write('BEAMGEO', self._get_struct_BEAMGEO())
+ writer.close()
+
+ # step 2 reading the file
+ reader = Octaveh5(3.6).open(self.test_3_6_fname)
+ # 2.1 check FT
+ data_readed = reader.get('FT')
+ self.assertEqual(data_readed, self._get_struct_FT() )
+ # 2.2 check PYHSTEXE
+ data_readed = reader.get('PYHSTEXE')
+ self.assertEqual(data_readed, self._get_struct_PYHSTEXE() )
+ # 2.3 check FTAXIS
+ data_readed = reader.get('FTAXIS')
+ self.assertEqual(data_readed, self._get_struct_FTAXIS() )
+ # 2.4 check PAGANIN
+ data_readed = reader.get('PAGANIN')
+ self.assertEqual(data_readed, self._get_struct_PAGANIN() )
+ # 2.5 check BEAMGEO
+ data_readed = reader.get('BEAMGEO')
+ self.assertEqual(data_readed, self._get_struct_BEAMGEO() )
+ reader.close()
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestOctaveH5))
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_specfile.py b/silx/io/test/test_specfile.py
new file mode 100644
index 0000000..884cb04
--- /dev/null
+++ b/silx/io/test/test_specfile.py
@@ -0,0 +1,431 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""Tests for specfile wrapper"""
+
+__authors__ = ["P. Knobel", "V.A. Sole"]
+__license__ = "MIT"
+__date__ = "24/04/2017"
+
+import gc
+import locale
+import logging
+import numpy
+import os
+import sys
+import tempfile
+import unittest
+
+logging.basicConfig()
+logger1 = logging.getLogger(__name__)
+
+from ..specfile import SpecFile, Scan
+from .. import specfile
+
+sftext = """#F /tmp/sf.dat
+#E 1455180875
+#D Thu Feb 11 09:54:35 2016
+#C imaging User = opid17
+#U00 user comment first line
+#U01 This is a dummy file to test SpecFile parsing
+#U02
+#U03 last line
+
+#O0 Pslit HGap MRTSlit UP MRTSlit DOWN
+#O1 Sslit1 VOff Sslit1 HOff Sslit1 VGap
+#o0 pshg mrtu mrtd
+#o2 ss1vo ss1ho ss1vg
+
+#J0 Seconds IA ion.mono Current
+#J1 xbpmc2 idgap1 Inorm
+
+#S 1 ascan ss1vo -4.55687 -0.556875 40 0.2
+#D Thu Feb 11 09:55:20 2016
+#T 0.2 (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 0 0
+#G3 0 0 0 0 0 0 0 0 0
+#G4 0
+#Q
+#P0 180.005 -0.66875 0.87125
+#P1 14.74255 16.197579 12.238283
+#UMI0 Current AutoM Shutter
+#UMI1 192.51 OFF FE open
+#UMI2 Refill in 39883 sec, Fill Mode: uniform multibunch / Message: Feb 11 08:00 Delivery:Next Refill at 21:00;
+#N 4
+#L first column 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 Thu Feb 11 10:00:31 2016
+#P0 80.005 -1.66875 1.87125
+#P1 4.74255 6.197579 2.238283
+#N 5
+#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 26 yyyyyy
+#D Thu Feb 11 09:55:20 2016
+#P0 80.005 -1.66875 1.87125
+#P1 4.74255 6.197579 2.238283
+#N 4
+#L first column second column 3rd_col
+#C Sat Oct 31 15:51:47 1998. Scan aborted after 0 points.
+
+#F /tmp/sf.dat
+#E 1455180876
+#D Thu Feb 11 09:54:36 2016
+
+#S 1 aaaaaa
+#U first duplicate line
+#U second duplicate line
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+3 4
+@A 3.1 4 5
+5 6
+@A 6 7.7 8
+"""
+
+
+loc = locale.getlocale(locale.LC_NUMERIC)
+try:
+ locale.setlocale(locale.LC_NUMERIC, 'de_DE.utf8')
+except locale.Error:
+ try_DE = False
+else:
+ try_DE = True
+ locale.setlocale(locale.LC_NUMERIC, loc)
+
+
+class TestSpecFile(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname1 = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ fd2, cls.fname2 = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd2, sftext[370:923])
+ else:
+ os.write(fd2, bytes(sftext[370:923], 'ascii'))
+ os.close(fd2)
+
+ fd3, cls.fname3 = tempfile.mkstemp(text=False)
+ txt = sftext[371:923]
+ if sys.version < '3.0':
+ os.write(fd3, txt)
+ else:
+ os.write(fd3, bytes(txt, 'ascii'))
+ os.close(fd3)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname1)
+ os.unlink(cls.fname2)
+ os.unlink(cls.fname3)
+
+ def setUp(self):
+ self.sf = SpecFile(self.fname1)
+ self.scan1 = self.sf[0]
+ self.scan1_2 = self.sf["1.2"]
+ self.scan25 = self.sf["25.1"]
+ self.empty_scan = self.sf["26.1"]
+
+ self.sf_no_fhdr = SpecFile(self.fname2)
+ self.scan1_no_fhdr = self.sf_no_fhdr[0]
+
+ self.sf_no_fhdr_crash = SpecFile(self.fname3)
+ self.scan1_no_fhdr_crash = self.sf_no_fhdr_crash[0]
+
+ def tearDown(self):
+ del self.sf
+ del self.sf_no_fhdr
+ del self.scan1
+ del self.scan1_2
+ del self.scan25
+ del self.scan1_no_fhdr
+ del self.sf_no_fhdr_crash
+ del self.scan1_no_fhdr_crash
+ del self.empty_scan
+ gc.collect()
+
+ def test_open(self):
+ self.assertIsInstance(self.sf, SpecFile)
+ with self.assertRaises(specfile.SfErrFileOpen):
+ sf2 = SpecFile("doesnt_exist.dat")
+
+ # test filename types unicode and bytes
+ if sys.version_info[0] < 3:
+ try:
+ SpecFile(self.fname1)
+ except TypeError:
+ self.fail("failed to handle filename as python2 str")
+ try:
+ SpecFile(unicode(self.fname1))
+ except TypeError:
+ self.fail("failed to handle filename as python2 unicode")
+ else:
+ try:
+ SpecFile(self.fname1)
+ except TypeError:
+ self.fail("failed to handle filename as python3 str")
+ try:
+ SpecFile(bytes(self.fname1, 'utf-8'))
+ except TypeError:
+ self.fail("failed to handle filename as python3 bytes")
+
+ def test_number_of_scans(self):
+ self.assertEqual(4, len(self.sf))
+
+ def test_list_of_scan_indices(self):
+ self.assertEqual(self.sf.list(),
+ [1, 25, 26, 1])
+ self.assertEqual(self.sf.keys(),
+ ["1.1", "25.1", "26.1", "1.2"])
+
+ def test_index_number_order(self):
+ self.assertEqual(self.sf.index(1, 2), 3) #sf["1.2"]==sf[3]
+ self.assertEqual(self.sf.number(1), 25) #sf[1]==sf["25"]
+ self.assertEqual(self.sf.order(3), 2) #sf[3]==sf["1.2"]
+ with self.assertRaises(specfile.SfErrScanNotFound):
+ self.sf.index(3, 2)
+ with self.assertRaises(specfile.SfErrScanNotFound):
+ self.sf.index(99)
+
+ def test_getitem(self):
+ self.assertIsInstance(self.sf[2], Scan)
+ self.assertIsInstance(self.sf["1.2"], Scan)
+ # int out of range
+ with self.assertRaisesRegexp(IndexError, 'Scan index must be in ran'):
+ self.sf[107]
+ # float indexing not allowed
+ with self.assertRaisesRegexp(TypeError, 'The scan identification k'):
+ self.sf[1.2]
+ # non existant scan with "N.M" indexing
+ with self.assertRaises(KeyError):
+ self.sf["3.2"]
+
+ def test_specfile_iterator(self):
+ i=0
+ for scan in self.sf:
+ if i == 1:
+ self.assertEqual(scan.motor_positions,
+ self.sf[1].motor_positions)
+ i += 1
+ # number of returned scans
+ self.assertEqual(i, len(self.sf))
+
+ def test_scan_index(self):
+ self.assertEqual(self.scan1.index, 0)
+ self.assertEqual(self.scan1_2.index, 3)
+ self.assertEqual(self.scan25.index, 1)
+
+ def test_scan_headers(self):
+ self.assertEqual(self.scan25.scan_header_dict['S'],
+ "25 ascan c3th 1.33245 1.52245 40 0.15")
+ self.assertEqual(self.scan1.header[17], '#G0 0')
+ self.assertEqual(len(self.scan1.header), 29)
+ # parsing headers with long keys
+ self.assertEqual(self.scan1.scan_header_dict['UMI0'],
+ 'Current AutoM Shutter')
+ # parsing empty headers
+ self.assertEqual(self.scan1.scan_header_dict['Q'], '')
+ # duplicate headers: concatenated (with newline)
+ self.assertEqual(self.scan1_2.scan_header_dict["U"],
+ "first duplicate line\nsecond duplicate line")
+
+ def test_file_headers(self):
+ self.assertEqual(self.scan1.header[1],
+ '#E 1455180875')
+ self.assertEqual(self.scan1.file_header_dict['F'],
+ '/tmp/sf.dat')
+
+ def test_multiple_file_headers(self):
+ """Scan 1.2 is after the second file header, with a different
+ Epoch"""
+ self.assertEqual(self.scan1_2.header[1],
+ '#E 1455180876')
+
+ def test_scan_labels(self):
+ self.assertEqual(self.scan1.labels,
+ ['first column', 'second column', '3rd_col'])
+
+ def test_data(self):
+ # data_line() and data_col() take 1-based indices as arg
+ self.assertAlmostEqual(self.scan1.data_line(1)[2],
+ 1.56)
+ # tests for data transposition between original file and .data attr
+ self.assertAlmostEqual(self.scan1.data[2, 0],
+ 8)
+ self.assertEqual(self.scan1.data.shape, (3, 4))
+ self.assertAlmostEqual(numpy.sum(self.scan1.data), 113.631)
+
+ def test_data_column_by_name(self):
+ self.assertAlmostEqual(self.scan25.data_column_by_name("col2")[1],
+ 1.2)
+ # Scan.data is transposed after readinq, so column is the first index
+ self.assertAlmostEqual(numpy.sum(self.scan25.data_column_by_name("col2")),
+ numpy.sum(self.scan25.data[2, :]))
+ with self.assertRaises(specfile.SfErrColNotFound):
+ self.scan25.data_column_by_name("ygfxgfyxg")
+
+ def test_motors(self):
+ self.assertEqual(len(self.scan1.motor_names), 6)
+ self.assertEqual(len(self.scan1.motor_positions), 6)
+ self.assertAlmostEqual(sum(self.scan1.motor_positions),
+ 223.385912)
+ self.assertEqual(self.scan1.motor_names[1], 'MRTSlit UP')
+ self.assertAlmostEqual(
+ self.scan25.motor_position_by_name('MRTSlit UP'),
+ -1.66875)
+
+ def test_absence_of_file_header(self):
+ """We expect Scan.file_header to be an empty list in the absence
+ of a file header.
+ """
+ self.assertEqual(len(self.scan1_no_fhdr.motor_names), 0)
+ # motor positions can still be read in the scan header
+ # even in the absence of motor names
+ self.assertAlmostEqual(sum(self.scan1_no_fhdr.motor_positions),
+ 223.385912)
+ self.assertEqual(len(self.scan1_no_fhdr.header), 15)
+ self.assertEqual(len(self.scan1_no_fhdr.scan_header), 15)
+ self.assertEqual(len(self.scan1_no_fhdr.file_header), 0)
+
+ def test_crash_absence_of_file_header(self):
+ """Test no crash in absence of file header and no leading newline
+ character
+ """
+ self.assertEqual(len(self.scan1_no_fhdr_crash.motor_names), 0)
+ # motor positions can still be read in the scan header
+ # even in the absence of motor names
+ self.assertAlmostEqual(sum(self.scan1_no_fhdr_crash.motor_positions),
+ 223.385912)
+ self.assertEqual(len(self.scan1_no_fhdr_crash.scan_header), 15)
+ self.assertEqual(len(self.scan1_no_fhdr_crash.file_header), 0)
+
+ def test_mca(self):
+ self.assertEqual(len(self.scan1.mca), 0)
+ self.assertEqual(len(self.scan1_2.mca), 3)
+ self.assertEqual(self.scan1_2.mca[1][2], 5)
+ self.assertEqual(sum(self.scan1_2.mca[2]), 21.7)
+
+ # Negative indexing
+ self.assertEqual(sum(self.scan1_2.mca[len(self.scan1_2.mca)-1]),
+ sum(self.scan1_2.mca[-1]))
+
+ # Test iterator
+ line_count, total_sum = (0, 0)
+ for mca_line in self.scan1_2.mca:
+ line_count += 1
+ total_sum += sum(mca_line)
+ self.assertEqual(line_count, 3)
+ self.assertAlmostEqual(total_sum, 36.8)
+
+ def test_mca_header(self):
+ self.assertEqual(self.scan1.mca_header_dict, {})
+ self.assertEqual(len(self.scan1_2.mca_header_dict), 4)
+ self.assertEqual(self.scan1_2.mca_header_dict["CALIB"], "1 2 3")
+ self.assertEqual(self.scan1_2.mca.calibration,
+ [[1., 2., 3.]])
+ # default calib in the absence of #@CALIB
+ self.assertEqual(self.scan25.mca.calibration,
+ [[0., 1., 0.]])
+ self.assertEqual(self.scan1_2.mca.channels,
+ [[0, 1, 2]])
+ # absence of #@CHANN and spectra
+ self.assertEqual(self.scan25.mca.channels,
+ [])
+
+ def test_empty_scan(self):
+ """Test reading a scan with no data points"""
+ self.assertEqual(len(self.empty_scan.labels),
+ 3)
+ col1 = self.empty_scan.data_column_by_name("second column")
+ self.assertEqual(col1.shape, (0, ))
+
+
+class TestSFLocale(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+ locale.setlocale(locale.LC_NUMERIC, loc) # restore saved locale
+ gc.collect()
+
+ def crunch_data(self):
+ self.sf3 = SpecFile(self.fname)
+ self.assertAlmostEqual(self.sf3[0].data_line(1)[2],
+ 1.56)
+ del self.sf3
+
+ @unittest.skipIf(not try_DE, "de_DE.utf8 locale not installed")
+ def test_locale_de_DE(self):
+ locale.setlocale(locale.LC_NUMERIC, 'de_DE.utf8')
+ self.crunch_data()
+
+ def test_locale_user(self):
+ locale.setlocale(locale.LC_NUMERIC, '') # use user's preferred locale
+ self.crunch_data()
+
+ def test_locale_C(self):
+ locale.setlocale(locale.LC_NUMERIC, 'C') # use default (C) locale
+ self.crunch_data()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecFile))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSFLocale))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_specfilewrapper.py b/silx/io/test/test_specfilewrapper.py
new file mode 100644
index 0000000..e9e1a24
--- /dev/null
+++ b/silx/io/test/test_specfilewrapper.py
@@ -0,0 +1,220 @@
+# 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.
+#
+# ############################################################################*/
+"""Tests for old specfile wrapper"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/07/2016"
+
+import gc
+import locale
+import logging
+import numpy
+import os
+import sys
+import tempfile
+import unittest
+
+logging.basicConfig()
+logger1 = logging.getLogger(__name__)
+
+from ..specfilewrapper import Specfile
+
+sftext = """#F /tmp/sf.dat
+#E 1455180875
+#D Thu Feb 11 09:54:35 2016
+#C imaging User = opid17
+#U00 user comment first line
+#U01 This is a dummy file to test SpecFile parsing
+#U02
+#U03 last line
+
+#O0 Pslit HGap MRTSlit UP MRTSlit DOWN
+#O1 Sslit1 VOff Sslit1 HOff Sslit1 VGap
+#o0 pshg mrtu mrtd
+#o2 ss1vo ss1ho ss1vg
+
+#J0 Seconds IA ion.mono Current
+#J1 xbpmc2 idgap1 Inorm
+
+#S 1 ascan ss1vo -4.55687 -0.556875 40 0.2
+#D Thu Feb 11 09:55:20 2016
+#T 0.2 (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 0 0
+#G3 0 0 0 0 0 0 0 0 0
+#G4 0
+#Q
+#P0 180.005 -0.66875 0.87125
+#P1 14.74255 16.197579 12.238283
+#UMI0 Current AutoM Shutter
+#UMI1 192.51 OFF FE open
+#UMI2 Refill in 39883 sec, Fill Mode: uniform multibunch / Message: Feb 11 08:00 Delivery:Next Refill at 21:00;
+#N 4
+#L first column 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 Thu Feb 11 10:00:31 2016
+#P0 80.005 -1.66875 1.87125
+#P1 4.74255 6.197579 2.238283
+#N 5
+#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
+
+#F /tmp/sf.dat
+#E 1455180876
+#D Thu Feb 11 09:54:36 2016
+
+#S 1 aaaaaa
+#U first duplicate line
+#U second duplicate line
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+3 4
+@A 3.1 4 5
+5 6
+@A 6 7.7 8
+"""
+
+
+class TestSpecfilewrapper(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname1 = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ fd2, cls.fname2 = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd2, sftext[370:-97])
+ else:
+ os.write(fd2, bytes(sftext[370:-97], 'ascii'))
+ os.close(fd2)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname1)
+ os.unlink(cls.fname2)
+
+ def setUp(self):
+ self.sf = Specfile(self.fname1)
+ self.scan1 = self.sf[0]
+ self.scan1_2 = self.sf.select("1.2")
+ self.scan25 = self.sf.select("25.1")
+
+ def tearDown(self):
+ del self.sf
+ del self.scan1
+ del self.scan1_2
+ del self.scan25
+ gc.collect()
+
+ def test_number_of_scans(self):
+ self.assertEqual(3, len(self.sf))
+
+ def test_list_of_scan_indices(self):
+ self.assertEqual(self.sf.list(),
+ '1,25,1')
+ self.assertEqual(self.sf.keys(),
+ ["1.1", "25.1", "1.2"])
+
+ def test_scan_headers(self):
+ self.assertEqual(self.scan25.header('S'),
+ ["#S 25 ascan c3th 1.33245 1.52245 40 0.15"])
+ self.assertEqual(self.scan1.header("G0"), ['#G0 0'])
+ # parsing headers with long keys
+ # parsing empty headers
+ self.assertEqual(self.scan1.header('Q'), ['#Q '])
+
+ def test_file_headers(self):
+ self.assertEqual(self.scan1.header("E"),
+ ['#E 1455180875'])
+ self.assertEqual(self.sf.title(),
+ "imaging")
+ self.assertEqual(self.sf.epoch(),
+ 1455180875)
+ self.assertEqual(self.sf.allmotors(),
+ ["Pslit HGap", "MRTSlit UP", "MRTSlit DOWN",
+ "Sslit1 VOff", "Sslit1 HOff", "Sslit1 VGap"])
+
+ def test_scan_labels(self):
+ self.assertEqual(self.scan1.alllabels(),
+ ['first column', 'second column', '3rd_col'])
+
+ def test_data(self):
+ self.assertAlmostEqual(self.scan1.dataline(3)[2],
+ -3.14)
+ self.assertAlmostEqual(self.scan1.datacol(1)[2],
+ 3.14)
+ # tests for data transposition between original file and .data attr
+ self.assertAlmostEqual(self.scan1.data()[2, 0],
+ 8)
+ self.assertEqual(self.scan1.data().shape, (3, 4))
+ self.assertAlmostEqual(numpy.sum(self.scan1.data()), 113.631)
+
+ def test_date(self):
+ self.assertEqual(self.scan1.date(),
+ "Thu Feb 11 09:55:20 2016")
+
+ def test_motors(self):
+ self.assertEqual(len(self.sf.allmotors()), 6)
+ self.assertEqual(len(self.scan1.allmotorpos()), 6)
+ self.assertAlmostEqual(sum(self.scan1.allmotorpos()),
+ 223.385912)
+ self.assertEqual(self.sf.allmotors()[1], 'MRTSlit UP')
+
+ def test_mca(self):
+ self.assertEqual(self.scan1_2.mca(2)[2], 5)
+ self.assertEqual(sum(self.scan1_2.mca(3)), 21.7)
+
+ def test_mca_header(self):
+ self.assertEqual(self.scan1_2.header("CALIB"),
+ ["#@CALIB 1 2 3"])
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecfilewrapper))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_spech5.py b/silx/io/test/test_spech5.py
new file mode 100644
index 0000000..ac250ab
--- /dev/null
+++ b/silx/io/test/test_spech5.py
@@ -0,0 +1,820 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""Tests for spech5"""
+import gc
+from numpy import array_equal
+import os
+import sys
+import tempfile
+import unittest
+import datetime
+from functools import partial
+
+from ..spech5 import (SpecH5, SpecH5Group,
+ SpecH5Dataset, spec_date_to_iso8601)
+from .. import specfile
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "11/05/2017"
+
+sftext = """#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
+
+#J0 Seconds IA ion.mono Current
+#J1 xbpmc2 idgap1 Inorm
+
+#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 4
+#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 5
+#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
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+@A 10 9 8
+@A 1 1 1.1
+3 4
+@A 3.1 4 5
+@A 7 6 5
+@A 1 1 1
+5 6
+@A 6 7.7 8
+@A 4 3 2
+@A 1 1 1
+
+#S 1000 bbbbb
+#G1 3.25 3.25 5.207 90 90 120 2.232368448 2.232368448 1.206680489 90 90 60 1 1 2 -1 2 2 26.132 7.41 -88.96 1.11 1.000012861 15.19 26.06 67.355 -88.96 1.11 1.000012861 15.11 0.723353 0.723353
+#G3 0.0106337923671 0.027529133 1.206191273 -1.43467075 0.7633438883 0.02401568018 -1.709143587 -2.097621783 0.02456954971
+#L a b
+1 2
+
+"""
+
+
+class TestSpecDate(unittest.TestCase):
+ """
+ Test of the spec_date_to_iso8601 function.
+ """
+ # TODO : time zone tests
+ # TODO : error cases
+
+ @classmethod
+ def setUpClass(cls):
+ import locale
+ # FYI : not threadsafe
+ cls.locale_saved = locale.setlocale(locale.LC_TIME)
+ locale.setlocale(locale.LC_TIME, 'C')
+
+ @classmethod
+ def tearDownClass(cls):
+ import locale
+ # FYI : not threadsafe
+ locale.setlocale(locale.LC_TIME, cls.locale_saved)
+
+ def setUp(self):
+ # covering all week days
+ self.n_days = range(1, 10)
+ # covering all months
+ self.n_months = range(1, 13)
+
+ self.n_years = [1999, 2016, 2020]
+ self.n_seconds = [0, 5, 26, 59]
+ self.n_minutes = [0, 9, 42, 59]
+ self.n_hours = [0, 2, 17, 23]
+
+ self.formats = ['%a %b %d %H:%M:%S %Y', '%a %Y/%m/%d %H:%M:%S']
+
+ self.check_date_formats = partial(self.__check_date_formats,
+ year=self.n_years[0],
+ month=self.n_months[0],
+ day=self.n_days[0],
+ hour=self.n_hours[0],
+ minute=self.n_minutes[0],
+ second=self.n_seconds[0],
+ msg=None)
+
+ def __check_date_formats(self,
+ year,
+ month,
+ day,
+ hour,
+ minute,
+ second,
+ msg=None):
+ dt = datetime.datetime(year, month, day, hour, minute, second)
+ expected_date = dt.isoformat()
+
+ for i_fmt, fmt in enumerate(self.formats):
+ spec_date = dt.strftime(fmt)
+ iso_date = spec_date_to_iso8601(spec_date)
+ self.assertEqual(iso_date,
+ expected_date,
+ msg='Testing {0}. format={1}. '
+ 'Expected "{2}", got "{3} ({4})" (dt={5}).'
+ ''.format(msg,
+ i_fmt,
+ expected_date,
+ iso_date,
+ spec_date,
+ dt))
+
+ def testYearsNominal(self):
+ for year in self.n_years:
+ self.check_date_formats(year=year, msg='year')
+
+ def testMonthsNominal(self):
+ for month in self.n_months:
+ self.check_date_formats(month=month, msg='month')
+
+ def testDaysNominal(self):
+ for day in self.n_days:
+ self.check_date_formats(day=day, msg='day')
+
+ def testHoursNominal(self):
+ for hour in self.n_hours:
+ self.check_date_formats(hour=hour, msg='hour')
+
+ def testMinutesNominal(self):
+ for minute in self.n_minutes:
+ self.check_date_formats(minute=minute, msg='minute')
+
+ def testSecondsNominal(self):
+ for second in self.n_seconds:
+ self.check_date_formats(second=second, msg='second')
+
+
+class TestSpecH5(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp()
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+
+ def setUp(self):
+ self.sfh5 = SpecH5(self.fname)
+
+ def tearDown(self):
+ # fix Win32 permission error when deleting temp file
+ del self.sfh5
+ gc.collect()
+
+ def testContainsFile(self):
+ self.assertIn("/1.2/measurement", self.sfh5)
+ self.assertIn("/25.1", self.sfh5)
+ self.assertIn("25.1", self.sfh5)
+ self.assertNotIn("25.2", self.sfh5)
+ # measurement is a child of a scan, full path would be required to
+ # access from root level
+ self.assertNotIn("measurement", self.sfh5)
+ # Groups may or may not have a trailing /
+ self.assertIn("/1.2/measurement/mca_1/", self.sfh5)
+ self.assertIn("/1.2/measurement/mca_1", self.sfh5)
+ # Datasets can't have a trailing /
+ self.assertNotIn("/1.2/measurement/mca_0/info/calibration/ ", self.sfh5)
+ # No mca_8
+ self.assertNotIn("/1.2/measurement/mca_8/info/calibration", self.sfh5)
+ # Link
+ self.assertIn("/1.2/measurement/mca_0/info/calibration", self.sfh5)
+
+ def testContainsGroup(self):
+ self.assertIn("measurement", self.sfh5["/1.2/"])
+ self.assertIn("measurement", self.sfh5["/1.2"])
+ self.assertIn("25.1", self.sfh5["/"])
+ self.assertNotIn("25.2", self.sfh5["/"])
+ self.assertIn("instrument/positioners/Sslit1 HOff", self.sfh5["/1.1"])
+ # illegal trailing "/" after dataset name
+ self.assertNotIn("instrument/positioners/Sslit1 HOff/",
+ self.sfh5["/1.1"])
+ # full path to element in group (OK)
+ self.assertIn("/1.1/instrument/positioners/Sslit1 HOff",
+ self.sfh5["/1.1/instrument"])
+ # full path to element outside group (illegal)
+ self.assertNotIn("/1.1/instrument/positioners/Sslit1 HOff",
+ self.sfh5["/1.1/measurement"])
+
+ def testDataColumn(self):
+ self.assertAlmostEqual(sum(self.sfh5["/1.2/measurement/duo"]),
+ 12.0)
+ self.assertAlmostEqual(
+ sum(self.sfh5["1.1"]["measurement"]["MRTSlit UP"]),
+ 87.891, places=4)
+
+ def testDate(self):
+ # start time is in Iso8601 format
+ self.assertEqual(self.sfh5["/1.1/start_time"],
+ b"2016-02-11T09:55:20")
+ self.assertEqual(self.sfh5["25.1/start_time"],
+ b"2015-03-14T03:53:50")
+
+ def testDatasetInstanceAttr(self):
+ """The SpecH5Dataset objects must implement some dummy attributes
+ to improve compatibility with widgets dealing with h5py datasets."""
+ self.assertIsNone(self.sfh5["/1.1/start_time"].compression)
+ self.assertIsNone(self.sfh5["1.1"]["measurement"]["MRTSlit UP"].chunks)
+
+ # error message must be explicit
+ with self.assertRaisesRegexp(
+ AttributeError,
+ "SpecH5Dataset has no attribute tOTo"):
+ dummy = self.sfh5["/1.1/start_time"].tOTo
+
+ def testGet(self):
+ """Test :meth:`SpecH5Group.get`"""
+ # default value of param *default* is None
+ self.assertIsNone(self.sfh5.get("toto"))
+ self.assertEqual(self.sfh5["25.1"].get("toto", default=-3),
+ -3)
+
+ self.assertEqual(self.sfh5.get("/1.1/start_time", default=-3),
+ b"2016-02-11T09:55:20")
+
+ def testGetClass(self):
+ """Test :meth:`SpecH5Group.get`"""
+ if h5py is None:
+ self.skipTest("h5py is not available")
+ self.assertIs(self.sfh5["1.1"].get("start_time", getclass=True),
+ h5py.Dataset)
+ self.assertIs(self.sfh5["1.1"].get("instrument", getclass=True),
+ h5py.Group)
+
+ # spech5 does not define external link, so there is no way
+ # a group can *get* a SpecH5 class
+
+ def testGetItemGroup(self):
+ group = self.sfh5["25.1"]["instrument"]
+ self.assertEqual(group["positioners"].keys(),
+ ["Pslit HGap", "MRTSlit UP", "MRTSlit DOWN",
+ "Sslit1 VOff", "Sslit1 HOff", "Sslit1 VGap"])
+ with self.assertRaises(KeyError):
+ group["Holy Grail"]
+
+ def testGetitemSpecH5(self):
+ self.assertEqual(self.sfh5["/1.2/instrument/positioners"],
+ self.sfh5["1.2"]["instrument"]["positioners"])
+
+ @unittest.skipIf(h5py is None, "test requires h5py (not installed)")
+ def testH5pyClass(self):
+ """Test :attr:`h5py_class` returns the corresponding h5py class
+ (h5py.File, h5py.Group, h5py.Dataset)"""
+ a_file = self.sfh5
+ self.assertIs(a_file.h5py_class,
+ h5py.File)
+
+ a_group = self.sfh5["/1.2/measurement"]
+ self.assertIs(a_group.h5py_class,
+ h5py.Group)
+
+ a_dataset = self.sfh5["/1.1/instrument/positioners/Sslit1 HOff"]
+ self.assertIs(a_dataset.h5py_class,
+ h5py.Dataset)
+
+ def testHeader(self):
+ file_header = self.sfh5["/1.2/instrument/specfile/file_header"]
+ scan_header = self.sfh5["/1.2/instrument/specfile/scan_header"]
+ # convert ndarray(dtype=numpy.string_) to str
+ if sys.version < '3.0':
+ file_header = str(file_header[()])
+ scan_header = str(scan_header[()])
+ else:
+ file_header = str(file_header.astype(str))
+ scan_header = str(scan_header.astype(str))
+
+ # File header has 10 lines
+ self.assertEqual(len(file_header.split("\n")), 10)
+ # 1.2 has 9 scan & mca header lines
+ self.assertEqual(len(scan_header.split("\n")), 9)
+
+ # line 4 of file header
+ self.assertEqual(
+ file_header.split("\n")[3],
+ "#C imaging User = opid17")
+ # line 4 of scan header
+ scan_header = self.sfh5["25.1/instrument/specfile/scan_header"]
+ if sys.version < '3.0':
+ scan_header = str(scan_header[()])
+ else:
+ scan_header = str(scan_header[()].astype(str))
+
+ self.assertEqual(
+ scan_header.split("\n")[3],
+ "#P1 4.74255 6.197579 2.238283")
+
+ def testLinks(self):
+ self.assertTrue(
+ array_equal(self.sfh5["/1.2/measurement/mca_0/data"],
+ self.sfh5["/1.2/instrument/mca_0/data"])
+ )
+ self.assertTrue(
+ array_equal(self.sfh5["/1.2/measurement/mca_0/info/data"],
+ self.sfh5["/1.2/instrument/mca_0/data"])
+ )
+ self.assertTrue(
+ array_equal(self.sfh5["/1.2/measurement/mca_0/info/channels"],
+ self.sfh5["/1.2/instrument/mca_0/channels"])
+ )
+ self.assertEqual(self.sfh5["/1.2/measurement/mca_0/info/"].keys(),
+ self.sfh5["/1.2/instrument/mca_0/"].keys())
+
+ self.assertEqual(self.sfh5["/1.2/measurement/mca_0/info/preset_time"],
+ self.sfh5["/1.2/instrument/mca_0/preset_time"])
+ self.assertEqual(self.sfh5["/1.2/measurement/mca_0/info/live_time"],
+ self.sfh5["/1.2/instrument/mca_0/live_time"])
+ self.assertEqual(self.sfh5["/1.2/measurement/mca_0/info/elapsed_time"],
+ self.sfh5["/1.2/instrument/mca_0/elapsed_time"])
+
+ def testListScanIndices(self):
+ self.assertEqual(self.sfh5.keys(),
+ ["1.1", "25.1", "1.2", "1000.1"])
+ self.assertEqual(self.sfh5["1.2"].attrs,
+ {"NX_class": "NXentry", })
+
+ def testMcaAbsent(self):
+ def access_absent_mca():
+ """This must raise a KeyError, because scan 1.1 has no MCA"""
+ return self.sfh5["/1.1/measurement/mca_0/"]
+ self.assertRaises(KeyError, access_absent_mca)
+
+ def testMcaCalib(self):
+ mca0_calib = self.sfh5["/1.2/measurement/mca_0/info/calibration"]
+ mca1_calib = self.sfh5["/1.2/measurement/mca_1/info/calibration"]
+ self.assertEqual(mca0_calib.tolist(),
+ [1, 2, 3])
+ # calibration is unique in this scan and applies to all analysers
+ self.assertEqual(mca0_calib.tolist(),
+ mca1_calib.tolist())
+
+ def testMcaChannels(self):
+ mca0_chann = self.sfh5["/1.2/measurement/mca_0/info/channels"]
+ mca1_chann = self.sfh5["/1.2/measurement/mca_1/info/channels"]
+ self.assertEqual(mca0_chann.tolist(),
+ [0, 1, 2])
+ self.assertEqual(mca0_chann.tolist(),
+ mca1_chann.tolist())
+
+ def testMcaCtime(self):
+ """Tests for #@CTIME mca header"""
+ datasets = ["preset_time", "live_time", "elapsed_time"]
+ for ds in datasets:
+ self.assertNotIn("/1.1/instrument/mca_0/" + ds, self.sfh5)
+ self.assertIn("/1.2/instrument/mca_0/" + ds, self.sfh5)
+
+ mca0_preset_time = self.sfh5["/1.2/instrument/mca_0/preset_time"]
+ mca1_preset_time = self.sfh5["/1.2/instrument/mca_1/preset_time"]
+ self.assertLess(mca0_preset_time - 123.4,
+ 10**-5)
+ # ctime is unique in a this scan and applies to all analysers
+ self.assertEqual(mca0_preset_time,
+ mca1_preset_time)
+
+ mca0_live_time = self.sfh5["/1.2/instrument/mca_0/live_time"]
+ mca1_live_time = self.sfh5["/1.2/instrument/mca_1/live_time"]
+ self.assertLess(mca0_live_time - 234.5,
+ 10**-5)
+ self.assertEqual(mca0_live_time,
+ mca1_live_time)
+
+ mca0_elapsed_time = self.sfh5["/1.2/instrument/mca_0/elapsed_time"]
+ mca1_elapsed_time = self.sfh5["/1.2/instrument/mca_1/elapsed_time"]
+ self.assertLess(mca0_elapsed_time - 345.6,
+ 10**-5)
+ self.assertEqual(mca0_elapsed_time,
+ mca1_elapsed_time)
+
+ def testMcaData(self):
+ # sum 1st MCA in scan 1.2 over rows
+ mca_0_data = self.sfh5["/1.2/measurement/mca_0/data"]
+ for summed_row, expected in zip(mca_0_data.sum(axis=1).tolist(),
+ [3.0, 12.1, 21.7]):
+ self.assertAlmostEqual(summed_row, expected, places=4)
+
+ # sum 3rd MCA in scan 1.2 along both axis
+ mca_2_data = self.sfh5["1.2"]["measurement"]["mca_2"]["data"]
+ self.assertAlmostEqual(sum(sum(mca_2_data)), 9.1, places=5)
+ # attrs
+ self.assertEqual(mca_0_data.attrs, {"interpretation": "spectrum"})
+
+ def testMotorPosition(self):
+ positioners_group = self.sfh5["/1.1/instrument/positioners"]
+ # MRTSlit DOWN position is defined in #P0 san header line
+ self.assertAlmostEqual(float(positioners_group["MRTSlit DOWN"]),
+ 0.87125)
+ # MRTSlit UP position is defined in first data column
+ for a, b in zip(positioners_group["MRTSlit UP"].tolist(),
+ [-1.23, 8.478100E+01, 3.14, 1.2]):
+ self.assertAlmostEqual(float(a), b, places=4)
+
+ def testNumberMcaAnalysers(self):
+ """Scan 1.2 has 2 data columns + 3 mca spectra per data line."""
+ self.assertEqual(len(self.sfh5["1.2"]["measurement"]), 5)
+
+ def testTitle(self):
+ self.assertEqual(self.sfh5["/25.1/title"],
+ b"25 ascan c3th 1.33245 1.52245 40 0.15")
+
+ # visit and visititems ignore links
+ def testVisit(self):
+ name_list = []
+ self.sfh5.visit(name_list.append)
+ self.assertIn('/1.2/instrument/positioners/Pslit HGap', name_list)
+ self.assertIn("/1.2/instrument/specfile/scan_header", name_list)
+ self.assertEqual(len(name_list), 100) #, "actual name list: %s" % "\n".join(name_list))
+
+ def testVisitItems(self):
+ dataset_name_list = []
+
+ def func(name, obj):
+ if isinstance(obj, SpecH5Dataset):
+ dataset_name_list.append(name)
+
+ self.sfh5.visititems(func)
+ self.assertIn('/1.2/instrument/positioners/Pslit HGap', dataset_name_list)
+ self.assertEqual(len(dataset_name_list), 73)
+
+ def testNotSpecH5(self):
+ fd, fname = tempfile.mkstemp()
+ os.write(fd, b"Not a spec file!")
+ os.close(fd)
+ self.assertRaises(specfile.SfErrFileOpen, SpecH5, fname)
+ os.unlink(fname)
+
+ def testSample(self):
+ self.assertNotIn("sample", self.sfh5["/1.1"])
+ self.assertIn("sample", self.sfh5["/1000.1"])
+ self.assertIn("ub_matrix", self.sfh5["/1000.1/sample"])
+ self.assertIn("unit_cell", self.sfh5["/1000.1/sample"])
+ self.assertIn("unit_cell_abc", self.sfh5["/1000.1/sample"])
+ self.assertIn("unit_cell_alphabetagamma", self.sfh5["/1000.1/sample"])
+
+
+sftext_multi_mca_headers = """
+#S 1 aaaaaa
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+#@MCA %16C
+#@CHANN 3 1 3 1
+#@CALIB 5.5 6.6 7.7
+#@CTIME 10 11 12
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+@A 10 9 8
+3 4
+@A 3.1 4 5
+@A 7 6 5
+5 6
+@A 6 7.7 8
+@A 4 3 2
+
+"""
+
+
+class TestSpecH5MultiMca(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext_multi_mca_headers)
+ else:
+ os.write(fd, bytes(sftext_multi_mca_headers, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+
+ def setUp(self):
+ self.sfh5 = SpecH5(self.fname)
+
+ def tearDown(self):
+ # fix Win32 permission error when deleting temp file
+ del self.sfh5
+ gc.collect()
+
+ def testMcaCalib(self):
+ mca0_calib = self.sfh5["/1.1/measurement/mca_0/info/calibration"]
+ mca1_calib = self.sfh5["/1.1/measurement/mca_1/info/calibration"]
+ self.assertEqual(mca0_calib.tolist(),
+ [1, 2, 3])
+ self.assertAlmostEqual(sum(mca1_calib.tolist()),
+ sum([5.5, 6.6, 7.7]),
+ places=5)
+
+ def testMcaChannels(self):
+ mca0_chann = self.sfh5["/1.1/measurement/mca_0/info/channels"]
+ mca1_chann = self.sfh5["/1.1/measurement/mca_1/info/channels"]
+ self.assertEqual(mca0_chann.tolist(),
+ [0., 1., 2.])
+ # @CHANN is unique in this scan and applies to all analysers
+ self.assertEqual(mca1_chann.tolist(),
+ [1., 2., 3.])
+
+ def testMcaCtime(self):
+ """Tests for #@CTIME mca header"""
+ mca0_preset_time = self.sfh5["/1.1/instrument/mca_0/preset_time"]
+ mca1_preset_time = self.sfh5["/1.1/instrument/mca_1/preset_time"]
+ self.assertLess(mca0_preset_time - 123.4,
+ 10**-5)
+ self.assertLess(mca1_preset_time - 10,
+ 10**-5)
+
+ mca0_live_time = self.sfh5["/1.1/instrument/mca_0/live_time"]
+ mca1_live_time = self.sfh5["/1.1/instrument/mca_1/live_time"]
+ self.assertLess(mca0_live_time - 234.5,
+ 10**-5)
+ self.assertLess(mca1_live_time - 11,
+ 10**-5)
+
+ mca0_elapsed_time = self.sfh5["/1.1/instrument/mca_0/elapsed_time"]
+ mca1_elapsed_time = self.sfh5["/1.1/instrument/mca_1/elapsed_time"]
+ self.assertLess(mca0_elapsed_time - 345.6,
+ 10**-5)
+ self.assertLess(mca1_elapsed_time - 12,
+ 10**-5)
+
+
+sftext_no_cols = r"""#F C:/DATA\test.mca
+#D Thu Jul 7 08:40:19 2016
+
+#S 1 31oct98.dat 22.1 If4
+#D Thu Jul 7 08:40:19 2016
+#C no data cols, one mca analyser, single spectrum
+#@MCA %16C
+#@CHANN 151 29 29 1
+#@CALIB 0 2 0
+@A 789 784 788 814 847 862 880 904 925 955 987 1015 1031 1070 1111 1139 \
+1203 1236 1290 1392 1492 1558 1688 1813 1977 2119 2346 2699 3121 3542 4102 4970 \
+6071 7611 10426 16188 28266 40348 50539 55555 56162 54162 47102 35718 24588 17034 12994 11444 \
+11808 13461 15687 18885 23827 31578 41999 49556 58084 59415 59456 55698 44525 28219 17680 12881 \
+9518 7415 6155 5246 4646 3978 3612 3299 3020 2761 2670 2472 2500 2310 2286 2106 \
+1989 1890 1782 1655 1421 1293 1135 990 879 757 672 618 532 488 445 424 \
+414 373 351 325 307 284 270 247 228 213 199 187 183 176 164 156 \
+153 140 142 130 118 118 103 101 97 86 90 86 87 81 75 82 \
+80 76 77 75 76 77 62 69 74 60 65 68 65 58 63 64 \
+63 59 60 56 57 60 55
+
+#S 2 31oct98.dat 22.1 If4
+#D Thu Jul 7 08:40:19 2016
+#C no data cols, one mca analyser, multiple spectra
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+@A 0 1 2
+@A 10 9 8
+@A 1 1 1.1
+@A 3.1 4 5
+@A 7 6 5
+@A 1 1 1
+@A 6 7.7 8
+@A 4 3 2
+@A 1 1 1
+
+#S 3 31oct98.dat 22.1 If4
+#D Thu Jul 7 08:40:19 2016
+#C no data cols, 3 mca analysers, multiple spectra
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+#@MCADEV 2
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+#@MCADEV 3
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#@CTIME 123.4 234.5 345.6
+@A 0 1 2
+@A 10 9 8
+@A 1 1 1.1
+@A 3.1 4 5
+@A 7 6 5
+@A 1 1 1
+@A 6 7.7 8
+@A 4 3 2
+@A 1 1 1
+"""
+
+
+class TestSpecH5NoDataCols(unittest.TestCase):
+ """Test reading SPEC files with only MCA data"""
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp()
+ if sys.version < '3.0':
+ os.write(fd, sftext_no_cols)
+ else:
+ os.write(fd, bytes(sftext_no_cols, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+
+ def setUp(self):
+ self.sfh5 = SpecH5(self.fname)
+
+ def tearDown(self):
+ # fix Win32 permission error when deleting temp file
+ del self.sfh5
+ gc.collect()
+
+ def testScan1(self):
+ # 1.1: single analyser, single spectrum, 151 channels
+ self.assertIn("mca_0",
+ self.sfh5["1.1/instrument/"])
+ self.assertEqual(self.sfh5["1.1/instrument/mca_0/data"].shape,
+ (1, 151))
+ self.assertNotIn("mca_1",
+ self.sfh5["1.1/instrument/"])
+
+ def testScan2(self):
+ # 2.1: single analyser, 9 spectra, 3 channels
+ self.assertIn("mca_0",
+ self.sfh5["2.1/instrument/"])
+ self.assertEqual(self.sfh5["2.1/instrument/mca_0/data"].shape,
+ (9, 3))
+ self.assertNotIn("mca_1",
+ self.sfh5["2.1/instrument/"])
+
+ def testScan3(self):
+ # 3.1: 3 analysers, 3 spectra/analyser, 3 channels
+ for i in range(3):
+ self.assertIn("mca_%d" % i,
+ self.sfh5["3.1/instrument/"])
+ self.assertEqual(
+ self.sfh5["3.1/instrument/mca_%d/data" % i].shape,
+ (3, 3))
+
+ self.assertNotIn("mca_3",
+ self.sfh5["3.1/instrument/"])
+
+
+sf_text_slash = r"""#F /data/id09/archive/logspecfiles/laue/2016/scan_231_laue_16-11-29.dat
+#D Sat Dec 10 22:20:59 2016
+#O0 Pslit/HGap MRTSlit%UP
+
+#S 1 laue_16-11-29.log 231.1 PD3/A
+#D Sat Dec 10 22:20:59 2016
+#P0 180.005 -0.66875
+#N 2
+#L GONY/mm PD3%A
+-2.015 5.250424e-05
+-2.01 5.30798e-05
+-2.005 5.281903e-05
+-2 5.220436e-05
+"""
+
+
+class TestSpecH5SlashInLabels(unittest.TestCase):
+ """Test reading SPEC files with labels containing a / character
+
+ The / character must be substituted with a %
+ """
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.fname = tempfile.mkstemp()
+ if sys.version < '3.0':
+ os.write(fd, sf_text_slash)
+ else:
+ os.write(fd, bytes(sf_text_slash, 'ascii'))
+ os.close(fd)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.fname)
+
+ def setUp(self):
+ self.sfh5 = SpecH5(self.fname)
+
+ def tearDown(self):
+ # fix Win32 permission error when deleting temp file
+ del self.sfh5
+ gc.collect()
+
+ def testLabels(self):
+ """Ensure `/` is substituted with `%` and
+ ensure legitimate `%` in names are still working"""
+ self.assertEqual(self.sfh5["1.1/measurement/"].keys(),
+ ["GONY%mm", "PD3%A"])
+
+ # substituted "%"
+ self.assertIn("GONY%mm",
+ self.sfh5["1.1/measurement/"])
+ self.assertNotIn("GONY/mm",
+ self.sfh5["1.1/measurement/"])
+ self.assertAlmostEqual(self.sfh5["1.1/measurement/GONY%mm"][0],
+ -2.015, places=4)
+ # legitimate "%"
+ self.assertIn("PD3%A",
+ self.sfh5["1.1/measurement/"])
+
+ def testMotors(self):
+ """Ensure `/` is substituted with `%` and
+ ensure legitimate `%` in names are still working"""
+ self.assertEqual(self.sfh5["1.1/instrument/positioners"].keys(),
+ ["Pslit%HGap", "MRTSlit%UP"])
+ # substituted "%"
+ self.assertIn("Pslit%HGap",
+ self.sfh5["1.1/instrument/positioners"])
+ self.assertNotIn("Pslit/HGap",
+ self.sfh5["1.1/instrument/positioners"])
+ self.assertAlmostEqual(
+ self.sfh5["1.1/instrument/positioners/Pslit%HGap"],
+ 180.005, places=4)
+ # legitimate "%"
+ self.assertIn("MRTSlit%UP",
+ self.sfh5["1.1/instrument/positioners"])
+
+
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecH5))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecDate))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecH5MultiMca))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecH5NoDataCols))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSpecH5SlashInLabels))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_spectoh5.py b/silx/io/test/test_spectoh5.py
new file mode 100644
index 0000000..f42f8a8
--- /dev/null
+++ b/silx/io/test/test_spectoh5.py
@@ -0,0 +1,197 @@
+# 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.
+#
+# ############################################################################*/
+"""Tests for SpecFile to HDF5 converter"""
+
+import gc
+from numpy import array_equal, string_
+import os
+import sys
+import tempfile
+import unittest
+
+try:
+ import h5py
+except ImportError:
+ h5py_missing = True
+else:
+ h5py_missing = False
+ from ..spech5 import SpecH5
+ from ..spectoh5 import convert, write_spec_to_h5
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/10/2016"
+
+
+sftext = """#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
+
+#J0 Seconds IA ion.mono Current
+#J1 xbpmc2 idgap1 Inorm
+
+#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 4
+#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 1 aaaaaa
+#D Thu Feb 11 10:00:32 2016
+#@MCADEV 1
+#@MCA %16C
+#@CHANN 3 0 2 1
+#@CALIB 1 2 3
+#N 3
+#L uno duo
+1 2
+@A 0 1 2
+@A 10 9 8
+3 4
+@A 3.1 4 5
+@A 7 6 5
+5 6
+@A 6 7.7 8
+@A 4 3 2
+"""
+
+
+@unittest.skipIf(h5py_missing, "Could not import h5py")
+class TestConvertSpecHDF5(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ fd, cls.spec_fname = tempfile.mkstemp(text=False)
+ if sys.version < '3.0':
+ os.write(fd, sftext)
+ else:
+ os.write(fd, bytes(sftext, 'ascii'))
+ os.close(fd)
+
+ fd, cls.h5_fname = tempfile.mkstemp(text=False)
+ # Close and delete (we just need the name)
+ os.close(fd)
+ os.unlink(cls.h5_fname)
+
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(cls.spec_fname)
+
+ def setUp(self):
+ convert(self.spec_fname, self.h5_fname)
+
+ self.sfh5 = SpecH5(self.spec_fname)
+ self.h5f = h5py.File(self.h5_fname)
+
+ def tearDown(self):
+ del self.sfh5
+ self.h5f.close()
+ del self.h5f
+ os.unlink(self.h5_fname)
+ gc.collect()
+
+ def testAppendToHDF5(self):
+ write_spec_to_h5(self.sfh5, self.h5f,
+ h5path="/foo/bar/spam")
+ self.assertTrue(
+ array_equal(self.h5f["/1.2/measurement/mca_1/data"],
+ self.h5f["/foo/bar/spam/1.2/measurement/mca_1/data"])
+ )
+
+ def testTitle(self):
+ """Test the value of a dataset"""
+ title12 = self.h5f["/1.2/title"].value
+ if sys.version > '3.0':
+ title12 = title12.decode()
+ self.assertEqual(title12,
+ "1 aaaaaa")
+
+ def testAttrs(self):
+ # Test root group (file) attributes
+ self.assertEqual(self.h5f.attrs["NX_class"],
+ string_("NXroot"))
+ # Test dataset attributes
+ ds = self.h5f["/1.2/instrument/mca_1/data"]
+ self.assertTrue("interpretation" in ds.attrs)
+ self.assertEqual(list(ds.attrs.values()),
+ [string_("spectrum")])
+ # Test group attributes
+ grp = self.h5f["1.1"]
+ self.assertEqual(grp.attrs["NX_class"],
+ string_("NXentry"))
+ self.assertEqual(len(list(grp.attrs.keys())),
+ 1)
+
+ def testHdf5HasSameMembers(self):
+ spec_member_list = []
+
+ def append_spec_members(name):
+ spec_member_list.append(name)
+ self.sfh5.visit(append_spec_members)
+
+ hdf5_member_list = []
+
+ def append_hdf5_members(name):
+ hdf5_member_list.append(name)
+ self.h5f.visit(append_hdf5_members)
+
+ # 1. For some reason, h5py visit method doesn't include the leading
+ # "/" character when it passes the member name to the function,
+ # even though an explicit the .name attribute of a member will
+ # have a leading "/"
+ spec_member_list = [m.lstrip("/") for m in spec_member_list]
+
+ self.assertEqual(set(hdf5_member_list),
+ set(spec_member_list))
+
+ def testLinks(self):
+ self.assertTrue(
+ array_equal(self.sfh5["/1.2/measurement/mca_0/data"],
+ self.h5f["/1.2/measurement/mca_0/data"])
+ )
+ self.assertTrue(
+ array_equal(self.h5f["/1.2/instrument/mca_1/channels"],
+ self.h5f["/1.2/measurement/mca_1/info/channels"])
+ )
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestConvertSpecHDF5))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/test/test_utils.py b/silx/io/test/test_utils.py
new file mode 100644
index 0000000..15d0005
--- /dev/null
+++ b/silx/io/test/test_utils.py
@@ -0,0 +1,510 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""Tests for utils module"""
+
+
+import numpy
+import os
+import re
+import shutil
+import tempfile
+import unittest
+
+from .. import utils
+
+try:
+ import h5py
+except ImportError:
+ h5py_missing = True
+else:
+ h5py_missing = False
+ from ..utils import h5ls
+
+try:
+ import fabio
+except ImportError:
+ fabio = None
+
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "11/01/2017"
+
+
+expected_spec1 = r"""#F .*
+#D .*
+
+#S 1 Ordinate1
+#D .*
+#N 2
+#L Abscissa Ordinate1
+1 4\.00
+2 5\.00
+3 6\.00
+"""
+
+expected_spec2 = expected_spec1 + """
+#S 2 Ordinate2
+#D .*
+#N 2
+#L Abscissa Ordinate2
+1 7\.00
+2 8\.00
+3 9\.00
+"""
+expected_csv = r"""Abscissa;Ordinate1;Ordinate2
+1;4\.00;7\.00e\+00
+2;5\.00;8\.00e\+00
+3;6\.00;9\.00e\+00
+"""
+
+expected_csv2 = r"""x;y0;y1
+1;4\.00;7\.00e\+00
+2;5\.00;8\.00e\+00
+3;6\.00;9\.00e\+00
+"""
+
+
+class TestSave(unittest.TestCase):
+ """Test saving curves as SpecFile:
+ """
+ def setUp(self):
+ self.tempdir = tempfile.mkdtemp()
+ self.spec_fname = os.path.join(self.tempdir, "savespec.dat")
+ self.csv_fname = os.path.join(self.tempdir, "savecsv.csv")
+ self.npy_fname = os.path.join(self.tempdir, "savenpy.npy")
+
+ self.x = [1, 2, 3]
+ self.xlab = "Abscissa"
+ self.y = [[4, 5, 6], [7, 8, 9]]
+ self.ylabs = ["Ordinate1", "Ordinate2"]
+
+ def tearDown(self):
+ if os.path.isfile(self.spec_fname):
+ os.unlink(self.spec_fname)
+ if os.path.isfile(self.csv_fname):
+ os.unlink(self.csv_fname)
+ if os.path.isfile(self.npy_fname):
+ os.unlink(self.npy_fname)
+ shutil.rmtree(self.tempdir)
+
+ def test_save_csv(self):
+ utils.save1D(self.csv_fname, self.x, self.y,
+ xlabel=self.xlab, ylabels=self.ylabs,
+ filetype="csv", fmt=["%d", "%.2f", "%.2e"],
+ csvdelim=";", autoheader=True)
+
+ csvf = open(self.csv_fname)
+ actual_csv = csvf.read()
+ csvf.close()
+
+ self.assertRegexpMatches(actual_csv, expected_csv)
+
+ def test_save_npy(self):
+ """npy file is saved with numpy.save after building a numpy array
+ and converting it to a named record array"""
+ npyf = open(self.npy_fname, "wb")
+ utils.save1D(npyf, self.x, self.y,
+ xlabel=self.xlab, ylabels=self.ylabs)
+ npyf.close()
+
+ npy_recarray = numpy.load(self.npy_fname)
+
+ self.assertEqual(npy_recarray.shape, (3,))
+ self.assertTrue(
+ numpy.array_equal(
+ npy_recarray['Ordinate1'],
+ numpy.array((4, 5, 6))))
+
+ def test_savespec_filename(self):
+ """Save SpecFile using savespec()"""
+ utils.savespec(self.spec_fname, self.x, self.y[0], xlabel=self.xlab,
+ ylabel=self.ylabs[0], fmt=["%d", "%.2f"], close_file=True,
+ scan_number=1)
+
+ specf = open(self.spec_fname)
+ actual_spec = specf.read()
+ specf.close()
+
+ self.assertRegexpMatches(actual_spec, expected_spec1)
+
+ def test_savespec_file_handle(self):
+ """Save SpecFile using savespec(), passing a file handle"""
+ # first savespec: open, write file header, save y[0] as scan 1,
+ # return file handle
+ specf = utils.savespec(self.spec_fname, self.x, self.y[0], xlabel=self.xlab,
+ ylabel=self.ylabs[0], fmt=["%d", "%.2f"],
+ close_file=False)
+
+ # second savespec: save y[1] as scan 2, close file
+ utils.savespec(specf, self.x, self.y[1], xlabel=self.xlab,
+ ylabel=self.ylabs[1], fmt=["%d", "%.2f"],
+ write_file_header=False, close_file=True,
+ scan_number=2)
+
+ specf = open(self.spec_fname)
+ actual_spec = specf.read()
+ specf.close()
+
+ self.assertRegexpMatches(actual_spec, expected_spec2)
+
+ def test_save_spec(self):
+ """Save SpecFile using save()"""
+ utils.save1D(self.spec_fname, self.x, self.y, xlabel=self.xlab,
+ ylabels=self.ylabs, filetype="spec", fmt=["%d", "%.2f"])
+
+ specf = open(self.spec_fname)
+ actual_spec = specf.read()
+ specf.close()
+ self.assertRegexpMatches(actual_spec, expected_spec2)
+
+ def test_save_csv_no_labels(self):
+ """Save csv using save(), with autoheader=True but
+ xlabel=None and ylabels=None
+ This is a non-regression test for bug #223"""
+ self.tempdir = tempfile.mkdtemp()
+ self.spec_fname = os.path.join(self.tempdir, "savespec.dat")
+ self.csv_fname = os.path.join(self.tempdir, "savecsv.csv")
+ self.npy_fname = os.path.join(self.tempdir, "savenpy.npy")
+
+ self.x = [1, 2, 3]
+ self.xlab = "Abscissa"
+ self.y = [[4, 5, 6], [7, 8, 9]]
+ self.ylabs = ["Ordinate1", "Ordinate2"]
+ utils.save1D(self.csv_fname, self.x, self.y,
+ autoheader=True, fmt=["%d", "%.2f", "%.2e"])
+
+ csvf = open(self.csv_fname)
+ actual_csv = csvf.read()
+ csvf.close()
+ self.assertRegexpMatches(actual_csv, expected_csv2)
+
+
+def assert_match_any_string_in_list(test, pattern, list_of_strings):
+ for string_ in list_of_strings:
+ if re.match(pattern, string_):
+ return True
+ return False
+
+
+@unittest.skipIf(h5py_missing, "Could not import h5py")
+class TestH5Ls(unittest.TestCase):
+ """Test displaying the following HDF5 file structure:
+
+ +foo
+ +bar
+ <HDF5 dataset "spam": shape (2, 2), type "<i8">
+ <HDF5 dataset "tmp": shape (3,), type "<i8">
+ <HDF5 dataset "data": shape (1,), type "<f8">
+
+ """
+ def assertMatchAnyStringInList(self, pattern, list_of_strings):
+ for string_ in list_of_strings:
+ if re.match(pattern, string_):
+ return None
+ raise AssertionError("regex pattern %s does not match any" % pattern +
+ " string in list " + str(list_of_strings))
+
+ def testHdf5(self):
+ fd, self.h5_fname = tempfile.mkstemp(text=False)
+ # Close and delete (we just want the name)
+ os.close(fd)
+ os.unlink(self.h5_fname)
+ self.h5f = h5py.File(self.h5_fname, "w")
+ self.h5f["/foo/bar/tmp"] = [1, 2, 3]
+ self.h5f["/foo/bar/spam"] = [[1, 2], [3, 4]]
+ self.h5f["/foo/data"] = [3.14]
+ self.h5f.close()
+
+ rep = h5ls(self.h5_fname)
+ lines = rep.split("\n")
+
+ self.assertIn("+foo", lines)
+ self.assertIn("\t+bar", lines)
+
+ self.assertMatchAnyStringInList(
+ r'\t\t<HDF5 dataset "tmp": shape \(3,\), type "<i[48]">',
+ lines)
+ self.assertMatchAnyStringInList(
+ r'\t\t<HDF5 dataset "spam": shape \(2, 2\), type "<i[48]">',
+ lines)
+ self.assertMatchAnyStringInList(
+ r'\t<HDF5 dataset "data": shape \(1,\), type "<f[48]">',
+ lines)
+
+ os.unlink(self.h5_fname)
+
+ # Following test case disabled d/t errors on AppVeyor:
+ # os.unlink(spec_fname)
+ # PermissionError: [WinError 32] The process cannot access the file because
+ # it is being used by another process: 'C:\\...\\savespec.dat'
+
+ # def testSpec(self):
+ # tempdir = tempfile.mkdtemp()
+ # spec_fname = os.path.join(tempdir, "savespec.dat")
+ #
+ # x = [1, 2, 3]
+ # xlab = "Abscissa"
+ # y = [[4, 5, 6], [7, 8, 9]]
+ # ylabs = ["Ordinate1", "Ordinate2"]
+ # utils.save1D(spec_fname, x, y, xlabel=xlab,
+ # ylabels=ylabs, filetype="spec",
+ # fmt=["%d", "%.2f"])
+ #
+ # rep = h5ls(spec_fname)
+ # lines = rep.split("\n")
+ # self.assertIn("+1.1", lines)
+ # self.assertIn("\t+instrument", lines)
+ #
+ # self.assertMatchAnyStringInList(
+ # r'\t\t\t<SPEC dataset "file_header": shape \(\), type "|S60">',
+ # lines)
+ # self.assertMatchAnyStringInList(
+ # r'\t\t<SPEC dataset "Ordinate1": shape \(3L?,\), type "<f4">',
+ # lines)
+ #
+ # os.unlink(spec_fname)
+ # shutil.rmtree(tempdir)
+
+
+class TestOpen(unittest.TestCase):
+ """Test `silx.io.utils.open` function."""
+
+ def testH5(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+ g = h5.create_group("arrays")
+ g.create_dataset("scalar", data=10)
+ h5.close()
+
+ # load it
+ f = utils.open(tmp.name)
+ self.assertIsNotNone(f)
+ self.assertIsInstance(f, h5py.File)
+ f.close()
+
+ def testH5With(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(suffix=".h5", delete=True)
+ tmp.file.close()
+ h5 = h5py.File(tmp.name, "w")
+ g = h5.create_group("arrays")
+ g.create_dataset("scalar", data=10)
+ h5.close()
+
+ # load it
+ with utils.open(tmp.name) as f:
+ self.assertIsNotNone(f)
+ self.assertIsInstance(f, h5py.File)
+
+ def testSpec(self):
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(mode="w+t", suffix=".dat", delete=True)
+ tmp.file.close()
+ utils.savespec(tmp.name, [1], [1.1], xlabel="x", ylabel="y",
+ fmt=["%d", "%.2f"], close_file=True, scan_number=1)
+
+ # load it
+ f = utils.open(tmp.name)
+ self.assertIsNotNone(f)
+ self.assertEquals(f.h5py_class, h5py.File)
+ f.close()
+
+ def testSpecWith(self):
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(mode="w+t", suffix=".dat", delete=True)
+ tmp.file.close()
+ utils.savespec(tmp.name, [1], [1.1], xlabel="x", ylabel="y",
+ fmt=["%d", "%.2f"], close_file=True, scan_number=1)
+
+ # load it
+ with utils.open(tmp.name) as f:
+ self.assertIsNotNone(f)
+ self.assertEquals(f.h5py_class, h5py.File)
+
+ def testEdf(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+ if fabio is None:
+ self.skipTest("Fabio is missing")
+
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(suffix=".edf", delete=True)
+ tmp.file.close()
+ header = fabio.fabioimage.OrderedDict()
+ header["integer"] = "10"
+ data = numpy.array([[10, 50], [50, 10]])
+ fabiofile = fabio.edfimage.EdfImage(data, header)
+ fabiofile.write(tmp.name)
+
+ # load it
+ f = utils.open(tmp.name)
+ self.assertIsNotNone(f)
+ self.assertEquals(f.h5py_class, h5py.File)
+ f.close()
+
+ def testEdfWith(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+ if fabio is None:
+ self.skipTest("Fabio is missing")
+
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(suffix=".edf", delete=True)
+ tmp.file.close()
+ header = fabio.fabioimage.OrderedDict()
+ header["integer"] = "10"
+ data = numpy.array([[10, 50], [50, 10]])
+ fabiofile = fabio.edfimage.EdfImage(data, header)
+ fabiofile.write(tmp.name)
+
+ # load it
+ with utils.open(tmp.name) as f:
+ self.assertIsNotNone(f)
+ self.assertEquals(f.h5py_class, h5py.File)
+
+ def testUnsupported(self):
+ # create a file
+ tmp = tempfile.NamedTemporaryFile(mode="w+t", suffix=".txt", delete=True)
+ tmp.write("Kikoo")
+ tmp.close()
+
+ # load it
+ self.assertRaises(IOError, utils.open, tmp.name)
+
+ def testNotExists(self):
+ # load it
+ self.assertRaises(IOError, utils.open, "#$.")
+
+
+class TestNodes(unittest.TestCase):
+ """Test `silx.io.utils.is_` functions."""
+ def test_real_h5py_objects(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ name = tempfile.mktemp(suffix=".h5")
+ try:
+ with h5py.File(name, "w") as h5file:
+ h5group = h5file.create_group("arrays")
+ h5dataset = h5group.create_dataset("scalar", data=10)
+
+ self.assertTrue(utils.is_file(h5file))
+ self.assertTrue(utils.is_group(h5file))
+ self.assertFalse(utils.is_dataset(h5file))
+
+ self.assertFalse(utils.is_file(h5group))
+ self.assertTrue(utils.is_group(h5group))
+ self.assertFalse(utils.is_dataset(h5group))
+
+ self.assertFalse(utils.is_file(h5dataset))
+ self.assertFalse(utils.is_group(h5dataset))
+ self.assertTrue(utils.is_dataset(h5dataset))
+ finally:
+ os.unlink(name)
+
+ def test_h5py_like_file(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ self.h5py_class = h5py.File
+ obj = Foo()
+ self.assertTrue(utils.is_file(obj))
+ self.assertTrue(utils.is_group(obj))
+ self.assertFalse(utils.is_dataset(obj))
+
+ def test_h5py_like_group(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ self.h5py_class = h5py.Group
+ obj = Foo()
+ self.assertFalse(utils.is_file(obj))
+ self.assertTrue(utils.is_group(obj))
+ self.assertFalse(utils.is_dataset(obj))
+
+ def test_h5py_like_dataset(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ self.h5py_class = h5py.Dataset
+ obj = Foo()
+ self.assertFalse(utils.is_file(obj))
+ self.assertFalse(utils.is_group(obj))
+ self.assertTrue(utils.is_dataset(obj))
+
+ def test_bad(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ pass
+ obj = Foo()
+ self.assertFalse(utils.is_file(obj))
+ self.assertFalse(utils.is_group(obj))
+ self.assertFalse(utils.is_dataset(obj))
+
+ def test_bad_api(self):
+ if h5py_missing:
+ self.skipTest("H5py is missing")
+
+ class Foo(object):
+ def __init__(self):
+ self.h5py_class = int
+ obj = Foo()
+ self.assertFalse(utils.is_file(obj))
+ self.assertFalse(utils.is_group(obj))
+ self.assertFalse(utils.is_dataset(obj))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestSave))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestH5Ls))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestOpen))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestNodes))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/io/utils.py b/silx/io/utils.py
new file mode 100644
index 0000000..2ab4496
--- /dev/null
+++ b/silx/io/utils.py
@@ -0,0 +1,500 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+""" I/O utility functions"""
+
+import numpy
+import os.path
+import sys
+import time
+import logging
+from silx.utils.decorators import deprecated
+
+try:
+ import h5py
+except ImportError as e:
+ h5py_missing = True
+ h5py_import_error = e
+else:
+ h5py_missing = False
+
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "13/12/2016"
+
+
+logger = logging.getLogger(__name__)
+
+string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+
+builtin_open = open
+
+
+def save1D(fname, x, y, xlabel=None, ylabels=None, filetype=None,
+ fmt="%.7g", csvdelim=";", newline="\n", header="",
+ footer="", comments="#", autoheader=False):
+ """Saves any number of curves to various formats: `Specfile`, `CSV`,
+ `txt` or `npy`. All curves must have the same number of points and share
+ the same ``x`` values.
+
+ :param fname: Output file path, or file handle open in write mode.
+ If ``fname`` is a path, file is opened in ``w`` mode. Existing file
+ with a same name will be overwritten.
+ :param x: 1D-Array (or list) of abscissa values.
+ :param y: 2D-array (or list of lists) of ordinates values. First index
+ is the curve index, second index is the sample index. The length
+ of the second dimension (number of samples) must be equal to
+ ``len(x)``. ``y`` can be a 1D-array in case there is only one curve
+ to be saved.
+ :param filetype: Filetype: ``"spec", "csv", "txt", "ndarray"``.
+ If ``None``, filetype is detected from file name extension
+ (``.dat, .csv, .txt, .npy``).
+ :param xlabel: Abscissa label
+ :param ylabels: List of `y` labels
+ :param fmt: Format string for data. You can specify a short format
+ string that defines a single format for both ``x`` and ``y`` values,
+ or a list of two different format strings (e.g. ``["%d", "%.7g"]``).
+ Default is ``"%.7g"``.
+ This parameter does not apply to the `npy` format.
+ :param csvdelim: String or character separating columns in `txt` and
+ `CSV` formats. The user is responsible for ensuring that this
+ delimiter is not used in data labels when writing a `CSV` file.
+ :param newline: String or character separating lines/records in `txt`
+ format (default is line break character ``\\n``).
+ :param header: String that will be written at the beginning of the file in
+ `txt` format.
+ :param footer: String that will be written at the end of the file in `txt`
+ format.
+ :param comments: String that will be prepended to the ``header`` and
+ ``footer`` strings, to mark them as comments. Default: ``#``.
+ :param autoheader: In `CSV` or `txt`, ``True`` causes the first header
+ line to be written as a standard CSV header line with column labels
+ separated by the specified CSV delimiter.
+
+ When saving to Specfile format, each curve is saved as a separate scan
+ with two data columns (``x`` and ``y``).
+
+ `CSV` and `txt` formats are similar, except that the `txt` format allows
+ user defined header and footer text blocks, whereas the `CSV` format has
+ only a single header line with columns labels separated by field
+ delimiters and no footer. The `txt` format also allows defining a record
+ separator different from a line break.
+
+ The `npy` format is written with ``numpy.save`` and can be read back with
+ ``numpy.load``. If ``xlabel`` and ``ylabels`` are undefined, data is saved
+ as a regular 2D ``numpy.ndarray`` (contatenation of ``x`` and ``y``). If
+ both ``xlabel`` and ``ylabels`` are defined, the data is saved as a
+ ``numpy.recarray`` after being transposed and having labels assigned to
+ columns.
+ """
+
+ available_formats = ["spec", "csv", "txt", "ndarray"]
+
+ if filetype is None:
+ exttypes = {".dat": "spec",
+ ".csv": "csv",
+ ".txt": "txt",
+ ".npy": "ndarray"}
+ outfname = (fname if not hasattr(fname, "name") else
+ fname.name)
+ fileext = os.path.splitext(outfname)[1]
+ if fileext in exttypes:
+ filetype = exttypes[fileext]
+ else:
+ raise IOError("File type unspecified and could not be " +
+ "inferred from file extension (not in " +
+ "txt, dat, csv, npy)")
+ else:
+ filetype = filetype.lower()
+
+ if filetype not in available_formats:
+ raise IOError("File type %s is not supported" % (filetype))
+
+ # default column headers
+ if xlabel is None:
+ xlabel = "x"
+ if ylabels is None:
+ if len(numpy.array(y).shape) > 1:
+ ylabels = ["y%d" % i for i in range(len(y))]
+ else:
+ ylabels = ["y"]
+ elif isinstance(ylabels, (list, tuple)):
+ # if ylabels is provided as a list, every element must
+ # be a string
+ ylabels = [ylabels[i] if ylabels[i] is not None else "y%d" % i
+ for i in range(len(ylabels))]
+
+ if filetype.lower() == "spec":
+ y_array = numpy.asarray(y)
+
+ # make sure y_array is a 2D array even for a single curve
+ if len(y_array.shape) == 1:
+ y_array.shape = (1, y_array.shape[0])
+ elif len(y_array.shape) > 2 or len(y_array.shape) < 1:
+ raise IndexError("y must be a 1D or 2D array")
+
+ # First curve
+ specf = savespec(fname, x, y_array[0], xlabel, ylabels[0], fmt=fmt,
+ scan_number=1, mode="w", write_file_header=True,
+ close_file=False)
+ # Other curves
+ for i in range(1, y_array.shape[0]):
+ specf = savespec(specf, x, y_array[i], xlabel, ylabels[i],
+ fmt=fmt, scan_number=i + 1, mode="w",
+ write_file_header=False, close_file=False)
+ # close file if we created it
+ if not hasattr(fname, "write"):
+ specf.close()
+
+ else:
+ autoheader_line = xlabel + csvdelim + csvdelim.join(ylabels)
+ if xlabel is not None and ylabels is not None and filetype == "csv":
+ # csv format: optional single header line with labels, no footer
+ if autoheader:
+ header = autoheader_line + newline
+ else:
+ header = ""
+ comments = ""
+ footer = ""
+ newline = "\n"
+ elif filetype == "txt" and autoheader:
+ # Comments string is added at the beginning of header string in
+ # savetxt(). We add another one after the first header line and
+ # before the rest of the header.
+ if header:
+ header = autoheader_line + newline + comments + header
+ else:
+ header = autoheader_line + newline
+
+ # Concatenate x and y in a single 2D array
+ X = numpy.vstack((x, y))
+
+ if filetype.lower() in ["csv", "txt"]:
+ X = X.transpose()
+ savetxt(fname, X, fmt=fmt, delimiter=csvdelim,
+ newline=newline, header=header, footer=footer,
+ comments=comments)
+
+ elif filetype.lower() == "ndarray":
+ if xlabel is not None and ylabels is not None:
+ labels = [xlabel] + ylabels
+
+ # .transpose is needed here because recarray labels
+ # apply to columns
+ X = numpy.core.records.fromrecords(X.transpose(),
+ names=labels)
+ numpy.save(fname, X)
+
+
+# Replace with numpy.savetxt when dropping support of numpy < 1.7.0
+def savetxt(fname, X, fmt="%.7g", delimiter=";", newline="\n",
+ header="", footer="", comments="#"):
+ """``numpy.savetxt`` backport of header and footer arguments from
+ numpy=1.7.0.
+
+ See ``numpy.savetxt`` help:
+ http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.savetxt.html
+ """
+ if not hasattr(fname, "name"):
+ ffile = builtin_open(fname, 'wb')
+ else:
+ ffile = fname
+
+ if header:
+ if sys.version_info[0] >= 3:
+ header = header.encode("utf-8")
+ ffile.write(header)
+
+ numpy.savetxt(ffile, X, fmt, delimiter, newline)
+
+ if footer:
+ footer = (comments + footer.replace(newline, newline + comments) +
+ newline)
+ if sys.version_info[0] >= 3:
+ footer = footer.encode("utf-8")
+ ffile.write(footer)
+
+ if not hasattr(fname, "name"):
+ ffile.close()
+
+
+def savespec(specfile, x, y, xlabel="X", ylabel="Y", fmt="%.7g",
+ scan_number=1, mode="w", write_file_header=True,
+ close_file=False):
+ """Saves one curve to a SpecFile.
+
+ The curve is saved as a scan with two data columns. To save multiple
+ curves to a single SpecFile, call this function for each curve by
+ providing the same file handle each time.
+
+ :param specfile: Output SpecFile name, or file handle open in write
+ or append mode. If a file name is provided, a new file is open in
+ write mode (existing file with the same name will be lost)
+ :param x: 1D-Array (or list) of abscissa values
+ :param y: 1D-array (or list) of ordinates values
+ :param xlabel: Abscissa label (default ``"X"``)
+ :param ylabel: Ordinate label
+ :param fmt: Format string for data. You can specify a short format
+ string that defines a single format for both ``x`` and ``y`` values,
+ or a list of two different format strings (e.g. ``["%d", "%.7g"]``).
+ Default is ``"%.7g"``.
+ :param scan_number: Scan number (default 1).
+ :param mode: Mode for opening file: ``w`` (default), ``a``, ``r+``,
+ ``w+``, ``a+``. This parameter is only relevant if ``specfile`` is a
+ path.
+ :param write_file_header: If ``True``, write a file header before writing
+ the scan (``#F`` and ``#D`` line).
+ :param close_file: If ``True``, close the file after saving curve.
+ :return: ``None`` if ``close_file`` is ``True``, else return the file
+ handle.
+ """
+ # Make sure we use binary mode for write
+ # (issue with windows: write() replaces \n with os.linesep in text mode)
+ if "b" not in mode:
+ first_letter = mode[0]
+ assert first_letter in "rwa"
+ mode = mode.replace(first_letter, first_letter + "b")
+
+ x_array = numpy.asarray(x)
+ y_array = numpy.asarray(y)
+
+ if y_array.shape[0] != x_array.shape[0]:
+ raise IndexError("X and Y columns must have the same length")
+
+ if isinstance(fmt, string_types) and fmt.count("%") == 1:
+ full_fmt_string = fmt + " " + fmt + "\n"
+ elif isinstance(fmt, (list, tuple)) and len(fmt) == 2:
+ full_fmt_string = " ".join(fmt) + "\n"
+ else:
+ raise ValueError("fmt must be a single format string or a list of " +
+ "two format strings")
+
+ if not hasattr(specfile, "write"):
+ f = builtin_open(specfile, mode)
+ else:
+ f = specfile
+
+ output = ""
+
+ current_date = "#D %s\n" % (time.ctime(time.time()))
+
+ if write_file_header:
+ output += "#F %s\n" % f.name
+ output += current_date
+ output += "\n"
+
+ output += "#S %d %s\n" % (scan_number, ylabel)
+ output += current_date
+ output += "#N 2\n"
+ output += "#L %s %s\n" % (xlabel, ylabel)
+ for i in range(y_array.shape[0]):
+ output += full_fmt_string % (x_array[i], y_array[i])
+ output += "\n"
+
+ f.write(output.encode())
+
+ if close_file:
+ f.close()
+ return None
+ return f
+
+
+def h5ls(h5group, lvl=0):
+ """Return a simple string representation of a HDF5 tree structure.
+
+ :param h5group: Any :class:`h5py.Group` or :class:`h5py.File` instance,
+ or a HDF5 file name
+ :param lvl: Number of tabulations added to the group. ``lvl`` is
+ incremented as we recursively process sub-groups.
+ :return: String representation of an HDF5 tree structure
+
+
+ Group names and dataset representation are printed preceded by a number of
+ tabulations corresponding to their depth in the tree structure.
+ Datasets are represented as :class:`h5py.Dataset` objects.
+
+ Example::
+
+ >>> print(h5ls("Downloads/sample.h5"))
+ +fields
+ +fieldB
+ <HDF5 dataset "z": shape (256, 256), type "<f4">
+ +fieldE
+ <HDF5 dataset "x": shape (256, 256), type "<f4">
+ <HDF5 dataset "y": shape (256, 256), type "<f4">
+
+ .. note:: This function requires `h5py <http://www.h5py.org/>`_ to be
+ installed.
+ """
+ if h5py_missing:
+ logger.error("h5ls requires h5py")
+ raise h5py_import_error
+
+ h5repr = ''
+ if is_group(h5group):
+ h5f = h5group
+ elif isinstance(h5group, string_types):
+ h5f = open(h5group) # silx.io.open
+ else:
+ raise TypeError("h5group must be a hdf5-like group object or a file name.")
+
+ for key in h5f.keys():
+ # group
+ if hasattr(h5f[key], 'keys'):
+ h5repr += '\t' * lvl + '+' + key
+ h5repr += '\n'
+ h5repr += h5ls(h5f[key], lvl + 1)
+ # dataset
+ else:
+ h5repr += '\t' * lvl
+ h5repr += str(h5f[key])
+ h5repr += '\n'
+
+ if isinstance(h5group, string_types):
+ h5f.close()
+
+ return h5repr
+
+
+def open(filename): # pylint:disable=redefined-builtin
+ """
+ Load a file as an `h5py.File`-like object.
+
+ Format supported:
+ - h5 files, if `h5py` module is installed
+ - Spec files if `SpecFile` module is installed
+ - a set of raster image formats (tiff, edf...) if `fabio` is installed
+
+ :param str filename: A filename
+ :raises: IOError if the file can't be loaded as an h5py.File like object
+ :rtype: h5py.File
+ """
+ if not os.path.isfile(filename):
+ raise IOError("Filename '%s' must be a file path" % filename)
+
+ if not h5py_missing:
+ if h5py.is_hdf5(filename):
+ return h5py.File(filename)
+
+ try:
+ from . import fabioh5
+ return fabioh5.File(filename)
+ except ImportError:
+ logger.debug("fabioh5 can't be loaded.", exc_info=True)
+ except Exception:
+ logger.debug("File '%s' can't be read as fabio file.", filename, exc_info=True)
+
+ try:
+ from . import spech5
+ return spech5.SpecH5(filename)
+ except ImportError:
+ logger.debug("spech5 can't be loaded.", exc_info=True)
+ except IOError:
+ logger.debug("File '%s' can't be read as spec file.", filename, exc_info=True)
+
+ raise IOError("File '%s' can't be read as HDF5" % filename)
+
+
+@deprecated
+def load(filename):
+ """
+ Load a file as an `h5py.File`-like object.
+
+ Format supported:
+ - h5 files, if `h5py` module is installed
+ - Spec files if `SpecFile` module is installed
+
+ .. deprecated:: 0.4
+ Use :meth:`open`, or :meth:`silx.io.open`. Will be removed in
+ Silx 0.5.
+
+ :param str filename: A filename
+ :raises: IOError if the file can't be loaded as an h5py.File like object
+ :rtype: h5py.File
+ """
+ return open(filename)
+
+
+def get_h5py_class(obj):
+ """Returns the h5py class from an object.
+
+ If it is an h5py object or an h5py-like object, an h5py class is returned.
+ If the object is not an h5py-like object, None is returned.
+
+ :param obj: An object
+ :return: An h5py object
+ """
+ if hasattr(obj, "h5py_class"):
+ return obj.h5py_class
+ elif isinstance(obj, (h5py.File, h5py.Group, h5py.Dataset)):
+ return obj.__class__
+ else:
+ return None
+
+
+def is_file(obj):
+ """
+ True is the object is an h5py.File-like object.
+
+ :param obj: An object
+ """
+ class_ = get_h5py_class(obj)
+ if class_ is None:
+ return False
+ return issubclass(class_, h5py.File)
+
+
+def is_group(obj):
+ """
+ True is the object is an h5py.Group-like object.
+
+ :param obj: An object
+ """
+ class_ = get_h5py_class(obj)
+ if class_ is None:
+ return False
+ return issubclass(class_, h5py.Group)
+
+
+def is_dataset(obj):
+ """
+ True is the object is an h5py.Dataset-like object.
+
+ :param obj: An object
+ """
+ class_ = get_h5py_class(obj)
+ if class_ is None:
+ return False
+ return issubclass(class_, h5py.Dataset)
+
+
+if h5py_missing:
+ def raise_h5py_missing(obj):
+ logger.error("get_h5py_class/is_file/is_group/is_dataset requires h5py")
+ raise h5py_import_error
+
+ get_h5py_class = raise_h5py_missing
+ is_file = raise_h5py_missing
+ is_group = raise_h5py_missing
+ is_dataset = raise_h5py_missing
diff --git a/silx/math/__init__.py b/silx/math/__init__.py
new file mode 100644
index 0000000..1ae8ec0
--- /dev/null
+++ b/silx/math/__init__.py
@@ -0,0 +1,31 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+
+__authors__ = ["D. Naudet", "V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "11/05/2017"
+
+from .histogram import Histogramnd # noqa
+from .histogram import HistogramndLut # noqa
+from .medianfilter import medfilt, medfilt1d, medfilt2d
diff --git a/silx/math/calibration.py b/silx/math/calibration.py
new file mode 100644
index 0000000..2328bd7
--- /dev/null
+++ b/silx/math/calibration.py
@@ -0,0 +1,178 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2017 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.
+#
+# ############################################################################*/
+"""
+This module provides classes to calibrate data.
+
+Classes
+-------
+
+- :class:`NoCalibration`
+- :class:`LinearCalibration`
+- :class:`ArrayCalibration`
+
+"""
+import numpy
+
+
+class AbstractCalibration(object):
+ """A calibration is a transformation to be applied to an axis (i.e. a 1D array).
+
+ """
+ def __init__(self):
+ super(AbstractCalibration, self).__init__()
+
+ def __call__(self, x):
+ """Apply calibration to an axis or to a value.
+
+ :param x: Axis (1-D array), or value"""
+ raise NotImplementedError(
+ "AbstractCalibration can not be used directly. " +
+ "You must subclass it and implement __call__")
+
+ def is_affine(self):
+ """Returns True for an affine calibration of the form
+ :math:`x \mapsto a + b * x`, or else False.
+ """
+ return False
+
+ def get_slope(self):
+ raise NotImplementedError(
+ "get_slope is implemented only for affine calibrations")
+
+
+class NoCalibration(AbstractCalibration):
+ """No calibration :math:`x \mapsto x`
+ """
+ def __init__(self):
+ super(NoCalibration, self).__init__()
+
+ def __call__(self, x):
+ return x
+
+ def is_affine(self):
+ return True
+
+ def get_slope(self):
+ return 1.
+
+
+class LinearCalibration(AbstractCalibration):
+ """Linear calibration :math:`x \mapsto a + b x`,
+ where *a* is the y-intercept and *b* is the slope.
+
+ :param y_intercept: y-intercept
+ :param slope: Slope of the affine transformation
+ """
+ def __init__(self, y_intercept, slope):
+ super(LinearCalibration, self).__init__()
+ self.constant = y_intercept
+ self.slope = slope
+
+ def __call__(self, x):
+ return self.constant + self.slope * x
+
+ def is_affine(self):
+ return True
+
+ def get_slope(self):
+ return self.slope
+
+
+class ArrayCalibration(AbstractCalibration):
+ """One-to-one mapping calibration, defined by an array *x'*,
+ such as :math:`x \mapsto x'`*.
+
+ This calibration can only be applied to x arrays of the same length as the
+ calibration array *x'*.
+ It is typically applied to an axis of indices or
+ channels (:math:`0, 1, ..., n-1`).
+
+ :param x1: Calibration array"""
+ def __init__(self, x1):
+ super(ArrayCalibration, self).__init__()
+ if not isinstance(x1, (list, tuple)) and not hasattr(x1, "shape"):
+ raise TypeError(
+ "The calibration array must be a sequence (list, dataset, array)")
+ self.calibration_array = numpy.array(x1)
+ self._is_affine = None
+
+ def __call__(self, x):
+ # calibrate the entire axis
+ if isinstance(x, (list, tuple, numpy.ndarray)):
+ assert len(self.calibration_array) == len(x)
+ return self.calibration_array
+ # calibrate one value, by index
+ if isinstance(x, int):
+ assert x < len(self.calibration_array)
+ return self.calibration_array[x]
+ raise ValueError("")
+
+ def is_affine(self):
+ """If all values in the calibration array are regularly spaced,
+ return True."""
+ if self._is_affine is None:
+ delta_x = self.calibration_array[1:] - self.calibration_array[:-1]
+ if not numpy.isclose(delta_x, delta_x[0]).all():
+ self._is_affine = False
+ else:
+ self._is_affine = True
+ return self._is_affine
+
+ def get_slope(self):
+ """If the calibration array is regularly spaced, return the spacing."""
+ if not self.is_affine():
+ raise AttributeError(
+ "get_slope only makes sense for affine transformations"
+ )
+ return self.calibration_array[1] - self.calibration_array[0]
+
+
+class FunctionCalibration(AbstractCalibration):
+ """Calibration defined by a function *f*, such as :math:`x \mapsto f(x)`*.
+
+ :param function: Calibration function"""
+ def __init__(self, function, is_affine=False):
+ super(FunctionCalibration, self).__init__()
+ if not hasattr(function, "__call__"):
+ raise TypeError("The calibration function must be a callable")
+ self.function = function
+ self._is_affine = is_affine
+
+ def __call__(self, x):
+ return self.function(x)
+
+ def is_affine(self):
+ """Return True if calibration is affine.
+ This is False by default, unless the object is instantiated with
+ ``is_affine=True``."""
+ return self._is_affine
+
+ def get_slope(self):
+ """If the calibration array is regularly spaced, return the spacing."""
+ if not self.is_affine():
+ raise AttributeError(
+ "get_slope only makes sense for affine transformations"
+ )
+ # fixme: what if function is not defined at x=1 or x=2?
+ return self.function(2) - self.function(1)
diff --git a/silx/math/combo/combo.c b/silx/math/combo/combo.c
new file mode 100644
index 0000000..caab878
--- /dev/null
+++ b/silx/math/combo/combo.c
@@ -0,0 +1,29857 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__combo
+#define __PYX_HAVE_API__combo
+#include "isnan.h"
+#include "pythread.h"
+#include "string.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+ "combo.pyx",
+ "stringsource",
+};
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+struct __pyx_defaults;
+typedef struct __pyx_defaults __pyx_defaults;
+struct __pyx_defaults1;
+typedef struct __pyx_defaults1 __pyx_defaults1;
+struct __pyx_defaults2;
+typedef struct __pyx_defaults2 __pyx_defaults2;
+struct __pyx_defaults3;
+typedef struct __pyx_defaults3 __pyx_defaults3;
+struct __pyx_defaults4;
+typedef struct __pyx_defaults4 __pyx_defaults4;
+struct __pyx_defaults5;
+typedef struct __pyx_defaults5 __pyx_defaults5;
+struct __pyx_defaults6;
+typedef struct __pyx_defaults6 __pyx_defaults6;
+struct __pyx_defaults7;
+typedef struct __pyx_defaults7 __pyx_defaults7;
+struct __pyx_defaults8;
+typedef struct __pyx_defaults8 __pyx_defaults8;
+struct __pyx_defaults9;
+typedef struct __pyx_defaults9 __pyx_defaults9;
+struct __pyx_defaults10;
+typedef struct __pyx_defaults10 __pyx_defaults10;
+struct __pyx_defaults11;
+typedef struct __pyx_defaults11 __pyx_defaults11;
+struct __pyx_defaults12;
+typedef struct __pyx_defaults12 __pyx_defaults12;
+struct __pyx_defaults13;
+typedef struct __pyx_defaults13 __pyx_defaults13;
+struct __pyx_defaults14;
+typedef struct __pyx_defaults14 __pyx_defaults14;
+struct __pyx_defaults15;
+typedef struct __pyx_defaults15 __pyx_defaults15;
+struct __pyx_defaults16;
+typedef struct __pyx_defaults16 __pyx_defaults16;
+struct __pyx_defaults17;
+typedef struct __pyx_defaults17 __pyx_defaults17;
+struct __pyx_defaults18;
+typedef struct __pyx_defaults18 __pyx_defaults18;
+struct __pyx_defaults19;
+typedef struct __pyx_defaults19 __pyx_defaults19;
+struct __pyx_defaults {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults1 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults2 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults3 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults4 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults5 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults6 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults7 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults8 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults9 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults10 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults11 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults12 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults13 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults14 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults15 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults16 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults17 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults18 {
+ int __pyx_arg_min_positive;
+};
+struct __pyx_defaults19 {
+ int __pyx_arg_min_positive;
+};
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o,n,NULL)
+static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_setattro))
+ return tp->tp_setattro(obj, attr_name, value);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_setattr))
+ return tp->tp_setattr(obj, PyString_AS_STRING(attr_name), value);
+#endif
+ return PyObject_SetAttr(obj, attr_name, value);
+}
+#else
+#define __Pyx_PyObject_DelAttrStr(o,n) PyObject_DelAttr(o,n)
+#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE int __Pyx_PyDict_Contains(PyObject* item, PyObject* dict, int eq) {
+ int result = PyDict_Contains(dict, item);
+ return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+ PyObject *value;
+ value = PyDict_GetItemWithError(d, key);
+ if (unlikely(!value)) {
+ if (!PyErr_Occurred()) {
+ PyObject* args = PyTuple_Pack(1, key);
+ if (likely(args))
+ PyErr_SetObject(PyExc_KeyError, args);
+ Py_XDECREF(args);
+ }
+ return NULL;
+ }
+ Py_INCREF(value);
+ return value;
+}
+#else
+ #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \
+ __Pyx_SetItemInt_Generic(o, to_py_func(i), v)))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v);
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** value1, PyObject** value2,
+ int is_tuple, int has_known_size, int decref_tuple);
+
+static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name,
+ Py_ssize_t* p_orig_length, int* p_is_dict);
+static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos,
+ PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases);
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
+
+#define __Pyx_CyFunction_USED 1
+#include <structmember.h>
+#define __Pyx_CYFUNCTION_STATICMETHOD 0x01
+#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02
+#define __Pyx_CYFUNCTION_CCLASS 0x04
+#define __Pyx_CyFunction_GetClosure(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_closure)
+#define __Pyx_CyFunction_GetClassObj(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_classobj)
+#define __Pyx_CyFunction_Defaults(type, f) \
+ ((type *)(((__pyx_CyFunctionObject *) (f))->defaults))
+#define __Pyx_CyFunction_SetDefaultsGetter(f, g) \
+ ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g)
+typedef struct {
+ PyCFunctionObject func;
+#if PY_VERSION_HEX < 0x030500A0
+ PyObject *func_weakreflist;
+#endif
+ PyObject *func_dict;
+ PyObject *func_name;
+ PyObject *func_qualname;
+ PyObject *func_doc;
+ PyObject *func_globals;
+ PyObject *func_code;
+ PyObject *func_closure;
+ PyObject *func_classobj;
+ void *defaults;
+ int defaults_pyobjects;
+ int flags;
+ PyObject *defaults_tuple;
+ PyObject *defaults_kwdict;
+ PyObject *(*defaults_getter)(PyObject *);
+ PyObject *func_annotations;
+} __pyx_CyFunctionObject;
+static PyTypeObject *__pyx_CyFunctionType = 0;
+#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \
+ __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code)
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
+ int flags, PyObject* qualname,
+ PyObject *self,
+ PyObject *module, PyObject *globals,
+ PyObject* code);
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m,
+ size_t size,
+ int pyobjects);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m,
+ PyObject *tuple);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m,
+ PyObject *dict);
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
+ PyObject *dict);
+static int __Pyx_CyFunction_init(void);
+
+static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name, PyObject *qualname,
+ PyObject *mkw, PyObject *modname, PyObject *doc);
+static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases, PyObject *dict,
+ PyObject *mkw, int calculate_metaclass, int allow_py2_metaclass);
+
+typedef struct {
+ __pyx_CyFunctionObject func;
+ PyObject *__signatures__;
+ PyObject *type;
+ PyObject *self;
+} __pyx_FusedFunctionObject;
+#define __pyx_FusedFunction_NewEx(ml, flags, qualname, self, module, globals, code) \
+ __pyx_FusedFunction_New(__pyx_FusedFunctionType, ml, flags, qualname, self, module, globals, code)
+static PyObject *__pyx_FusedFunction_New(PyTypeObject *type,
+ PyMethodDef *ml, int flags,
+ PyObject *qualname, PyObject *self,
+ PyObject *module, PyObject *globals,
+ PyObject *code);
+static int __pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self);
+static PyTypeObject *__pyx_FusedFunctionType = NULL;
+static int __pyx_FusedFunction_init(void);
+#define __Pyx_FusedFunction_USED
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_float(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_double(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_signed_char(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_signed_short(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_signed_int(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_signed_long(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_char(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_short(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_int(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_PY_LONG_LONG(PyObject *);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character);
+
+static PyObject *__pyx_memview_get_float(const char *itemp);
+static int __pyx_memview_set_float(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *);
+
+static PyObject *__pyx_memview_get_double(const char *itemp);
+static int __pyx_memview_set_double(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_signed__char(signed char value);
+
+static CYTHON_INLINE signed char __Pyx_PyInt_As_signed__char(PyObject *);
+
+static PyObject *__pyx_memview_get_signed_char(const char *itemp);
+static int __pyx_memview_set_signed_char(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_signed__short(signed short value);
+
+static CYTHON_INLINE signed short __Pyx_PyInt_As_signed__short(PyObject *);
+
+static PyObject *__pyx_memview_get_signed_short(const char *itemp);
+static int __pyx_memview_set_signed_short(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_signed__int(signed int value);
+
+static CYTHON_INLINE signed int __Pyx_PyInt_As_signed__int(PyObject *);
+
+static PyObject *__pyx_memview_get_signed_int(const char *itemp);
+static int __pyx_memview_set_signed_int(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_signed__long(signed long value);
+
+static CYTHON_INLINE signed long __Pyx_PyInt_As_signed__long(PyObject *);
+
+static PyObject *__pyx_memview_get_signed_long(const char *itemp);
+static int __pyx_memview_set_signed_long(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_char(unsigned char value);
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_As_unsigned_char(PyObject *);
+
+static PyObject *__pyx_memview_get_unsigned_char(const char *itemp);
+static int __pyx_memview_set_unsigned_char(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value);
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_As_unsigned_short(PyObject *);
+
+static PyObject *__pyx_memview_get_unsigned_short(const char *itemp);
+static int __pyx_memview_set_unsigned_short(const char *itemp, PyObject *obj);
+
+static PyObject *__pyx_memview_get_unsigned_int(const char *itemp);
+static int __pyx_memview_set_unsigned_int(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_PY_LONG_LONG(unsigned PY_LONG_LONG value);
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_As_unsigned_PY_LONG_LONG(PyObject *);
+
+static PyObject *__pyx_memview_get_unsigned_PY_LONG_LONG(const char *itemp);
+static int __pyx_memview_set_unsigned_PY_LONG_LONG(const char *itemp, PyObject *obj);
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'combo' */
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_float = { "float", NULL, sizeof(float), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_signed_char = { "signed char", NULL, sizeof(signed char), { 0 }, 0, IS_UNSIGNED(signed char) ? 'U' : 'I', IS_UNSIGNED(signed char), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_signed_short = { "signed short", NULL, sizeof(signed short), { 0 }, 0, IS_UNSIGNED(signed short) ? 'U' : 'I', IS_UNSIGNED(signed short), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_signed_int = { "signed int", NULL, sizeof(signed int), { 0 }, 0, IS_UNSIGNED(signed int) ? 'U' : 'I', IS_UNSIGNED(signed int), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_signed_long = { "signed long", NULL, sizeof(signed long), { 0 }, 0, IS_UNSIGNED(signed long) ? 'U' : 'I', IS_UNSIGNED(signed long), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_unsigned_char = { "unsigned char", NULL, sizeof(unsigned char), { 0 }, 0, IS_UNSIGNED(unsigned char) ? 'U' : 'I', IS_UNSIGNED(unsigned char), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_unsigned_short = { "unsigned short", NULL, sizeof(unsigned short), { 0 }, 0, IS_UNSIGNED(unsigned short) ? 'U' : 'I', IS_UNSIGNED(unsigned short), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_unsigned_int = { "unsigned int", NULL, sizeof(unsigned int), { 0 }, 0, IS_UNSIGNED(unsigned int) ? 'U' : 'I', IS_UNSIGNED(unsigned int), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_unsigned_PY_LONG_LONG = { "unsigned long long", NULL, sizeof(unsigned PY_LONG_LONG), { 0 }, 0, IS_UNSIGNED(unsigned PY_LONG_LONG) ? 'U' : 'I', IS_UNSIGNED(unsigned PY_LONG_LONG), 0 };
+#define __Pyx_MODULE_NAME "combo"
+int __pyx_module_is_main_combo = 0;
+
+/* Implementation of 'combo' */
+static PyObject *__pyx_builtin_object;
+static PyObject *__pyx_builtin_property;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_builtin_ImportError;
+static PyObject *__pyx_builtin_AttributeError;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_ord;
+static PyObject *__pyx_builtin_zip;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda2(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda3(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda4(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda5(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda6(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_5combo_13_MinMaxResult___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_minimum, PyObject *__pyx_v_min_pos, PyObject *__pyx_v_maximum, PyObject *__pyx_v_argmin, PyObject *__pyx_v_argmin_pos, PyObject *__pyx_v_argmax); /* proto */
+static PyObject *__pyx_pf_5combo_13_MinMaxResult_2__getitem__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_5combo__min_max(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_signatures, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs, CYTHON_UNUSED PyObject *__pyx_v_defaults); /* proto */
+static PyObject *__pyx_pf_5combo_46__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_4_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_48__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_6_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_50__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_8_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_52__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_10_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_54__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_12_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_56__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_14_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_58__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_16_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_60__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_18_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_62__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_20_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_64__defaults__(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_5combo_22_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive); /* proto */
+static PyObject *__pyx_pf_5combo_2min_max(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, int __pyx_v_min_positive); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_O[] = "O";
+static char __pyx_k_c[] = "c";
+static char __pyx_k__3[] = "()";
+static char __pyx_k__5[] = "|";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k_doc[] = "doc";
+static char __pyx_k_key[] = "key";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_ord[] = "ord";
+static char __pyx_k_zip[] = "zip";
+static char __pyx_k_args[] = "args";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_data[] = "data";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_init[] = "__init__";
+static char __pyx_k_kind[] = "kind";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_self[] = "self";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_combo[] = "combo";
+static char __pyx_k_doc_2[] = "__doc__";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_float[] = "float";
+static char __pyx_k_index[] = "index";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_ravel[] = "ravel";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_split[] = "split";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_strip[] = "strip";
+static char __pyx_k_value[] = "value";
+static char __pyx_k_argmax[] = "_argmax";
+static char __pyx_k_argmin[] = "_argmin";
+static char __pyx_k_double[] = "double";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_kwargs[] = "kwargs";
+static char __pyx_k_length[] = "length";
+static char __pyx_k_minpos[] = "minpos";
+static char __pyx_k_module[] = "__module__";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_object[] = "object";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_getitem[] = "__getitem__";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_maximum[] = "_maximum";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_min_max[] = "_min_max";
+static char __pyx_k_min_pos[] = "min_pos";
+static char __pyx_k_minimum[] = "_minimum";
+static char __pyx_k_ndarray[] = "ndarray";
+static char __pyx_k_prepare[] = "__prepare__";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_argmax_2[] = "argmax";
+static char __pyx_k_argmin_2[] = "argmin";
+static char __pyx_k_defaults[] = "defaults";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_property[] = "property";
+static char __pyx_k_qualname[] = "__qualname__";
+static char __pyx_k_T_Vincent[] = "T. Vincent";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_max_index[] = "max_index";
+static char __pyx_k_maximum_2[] = "maximum";
+static char __pyx_k_metaclass[] = "__metaclass__";
+static char __pyx_k_min_index[] = "min_index";
+static char __pyx_k_min_max_2[] = "min_max";
+static char __pyx_k_minimum_2[] = "minimum";
+static char __pyx_k_20_12_2016[] = "20/12/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_argmin_pos[] = "argmin_pos";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_signatures[] = "signatures";
+static char __pyx_k_signed_int[] = "signed int";
+static char __pyx_k_ImportError[] = "ImportError";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_signed_char[] = "signed char";
+static char __pyx_k_signed_long[] = "signed long";
+static char __pyx_k_MinMaxResult[] = "_MinMaxResult";
+static char __pyx_k_min_positive[] = "_min_positive";
+static char __pyx_k_signed_short[] = "signed short";
+static char __pyx_k_unsigned_int[] = "unsigned int";
+static char __pyx_k_min_pos_index[] = "min_pos_index";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_unsigned_char[] = "unsigned char";
+static char __pyx_k_AttributeError[] = "AttributeError";
+static char __pyx_k_min_positive_2[] = "min_positive";
+static char __pyx_k_unsigned_short[] = "unsigned short";
+static char __pyx_k_Zero_size_array[] = "Zero-size array";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_argmin_positive[] = "_argmin_positive";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_min_max_line_195[] = "min_max (line 195)";
+static char __pyx_k_argmin_positive_2[] = "argmin_positive";
+static char __pyx_k_ascontiguousarray[] = "ascontiguousarray";
+static char __pyx_k_Index_out_of_range[] = "Index out of range";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_unsigned_long_long[] = "unsigned long long";
+static char __pyx_k_MinMaxResult___init[] = "_MinMaxResult.__init__";
+static char __pyx_k_MinMaxResult_lambda[] = "_MinMaxResult.<lambda>";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_MinMaxResult___getitem[] = "_MinMaxResult.__getitem__";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_Maximum_value_of_the_array[] = "Maximum value of the array";
+static char __pyx_k_Minimum_value_of_the_array[] = "Minimum value of the array";
+static char __pyx_k_No_matching_signature_found[] = "No matching signature found";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_Expected_at_least_d_arguments[] = "Expected at least %d arguments";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_Index_of_the_first_occurence_of[] = "Index of the first occurence of the minimum value";
+static char __pyx_k_Object_storing_result_from_func[] = "Object storing result from :func:`min_max`";
+static char __pyx_k_Strictly_positive_minimum_value[] = "Strictly positive minimum value\n\n It is None if no value is strictly positive.\n ";
+static char __pyx_k_mntdirect__tmp_14_days_tvincent[] = "/mntdirect/_tmp_14_days/tvincent/combo.pyx";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Function_call_with_ambiguous_arg[] = "Function call with ambiguous argument types";
+static char __pyx_k_Index_of_the_strictly_positive_m[] = "Index of the strictly positive minimum value.\n\n It is None if no value is strictly positive.\n It is the index of the first occurence.";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_Returns_min_max_and_optionally_s[] = "Returns min, max and optionally strictly positive min of data.\n\n It also computes the indices of first occurence of min/max.\n\n NaNs are ignored while computing min/max unless all data is NaNs,\n in which case returned min/max are NaNs.\n\n Examples:\n\n >>> import numpy\n >>> data = numpy.arange(10)\n\n Usage as a function returning min and max:\n\n >>> min_, max_ = min_max(data)\n\n Usage as a function returning a result object to access all information:\n\n >>> result = min_max(data) # Do not get positive min\n >>> result.minimum, result.argmin\n 0, 0\n >>> result.maximum, result.argmax\n 9, 10\n >>> result.min_positive, result.argmin_positive # Not computed\n None, None\n\n Getting strictly positive min information:\n\n >>> result = min_max(data, min_positive=True)\n >>> result.min_positive, result.argmin_positive # Computed\n 1, 1\n\n :param data: Array-like dataset\n :param bool min_positive: True to compute the positive min and argmin\n Default: False.\n :returns: An object with minimum, maximum and min_positive attributes\n and the indices of first occurence in the flattened data:\n argmin, argmax and argmin_positive attributes.\n If all data is <= 0 or min_positive argument is False, then\n min_positive and argmin_positive are None.\n :raises: ValueError if data is empty\n ";
+static char __pyx_k_This_module_provides_combination[] = "This module provides combination of statistics as single operation.\n\nFor now it provides min/max (and optionally positive min) and indices\nof first occurences (i.e., argmin/argmax) in a single pass.\n";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static char __pyx_k_Index_of_the_first_occurence_of_2[] = "Index of the first occurence of the maximum value";
+static PyObject *__pyx_kp_s_20_12_2016;
+static PyObject *__pyx_n_s_AttributeError;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_kp_s_Expected_at_least_d_arguments;
+static PyObject *__pyx_kp_s_Function_call_with_ambiguous_arg;
+static PyObject *__pyx_n_s_ImportError;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Index_of_the_first_occurence_of;
+static PyObject *__pyx_kp_s_Index_of_the_first_occurence_of_2;
+static PyObject *__pyx_kp_s_Index_of_the_strictly_positive_m;
+static PyObject *__pyx_kp_s_Index_out_of_range;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_kp_s_Maximum_value_of_the_array;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_n_s_MinMaxResult;
+static PyObject *__pyx_n_s_MinMaxResult___getitem;
+static PyObject *__pyx_n_s_MinMaxResult___init;
+static PyObject *__pyx_n_s_MinMaxResult_lambda;
+static PyObject *__pyx_kp_s_Minimum_value_of_the_array;
+static PyObject *__pyx_kp_s_No_matching_signature_found;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Object_storing_result_from_func;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_kp_u_Returns_min_max_and_optionally_s;
+static PyObject *__pyx_kp_s_Strictly_positive_minimum_value;
+static PyObject *__pyx_kp_s_T_Vincent;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_kp_s_Zero_size_array;
+static PyObject *__pyx_kp_s__3;
+static PyObject *__pyx_kp_s__5;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_argmax;
+static PyObject *__pyx_n_s_argmax_2;
+static PyObject *__pyx_n_s_argmin;
+static PyObject *__pyx_n_s_argmin_2;
+static PyObject *__pyx_n_s_argmin_pos;
+static PyObject *__pyx_n_s_argmin_positive;
+static PyObject *__pyx_n_s_argmin_positive_2;
+static PyObject *__pyx_n_s_args;
+static PyObject *__pyx_n_s_ascontiguousarray;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_n_s_combo;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_data;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_defaults;
+static PyObject *__pyx_n_s_doc;
+static PyObject *__pyx_n_s_doc_2;
+static PyObject *__pyx_n_s_double;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_n_s_getitem;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_index;
+static PyObject *__pyx_n_s_init;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_key;
+static PyObject *__pyx_n_s_kind;
+static PyObject *__pyx_n_s_kwargs;
+static PyObject *__pyx_n_s_length;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_max_index;
+static PyObject *__pyx_n_s_maximum;
+static PyObject *__pyx_n_s_maximum_2;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_n_s_metaclass;
+static PyObject *__pyx_n_s_min_index;
+static PyObject *__pyx_n_s_min_max;
+static PyObject *__pyx_n_s_min_max_2;
+static PyObject *__pyx_kp_u_min_max_line_195;
+static PyObject *__pyx_n_s_min_pos;
+static PyObject *__pyx_n_s_min_pos_index;
+static PyObject *__pyx_n_s_min_positive;
+static PyObject *__pyx_n_s_min_positive_2;
+static PyObject *__pyx_n_s_minimum;
+static PyObject *__pyx_n_s_minimum_2;
+static PyObject *__pyx_n_s_minpos;
+static PyObject *__pyx_kp_s_mntdirect__tmp_14_days_tvincent;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_module;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_n_s_ndarray;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_n_s_object;
+static PyObject *__pyx_n_s_ord;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_n_s_prepare;
+static PyObject *__pyx_n_s_property;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_qualname;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_ravel;
+static PyObject *__pyx_n_s_self;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_signatures;
+static PyObject *__pyx_kp_s_signed_char;
+static PyObject *__pyx_kp_s_signed_int;
+static PyObject *__pyx_kp_s_signed_long;
+static PyObject *__pyx_kp_s_signed_short;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_split;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_strip;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_kp_s_unsigned_char;
+static PyObject *__pyx_kp_s_unsigned_int;
+static PyObject *__pyx_kp_s_unsigned_long_long;
+static PyObject *__pyx_kp_s_unsigned_short;
+static PyObject *__pyx_n_s_value;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_n_s_zip;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_k__2;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__26;
+static PyObject *__pyx_slice__27;
+static PyObject *__pyx_slice__28;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__30;
+static PyObject *__pyx_tuple__32;
+static PyObject *__pyx_tuple__34;
+static PyObject *__pyx_tuple__36;
+static PyObject *__pyx_tuple__38;
+static PyObject *__pyx_tuple__39;
+static PyObject *__pyx_tuple__40;
+static PyObject *__pyx_tuple__41;
+static PyObject *__pyx_tuple__42;
+static PyObject *__pyx_codeobj__31;
+static PyObject *__pyx_codeobj__33;
+static PyObject *__pyx_codeobj__35;
+static PyObject *__pyx_codeobj__37;
+
+/* "combo.pyx":72
+ *
+ * minimum = property(
+ * lambda self: self._minimum, # <<<<<<<<<<<<<<
+ * doc="Minimum value of the array")
+ * maximum = property(
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_4lambda1(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static PyMethodDef __pyx_mdef_5combo_13_MinMaxResult_4lambda1 = {"lambda1", (PyCFunction)__pyx_pw_5combo_13_MinMaxResult_4lambda1, METH_O, 0};
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_4lambda1(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("lambda1 (wrapper)", 0);
+ __pyx_r = __pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda1(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda1(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("lambda1", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_minimum); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("combo._MinMaxResult.lambda1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "combo.pyx":75
+ * doc="Minimum value of the array")
+ * maximum = property(
+ * lambda self: self._maximum, # <<<<<<<<<<<<<<
+ * doc="Maximum value of the array")
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_5lambda2(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static PyMethodDef __pyx_mdef_5combo_13_MinMaxResult_5lambda2 = {"lambda2", (PyCFunction)__pyx_pw_5combo_13_MinMaxResult_5lambda2, METH_O, 0};
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_5lambda2(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("lambda2 (wrapper)", 0);
+ __pyx_r = __pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda2(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda2(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("lambda2", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_maximum); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("combo._MinMaxResult.lambda2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "combo.pyx":79
+ *
+ * argmin = property(
+ * lambda self: self._argmin, # <<<<<<<<<<<<<<
+ * doc="Index of the first occurence of the minimum value")
+ * argmax = property(
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_6lambda3(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static PyMethodDef __pyx_mdef_5combo_13_MinMaxResult_6lambda3 = {"lambda3", (PyCFunction)__pyx_pw_5combo_13_MinMaxResult_6lambda3, METH_O, 0};
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_6lambda3(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("lambda3 (wrapper)", 0);
+ __pyx_r = __pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda3(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda3(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("lambda3", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_argmin); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("combo._MinMaxResult.lambda3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "combo.pyx":82
+ * doc="Index of the first occurence of the minimum value")
+ * argmax = property(
+ * lambda self: self._argmax, # <<<<<<<<<<<<<<
+ * doc="Index of the first occurence of the maximum value")
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_7lambda4(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static PyMethodDef __pyx_mdef_5combo_13_MinMaxResult_7lambda4 = {"lambda4", (PyCFunction)__pyx_pw_5combo_13_MinMaxResult_7lambda4, METH_O, 0};
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_7lambda4(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("lambda4 (wrapper)", 0);
+ __pyx_r = __pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda4(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda4(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("lambda4", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_argmax); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("combo._MinMaxResult.lambda4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "combo.pyx":86
+ *
+ * min_positive = property(
+ * lambda self: self._min_positive, # <<<<<<<<<<<<<<
+ * doc="""Strictly positive minimum value
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_8lambda5(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static PyMethodDef __pyx_mdef_5combo_13_MinMaxResult_8lambda5 = {"lambda5", (PyCFunction)__pyx_pw_5combo_13_MinMaxResult_8lambda5, METH_O, 0};
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_8lambda5(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("lambda5 (wrapper)", 0);
+ __pyx_r = __pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda5(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda5(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("lambda5", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("combo._MinMaxResult.lambda5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "combo.pyx":92
+ * """)
+ * argmin_positive = property(
+ * lambda self: self._argmin_positive, # <<<<<<<<<<<<<<
+ * doc="""Index of the strictly positive minimum value.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_9lambda6(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
+static PyMethodDef __pyx_mdef_5combo_13_MinMaxResult_9lambda6 = {"lambda6", (PyCFunction)__pyx_pw_5combo_13_MinMaxResult_9lambda6, METH_O, 0};
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_9lambda6(PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("lambda6 (wrapper)", 0);
+ __pyx_r = __pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda6(__pyx_self, ((PyObject *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_lambda_funcdef_5combo_13_MinMaxResult_lambda6(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("lambda6", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_argmin_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("combo._MinMaxResult.lambda6", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "combo.pyx":61
+ * """Object storing result from :func:`min_max`"""
+ *
+ * def __init__(self, minimum, min_pos, maximum, # <<<<<<<<<<<<<<
+ * argmin, argmin_pos, argmax):
+ * self._minimum = minimum
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_5combo_13_MinMaxResult_1__init__ = {"__init__", (PyCFunction)__pyx_pw_5combo_13_MinMaxResult_1__init__, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_1__init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_minimum = 0;
+ PyObject *__pyx_v_min_pos = 0;
+ PyObject *__pyx_v_maximum = 0;
+ PyObject *__pyx_v_argmin = 0;
+ PyObject *__pyx_v_argmin_pos = 0;
+ PyObject *__pyx_v_argmax = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_minimum_2,&__pyx_n_s_min_pos,&__pyx_n_s_maximum_2,&__pyx_n_s_argmin_2,&__pyx_n_s_argmin_pos,&__pyx_n_s_argmax_2,0};
+ PyObject* values[7] = {0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_minimum_2)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 7, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_pos)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 7, 7, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_maximum_2)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 7, 7, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_argmin_2)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 7, 7, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_argmin_pos)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 7, 7, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_argmax_2)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 7, 7, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 7) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_minimum = values[1];
+ __pyx_v_min_pos = values[2];
+ __pyx_v_maximum = values[3];
+ __pyx_v_argmin = values[4];
+ __pyx_v_argmin_pos = values[5];
+ __pyx_v_argmax = values[6];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 7, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._MinMaxResult.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_13_MinMaxResult___init__(__pyx_self, __pyx_v_self, __pyx_v_minimum, __pyx_v_min_pos, __pyx_v_maximum, __pyx_v_argmin, __pyx_v_argmin_pos, __pyx_v_argmax);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_13_MinMaxResult___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_minimum, PyObject *__pyx_v_min_pos, PyObject *__pyx_v_maximum, PyObject *__pyx_v_argmin, PyObject *__pyx_v_argmin_pos, PyObject *__pyx_v_argmax) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "combo.pyx":63
+ * def __init__(self, minimum, min_pos, maximum,
+ * argmin, argmin_pos, argmax):
+ * self._minimum = minimum # <<<<<<<<<<<<<<
+ * self._min_positive = min_pos
+ * self._maximum = maximum
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_minimum, __pyx_v_minimum) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":64
+ * argmin, argmin_pos, argmax):
+ * self._minimum = minimum
+ * self._min_positive = min_pos # <<<<<<<<<<<<<<
+ * self._maximum = maximum
+ *
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_min_positive, __pyx_v_min_pos) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":65
+ * self._minimum = minimum
+ * self._min_positive = min_pos
+ * self._maximum = maximum # <<<<<<<<<<<<<<
+ *
+ * self._argmin = argmin
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_maximum, __pyx_v_maximum) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":67
+ * self._maximum = maximum
+ *
+ * self._argmin = argmin # <<<<<<<<<<<<<<
+ * self._argmin_positive = argmin_pos
+ * self._argmax = argmax
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_argmin, __pyx_v_argmin) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":68
+ *
+ * self._argmin = argmin
+ * self._argmin_positive = argmin_pos # <<<<<<<<<<<<<<
+ * self._argmax = argmax
+ *
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_argmin_positive, __pyx_v_argmin_pos) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":69
+ * self._argmin = argmin
+ * self._argmin_positive = argmin_pos
+ * self._argmax = argmax # <<<<<<<<<<<<<<
+ *
+ * minimum = property(
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_self, __pyx_n_s_argmax, __pyx_v_argmax) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":61
+ * """Object storing result from :func:`min_max`"""
+ *
+ * def __init__(self, minimum, min_pos, maximum, # <<<<<<<<<<<<<<
+ * argmin, argmin_pos, argmax):
+ * self._minimum = minimum
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_AddTraceback("combo._MinMaxResult.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "combo.pyx":98
+ * It is the index of the first occurence.""")
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * if key == 0:
+ * return self.minimum
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_3__getitem__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_5combo_13_MinMaxResult_3__getitem__ = {"__getitem__", (PyCFunction)__pyx_pw_5combo_13_MinMaxResult_3__getitem__, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_5combo_13_MinMaxResult_3__getitem__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_self = 0;
+ PyObject *__pyx_v_key = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_self,&__pyx_n_s_key,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_self)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__getitem__", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__getitem__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_self = values[0];
+ __pyx_v_key = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__getitem__", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._MinMaxResult.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_13_MinMaxResult_2__getitem__(__pyx_self, __pyx_v_self, __pyx_v_key);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_13_MinMaxResult_2__getitem__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "combo.pyx":99
+ *
+ * def __getitem__(self, key):
+ * if key == 0: # <<<<<<<<<<<<<<
+ * return self.minimum
+ * elif key == 1:
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_key, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_2) {
+
+ /* "combo.pyx":100
+ * def __getitem__(self, key):
+ * if key == 0:
+ * return self.minimum # <<<<<<<<<<<<<<
+ * elif key == 1:
+ * return self.maximum
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_minimum_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "combo.pyx":101
+ * if key == 0:
+ * return self.minimum
+ * elif key == 1: # <<<<<<<<<<<<<<
+ * return self.maximum
+ * else:
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_key, __pyx_int_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_2) {
+
+ /* "combo.pyx":102
+ * return self.minimum
+ * elif key == 1:
+ * return self.maximum # <<<<<<<<<<<<<<
+ * else:
+ * raise IndexError("Index out of range")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_n_s_maximum_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":104
+ * return self.maximum
+ * else:
+ * raise IndexError("Index out of range") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":98
+ * It is the index of the first occurence.""")
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * if key == 0:
+ * return self.minimum
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("combo._MinMaxResult.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_1_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_5combo__min_max[] = "See :func:`min_max` for documentation.";
+static PyMethodDef __pyx_mdef_5combo_1_min_max = {"_min_max", (PyCFunction)__pyx_pw_5combo_1_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_pw_5combo_1_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_signatures = 0;
+ PyObject *__pyx_v_args = 0;
+ PyObject *__pyx_v_kwargs = 0;
+ CYTHON_UNUSED PyObject *__pyx_v_defaults = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__pyx_fused_cpdef (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_signatures,&__pyx_n_s_args,&__pyx_n_s_kwargs,&__pyx_n_s_defaults,0};
+ PyObject* values[4] = {0,0,0,0};
+ values[1] = __pyx_k__2;
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_signatures)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_args);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kwargs)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_defaults)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_fused_cpdef") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_signatures = values[0];
+ __pyx_v_args = values[1];
+ __pyx_v_kwargs = values[2];
+ __pyx_v_defaults = values[3];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo.__pyx_fused_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo__min_max(__pyx_self, __pyx_v_signatures, __pyx_v_args, __pyx_v_kwargs, __pyx_v_defaults);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo__min_max(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_signatures, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs, CYTHON_UNUSED PyObject *__pyx_v_defaults) {
+ PyObject *__pyx_v_dest_sig = NULL;
+ PyObject *__pyx_v_ndarray = 0;
+ PyObject *__pyx_v_numpy = NULL;
+ __Pyx_memviewslice __pyx_v_memslice;
+ Py_ssize_t __pyx_v_itemsize;
+ int __pyx_v_dtype_signed;
+ char __pyx_v_kind;
+ int __pyx_v_signed_short_is_signed;
+ int __pyx_v_signed_long_is_signed;
+ int __pyx_v_signed_int_is_signed;
+ int __pyx_v_unsigned_long_long_is_signed;
+ int __pyx_v_signed_char_is_signed;
+ int __pyx_v_unsigned_short_is_signed;
+ int __pyx_v_unsigned_int_is_signed;
+ int __pyx_v_unsigned_char_is_signed;
+ PyObject *__pyx_v_arg = NULL;
+ PyObject *__pyx_v_dtype = NULL;
+ PyObject *__pyx_v_arg_base = NULL;
+ PyObject *__pyx_v_candidates = NULL;
+ PyObject *__pyx_v_sig = NULL;
+ int __pyx_v_match_found;
+ PyObject *__pyx_v_src_type = NULL;
+ PyObject *__pyx_v_dst_type = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ char __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ PyObject *(*__pyx_t_15)(PyObject *);
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ PyObject *__pyx_t_18 = NULL;
+ PyObject *(*__pyx_t_19)(PyObject *);
+ int __pyx_t_20;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_min_max", 0);
+ __Pyx_INCREF(__pyx_v_kwargs);
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(Py_None);
+ PyList_SET_ITEM(__pyx_t_1, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_v_dest_sig = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = (__pyx_v_kwargs == Py_None);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF_SET(__pyx_v_kwargs, __pyx_t_1);
+ __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+ {
+ __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_6);
+ /*try:*/ {
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_numpy = __pyx_t_1;
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_numpy, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(PyType_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "type", Py_TYPE(__pyx_t_1)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __pyx_v_ndarray = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_7 = PyErr_ExceptionMatches(__pyx_builtin_ImportError) || PyErr_ExceptionMatches(__pyx_builtin_AttributeError) || PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_7) {
+ __Pyx_AddTraceback("combo.__pyx_fused_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_8, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_INCREF(Py_None);
+ __Pyx_XDECREF_SET(__pyx_v_ndarray, ((PyObject*)Py_None));
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L5_exception_handled;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
+ goto __pyx_L1_error;
+ __pyx_L5_exception_handled:;
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
+ __pyx_L11_try_end:;
+ }
+ __pyx_v_itemsize = -1;
+ __pyx_v_signed_short_is_signed = (((signed short)-1) < 0);
+ __pyx_v_signed_long_is_signed = (((signed long)-1) < 0);
+ __pyx_v_signed_int_is_signed = (((signed int)-1) < 0);
+ __pyx_v_unsigned_long_long_is_signed = (((unsigned PY_LONG_LONG)-1) < 0);
+ __pyx_v_signed_char_is_signed = (((signed char)-1) < 0);
+ __pyx_v_unsigned_short_is_signed = (((unsigned short)-1) < 0);
+ __pyx_v_unsigned_int_is_signed = (((unsigned int)-1) < 0);
+ __pyx_v_unsigned_char_is_signed = (((unsigned char)-1) < 0);
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((0 < __pyx_t_10) != 0);
+ if (__pyx_t_3) {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = PyTuple_GET_ITEM(((PyObject*)__pyx_v_args), 0);
+ __Pyx_INCREF(__pyx_t_9);
+ __pyx_v_arg = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L14;
+ }
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = (__Pyx_PyDict_Contains(__pyx_n_s_data, ((PyObject*)__pyx_v_kwargs), Py_EQ)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = __Pyx_PyDict_GetItem(((PyObject*)__pyx_v_kwargs), __pyx_n_s_data); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_v_arg = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_8 = __Pyx_PyString_Format(__pyx_kp_s_Expected_at_least_d_arguments, __pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L14:;
+ if (0) {
+ goto __pyx_L15;
+ }
+ /*else*/ {
+ while (1) {
+ if (!1) break;
+ __pyx_t_2 = (__pyx_v_ndarray != ((PyObject*)Py_None));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_arg, __pyx_v_ndarray);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_dtype); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_dtype = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L19;
+ }
+ __pyx_t_2 = (__pyx_memoryview_check(__pyx_v_arg) != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_base); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_arg_base = __pyx_t_8;
+ __pyx_t_8 = 0;
+ __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_arg_base, __pyx_v_ndarray);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg_base, __pyx_n_s_dtype); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_dtype = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __pyx_v_dtype = Py_None;
+ }
+ __pyx_L20:;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __pyx_v_dtype = Py_None;
+ }
+ __pyx_L19:;
+ __pyx_v_itemsize = -1;
+ __pyx_t_3 = (__pyx_v_dtype != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_itemsize = __pyx_t_10;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_11 = __Pyx_PyInt_As_char(__pyx_t_8); if (unlikely((__pyx_t_11 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_kind = __pyx_t_11;
+ __pyx_v_dtype_signed = (__pyx_v_kind == 'i');
+ switch (__pyx_v_kind) {
+ case 'i':
+ case 'u':
+ __pyx_t_3 = (((sizeof(signed char)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v_signed_char_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_signed_char, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(signed short)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L27_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L27_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v_signed_short_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L27_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_signed_short, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(signed int)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L31_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L31_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v_signed_int_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L31_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_signed_int, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(signed long)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L35_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L35_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v_signed_long_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L35_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_signed_long, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(unsigned char)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L39_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L39_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v_unsigned_char_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L39_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_unsigned_char, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(unsigned short)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L43_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L43_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v_unsigned_short_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L43_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_unsigned_short, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(unsigned int)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L47_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L47_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v_unsigned_int_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L47_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_unsigned_int, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(unsigned PY_LONG_LONG)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L51_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L51_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v_unsigned_long_long_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L51_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_unsigned_long_long, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ break;
+ case 'f':
+ __pyx_t_3 = (((sizeof(float)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L55_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L55_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(double)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L58_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L58_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_double, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ break;
+ case 'c':
+ break;
+ case 'O':
+ break;
+ default: break;
+ }
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L61_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(float))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L61_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_float(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L60;
+ }
+ __pyx_L60:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L65_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(double))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L65_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_double, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L64;
+ }
+ __pyx_L64:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L69_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(signed char))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L69_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_signed_char(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_signed_char, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L68;
+ }
+ __pyx_L68:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L73_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(signed short))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L73_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_signed_short(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_signed_short, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L72;
+ }
+ __pyx_L72:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L77_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(signed int))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L77_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_signed_int(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_signed_int, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L76;
+ }
+ __pyx_L76:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L81_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(signed long))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L81_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_signed_long(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_signed_long, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L80;
+ }
+ __pyx_L80:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L85_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(unsigned char))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L85_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_char(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_unsigned_char, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L84;
+ }
+ __pyx_L84:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L89_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(unsigned short))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L89_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_short(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_unsigned_short, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L88;
+ }
+ __pyx_L88:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L93_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(unsigned int))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L93_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_int(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_unsigned_int, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L92;
+ }
+ __pyx_L92:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L97_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(unsigned PY_LONG_LONG))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L97_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_PY_LONG_LONG(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_kp_s_unsigned_long_long, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L96;
+ }
+ __pyx_L96:;
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, Py_None, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_L17_break:;
+ }
+ __pyx_L15:;
+ __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_candidates = ((PyObject*)__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_10 = 0;
+ if (unlikely(__pyx_v_signatures == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = __Pyx_dict_iterator(((PyObject*)__pyx_v_signatures), 1, ((PyObject *)NULL), (&__pyx_t_12), (&__pyx_t_7)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_8);
+ __pyx_t_8 = __pyx_t_9;
+ __pyx_t_9 = 0;
+ while (1) {
+ __pyx_t_13 = __Pyx_dict_iter_next(__pyx_t_8, __pyx_t_12, &__pyx_t_10, &__pyx_t_9, NULL, NULL, __pyx_t_7);
+ if (unlikely(__pyx_t_13 == 0)) break;
+ if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF_SET(__pyx_v_sig, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_match_found = 0;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_sig, __pyx_n_s_strip); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_split); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_dest_sig);
+ PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_dest_sig);
+ __Pyx_GIVEREF(__pyx_v_dest_sig);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_zip, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+ __pyx_t_9 = __pyx_t_1; __Pyx_INCREF(__pyx_t_9); __pyx_t_14 = 0;
+ __pyx_t_15 = NULL;
+ } else {
+ __pyx_t_14 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_15 = Py_TYPE(__pyx_t_9)->tp_iternext; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_15)) {
+ if (likely(PyList_CheckExact(__pyx_t_9))) {
+ if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_9)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_14); __Pyx_INCREF(__pyx_t_1); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_9, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_14 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_14); __Pyx_INCREF(__pyx_t_1); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_9, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_1 = __pyx_t_15(__pyx_t_9);
+ if (unlikely(!__pyx_t_1)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ }
+ if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_16 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_17 = PyTuple_GET_ITEM(sequence, 1);
+ } else {
+ __pyx_t_16 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_17 = PyList_GET_ITEM(sequence, 1);
+ }
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(__pyx_t_17);
+ #else
+ __pyx_t_16 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ Py_ssize_t index = -1;
+ __pyx_t_18 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_18);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_19 = Py_TYPE(__pyx_t_18)->tp_iternext;
+ index = 0; __pyx_t_16 = __pyx_t_19(__pyx_t_18); if (unlikely(!__pyx_t_16)) goto __pyx_L104_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_16);
+ index = 1; __pyx_t_17 = __pyx_t_19(__pyx_t_18); if (unlikely(!__pyx_t_17)) goto __pyx_L104_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_17);
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_19(__pyx_t_18), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_19 = NULL;
+ __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
+ goto __pyx_L105_unpacking_done;
+ __pyx_L104_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
+ __pyx_t_19 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_L105_unpacking_done:;
+ }
+ __Pyx_XDECREF_SET(__pyx_v_src_type, __pyx_t_16);
+ __pyx_t_16 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_dst_type, __pyx_t_17);
+ __pyx_t_17 = 0;
+ __pyx_t_2 = (__pyx_v_dst_type != Py_None);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_src_type, __pyx_v_dst_type, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_3) {
+ __pyx_v_match_found = 1;
+ goto __pyx_L107;
+ }
+ /*else*/ {
+ __pyx_v_match_found = 0;
+ goto __pyx_L103_break;
+ }
+ __pyx_L107:;
+ goto __pyx_L106;
+ }
+ __pyx_L106:;
+ }
+ __pyx_L103_break:;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_3 = (__pyx_v_match_found != 0);
+ if (__pyx_t_3) {
+ __pyx_t_20 = __Pyx_PyList_Append(__pyx_v_candidates, __pyx_v_sig); if (unlikely(__pyx_t_20 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L108;
+ }
+ __pyx_L108:;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = (__pyx_v_candidates != Py_None) && (PyList_GET_SIZE(__pyx_v_candidates) != 0);
+ __pyx_t_2 = ((!__pyx_t_3) != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_12 = PyList_GET_SIZE(__pyx_v_candidates); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((__pyx_t_12 > 1) != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+ __Pyx_XDECREF(__pyx_r);
+ if (unlikely(__pyx_v_signatures == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = __Pyx_PyDict_GetItem(((PyObject*)__pyx_v_signatures), PyList_GET_ITEM(__pyx_v_candidates, 0)); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_r = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L0;
+ }
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_18);
+ __Pyx_AddTraceback("combo.__pyx_fused_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_dest_sig);
+ __Pyx_XDECREF(__pyx_v_ndarray);
+ __Pyx_XDECREF(__pyx_v_numpy);
+ __Pyx_XDECREF(__pyx_v_arg);
+ __Pyx_XDECREF(__pyx_v_dtype);
+ __Pyx_XDECREF(__pyx_v_arg_base);
+ __Pyx_XDECREF(__pyx_v_candidates);
+ __Pyx_XDECREF(__pyx_v_sig);
+ __Pyx_XDECREF(__pyx_v_src_type);
+ __Pyx_XDECREF(__pyx_v_dst_type);
+ __Pyx_XDECREF(__pyx_v_kwargs);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_46__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults10, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0__pyx_pw_5combo_5_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0__pyx_mdef_5combo_5_min_max = {"__pyx_fuse_0_min_max", (PyCFunction)__pyx_fuse_0__pyx_pw_5combo_5_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_0__pyx_pw_5combo_5_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults10 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults10, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_float(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_4_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_4_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ float __pyx_v_value;
+ float __pyx_v_minimum;
+ float __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ double __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ unsigned int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ PyObject *__pyx_t_18 = NULL;
+ Py_ssize_t __pyx_t_19;
+ PyObject *__pyx_t_20 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_float, (int (*)(char *, PyObject *)) __pyx_memview_set_float, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((float *) ( /* dim=0 */ ((char *) (((float *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0.0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0.0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":137
+ * if _number in cython.floating:
+ * # For floating, loop until first not NaN value
+ * for index in range(length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if not isnan(value):
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":138
+ * # For floating, loop until first not NaN value
+ * for index in range(length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if not isnan(value):
+ * minimum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((float *) ( /* dim=0 */ ((char *) (((float *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":139
+ * for index in range(length):
+ * value = data[index]
+ * if not isnan(value): # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((!(isnan(__pyx_v_value) != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":140
+ * value = data[index]
+ * if not isnan(value):
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ * maximum = value
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":141
+ * if not isnan(value):
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_v_min_index = __pyx_v_index;
+
+ /* "combo.pyx":142
+ * minimum = value
+ * min_index = index
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * break
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":143
+ * min_index = index
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_max_index = __pyx_v_index;
+
+ /* "combo.pyx":144
+ * maximum = value
+ * max_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * if not min_positive:
+ */
+ goto __pyx_L11_break;
+ }
+ }
+ __pyx_L11_break:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((float *) ( /* dim=0 */ ((char *) (((float *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+ }
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((float *) ( /* dim=0 */ ((char *) (((float *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L19;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L19;
+ }
+ __pyx_L19:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0.0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L18_break;
+ }
+ }
+ __pyx_L18_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_10 = __pyx_v_index;
+ __pyx_v_value = (*((float *) ( /* dim=0 */ ((char *) (((float *) __pyx_v_data.data) + __pyx_t_10)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0.0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L26_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L26_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L25;
+ }
+ __pyx_L25:;
+ }
+ __pyx_L23:;
+ }
+ }
+ __pyx_L13:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_12 = PyFloat_FromDouble(__pyx_v_minimum); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0.0) != 0)) {
+ __pyx_t_14 = PyFloat_FromDouble(__pyx_v_min_pos); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __pyx_t_13 = __pyx_t_14;
+ __pyx_t_14 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_13 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_14 = PyFloat_FromDouble(__pyx_v_maximum); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_15 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0.0) != 0)) {
+ __pyx_t_17 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ __pyx_t_16 = __pyx_t_17;
+ __pyx_t_17 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_16 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_17 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ __pyx_t_18 = NULL;
+ __pyx_t_19 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_11))) {
+ __pyx_t_18 = PyMethod_GET_SELF(__pyx_t_11);
+ if (likely(__pyx_t_18)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+ __Pyx_INCREF(__pyx_t_18);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_11, function);
+ __pyx_t_19 = 1;
+ }
+ }
+ __pyx_t_20 = PyTuple_New(6+__pyx_t_19); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_20);
+ if (__pyx_t_18) {
+ PyTuple_SET_ITEM(__pyx_t_20, 0, __pyx_t_18); __Pyx_GIVEREF(__pyx_t_18); __pyx_t_18 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_20, 0+__pyx_t_19, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_20, 1+__pyx_t_19, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_20, 2+__pyx_t_19, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_20, 3+__pyx_t_19, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_20, 4+__pyx_t_19, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_20, 5+__pyx_t_19, __pyx_t_17);
+ __Pyx_GIVEREF(__pyx_t_17);
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_17 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_20, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_18);
+ __Pyx_XDECREF(__pyx_t_20);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_48__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults11, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1__pyx_pw_5combo_7_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1__pyx_mdef_5combo_7_min_max = {"__pyx_fuse_1_min_max", (PyCFunction)__pyx_fuse_1__pyx_pw_5combo_7_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_1__pyx_pw_5combo_7_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults11 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults11, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_double(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_6_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_6_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ double __pyx_v_value;
+ double __pyx_v_minimum;
+ double __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ double __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ unsigned int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ PyObject *__pyx_t_18 = NULL;
+ Py_ssize_t __pyx_t_19;
+ PyObject *__pyx_t_20 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0.0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0.0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":137
+ * if _number in cython.floating:
+ * # For floating, loop until first not NaN value
+ * for index in range(length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if not isnan(value):
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":138
+ * # For floating, loop until first not NaN value
+ * for index in range(length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if not isnan(value):
+ * minimum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":139
+ * for index in range(length):
+ * value = data[index]
+ * if not isnan(value): # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((!(isnan(__pyx_v_value) != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":140
+ * value = data[index]
+ * if not isnan(value):
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ * maximum = value
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":141
+ * if not isnan(value):
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_v_min_index = __pyx_v_index;
+
+ /* "combo.pyx":142
+ * minimum = value
+ * min_index = index
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * break
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":143
+ * min_index = index
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_max_index = __pyx_v_index;
+
+ /* "combo.pyx":144
+ * maximum = value
+ * max_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * if not min_positive:
+ */
+ goto __pyx_L11_break;
+ }
+ }
+ __pyx_L11_break:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+ }
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L19;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L19;
+ }
+ __pyx_L19:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0.0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L18_break;
+ }
+ }
+ __pyx_L18_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_10 = __pyx_v_index;
+ __pyx_v_value = (*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data.data) + __pyx_t_10)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0.0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L26_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L26_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L25;
+ }
+ __pyx_L25:;
+ }
+ __pyx_L23:;
+ }
+ }
+ __pyx_L13:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_12 = PyFloat_FromDouble(__pyx_v_minimum); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0.0) != 0)) {
+ __pyx_t_14 = PyFloat_FromDouble(__pyx_v_min_pos); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ __pyx_t_13 = __pyx_t_14;
+ __pyx_t_14 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_13 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_14 = PyFloat_FromDouble(__pyx_v_maximum); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_15 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0.0) != 0)) {
+ __pyx_t_17 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ __pyx_t_16 = __pyx_t_17;
+ __pyx_t_17 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_16 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_17 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ __pyx_t_18 = NULL;
+ __pyx_t_19 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_11))) {
+ __pyx_t_18 = PyMethod_GET_SELF(__pyx_t_11);
+ if (likely(__pyx_t_18)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+ __Pyx_INCREF(__pyx_t_18);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_11, function);
+ __pyx_t_19 = 1;
+ }
+ }
+ __pyx_t_20 = PyTuple_New(6+__pyx_t_19); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_20);
+ if (__pyx_t_18) {
+ PyTuple_SET_ITEM(__pyx_t_20, 0, __pyx_t_18); __Pyx_GIVEREF(__pyx_t_18); __pyx_t_18 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_20, 0+__pyx_t_19, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_20, 1+__pyx_t_19, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_20, 2+__pyx_t_19, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_20, 3+__pyx_t_19, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_20, 4+__pyx_t_19, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_20, 5+__pyx_t_19, __pyx_t_17);
+ __Pyx_GIVEREF(__pyx_t_17);
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_17 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_20, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_18);
+ __Pyx_XDECREF(__pyx_t_20);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_50__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults12, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2__pyx_pw_5combo_9_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2__pyx_mdef_5combo_9_min_max = {"__pyx_fuse_2_min_max", (PyCFunction)__pyx_fuse_2__pyx_pw_5combo_9_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_2__pyx_pw_5combo_9_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults12 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults12, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_signed_char(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_8_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_8_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ signed char __pyx_v_value;
+ signed char __pyx_v_minimum;
+ signed char __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ long __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ Py_ssize_t __pyx_t_18;
+ PyObject *__pyx_t_19 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_signed_char, (int (*)(char *, PyObject *)) __pyx_memview_set_signed_char, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((signed char *) ( /* dim=0 */ ((char *) (((signed char *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((signed char *) ( /* dim=0 */ ((char *) (((signed char *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ }
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((signed char *) ( /* dim=0 */ ((char *) (((signed char *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L15_break;
+ }
+ }
+ __pyx_L15_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((signed char *) ( /* dim=0 */ ((char *) (((signed char *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+ }
+ __pyx_L20:;
+ }
+ }
+ __pyx_L10:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_11 = __Pyx_PyInt_From_signed__char(__pyx_v_minimum); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_13 = __Pyx_PyInt_From_long(__pyx_v_min_pos); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __pyx_t_12 = __pyx_t_13;
+ __pyx_t_13 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_12 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_13 = __Pyx_PyInt_From_signed__char(__pyx_v_maximum); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_14 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_15 = __pyx_t_16;
+ __pyx_t_16 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_15 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = NULL;
+ __pyx_t_18 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_17)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_17);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_18 = 1;
+ }
+ }
+ __pyx_t_19 = PyTuple_New(6+__pyx_t_18); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_19);
+ if (__pyx_t_17) {
+ PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_17); __pyx_t_17 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_19, 0+__pyx_t_18, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_19, 1+__pyx_t_18, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_19, 2+__pyx_t_18, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_19, 3+__pyx_t_18, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_19, 4+__pyx_t_18, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_19, 5+__pyx_t_18, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_11 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_19);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_52__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults13, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3__pyx_pw_5combo_11_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3__pyx_mdef_5combo_11_min_max = {"__pyx_fuse_3_min_max", (PyCFunction)__pyx_fuse_3__pyx_pw_5combo_11_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_3__pyx_pw_5combo_11_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults13 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults13, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_signed_short(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_10_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_10_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ signed short __pyx_v_value;
+ signed short __pyx_v_minimum;
+ signed short __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ long __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ Py_ssize_t __pyx_t_18;
+ PyObject *__pyx_t_19 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_signed_short, (int (*)(char *, PyObject *)) __pyx_memview_set_signed_short, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((signed short *) ( /* dim=0 */ ((char *) (((signed short *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((signed short *) ( /* dim=0 */ ((char *) (((signed short *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ }
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((signed short *) ( /* dim=0 */ ((char *) (((signed short *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L15_break;
+ }
+ }
+ __pyx_L15_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((signed short *) ( /* dim=0 */ ((char *) (((signed short *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+ }
+ __pyx_L20:;
+ }
+ }
+ __pyx_L10:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_11 = __Pyx_PyInt_From_signed__short(__pyx_v_minimum); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_13 = __Pyx_PyInt_From_long(__pyx_v_min_pos); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __pyx_t_12 = __pyx_t_13;
+ __pyx_t_13 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_12 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_13 = __Pyx_PyInt_From_signed__short(__pyx_v_maximum); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_14 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_15 = __pyx_t_16;
+ __pyx_t_16 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_15 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = NULL;
+ __pyx_t_18 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_17)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_17);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_18 = 1;
+ }
+ }
+ __pyx_t_19 = PyTuple_New(6+__pyx_t_18); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_19);
+ if (__pyx_t_17) {
+ PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_17); __pyx_t_17 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_19, 0+__pyx_t_18, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_19, 1+__pyx_t_18, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_19, 2+__pyx_t_18, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_19, 3+__pyx_t_18, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_19, 4+__pyx_t_18, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_19, 5+__pyx_t_18, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_11 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_19);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_54__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults14, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_4__pyx_pw_5combo_13_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_4__pyx_mdef_5combo_13_min_max = {"__pyx_fuse_4_min_max", (PyCFunction)__pyx_fuse_4__pyx_pw_5combo_13_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_4__pyx_pw_5combo_13_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults14 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults14, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_signed_int(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_12_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_12_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ signed int __pyx_v_value;
+ signed int __pyx_v_minimum;
+ signed int __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ long __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ Py_ssize_t __pyx_t_18;
+ PyObject *__pyx_t_19 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_4_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_signed_int, (int (*)(char *, PyObject *)) __pyx_memview_set_signed_int, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((signed int *) ( /* dim=0 */ ((char *) (((signed int *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((signed int *) ( /* dim=0 */ ((char *) (((signed int *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ }
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((signed int *) ( /* dim=0 */ ((char *) (((signed int *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L15_break;
+ }
+ }
+ __pyx_L15_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((signed int *) ( /* dim=0 */ ((char *) (((signed int *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+ }
+ __pyx_L20:;
+ }
+ }
+ __pyx_L10:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_11 = __Pyx_PyInt_From_signed__int(__pyx_v_minimum); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_13 = __Pyx_PyInt_From_long(__pyx_v_min_pos); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __pyx_t_12 = __pyx_t_13;
+ __pyx_t_13 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_12 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_13 = __Pyx_PyInt_From_signed__int(__pyx_v_maximum); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_14 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_15 = __pyx_t_16;
+ __pyx_t_16 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_15 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = NULL;
+ __pyx_t_18 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_17)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_17);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_18 = 1;
+ }
+ }
+ __pyx_t_19 = PyTuple_New(6+__pyx_t_18); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_19);
+ if (__pyx_t_17) {
+ PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_17); __pyx_t_17 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_19, 0+__pyx_t_18, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_19, 1+__pyx_t_18, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_19, 2+__pyx_t_18, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_19, 3+__pyx_t_18, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_19, 4+__pyx_t_18, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_19, 5+__pyx_t_18, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_11 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_19);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_56__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults15, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_5__pyx_pw_5combo_15_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_5__pyx_mdef_5combo_15_min_max = {"__pyx_fuse_5_min_max", (PyCFunction)__pyx_fuse_5__pyx_pw_5combo_15_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_5__pyx_pw_5combo_15_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults15 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults15, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_signed_long(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_14_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_14_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ signed long __pyx_v_value;
+ signed long __pyx_v_minimum;
+ signed long __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ long __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ Py_ssize_t __pyx_t_18;
+ PyObject *__pyx_t_19 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_5_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_signed_long, (int (*)(char *, PyObject *)) __pyx_memview_set_signed_long, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((signed long *) ( /* dim=0 */ ((char *) (((signed long *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((signed long *) ( /* dim=0 */ ((char *) (((signed long *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ }
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((signed long *) ( /* dim=0 */ ((char *) (((signed long *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L15_break;
+ }
+ }
+ __pyx_L15_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((signed long *) ( /* dim=0 */ ((char *) (((signed long *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+ }
+ __pyx_L20:;
+ }
+ }
+ __pyx_L10:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_11 = __Pyx_PyInt_From_signed__long(__pyx_v_minimum); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_13 = __Pyx_PyInt_From_long(__pyx_v_min_pos); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __pyx_t_12 = __pyx_t_13;
+ __pyx_t_13 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_12 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_13 = __Pyx_PyInt_From_signed__long(__pyx_v_maximum); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_14 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_15 = __pyx_t_16;
+ __pyx_t_16 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_15 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = NULL;
+ __pyx_t_18 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_17)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_17);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_18 = 1;
+ }
+ }
+ __pyx_t_19 = PyTuple_New(6+__pyx_t_18); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_19);
+ if (__pyx_t_17) {
+ PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_17); __pyx_t_17 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_19, 0+__pyx_t_18, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_19, 1+__pyx_t_18, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_19, 2+__pyx_t_18, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_19, 3+__pyx_t_18, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_19, 4+__pyx_t_18, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_19, 5+__pyx_t_18, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_11 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_19);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_58__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults16, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_6__pyx_pw_5combo_17_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_6__pyx_mdef_5combo_17_min_max = {"__pyx_fuse_6_min_max", (PyCFunction)__pyx_fuse_6__pyx_pw_5combo_17_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_6__pyx_pw_5combo_17_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults16 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults16, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_char(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_16_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_16_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ unsigned char __pyx_v_value;
+ unsigned char __pyx_v_minimum;
+ unsigned char __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ long __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ Py_ssize_t __pyx_t_18;
+ PyObject *__pyx_t_19 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_6_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_unsigned_char, (int (*)(char *, PyObject *)) __pyx_memview_set_unsigned_char, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((unsigned char *) ( /* dim=0 */ ((char *) (((unsigned char *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned char *) ( /* dim=0 */ ((char *) (((unsigned char *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ }
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned char *) ( /* dim=0 */ ((char *) (((unsigned char *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L15_break;
+ }
+ }
+ __pyx_L15_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned char *) ( /* dim=0 */ ((char *) (((unsigned char *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+ }
+ __pyx_L20:;
+ }
+ }
+ __pyx_L10:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_11 = __Pyx_PyInt_From_unsigned_char(__pyx_v_minimum); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_13 = __Pyx_PyInt_From_long(__pyx_v_min_pos); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __pyx_t_12 = __pyx_t_13;
+ __pyx_t_13 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_12 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_13 = __Pyx_PyInt_From_unsigned_char(__pyx_v_maximum); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_14 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_15 = __pyx_t_16;
+ __pyx_t_16 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_15 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = NULL;
+ __pyx_t_18 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_17)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_17);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_18 = 1;
+ }
+ }
+ __pyx_t_19 = PyTuple_New(6+__pyx_t_18); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_19);
+ if (__pyx_t_17) {
+ PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_17); __pyx_t_17 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_19, 0+__pyx_t_18, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_19, 1+__pyx_t_18, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_19, 2+__pyx_t_18, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_19, 3+__pyx_t_18, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_19, 4+__pyx_t_18, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_19, 5+__pyx_t_18, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_11 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_19);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_60__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults17, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_7__pyx_pw_5combo_19_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_7__pyx_mdef_5combo_19_min_max = {"__pyx_fuse_7_min_max", (PyCFunction)__pyx_fuse_7__pyx_pw_5combo_19_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_7__pyx_pw_5combo_19_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults17 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults17, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_short(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_18_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_18_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ unsigned short __pyx_v_value;
+ unsigned short __pyx_v_minimum;
+ unsigned short __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ long __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ Py_ssize_t __pyx_t_18;
+ PyObject *__pyx_t_19 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_7_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_unsigned_short, (int (*)(char *, PyObject *)) __pyx_memview_set_unsigned_short, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((unsigned short *) ( /* dim=0 */ ((char *) (((unsigned short *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned short *) ( /* dim=0 */ ((char *) (((unsigned short *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ }
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned short *) ( /* dim=0 */ ((char *) (((unsigned short *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L15_break;
+ }
+ }
+ __pyx_L15_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned short *) ( /* dim=0 */ ((char *) (((unsigned short *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+ }
+ __pyx_L20:;
+ }
+ }
+ __pyx_L10:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_11 = __Pyx_PyInt_From_unsigned_short(__pyx_v_minimum); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_13 = __Pyx_PyInt_From_long(__pyx_v_min_pos); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __pyx_t_12 = __pyx_t_13;
+ __pyx_t_13 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_12 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_13 = __Pyx_PyInt_From_unsigned_short(__pyx_v_maximum); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_14 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_15 = __pyx_t_16;
+ __pyx_t_16 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_15 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = NULL;
+ __pyx_t_18 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_17)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_17);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_18 = 1;
+ }
+ }
+ __pyx_t_19 = PyTuple_New(6+__pyx_t_18); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_19);
+ if (__pyx_t_17) {
+ PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_17); __pyx_t_17 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_19, 0+__pyx_t_18, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_19, 1+__pyx_t_18, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_19, 2+__pyx_t_18, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_19, 3+__pyx_t_18, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_19, 4+__pyx_t_18, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_19, 5+__pyx_t_18, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_11 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_19);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_62__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults18, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_8__pyx_pw_5combo_21_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_8__pyx_mdef_5combo_21_min_max = {"__pyx_fuse_8_min_max", (PyCFunction)__pyx_fuse_8__pyx_pw_5combo_21_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_8__pyx_pw_5combo_21_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults18 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults18, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_int(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_20_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_20_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ unsigned int __pyx_v_value;
+ unsigned int __pyx_v_minimum;
+ unsigned int __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ long __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ Py_ssize_t __pyx_t_18;
+ PyObject *__pyx_t_19 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_8_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_unsigned_int, (int (*)(char *, PyObject *)) __pyx_memview_set_unsigned_int, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((unsigned int *) ( /* dim=0 */ ((char *) (((unsigned int *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned int *) ( /* dim=0 */ ((char *) (((unsigned int *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ }
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned int *) ( /* dim=0 */ ((char *) (((unsigned int *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L15_break;
+ }
+ }
+ __pyx_L15_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned int *) ( /* dim=0 */ ((char *) (((unsigned int *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+ }
+ __pyx_L20:;
+ }
+ }
+ __pyx_L10:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_11 = __Pyx_PyInt_From_unsigned_int(__pyx_v_minimum); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_13 = __Pyx_PyInt_From_long(__pyx_v_min_pos); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __pyx_t_12 = __pyx_t_13;
+ __pyx_t_13 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_12 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_13 = __Pyx_PyInt_From_unsigned_int(__pyx_v_maximum); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_14 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_15 = __pyx_t_16;
+ __pyx_t_16 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_15 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = NULL;
+ __pyx_t_18 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_17)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_17);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_18 = 1;
+ }
+ }
+ __pyx_t_19 = PyTuple_New(6+__pyx_t_18); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_19);
+ if (__pyx_t_17) {
+ PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_17); __pyx_t_17 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_19, 0+__pyx_t_18, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_19, 1+__pyx_t_18, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_19, 2+__pyx_t_18, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_19, 3+__pyx_t_18, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_19, 4+__pyx_t_18, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_19, 5+__pyx_t_18, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_11 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_19);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_64__defaults__(CYTHON_UNUSED PyObject *__pyx_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__defaults__", 0);
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__Pyx_CyFunction_Defaults(__pyx_defaults19, __pyx_self)->__pyx_arg_min_positive); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("combo.__defaults__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_9__pyx_pw_5combo_23_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_9__pyx_mdef_5combo_23_min_max = {"__pyx_fuse_9_min_max", (PyCFunction)__pyx_fuse_9__pyx_pw_5combo_23_min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo__min_max};
+static PyObject *__pyx_fuse_9__pyx_pw_5combo_23_min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ __pyx_defaults19 *__pyx_dynamic_args = __Pyx_CyFunction_Defaults(__pyx_defaults19, __pyx_self);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_PY_LONG_LONG(values[0]); if (unlikely(!__pyx_v_data.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = __pyx_dynamic_args->__pyx_arg_min_positive;
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5combo_22_min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_22_min_max(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_data, int __pyx_v_min_positive) {
+ unsigned PY_LONG_LONG __pyx_v_value;
+ unsigned PY_LONG_LONG __pyx_v_minimum;
+ unsigned PY_LONG_LONG __pyx_v_maximum;
+ unsigned int __pyx_v_length;
+ unsigned int __pyx_v_index;
+ unsigned int __pyx_v_min_index;
+ unsigned int __pyx_v_min_pos_index;
+ unsigned int __pyx_v_max_index;
+ unsigned PY_LONG_LONG __pyx_v_min_pos;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ unsigned int __pyx_t_5;
+ unsigned int __pyx_t_6;
+ unsigned int __pyx_t_7;
+ unsigned int __pyx_t_8;
+ unsigned int __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ Py_ssize_t __pyx_t_18;
+ PyObject *__pyx_t_19 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_fuse_9_min_max", 0);
+
+ /* "combo.pyx":115
+ * _number value, minimum, minpos, maximum
+ * unsigned int length
+ * unsigned int index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ */
+ __pyx_v_index = 0;
+
+ /* "combo.pyx":116
+ * unsigned int length
+ * unsigned int index = 0
+ * unsigned int min_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0
+ */
+ __pyx_v_min_index = 0;
+
+ /* "combo.pyx":117
+ * unsigned int index = 0
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0 # <<<<<<<<<<<<<<
+ * unsigned int max_index = 0
+ *
+ */
+ __pyx_v_min_pos_index = 0;
+
+ /* "combo.pyx":118
+ * unsigned int min_index = 0
+ * unsigned int min_pos_index = 0
+ * unsigned int max_index = 0 # <<<<<<<<<<<<<<
+ *
+ * length = len(data)
+ */
+ __pyx_v_max_index = 0;
+
+ /* "combo.pyx":120
+ * unsigned int max_index = 0
+ *
+ * length = len(data) # <<<<<<<<<<<<<<
+ *
+ * if length == 0:
+ */
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data, 1, (PyObject *(*)(char *)) __pyx_memview_get_unsigned_PY_LONG_LONG, (int (*)(char *, PyObject *)) __pyx_memview_set_unsigned_PY_LONG_LONG, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_length = __pyx_t_2;
+
+ /* "combo.pyx":122
+ * length = len(data)
+ *
+ * if length == 0: # <<<<<<<<<<<<<<
+ * raise ValueError('Zero-size array')
+ *
+ */
+ __pyx_t_3 = ((__pyx_v_length == 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "combo.pyx":127
+ * with nogil:
+ * # Init starting values
+ * value = data[0] # <<<<<<<<<<<<<<
+ * minimum = value
+ * maximum = value
+ */
+ __pyx_t_2 = 0;
+ __pyx_v_value = (*((unsigned PY_LONG_LONG *) ( /* dim=0 */ ((char *) (((unsigned PY_LONG_LONG *) __pyx_v_data.data) + __pyx_t_2)) )));
+
+ /* "combo.pyx":128
+ * # Init starting values
+ * value = data[0]
+ * minimum = value # <<<<<<<<<<<<<<
+ * maximum = value
+ * if min_positive and value > 0:
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":129
+ * value = data[0]
+ * minimum = value
+ * maximum = value # <<<<<<<<<<<<<<
+ * if min_positive and value > 0:
+ * min_pos = value
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":130
+ * minimum = value
+ * maximum = value
+ * if min_positive and value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * else:
+ */
+ __pyx_t_4 = (__pyx_v_min_positive != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L8_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L8_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":131
+ * maximum = value
+ * if min_positive and value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * else:
+ * min_pos = 0
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":133
+ * min_pos = value
+ * else:
+ * min_pos = 0 # <<<<<<<<<<<<<<
+ *
+ * if _number in cython.floating:
+ */
+ __pyx_v_min_pos = 0;
+ }
+ __pyx_L7:;
+
+ /* "combo.pyx":146
+ * break
+ *
+ * if not min_positive: # <<<<<<<<<<<<<<
+ * for index in range(index, length):
+ * value = data[index]
+ */
+ __pyx_t_3 = ((!(__pyx_v_min_positive != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":147
+ *
+ * if not min_positive:
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":148
+ * if not min_positive:
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_7 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned PY_LONG_LONG *) ( /* dim=0 */ ((char *) (((unsigned PY_LONG_LONG *) __pyx_v_data.data) + __pyx_t_7)) )));
+
+ /* "combo.pyx":149
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":150
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":151
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+
+ /* "combo.pyx":152
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":153
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":154
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ }
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":158
+ * else:
+ * # Loop until min_pos is defined
+ * for index in range(index, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = __pyx_v_index; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":159
+ * # Loop until min_pos is defined
+ * for index in range(index, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_8 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned PY_LONG_LONG *) ( /* dim=0 */ ((char *) (((unsigned PY_LONG_LONG *) __pyx_v_data.data) + __pyx_t_8)) )));
+
+ /* "combo.pyx":160
+ * for index in range(index, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":161
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * elif value < minimum:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":162
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * elif value < minimum:
+ * minimum = value
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+
+ /* "combo.pyx":163
+ * maximum = value
+ * max_index = index
+ * elif value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":164
+ * max_index = index
+ * elif value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":165
+ * elif value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "combo.pyx":167
+ * min_index = index
+ *
+ * if value > 0: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":168
+ *
+ * if value > 0:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ * break
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":169
+ * if value > 0:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+
+ /* "combo.pyx":170
+ * min_pos = value
+ * min_pos_index = index
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Loop until the end
+ */
+ goto __pyx_L15_break;
+ }
+ }
+ __pyx_L15_break:;
+
+ /* "combo.pyx":173
+ *
+ * # Loop until the end
+ * for index in range(index+1, length): # <<<<<<<<<<<<<<
+ * value = data[index]
+ * if value > maximum:
+ */
+ __pyx_t_5 = __pyx_v_length;
+ for (__pyx_t_6 = (__pyx_v_index + 1); __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
+ __pyx_v_index = __pyx_t_6;
+
+ /* "combo.pyx":174
+ * # Loop until the end
+ * for index in range(index+1, length):
+ * value = data[index] # <<<<<<<<<<<<<<
+ * if value > maximum:
+ * maximum = value
+ */
+ __pyx_t_9 = __pyx_v_index;
+ __pyx_v_value = (*((unsigned PY_LONG_LONG *) ( /* dim=0 */ ((char *) (((unsigned PY_LONG_LONG *) __pyx_v_data.data) + __pyx_t_9)) )));
+
+ /* "combo.pyx":175
+ * for index in range(index+1, length):
+ * value = data[index]
+ * if value > maximum: # <<<<<<<<<<<<<<
+ * maximum = value
+ * max_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value > __pyx_v_maximum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":176
+ * value = data[index]
+ * if value > maximum:
+ * maximum = value # <<<<<<<<<<<<<<
+ * max_index = index
+ * else:
+ */
+ __pyx_v_maximum = __pyx_v_value;
+
+ /* "combo.pyx":177
+ * if value > maximum:
+ * maximum = value
+ * max_index = index # <<<<<<<<<<<<<<
+ * else:
+ * if value < minimum:
+ */
+ __pyx_v_max_index = __pyx_v_index;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "combo.pyx":179
+ * max_index = index
+ * else:
+ * if value < minimum: # <<<<<<<<<<<<<<
+ * minimum = value
+ * min_index = index
+ */
+ __pyx_t_3 = ((__pyx_v_value < __pyx_v_minimum) != 0);
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":180
+ * else:
+ * if value < minimum:
+ * minimum = value # <<<<<<<<<<<<<<
+ * min_index = index
+ *
+ */
+ __pyx_v_minimum = __pyx_v_value;
+
+ /* "combo.pyx":181
+ * if value < minimum:
+ * minimum = value
+ * min_index = index # <<<<<<<<<<<<<<
+ *
+ * if value > 0 and value < min_pos:
+ */
+ __pyx_v_min_index = __pyx_v_index;
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "combo.pyx":183
+ * min_index = index
+ *
+ * if value > 0 and value < min_pos: # <<<<<<<<<<<<<<
+ * min_pos = value
+ * min_pos_index = index
+ */
+ __pyx_t_4 = ((__pyx_v_value > 0) != 0);
+ if (__pyx_t_4) {
+ } else {
+ __pyx_t_3 = __pyx_t_4;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_4 = ((__pyx_v_value < __pyx_v_min_pos) != 0);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "combo.pyx":184
+ *
+ * if value > 0 and value < min_pos:
+ * min_pos = value # <<<<<<<<<<<<<<
+ * min_pos_index = index
+ *
+ */
+ __pyx_v_min_pos = __pyx_v_value;
+
+ /* "combo.pyx":185
+ * if value > 0 and value < min_pos:
+ * min_pos = value
+ * min_pos_index = index # <<<<<<<<<<<<<<
+ *
+ * return _MinMaxResult(minimum,
+ */
+ __pyx_v_min_pos_index = __pyx_v_index;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+ }
+ __pyx_L20:;
+ }
+ }
+ __pyx_L10:;
+ }
+
+ /* "combo.pyx":125
+ * raise ValueError('Zero-size array')
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * # Init starting values
+ * value = data[0]
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ }
+ }
+
+ /* "combo.pyx":187
+ * min_pos_index = index
+ *
+ * return _MinMaxResult(minimum, # <<<<<<<<<<<<<<
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_MinMaxResult); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_11 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_minimum); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+
+ /* "combo.pyx":188
+ *
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * maximum,
+ * min_index,
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_13 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_min_pos); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ __pyx_t_12 = __pyx_t_13;
+ __pyx_t_13 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_12 = Py_None;
+ }
+
+ /* "combo.pyx":189
+ * return _MinMaxResult(minimum,
+ * min_pos if min_pos > 0 else None,
+ * maximum, # <<<<<<<<<<<<<<
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ */
+ __pyx_t_13 = __Pyx_PyInt_From_unsigned_PY_LONG_LONG(__pyx_v_maximum); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+
+ /* "combo.pyx":190
+ * min_pos if min_pos > 0 else None,
+ * maximum,
+ * min_index, # <<<<<<<<<<<<<<
+ * min_pos_index if min_pos > 0 else None,
+ * max_index)
+ */
+ __pyx_t_14 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_index); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+
+ /* "combo.pyx":191
+ * maximum,
+ * min_index,
+ * min_pos_index if min_pos > 0 else None, # <<<<<<<<<<<<<<
+ * max_index)
+ *
+ */
+ if (((__pyx_v_min_pos > 0) != 0)) {
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_min_pos_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_15 = __pyx_t_16;
+ __pyx_t_16 = 0;
+ } else {
+ __Pyx_INCREF(Py_None);
+ __pyx_t_15 = Py_None;
+ }
+
+ /* "combo.pyx":192
+ * min_index,
+ * min_pos_index if min_pos > 0 else None,
+ * max_index) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_16 = __Pyx_PyInt_From_unsigned_int(__pyx_v_max_index); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = NULL;
+ __pyx_t_18 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_17)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_17);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ __pyx_t_18 = 1;
+ }
+ }
+ __pyx_t_19 = PyTuple_New(6+__pyx_t_18); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_19);
+ if (__pyx_t_17) {
+ PyTuple_SET_ITEM(__pyx_t_19, 0, __pyx_t_17); __Pyx_GIVEREF(__pyx_t_17); __pyx_t_17 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_19, 0+__pyx_t_18, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_19, 1+__pyx_t_18, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_19, 2+__pyx_t_18, __pyx_t_13);
+ __Pyx_GIVEREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_19, 3+__pyx_t_18, __pyx_t_14);
+ __Pyx_GIVEREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_19, 4+__pyx_t_18, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_19, 5+__pyx_t_18, __pyx_t_16);
+ __Pyx_GIVEREF(__pyx_t_16);
+ __pyx_t_11 = 0;
+ __pyx_t_12 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_16 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_19, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_19);
+ __Pyx_AddTraceback("combo._min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "combo.pyx":195
+ *
+ *
+ * def min_max(data not None, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """Returns min, max and optionally strictly positive min of data.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5combo_3min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_5combo_2min_max[] = "Returns min, max and optionally strictly positive min of data.\n\n It also computes the indices of first occurence of min/max.\n\n NaNs are ignored while computing min/max unless all data is NaNs,\n in which case returned min/max are NaNs.\n\n Examples:\n\n >>> import numpy\n >>> data = numpy.arange(10)\n\n Usage as a function returning min and max:\n\n >>> min_, max_ = min_max(data)\n\n Usage as a function returning a result object to access all information:\n\n >>> result = min_max(data) # Do not get positive min\n >>> result.minimum, result.argmin\n 0, 0\n >>> result.maximum, result.argmax\n 9, 10\n >>> result.min_positive, result.argmin_positive # Not computed\n None, None\n\n Getting strictly positive min information:\n\n >>> result = min_max(data, min_positive=True)\n >>> result.min_positive, result.argmin_positive # Computed\n 1, 1\n\n :param data: Array-like dataset\n :param bool min_positive: True to compute the positive min and argmin\n Default: False.\n :returns: An object with minimum, maximum and min_positive attributes\n and the indices of first occurence in the flattened data:\n argmin, argmax and argmin_positive attributes.\n If all data is <= 0 or min_positive argument is False, then\n min_positive and argmin_positive are None.\n :raises: ValueError if data is empty\n ";
+static PyMethodDef __pyx_mdef_5combo_3min_max = {"min_max", (PyCFunction)__pyx_pw_5combo_3min_max, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5combo_2min_max};
+static PyObject *__pyx_pw_5combo_3min_max(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ int __pyx_v_min_positive;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("min_max (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_min_positive_2,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_min_positive_2);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "min_max") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = values[0];
+ if (values[1]) {
+ __pyx_v_min_positive = __Pyx_PyObject_IsTrue(values[1]); if (unlikely((__pyx_v_min_positive == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_min_positive = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("min_max", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("combo.min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(((PyObject *)__pyx_v_data) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "data"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_pf_5combo_2min_max(__pyx_self, __pyx_v_data, __pyx_v_min_positive);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5combo_2min_max(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, int __pyx_v_min_positive) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("min_max", 0);
+
+ /* "combo.pyx":238
+ * :raises: ValueError if data is empty
+ * """
+ * return _min_max(numpy.ascontiguousarray(data).ravel(), min_positive) # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_min_max); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_data); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_ravel); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_min_positive); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_7 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_8, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_3 = 0;
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "combo.pyx":195
+ *
+ *
+ * def min_max(data not None, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """Returns min, max and optionally strictly positive min of data.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("combo.min_max", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__26);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__26);
+ __Pyx_GIVEREF(__pyx_slice__26);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__27); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__28);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__28);
+ __Pyx_GIVEREF(__pyx_slice__28);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "combo.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "combo.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "combo.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "combo._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "combo",
+ __pyx_k_This_module_provides_combination, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_20_12_2016, __pyx_k_20_12_2016, sizeof(__pyx_k_20_12_2016), 0, 0, 1, 0},
+ {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Expected_at_least_d_arguments, __pyx_k_Expected_at_least_d_arguments, sizeof(__pyx_k_Expected_at_least_d_arguments), 0, 0, 1, 0},
+ {&__pyx_kp_s_Function_call_with_ambiguous_arg, __pyx_k_Function_call_with_ambiguous_arg, sizeof(__pyx_k_Function_call_with_ambiguous_arg), 0, 0, 1, 0},
+ {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Index_of_the_first_occurence_of, __pyx_k_Index_of_the_first_occurence_of, sizeof(__pyx_k_Index_of_the_first_occurence_of), 0, 0, 1, 0},
+ {&__pyx_kp_s_Index_of_the_first_occurence_of_2, __pyx_k_Index_of_the_first_occurence_of_2, sizeof(__pyx_k_Index_of_the_first_occurence_of_2), 0, 0, 1, 0},
+ {&__pyx_kp_s_Index_of_the_strictly_positive_m, __pyx_k_Index_of_the_strictly_positive_m, sizeof(__pyx_k_Index_of_the_strictly_positive_m), 0, 0, 1, 0},
+ {&__pyx_kp_s_Index_out_of_range, __pyx_k_Index_out_of_range, sizeof(__pyx_k_Index_out_of_range), 0, 0, 1, 0},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_kp_s_Maximum_value_of_the_array, __pyx_k_Maximum_value_of_the_array, sizeof(__pyx_k_Maximum_value_of_the_array), 0, 0, 1, 0},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_n_s_MinMaxResult, __pyx_k_MinMaxResult, sizeof(__pyx_k_MinMaxResult), 0, 0, 1, 1},
+ {&__pyx_n_s_MinMaxResult___getitem, __pyx_k_MinMaxResult___getitem, sizeof(__pyx_k_MinMaxResult___getitem), 0, 0, 1, 1},
+ {&__pyx_n_s_MinMaxResult___init, __pyx_k_MinMaxResult___init, sizeof(__pyx_k_MinMaxResult___init), 0, 0, 1, 1},
+ {&__pyx_n_s_MinMaxResult_lambda, __pyx_k_MinMaxResult_lambda, sizeof(__pyx_k_MinMaxResult_lambda), 0, 0, 1, 1},
+ {&__pyx_kp_s_Minimum_value_of_the_array, __pyx_k_Minimum_value_of_the_array, sizeof(__pyx_k_Minimum_value_of_the_array), 0, 0, 1, 0},
+ {&__pyx_kp_s_No_matching_signature_found, __pyx_k_No_matching_signature_found, sizeof(__pyx_k_No_matching_signature_found), 0, 0, 1, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Object_storing_result_from_func, __pyx_k_Object_storing_result_from_func, sizeof(__pyx_k_Object_storing_result_from_func), 0, 0, 1, 0},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_kp_u_Returns_min_max_and_optionally_s, __pyx_k_Returns_min_max_and_optionally_s, sizeof(__pyx_k_Returns_min_max_and_optionally_s), 0, 1, 0, 0},
+ {&__pyx_kp_s_Strictly_positive_minimum_value, __pyx_k_Strictly_positive_minimum_value, sizeof(__pyx_k_Strictly_positive_minimum_value), 0, 0, 1, 0},
+ {&__pyx_kp_s_T_Vincent, __pyx_k_T_Vincent, sizeof(__pyx_k_T_Vincent), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Zero_size_array, __pyx_k_Zero_size_array, sizeof(__pyx_k_Zero_size_array), 0, 0, 1, 0},
+ {&__pyx_kp_s__3, __pyx_k__3, sizeof(__pyx_k__3), 0, 0, 1, 0},
+ {&__pyx_kp_s__5, __pyx_k__5, sizeof(__pyx_k__5), 0, 0, 1, 0},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_argmax, __pyx_k_argmax, sizeof(__pyx_k_argmax), 0, 0, 1, 1},
+ {&__pyx_n_s_argmax_2, __pyx_k_argmax_2, sizeof(__pyx_k_argmax_2), 0, 0, 1, 1},
+ {&__pyx_n_s_argmin, __pyx_k_argmin, sizeof(__pyx_k_argmin), 0, 0, 1, 1},
+ {&__pyx_n_s_argmin_2, __pyx_k_argmin_2, sizeof(__pyx_k_argmin_2), 0, 0, 1, 1},
+ {&__pyx_n_s_argmin_pos, __pyx_k_argmin_pos, sizeof(__pyx_k_argmin_pos), 0, 0, 1, 1},
+ {&__pyx_n_s_argmin_positive, __pyx_k_argmin_positive, sizeof(__pyx_k_argmin_positive), 0, 0, 1, 1},
+ {&__pyx_n_s_argmin_positive_2, __pyx_k_argmin_positive_2, sizeof(__pyx_k_argmin_positive_2), 0, 0, 1, 1},
+ {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1},
+ {&__pyx_n_s_ascontiguousarray, __pyx_k_ascontiguousarray, sizeof(__pyx_k_ascontiguousarray), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_n_s_combo, __pyx_k_combo, sizeof(__pyx_k_combo), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_defaults, __pyx_k_defaults, sizeof(__pyx_k_defaults), 0, 0, 1, 1},
+ {&__pyx_n_s_doc, __pyx_k_doc, sizeof(__pyx_k_doc), 0, 0, 1, 1},
+ {&__pyx_n_s_doc_2, __pyx_k_doc_2, sizeof(__pyx_k_doc_2), 0, 0, 1, 1},
+ {&__pyx_n_s_double, __pyx_k_double, sizeof(__pyx_k_double), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_float, __pyx_k_float, sizeof(__pyx_k_float), 0, 0, 1, 1},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_n_s_getitem, __pyx_k_getitem, sizeof(__pyx_k_getitem), 0, 0, 1, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_index, __pyx_k_index, sizeof(__pyx_k_index), 0, 0, 1, 1},
+ {&__pyx_n_s_init, __pyx_k_init, sizeof(__pyx_k_init), 0, 0, 1, 1},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_key, __pyx_k_key, sizeof(__pyx_k_key), 0, 0, 1, 1},
+ {&__pyx_n_s_kind, __pyx_k_kind, sizeof(__pyx_k_kind), 0, 0, 1, 1},
+ {&__pyx_n_s_kwargs, __pyx_k_kwargs, sizeof(__pyx_k_kwargs), 0, 0, 1, 1},
+ {&__pyx_n_s_length, __pyx_k_length, sizeof(__pyx_k_length), 0, 0, 1, 1},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_max_index, __pyx_k_max_index, sizeof(__pyx_k_max_index), 0, 0, 1, 1},
+ {&__pyx_n_s_maximum, __pyx_k_maximum, sizeof(__pyx_k_maximum), 0, 0, 1, 1},
+ {&__pyx_n_s_maximum_2, __pyx_k_maximum_2, sizeof(__pyx_k_maximum_2), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_n_s_metaclass, __pyx_k_metaclass, sizeof(__pyx_k_metaclass), 0, 0, 1, 1},
+ {&__pyx_n_s_min_index, __pyx_k_min_index, sizeof(__pyx_k_min_index), 0, 0, 1, 1},
+ {&__pyx_n_s_min_max, __pyx_k_min_max, sizeof(__pyx_k_min_max), 0, 0, 1, 1},
+ {&__pyx_n_s_min_max_2, __pyx_k_min_max_2, sizeof(__pyx_k_min_max_2), 0, 0, 1, 1},
+ {&__pyx_kp_u_min_max_line_195, __pyx_k_min_max_line_195, sizeof(__pyx_k_min_max_line_195), 0, 1, 0, 0},
+ {&__pyx_n_s_min_pos, __pyx_k_min_pos, sizeof(__pyx_k_min_pos), 0, 0, 1, 1},
+ {&__pyx_n_s_min_pos_index, __pyx_k_min_pos_index, sizeof(__pyx_k_min_pos_index), 0, 0, 1, 1},
+ {&__pyx_n_s_min_positive, __pyx_k_min_positive, sizeof(__pyx_k_min_positive), 0, 0, 1, 1},
+ {&__pyx_n_s_min_positive_2, __pyx_k_min_positive_2, sizeof(__pyx_k_min_positive_2), 0, 0, 1, 1},
+ {&__pyx_n_s_minimum, __pyx_k_minimum, sizeof(__pyx_k_minimum), 0, 0, 1, 1},
+ {&__pyx_n_s_minimum_2, __pyx_k_minimum_2, sizeof(__pyx_k_minimum_2), 0, 0, 1, 1},
+ {&__pyx_n_s_minpos, __pyx_k_minpos, sizeof(__pyx_k_minpos), 0, 0, 1, 1},
+ {&__pyx_kp_s_mntdirect__tmp_14_days_tvincent, __pyx_k_mntdirect__tmp_14_days_tvincent, sizeof(__pyx_k_mntdirect__tmp_14_days_tvincent), 0, 0, 1, 0},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_module, __pyx_k_module, sizeof(__pyx_k_module), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_n_s_ndarray, __pyx_k_ndarray, sizeof(__pyx_k_ndarray), 0, 0, 1, 1},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_n_s_object, __pyx_k_object, sizeof(__pyx_k_object), 0, 0, 1, 1},
+ {&__pyx_n_s_ord, __pyx_k_ord, sizeof(__pyx_k_ord), 0, 0, 1, 1},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_n_s_prepare, __pyx_k_prepare, sizeof(__pyx_k_prepare), 0, 0, 1, 1},
+ {&__pyx_n_s_property, __pyx_k_property, sizeof(__pyx_k_property), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_qualname, __pyx_k_qualname, sizeof(__pyx_k_qualname), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_ravel, __pyx_k_ravel, sizeof(__pyx_k_ravel), 0, 0, 1, 1},
+ {&__pyx_n_s_self, __pyx_k_self, sizeof(__pyx_k_self), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_signatures, __pyx_k_signatures, sizeof(__pyx_k_signatures), 0, 0, 1, 1},
+ {&__pyx_kp_s_signed_char, __pyx_k_signed_char, sizeof(__pyx_k_signed_char), 0, 0, 1, 0},
+ {&__pyx_kp_s_signed_int, __pyx_k_signed_int, sizeof(__pyx_k_signed_int), 0, 0, 1, 0},
+ {&__pyx_kp_s_signed_long, __pyx_k_signed_long, sizeof(__pyx_k_signed_long), 0, 0, 1, 0},
+ {&__pyx_kp_s_signed_short, __pyx_k_signed_short, sizeof(__pyx_k_signed_short), 0, 0, 1, 0},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_split, __pyx_k_split, sizeof(__pyx_k_split), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_strip, __pyx_k_strip, sizeof(__pyx_k_strip), 0, 0, 1, 1},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_kp_s_unsigned_char, __pyx_k_unsigned_char, sizeof(__pyx_k_unsigned_char), 0, 0, 1, 0},
+ {&__pyx_kp_s_unsigned_int, __pyx_k_unsigned_int, sizeof(__pyx_k_unsigned_int), 0, 0, 1, 0},
+ {&__pyx_kp_s_unsigned_long_long, __pyx_k_unsigned_long_long, sizeof(__pyx_k_unsigned_long_long), 0, 0, 1, 0},
+ {&__pyx_kp_s_unsigned_short, __pyx_k_unsigned_short, sizeof(__pyx_k_unsigned_short), 0, 0, 1, 0},
+ {&__pyx_n_s_value, __pyx_k_value, sizeof(__pyx_k_value), 0, 0, 1, 1},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {&__pyx_n_s_zip, __pyx_k_zip, sizeof(__pyx_k_zip), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_object = __Pyx_GetBuiltinName(__pyx_n_s_object); if (!__pyx_builtin_object) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_property = __Pyx_GetBuiltinName(__pyx_n_s_property); if (!__pyx_builtin_property) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ord = __Pyx_GetBuiltinName(__pyx_n_s_ord); if (!__pyx_builtin_ord) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_zip = __Pyx_GetBuiltinName(__pyx_n_s_zip); if (!__pyx_builtin_zip) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "combo.pyx":104
+ * return self.maximum
+ * else:
+ * raise IndexError("Index out of range") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_Index_out_of_range); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s__3); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s__5); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_No_matching_signature_found); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__7);
+ __Pyx_GIVEREF(__pyx_tuple__7);
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_Function_call_with_ambiguous_arg); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "combo.pyx":123
+ *
+ * if length == 0:
+ * raise ValueError('Zero-size array') # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__12);
+ __Pyx_GIVEREF(__pyx_tuple__12);
+ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__13);
+ __Pyx_GIVEREF(__pyx_tuple__13);
+ __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__14);
+ __Pyx_GIVEREF(__pyx_tuple__14);
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+ __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_Zero_size_array); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__19);
+ __Pyx_GIVEREF(__pyx_tuple__19);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__21)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__21);
+ __Pyx_GIVEREF(__pyx_tuple__21);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__22);
+ __Pyx_GIVEREF(__pyx_tuple__22);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__23)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__23);
+ __Pyx_GIVEREF(__pyx_tuple__23);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__24);
+ __Pyx_GIVEREF(__pyx_tuple__24);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__25);
+ __Pyx_GIVEREF(__pyx_tuple__25);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__26 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__26)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__26);
+ __Pyx_GIVEREF(__pyx_slice__26);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__27 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__27)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__27);
+ __Pyx_GIVEREF(__pyx_slice__27);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__28 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__28)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__28);
+ __Pyx_GIVEREF(__pyx_slice__28);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__29)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__29);
+ __Pyx_GIVEREF(__pyx_tuple__29);
+
+ /* "combo.pyx":61
+ * """Object storing result from :func:`min_max`"""
+ *
+ * def __init__(self, minimum, min_pos, maximum, # <<<<<<<<<<<<<<
+ * argmin, argmin_pos, argmax):
+ * self._minimum = minimum
+ */
+ __pyx_tuple__30 = PyTuple_Pack(7, __pyx_n_s_self, __pyx_n_s_minimum_2, __pyx_n_s_min_pos, __pyx_n_s_maximum_2, __pyx_n_s_argmin_2, __pyx_n_s_argmin_pos, __pyx_n_s_argmax_2); if (unlikely(!__pyx_tuple__30)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__30);
+ __Pyx_GIVEREF(__pyx_tuple__30);
+ __pyx_codeobj__31 = (PyObject*)__Pyx_PyCode_New(7, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__30, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__tmp_14_days_tvincent, __pyx_n_s_init, 61, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__31)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":98
+ * It is the index of the first occurence.""")
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * if key == 0:
+ * return self.minimum
+ */
+ __pyx_tuple__32 = PyTuple_Pack(2, __pyx_n_s_self, __pyx_n_s_key); if (unlikely(!__pyx_tuple__32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__32);
+ __Pyx_GIVEREF(__pyx_tuple__32);
+ __pyx_codeobj__33 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__32, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__tmp_14_days_tvincent, __pyx_n_s_getitem, 98, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__33)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+ __pyx_tuple__34 = PyTuple_Pack(12, __pyx_n_s_data, __pyx_n_s_min_positive_2, __pyx_n_s_value, __pyx_n_s_minimum_2, __pyx_n_s_minpos, __pyx_n_s_maximum_2, __pyx_n_s_length, __pyx_n_s_index, __pyx_n_s_min_index, __pyx_n_s_min_pos_index, __pyx_n_s_max_index, __pyx_n_s_min_pos); if (unlikely(!__pyx_tuple__34)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__34);
+ __Pyx_GIVEREF(__pyx_tuple__34);
+ __pyx_codeobj__35 = (PyObject*)__Pyx_PyCode_New(2, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__34, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__tmp_14_days_tvincent, __pyx_n_s_min_max, 110, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__35)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":195
+ *
+ *
+ * def min_max(data not None, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """Returns min, max and optionally strictly positive min of data.
+ *
+ */
+ __pyx_tuple__36 = PyTuple_Pack(2, __pyx_n_s_data, __pyx_n_s_min_positive_2); if (unlikely(!__pyx_tuple__36)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__36);
+ __Pyx_GIVEREF(__pyx_tuple__36);
+ __pyx_codeobj__37 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__36, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__tmp_14_days_tvincent, __pyx_n_s_min_max_2, 195, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__37)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__38 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__38)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__38);
+ __Pyx_GIVEREF(__pyx_tuple__38);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__39 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__39)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__39);
+ __Pyx_GIVEREF(__pyx_tuple__39);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__40 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__40)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__40);
+ __Pyx_GIVEREF(__pyx_tuple__40);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__41 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__41)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__41);
+ __Pyx_GIVEREF(__pyx_tuple__41);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__42 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__42)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__42);
+ __Pyx_GIVEREF(__pyx_tuple__42);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initcombo(void); /*proto*/
+PyMODINIT_FUNC initcombo(void)
+#else
+PyMODINIT_FUNC PyInit_combo(void); /*proto*/
+PyMODINIT_FUNC PyInit_combo(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_combo(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("combo", __pyx_methods, __pyx_k_This_module_provides_combination, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_combo) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "combo")) {
+ if (unlikely(PyDict_SetItemString(modules, "combo", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "combo.pyx":31
+ * """
+ *
+ * __authors__ = ["T. Vincent"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "20/12/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_T_Vincent);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_T_Vincent);
+ __Pyx_GIVEREF(__pyx_kp_s_T_Vincent);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "combo.pyx":32
+ *
+ * __authors__ = ["T. Vincent"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "20/12/2016"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":33
+ * __authors__ = ["T. Vincent"]
+ * __license__ = "MIT"
+ * __date__ = "20/12/2016" # <<<<<<<<<<<<<<
+ *
+ * cimport cython
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_20_12_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "combo.pyx":42
+ * bint isnan(double x) nogil
+ *
+ * import numpy # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "combo.pyx":58
+ *
+ *
+ * class _MinMaxResult(object): # <<<<<<<<<<<<<<
+ * """Object storing result from :func:`min_max`"""
+ *
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_builtin_object);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_builtin_object);
+ __Pyx_GIVEREF(__pyx_builtin_object);
+ __pyx_t_2 = __Pyx_CalculateMetaclass(NULL, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_2, __pyx_t_1, __pyx_n_s_MinMaxResult, __pyx_n_s_MinMaxResult, (PyObject *) NULL, __pyx_n_s_combo, __pyx_kp_s_Object_storing_result_from_func); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "combo.pyx":61
+ * """Object storing result from :func:`min_max`"""
+ *
+ * def __init__(self, minimum, min_pos, maximum, # <<<<<<<<<<<<<<
+ * argmin, argmin_pos, argmax):
+ * self._minimum = minimum
+ */
+ __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_5combo_13_MinMaxResult_1__init__, 0, __pyx_n_s_MinMaxResult___init, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__31)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_init, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "combo.pyx":72
+ *
+ * minimum = property(
+ * lambda self: self._minimum, # <<<<<<<<<<<<<<
+ * doc="Minimum value of the array")
+ * maximum = property(
+ */
+ __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_5combo_13_MinMaxResult_4lambda1, 0, __pyx_n_s_MinMaxResult_lambda, NULL, __pyx_n_s_combo, __pyx_d, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+
+ /* "combo.pyx":71
+ * self._argmax = argmax
+ *
+ * minimum = property( # <<<<<<<<<<<<<<
+ * lambda self: self._minimum,
+ * doc="Minimum value of the array")
+ */
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_doc, __pyx_kp_s_Minimum_value_of_the_array) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_minimum_2, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "combo.pyx":75
+ * doc="Minimum value of the array")
+ * maximum = property(
+ * lambda self: self._maximum, # <<<<<<<<<<<<<<
+ * doc="Maximum value of the array")
+ *
+ */
+ __pyx_t_6 = __Pyx_CyFunction_NewEx(&__pyx_mdef_5combo_13_MinMaxResult_5lambda2, 0, __pyx_n_s_MinMaxResult_lambda, NULL, __pyx_n_s_combo, __pyx_d, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "combo.pyx":74
+ * lambda self: self._minimum,
+ * doc="Minimum value of the array")
+ * maximum = property( # <<<<<<<<<<<<<<
+ * lambda self: self._maximum,
+ * doc="Maximum value of the array")
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_doc, __pyx_kp_s_Maximum_value_of_the_array) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_maximum_2, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "combo.pyx":79
+ *
+ * argmin = property(
+ * lambda self: self._argmin, # <<<<<<<<<<<<<<
+ * doc="Index of the first occurence of the minimum value")
+ * argmax = property(
+ */
+ __pyx_t_5 = __Pyx_CyFunction_NewEx(&__pyx_mdef_5combo_13_MinMaxResult_6lambda3, 0, __pyx_n_s_MinMaxResult_lambda, NULL, __pyx_n_s_combo, __pyx_d, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "combo.pyx":78
+ * doc="Maximum value of the array")
+ *
+ * argmin = property( # <<<<<<<<<<<<<<
+ * lambda self: self._argmin,
+ * doc="Index of the first occurence of the minimum value")
+ */
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_doc, __pyx_kp_s_Index_of_the_first_occurence_of) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_argmin_2, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "combo.pyx":82
+ * doc="Index of the first occurence of the minimum value")
+ * argmax = property(
+ * lambda self: self._argmax, # <<<<<<<<<<<<<<
+ * doc="Index of the first occurence of the maximum value")
+ *
+ */
+ __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_5combo_13_MinMaxResult_7lambda4, 0, __pyx_n_s_MinMaxResult_lambda, NULL, __pyx_n_s_combo, __pyx_d, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+
+ /* "combo.pyx":81
+ * lambda self: self._argmin,
+ * doc="Index of the first occurence of the minimum value")
+ * argmax = property( # <<<<<<<<<<<<<<
+ * lambda self: self._argmax,
+ * doc="Index of the first occurence of the maximum value")
+ */
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_doc, __pyx_kp_s_Index_of_the_first_occurence_of_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_argmax_2, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "combo.pyx":86
+ *
+ * min_positive = property(
+ * lambda self: self._min_positive, # <<<<<<<<<<<<<<
+ * doc="""Strictly positive minimum value
+ *
+ */
+ __pyx_t_6 = __Pyx_CyFunction_NewEx(&__pyx_mdef_5combo_13_MinMaxResult_8lambda5, 0, __pyx_n_s_MinMaxResult_lambda, NULL, __pyx_n_s_combo, __pyx_d, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "combo.pyx":85
+ * doc="Index of the first occurence of the maximum value")
+ *
+ * min_positive = property( # <<<<<<<<<<<<<<
+ * lambda self: self._min_positive,
+ * doc="""Strictly positive minimum value
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_doc, __pyx_kp_s_Strictly_positive_minimum_value) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_min_positive_2, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "combo.pyx":92
+ * """)
+ * argmin_positive = property(
+ * lambda self: self._argmin_positive, # <<<<<<<<<<<<<<
+ * doc="""Index of the strictly positive minimum value.
+ *
+ */
+ __pyx_t_5 = __Pyx_CyFunction_NewEx(&__pyx_mdef_5combo_13_MinMaxResult_9lambda6, 0, __pyx_n_s_MinMaxResult_lambda, NULL, __pyx_n_s_combo, __pyx_d, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "combo.pyx":91
+ * It is None if no value is strictly positive.
+ * """)
+ * argmin_positive = property( # <<<<<<<<<<<<<<
+ * lambda self: self._argmin_positive,
+ * doc="""Index of the strictly positive minimum value.
+ */
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_doc, __pyx_kp_s_Index_of_the_strictly_positive_m) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_argmin_positive_2, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "combo.pyx":98
+ * It is the index of the first occurence.""")
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * if key == 0:
+ * return self.minimum
+ */
+ __pyx_t_4 = __Pyx_CyFunction_NewEx(&__pyx_mdef_5combo_13_MinMaxResult_3__getitem__, 0, __pyx_n_s_MinMaxResult___getitem, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__33)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyObject_SetItem(__pyx_t_3, __pyx_n_s_getitem, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "combo.pyx":58
+ *
+ *
+ * class _MinMaxResult(object): # <<<<<<<<<<<<<<
+ * """Object storing result from :func:`min_max`"""
+ *
+ */
+ __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_2, __pyx_n_s_MinMaxResult, __pyx_t_1, __pyx_t_3, NULL, 0, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_MinMaxResult, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "combo.pyx":110
+ * @cython.boundscheck(False)
+ * @cython.wraparound(False)
+ * def _min_max(_number[::1] data, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """See :func:`min_max` for documentation."""
+ * cdef:
+ */
+ __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_k__2 = __pyx_t_1;
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0__pyx_mdef_5combo_5_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults10), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults10, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_46__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_float, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1__pyx_mdef_5combo_7_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults11), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults11, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_48__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_double, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2__pyx_mdef_5combo_9_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults12), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults12, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_50__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_signed_char, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3__pyx_mdef_5combo_11_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults13), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults13, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_52__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_signed_short, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_4__pyx_mdef_5combo_13_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults14), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults14, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_54__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_signed_int, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_5__pyx_mdef_5combo_15_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults15), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults15, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_56__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_signed_long, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_6__pyx_mdef_5combo_17_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults16), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults16, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_58__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_unsigned_char, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_7__pyx_mdef_5combo_19_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults17), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults17, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_60__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_unsigned_short, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_8__pyx_mdef_5combo_21_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults18), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults18, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_62__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_unsigned_int, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_fuse_9__pyx_mdef_5combo_23_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!__Pyx_CyFunction_InitDefaults(__pyx_t_3, sizeof(__pyx_defaults19), 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_CyFunction_Defaults(__pyx_defaults19, __pyx_t_3)->__pyx_arg_min_positive = 0;
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_64__defaults__);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_unsigned_long_long, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_FusedFunction_NewEx(&__pyx_mdef_5combo_1_min_max, 0, __pyx_n_s_min_max, NULL, __pyx_n_s_combo, __pyx_d, ((PyObject *)__pyx_codeobj__35)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_3, __pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsGetter(__pyx_t_3, __pyx_pf_5combo_46__defaults__);
+ ((__pyx_FusedFunctionObject *) __pyx_t_3)->__signatures__ = __pyx_t_1;
+ __Pyx_GIVEREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_min_max, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "combo.pyx":195
+ *
+ *
+ * def min_max(data not None, bint min_positive=False): # <<<<<<<<<<<<<<
+ * """Returns min, max and optionally strictly positive min of data.
+ *
+ */
+ __pyx_t_4 = PyCFunction_NewEx(&__pyx_mdef_5combo_3min_max, NULL, __pyx_n_s_combo); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_min_max_2, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "combo.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * # /[inserted by cython to avoid comment start]*##########################################################################
+ * #
+ */
+ __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyDict_SetItem(__pyx_t_4, __pyx_kp_u_min_max_line_195, __pyx_kp_u_Returns_min_max_and_optionally_s) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_4 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__38, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__39, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__40, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__41, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__42, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "__pyxutil":2
+ *
+ * cdef extern from *: # <<<<<<<<<<<<<<
+ * void __pyx_PyErr_Clear "PyErr_Clear" ()
+ * __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_float(object)
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init combo", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init combo");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+ int r;
+ if (!j) return -1;
+ r = PyObject_SetItem(o, j, v);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o));
+ if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+ PyObject* old = PyList_GET_ITEM(o, n);
+ Py_INCREF(v);
+ PyList_SET_ITEM(o, n, v);
+ Py_DECREF(old);
+ return 1;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_ass_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return -1;
+ }
+ }
+ return m->sq_ass_item(o, i, v);
+ }
+ }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+ if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) {
+#else
+ if (is_list || PySequence_Check(o)) {
+#endif
+ return PySequence_SetItem(o, i, v);
+ }
+#endif
+ return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* exc_type = tstate->curexc_type;
+ if (unlikely(exc_type)) {
+ if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+ PyObject *exc_value, *exc_tb;
+ exc_value = tstate->curexc_value;
+ exc_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+ Py_DECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#else
+ if (unlikely(PyErr_Occurred())) {
+ if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+ PyErr_Clear();
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
+ PyObject *method, *result = NULL;
+ method = __Pyx_PyObject_GetAttrStr(obj, method_name);
+ if (unlikely(!method)) goto bad;
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyMethod_Check(method))) {
+ PyObject *self = PyMethod_GET_SELF(method);
+ if (likely(self)) {
+ PyObject *function = PyMethod_GET_FUNCTION(method);
+ result = __Pyx_PyObject_CallOneArg(function, self);
+ Py_DECREF(method);
+ return result;
+ }
+ }
+#endif
+ result = __Pyx_PyObject_CallNoArg(method);
+ Py_DECREF(method);
+bad:
+ return result;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+ if (unlikely(retval)) {
+ Py_DECREF(retval);
+ __Pyx_RaiseTooManyValuesError(expected);
+ return -1;
+ } else {
+ return __Pyx_IterFinish();
+ }
+ return 0;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
+ if (t == Py_None) {
+ __Pyx_RaiseNoneNotIterableError();
+ } else if (PyTuple_GET_SIZE(t) < index) {
+ __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
+ } else {
+ __Pyx_RaiseTooManyValuesError(index);
+ }
+}
+
+static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2,
+ int is_tuple, int has_known_size, int decref_tuple) {
+ Py_ssize_t index;
+ PyObject *value1 = NULL, *value2 = NULL, *iter = NULL;
+ if (!is_tuple && unlikely(!PyTuple_Check(tuple))) {
+ iternextfunc iternext;
+ iter = PyObject_GetIter(tuple);
+ if (unlikely(!iter)) goto bad;
+ if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; }
+ iternext = Py_TYPE(iter)->tp_iternext;
+ value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; }
+ value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; }
+ if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad;
+ Py_DECREF(iter);
+ } else {
+ if (!has_known_size && unlikely(PyTuple_GET_SIZE(tuple) != 2)) {
+ __Pyx_UnpackTupleError(tuple, 2);
+ goto bad;
+ }
+#if CYTHON_COMPILING_IN_PYPY
+ value1 = PySequence_ITEM(tuple, 0);
+ if (unlikely(!value1)) goto bad;
+ value2 = PySequence_ITEM(tuple, 1);
+ if (unlikely(!value2)) goto bad;
+#else
+ value1 = PyTuple_GET_ITEM(tuple, 0);
+ value2 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(value1);
+ Py_INCREF(value2);
+#endif
+ if (decref_tuple) { Py_DECREF(tuple); }
+ }
+ *pvalue1 = value1;
+ *pvalue2 = value2;
+ return 0;
+unpacking_failed:
+ if (!has_known_size && __Pyx_IterFinish() == 0)
+ __Pyx_RaiseNeedMoreValuesError(index);
+bad:
+ Py_XDECREF(iter);
+ Py_XDECREF(value1);
+ Py_XDECREF(value2);
+ if (decref_tuple) { Py_XDECREF(tuple); }
+ return -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name,
+ Py_ssize_t* p_orig_length, int* p_source_is_dict) {
+ is_dict = is_dict || likely(PyDict_CheckExact(iterable));
+ *p_source_is_dict = is_dict;
+#if !CYTHON_COMPILING_IN_PYPY
+ if (is_dict) {
+ *p_orig_length = PyDict_Size(iterable);
+ Py_INCREF(iterable);
+ return iterable;
+ }
+#endif
+ *p_orig_length = 0;
+ if (method_name) {
+ PyObject* iter;
+ iterable = __Pyx_PyObject_CallMethod0(iterable, method_name);
+ if (!iterable)
+ return NULL;
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable))
+ return iterable;
+#endif
+ iter = PyObject_GetIter(iterable);
+ Py_DECREF(iterable);
+ return iter;
+ }
+ return PyObject_GetIter(iterable);
+}
+static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* iter_obj, Py_ssize_t orig_length, Py_ssize_t* ppos,
+ PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) {
+ PyObject* next_item;
+#if !CYTHON_COMPILING_IN_PYPY
+ if (source_is_dict) {
+ PyObject *key, *value;
+ if (unlikely(orig_length != PyDict_Size(iter_obj))) {
+ PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration");
+ return -1;
+ }
+ if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) {
+ return 0;
+ }
+ if (pitem) {
+ PyObject* tuple = PyTuple_New(2);
+ if (unlikely(!tuple)) {
+ return -1;
+ }
+ Py_INCREF(key);
+ Py_INCREF(value);
+ PyTuple_SET_ITEM(tuple, 0, key);
+ PyTuple_SET_ITEM(tuple, 1, value);
+ *pitem = tuple;
+ } else {
+ if (pkey) {
+ Py_INCREF(key);
+ *pkey = key;
+ }
+ if (pvalue) {
+ Py_INCREF(value);
+ *pvalue = value;
+ }
+ }
+ return 1;
+ } else if (PyTuple_CheckExact(iter_obj)) {
+ Py_ssize_t pos = *ppos;
+ if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0;
+ *ppos = pos + 1;
+ next_item = PyTuple_GET_ITEM(iter_obj, pos);
+ Py_INCREF(next_item);
+ } else if (PyList_CheckExact(iter_obj)) {
+ Py_ssize_t pos = *ppos;
+ if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0;
+ *ppos = pos + 1;
+ next_item = PyList_GET_ITEM(iter_obj, pos);
+ Py_INCREF(next_item);
+ } else
+#endif
+ {
+ next_item = PyIter_Next(iter_obj);
+ if (unlikely(!next_item)) {
+ return __Pyx_IterFinish();
+ }
+ }
+ if (pitem) {
+ *pitem = next_item;
+ } else if (pkey && pvalue) {
+ if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1))
+ return -1;
+ } else if (pkey) {
+ *pkey = next_item;
+ } else {
+ *pvalue = next_item;
+ }
+ return 1;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+static PyObject *__Pyx_CalculateMetaclass(PyTypeObject *metaclass, PyObject *bases) {
+ Py_ssize_t i, nbases = PyTuple_GET_SIZE(bases);
+ for (i=0; i < nbases; i++) {
+ PyTypeObject *tmptype;
+ PyObject *tmp = PyTuple_GET_ITEM(bases, i);
+ tmptype = Py_TYPE(tmp);
+#if PY_MAJOR_VERSION < 3
+ if (tmptype == &PyClass_Type)
+ continue;
+#endif
+ if (!metaclass) {
+ metaclass = tmptype;
+ continue;
+ }
+ if (PyType_IsSubtype(metaclass, tmptype))
+ continue;
+ if (PyType_IsSubtype(tmptype, metaclass)) {
+ metaclass = tmptype;
+ continue;
+ }
+ PyErr_SetString(PyExc_TypeError,
+ "metaclass conflict: "
+ "the metaclass of a derived class "
+ "must be a (non-strict) subclass "
+ "of the metaclasses of all its bases");
+ return NULL;
+ }
+ if (!metaclass) {
+#if PY_MAJOR_VERSION < 3
+ metaclass = &PyClass_Type;
+#else
+ metaclass = &PyType_Type;
+#endif
+ }
+ Py_INCREF((PyObject*) metaclass);
+ return (PyObject*) metaclass;
+}
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
+ PyObject* fake_module;
+ PyTypeObject* cached_type = NULL;
+ fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
+ if (!fake_module) return NULL;
+ Py_INCREF(fake_module);
+ cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
+ if (cached_type) {
+ if (!PyType_Check((PyObject*)cached_type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s is not a type object",
+ type->tp_name);
+ goto bad;
+ }
+ if (cached_type->tp_basicsize != type->tp_basicsize) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s has the wrong size, try recompiling",
+ type->tp_name);
+ goto bad;
+ }
+ } else {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+ PyErr_Clear();
+ if (PyType_Ready(type) < 0) goto bad;
+ if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
+ goto bad;
+ Py_INCREF(type);
+ cached_type = type;
+ }
+done:
+ Py_DECREF(fake_module);
+ return cached_type;
+bad:
+ Py_XDECREF(cached_type);
+ cached_type = NULL;
+ goto done;
+}
+
+static PyObject *
+__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure)
+{
+ if (unlikely(op->func_doc == NULL)) {
+ if (op->func.m_ml->ml_doc) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc);
+#else
+ op->func_doc = PyString_FromString(op->func.m_ml->ml_doc);
+#endif
+ if (unlikely(op->func_doc == NULL))
+ return NULL;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+ Py_INCREF(op->func_doc);
+ return op->func_doc;
+}
+static int
+__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp = op->func_doc;
+ if (value == NULL) {
+ value = Py_None;
+ }
+ Py_INCREF(value);
+ op->func_doc = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_name == NULL)) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name);
+#else
+ op->func_name = PyString_InternFromString(op->func.m_ml->ml_name);
+#endif
+ if (unlikely(op->func_name == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_name);
+ return op->func_name;
+}
+static int
+__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__name__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_name;
+ Py_INCREF(value);
+ op->func_name = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_qualname);
+ return op->func_qualname;
+}
+static int
+__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__qualname__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_qualname;
+ Py_INCREF(value);
+ op->func_qualname = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure)
+{
+ PyObject *self;
+ self = m->func_closure;
+ if (self == NULL)
+ self = Py_None;
+ Py_INCREF(self);
+ return self;
+}
+static PyObject *
+__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_dict == NULL)) {
+ op->func_dict = PyDict_New();
+ if (unlikely(op->func_dict == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_dict);
+ return op->func_dict;
+}
+static int
+__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+ if (unlikely(value == NULL)) {
+ PyErr_SetString(PyExc_TypeError,
+ "function's dictionary may not be deleted");
+ return -1;
+ }
+ if (unlikely(!PyDict_Check(value))) {
+ PyErr_SetString(PyExc_TypeError,
+ "setting function's dictionary to a non-dict");
+ return -1;
+ }
+ tmp = op->func_dict;
+ Py_INCREF(value);
+ op->func_dict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_globals);
+ return op->func_globals;
+}
+static PyObject *
+__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op)
+{
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+static PyObject *
+__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op)
+{
+ PyObject* result = (op->func_code) ? op->func_code : Py_None;
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) {
+ PyObject *res = op->defaults_getter((PyObject *) op);
+ if (unlikely(!res))
+ return -1;
+ op->defaults_tuple = PyTuple_GET_ITEM(res, 0);
+ Py_INCREF(op->defaults_tuple);
+ op->defaults_kwdict = PyTuple_GET_ITEM(res, 1);
+ Py_INCREF(op->defaults_kwdict);
+ Py_DECREF(res);
+ return 0;
+}
+static int
+__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyTuple_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__defaults__ must be set to a tuple object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_tuple;
+ op->defaults_tuple = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_tuple;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_tuple;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__kwdefaults__ must be set to a dict object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_kwdict;
+ op->defaults_kwdict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_kwdict;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_kwdict;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value || value == Py_None) {
+ value = NULL;
+ } else if (!PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__annotations__ must be set to a dict object");
+ return -1;
+ }
+ Py_XINCREF(value);
+ tmp = op->func_annotations;
+ op->func_annotations = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->func_annotations;
+ if (unlikely(!result)) {
+ result = PyDict_New();
+ if (unlikely(!result)) return NULL;
+ op->func_annotations = result;
+ }
+ Py_INCREF(result);
+ return result;
+}
+static PyGetSetDef __pyx_CyFunction_getsets[] = {
+ {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0},
+ {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0},
+ {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0},
+ {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+#ifndef PY_WRITE_RESTRICTED
+#define PY_WRITE_RESTRICTED WRITE_RESTRICTED
+#endif
+static PyMemberDef __pyx_CyFunction_members[] = {
+ {(char *) "__module__", T_OBJECT, offsetof(__pyx_CyFunctionObject, func.m_module), PY_WRITE_RESTRICTED, 0},
+ {0, 0, 0, 0, 0}
+};
+static PyObject *
+__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromString(m->func.m_ml->ml_name);
+#else
+ return PyString_FromString(m->func.m_ml->ml_name);
+#endif
+}
+static PyMethodDef __pyx_CyFunction_methods[] = {
+ {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0},
+ {0, 0, 0, 0}
+};
+#if PY_VERSION_HEX < 0x030500A0
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist)
+#else
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
+#endif
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname,
+ PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
+ __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
+ if (op == NULL)
+ return NULL;
+ op->flags = flags;
+ __Pyx_CyFunction_weakreflist(op) = NULL;
+ op->func.m_ml = ml;
+ op->func.m_self = (PyObject *) op;
+ Py_XINCREF(closure);
+ op->func_closure = closure;
+ Py_XINCREF(module);
+ op->func.m_module = module;
+ op->func_dict = NULL;
+ op->func_name = NULL;
+ Py_INCREF(qualname);
+ op->func_qualname = qualname;
+ op->func_doc = NULL;
+ op->func_classobj = NULL;
+ op->func_globals = globals;
+ Py_INCREF(op->func_globals);
+ Py_XINCREF(code);
+ op->func_code = code;
+ op->defaults_pyobjects = 0;
+ op->defaults = NULL;
+ op->defaults_tuple = NULL;
+ op->defaults_kwdict = NULL;
+ op->defaults_getter = NULL;
+ op->func_annotations = NULL;
+ PyObject_GC_Track(op);
+ return (PyObject *) op;
+}
+static int
+__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
+{
+ Py_CLEAR(m->func_closure);
+ Py_CLEAR(m->func.m_module);
+ Py_CLEAR(m->func_dict);
+ Py_CLEAR(m->func_name);
+ Py_CLEAR(m->func_qualname);
+ Py_CLEAR(m->func_doc);
+ Py_CLEAR(m->func_globals);
+ Py_CLEAR(m->func_code);
+ Py_CLEAR(m->func_classobj);
+ Py_CLEAR(m->defaults_tuple);
+ Py_CLEAR(m->defaults_kwdict);
+ Py_CLEAR(m->func_annotations);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_XDECREF(pydefaults[i]);
+ PyMem_Free(m->defaults);
+ m->defaults = NULL;
+ }
+ return 0;
+}
+static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
+{
+ PyObject_GC_UnTrack(m);
+ if (__Pyx_CyFunction_weakreflist(m) != NULL)
+ PyObject_ClearWeakRefs((PyObject *) m);
+ __Pyx_CyFunction_clear(m);
+ PyObject_GC_Del(m);
+}
+static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg)
+{
+ Py_VISIT(m->func_closure);
+ Py_VISIT(m->func.m_module);
+ Py_VISIT(m->func_dict);
+ Py_VISIT(m->func_name);
+ Py_VISIT(m->func_qualname);
+ Py_VISIT(m->func_doc);
+ Py_VISIT(m->func_globals);
+ Py_VISIT(m->func_code);
+ Py_VISIT(m->func_classobj);
+ Py_VISIT(m->defaults_tuple);
+ Py_VISIT(m->defaults_kwdict);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_VISIT(pydefaults[i]);
+ }
+ return 0;
+}
+static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
+ Py_INCREF(func);
+ return func;
+ }
+ if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) {
+ if (type == NULL)
+ type = (PyObject *)(Py_TYPE(obj));
+ return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type)));
+ }
+ if (obj == Py_None)
+ obj = NULL;
+ return __Pyx_PyMethod_New(func, obj, type);
+}
+static PyObject*
+__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromFormat("<cyfunction %U at %p>",
+ op->func_qualname, (void *)op);
+#else
+ return PyString_FromFormat("<cyfunction %s at %p>",
+ PyString_AsString(op->func_qualname), (void *)op);
+#endif
+}
+#if CYTHON_COMPILING_IN_PYPY
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyCFunctionObject* f = (PyCFunctionObject*)func;
+ PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ PyObject *self = PyCFunction_GET_SELF(func);
+ Py_ssize_t size;
+ switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+ case METH_VARARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0)
+ return (*meth)(self, arg);
+ break;
+ case METH_VARARGS | METH_KEYWORDS:
+ return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+ case METH_NOARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 0)
+ return (*meth)(self, NULL);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes no arguments (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ case METH_O:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 1)
+ return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes exactly one argument (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError, "Bad call flags in "
+ "__Pyx_CyFunction_Call. METH_OLDARGS is no "
+ "longer supported!");
+ return NULL;
+ }
+ PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+ f->m_ml->ml_name);
+ return NULL;
+}
+#else
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ return PyCFunction_Call(func, arg, kw);
+}
+#endif
+static PyTypeObject __pyx_CyFunctionType_type = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "cython_function_or_method",
+ sizeof(__pyx_CyFunctionObject),
+ 0,
+ (destructor) __Pyx_CyFunction_dealloc,
+ 0,
+ 0,
+ 0,
+#if PY_MAJOR_VERSION < 3
+ 0,
+#else
+ 0,
+#endif
+ (reprfunc) __Pyx_CyFunction_repr,
+ 0,
+ 0,
+ 0,
+ 0,
+ __Pyx_CyFunction_Call,
+ 0,
+ 0,
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ 0,
+ (traverseproc) __Pyx_CyFunction_traverse,
+ (inquiry) __Pyx_CyFunction_clear,
+ 0,
+#if PY_VERSION_HEX < 0x030500A0
+ offsetof(__pyx_CyFunctionObject, func_weakreflist),
+#else
+ offsetof(PyCFunctionObject, m_weakreflist),
+#endif
+ 0,
+ 0,
+ __pyx_CyFunction_methods,
+ __pyx_CyFunction_members,
+ __pyx_CyFunction_getsets,
+ 0,
+ 0,
+ __Pyx_CyFunction_descr_get,
+ 0,
+ offsetof(__pyx_CyFunctionObject, func_dict),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ 0,
+#endif
+};
+static int __Pyx_CyFunction_init(void) {
+#if !CYTHON_COMPILING_IN_PYPY
+ __pyx_CyFunctionType_type.tp_call = PyCFunction_Call;
+#endif
+ __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
+ if (__pyx_CyFunctionType == NULL) {
+ return -1;
+ }
+ return 0;
+}
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults = PyMem_Malloc(size);
+ if (!m->defaults)
+ return PyErr_NoMemory();
+ memset(m->defaults, 0, size);
+ m->defaults_pyobjects = pyobjects;
+ return m->defaults;
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_tuple = tuple;
+ Py_INCREF(tuple);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_kwdict = dict;
+ Py_INCREF(dict);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->func_annotations = dict;
+ Py_INCREF(dict);
+}
+
+static PyObject *__Pyx_Py3MetaclassPrepare(PyObject *metaclass, PyObject *bases, PyObject *name,
+ PyObject *qualname, PyObject *mkw, PyObject *modname, PyObject *doc) {
+ PyObject *ns;
+ if (metaclass) {
+ PyObject *prep = __Pyx_PyObject_GetAttrStr(metaclass, __pyx_n_s_prepare);
+ if (prep) {
+ PyObject *pargs = PyTuple_Pack(2, name, bases);
+ if (unlikely(!pargs)) {
+ Py_DECREF(prep);
+ return NULL;
+ }
+ ns = PyObject_Call(prep, pargs, mkw);
+ Py_DECREF(prep);
+ Py_DECREF(pargs);
+ } else {
+ if (unlikely(!PyErr_ExceptionMatches(PyExc_AttributeError)))
+ return NULL;
+ PyErr_Clear();
+ ns = PyDict_New();
+ }
+ } else {
+ ns = PyDict_New();
+ }
+ if (unlikely(!ns))
+ return NULL;
+ if (unlikely(PyObject_SetItem(ns, __pyx_n_s_module, modname) < 0)) goto bad;
+ if (unlikely(PyObject_SetItem(ns, __pyx_n_s_qualname, qualname) < 0)) goto bad;
+ if (unlikely(doc && PyObject_SetItem(ns, __pyx_n_s_doc_2, doc) < 0)) goto bad;
+ return ns;
+bad:
+ Py_DECREF(ns);
+ return NULL;
+}
+static PyObject *__Pyx_Py3ClassCreate(PyObject *metaclass, PyObject *name, PyObject *bases,
+ PyObject *dict, PyObject *mkw,
+ int calculate_metaclass, int allow_py2_metaclass) {
+ PyObject *result, *margs;
+ PyObject *owned_metaclass = NULL;
+ if (allow_py2_metaclass) {
+ owned_metaclass = PyObject_GetItem(dict, __pyx_n_s_metaclass);
+ if (owned_metaclass) {
+ metaclass = owned_metaclass;
+ } else if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) {
+ PyErr_Clear();
+ } else {
+ return NULL;
+ }
+ }
+ if (calculate_metaclass && (!metaclass || PyType_Check(metaclass))) {
+ metaclass = __Pyx_CalculateMetaclass((PyTypeObject*) metaclass, bases);
+ Py_XDECREF(owned_metaclass);
+ if (unlikely(!metaclass))
+ return NULL;
+ owned_metaclass = metaclass;
+ }
+ margs = PyTuple_Pack(3, name, bases, dict);
+ if (unlikely(!margs)) {
+ result = NULL;
+ } else {
+ result = PyObject_Call(metaclass, margs, mkw);
+ Py_DECREF(margs);
+ }
+ Py_XDECREF(owned_metaclass);
+ return result;
+}
+
+static PyObject *
+__pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags,
+ PyObject *qualname, PyObject *self,
+ PyObject *module, PyObject *globals,
+ PyObject *code)
+{
+ __pyx_FusedFunctionObject *fusedfunc =
+ (__pyx_FusedFunctionObject *) __Pyx_CyFunction_New(type, ml, flags, qualname,
+ self, module, globals, code);
+ if (!fusedfunc)
+ return NULL;
+ fusedfunc->__signatures__ = NULL;
+ fusedfunc->type = NULL;
+ fusedfunc->self = NULL;
+ return (PyObject *) fusedfunc;
+}
+static void __pyx_FusedFunction_dealloc(__pyx_FusedFunctionObject *self) {
+ __pyx_FusedFunction_clear(self);
+ __pyx_FusedFunctionType->tp_free((PyObject *) self);
+}
+static int
+__pyx_FusedFunction_traverse(__pyx_FusedFunctionObject *self,
+ visitproc visit,
+ void *arg)
+{
+ Py_VISIT(self->self);
+ Py_VISIT(self->type);
+ Py_VISIT(self->__signatures__);
+ return __Pyx_CyFunction_traverse((__pyx_CyFunctionObject *) self, visit, arg);
+}
+static int
+__pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self)
+{
+ Py_CLEAR(self->self);
+ Py_CLEAR(self->type);
+ Py_CLEAR(self->__signatures__);
+ return __Pyx_CyFunction_clear((__pyx_CyFunctionObject *) self);
+}
+static PyObject *
+__pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+ __pyx_FusedFunctionObject *func, *meth;
+ func = (__pyx_FusedFunctionObject *) self;
+ if (func->self || func->func.flags & __Pyx_CYFUNCTION_STATICMETHOD) {
+ Py_INCREF(self);
+ return self;
+ }
+ if (obj == Py_None)
+ obj = NULL;
+ meth = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_NewEx(
+ ((PyCFunctionObject *) func)->m_ml,
+ ((__pyx_CyFunctionObject *) func)->flags,
+ ((__pyx_CyFunctionObject *) func)->func_qualname,
+ ((__pyx_CyFunctionObject *) func)->func_closure,
+ ((PyCFunctionObject *) func)->m_module,
+ ((__pyx_CyFunctionObject *) func)->func_globals,
+ ((__pyx_CyFunctionObject *) func)->func_code);
+ if (!meth)
+ return NULL;
+ Py_XINCREF(func->func.func_classobj);
+ meth->func.func_classobj = func->func.func_classobj;
+ Py_XINCREF(func->__signatures__);
+ meth->__signatures__ = func->__signatures__;
+ Py_XINCREF(type);
+ meth->type = type;
+ Py_XINCREF(func->func.defaults_tuple);
+ meth->func.defaults_tuple = func->func.defaults_tuple;
+ if (func->func.flags & __Pyx_CYFUNCTION_CLASSMETHOD)
+ obj = type;
+ Py_XINCREF(obj);
+ meth->self = obj;
+ return (PyObject *) meth;
+}
+static PyObject *
+_obj_to_str(PyObject *obj)
+{
+ if (PyType_Check(obj))
+ return PyObject_GetAttr(obj, __pyx_n_s_name_2);
+ else
+ return PyObject_Str(obj);
+}
+static PyObject *
+__pyx_FusedFunction_getitem(__pyx_FusedFunctionObject *self, PyObject *idx)
+{
+ PyObject *signature = NULL;
+ PyObject *unbound_result_func;
+ PyObject *result_func = NULL;
+ if (self->__signatures__ == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Function is not fused");
+ return NULL;
+ }
+ if (PyTuple_Check(idx)) {
+ PyObject *list = PyList_New(0);
+ Py_ssize_t n = PyTuple_GET_SIZE(idx);
+ PyObject *string = NULL;
+ PyObject *sep = NULL;
+ int i;
+ if (!list)
+ return NULL;
+ for (i = 0; i < n; i++) {
+ PyObject *item = PyTuple_GET_ITEM(idx, i);
+ string = _obj_to_str(item);
+ if (!string || PyList_Append(list, string) < 0)
+ goto __pyx_err;
+ Py_DECREF(string);
+ }
+ sep = PyUnicode_FromString("|");
+ if (sep)
+ signature = PyUnicode_Join(sep, list);
+__pyx_err:
+;
+ Py_DECREF(list);
+ Py_XDECREF(sep);
+ } else {
+ signature = _obj_to_str(idx);
+ }
+ if (!signature)
+ return NULL;
+ unbound_result_func = PyObject_GetItem(self->__signatures__, signature);
+ if (unbound_result_func) {
+ if (self->self || self->type) {
+ __pyx_FusedFunctionObject *unbound = (__pyx_FusedFunctionObject *) unbound_result_func;
+ Py_CLEAR(unbound->func.func_classobj);
+ Py_XINCREF(self->func.func_classobj);
+ unbound->func.func_classobj = self->func.func_classobj;
+ result_func = __pyx_FusedFunction_descr_get(unbound_result_func,
+ self->self, self->type);
+ } else {
+ result_func = unbound_result_func;
+ Py_INCREF(result_func);
+ }
+ }
+ Py_DECREF(signature);
+ Py_XDECREF(unbound_result_func);
+ return result_func;
+}
+static PyObject *
+__pyx_FusedFunction_callfunction(PyObject *func, PyObject *args, PyObject *kw)
+{
+ __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func;
+ PyObject *result;
+ int static_specialized = (cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD &&
+ !((__pyx_FusedFunctionObject *) func)->__signatures__);
+ if (cyfunc->flags & __Pyx_CYFUNCTION_CCLASS && !static_specialized) {
+ Py_ssize_t argc;
+ PyObject *new_args;
+ PyObject *self;
+ PyObject *m_self;
+ argc = PyTuple_GET_SIZE(args);
+ new_args = PyTuple_GetSlice(args, 1, argc);
+ if (!new_args)
+ return NULL;
+ self = PyTuple_GetItem(args, 0);
+ if (!self)
+ return NULL;
+ m_self = cyfunc->func.m_self;
+ cyfunc->func.m_self = self;
+ result = __Pyx_CyFunction_Call(func, new_args, kw);
+ cyfunc->func.m_self = m_self;
+ Py_DECREF(new_args);
+ } else {
+ result = __Pyx_CyFunction_Call(func, args, kw);
+ }
+ return result;
+}
+static PyObject *
+__pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
+{
+ __pyx_FusedFunctionObject *binding_func = (__pyx_FusedFunctionObject *) func;
+ Py_ssize_t argc = PyTuple_GET_SIZE(args);
+ PyObject *new_args = NULL;
+ __pyx_FusedFunctionObject *new_func = NULL;
+ PyObject *result = NULL;
+ PyObject *self = NULL;
+ int is_staticmethod = binding_func->func.flags & __Pyx_CYFUNCTION_STATICMETHOD;
+ int is_classmethod = binding_func->func.flags & __Pyx_CYFUNCTION_CLASSMETHOD;
+ if (binding_func->self) {
+ Py_ssize_t i;
+ new_args = PyTuple_New(argc + 1);
+ if (!new_args)
+ return NULL;
+ self = binding_func->self;
+ Py_INCREF(self);
+ PyTuple_SET_ITEM(new_args, 0, self);
+ for (i = 0; i < argc; i++) {
+ PyObject *item = PyTuple_GET_ITEM(args, i);
+ Py_INCREF(item);
+ PyTuple_SET_ITEM(new_args, i + 1, item);
+ }
+ args = new_args;
+ } else if (binding_func->type) {
+ if (argc < 1) {
+ PyErr_SetString(PyExc_TypeError, "Need at least one argument, 0 given.");
+ return NULL;
+ }
+ self = PyTuple_GET_ITEM(args, 0);
+ }
+ if (self && !is_classmethod && !is_staticmethod &&
+ !PyObject_IsInstance(self, binding_func->type)) {
+ PyErr_Format(PyExc_TypeError,
+ "First argument should be of type %.200s, got %.200s.",
+ ((PyTypeObject *) binding_func->type)->tp_name,
+ self->ob_type->tp_name);
+ goto __pyx_err;
+ }
+ if (binding_func->__signatures__) {
+ PyObject *tup = PyTuple_Pack(4, binding_func->__signatures__, args,
+ kw == NULL ? Py_None : kw,
+ binding_func->func.defaults_tuple);
+ if (!tup)
+ goto __pyx_err;
+ new_func = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_callfunction(func, tup, NULL);
+ Py_DECREF(tup);
+ if (!new_func)
+ goto __pyx_err;
+ Py_XINCREF(binding_func->func.func_classobj);
+ Py_CLEAR(new_func->func.func_classobj);
+ new_func->func.func_classobj = binding_func->func.func_classobj;
+ func = (PyObject *) new_func;
+ }
+ result = __pyx_FusedFunction_callfunction(func, args, kw);
+__pyx_err:
+ Py_XDECREF(new_args);
+ Py_XDECREF((PyObject *) new_func);
+ return result;
+}
+static PyMemberDef __pyx_FusedFunction_members[] = {
+ {(char *) "__signatures__",
+ T_OBJECT,
+ offsetof(__pyx_FusedFunctionObject, __signatures__),
+ READONLY,
+ 0},
+ {0, 0, 0, 0, 0},
+};
+static PyMappingMethods __pyx_FusedFunction_mapping_methods = {
+ 0,
+ (binaryfunc) __pyx_FusedFunction_getitem,
+ 0,
+};
+static PyTypeObject __pyx_FusedFunctionType_type = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "fused_cython_function",
+ sizeof(__pyx_FusedFunctionObject),
+ 0,
+ (destructor) __pyx_FusedFunction_dealloc,
+ 0,
+ 0,
+ 0,
+#if PY_MAJOR_VERSION < 3
+ 0,
+#else
+ 0,
+#endif
+ 0,
+ 0,
+ 0,
+ &__pyx_FusedFunction_mapping_methods,
+ 0,
+ (ternaryfunc) __pyx_FusedFunction_call,
+ 0,
+ 0,
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
+ 0,
+ (traverseproc) __pyx_FusedFunction_traverse,
+ (inquiry) __pyx_FusedFunction_clear,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_FusedFunction_members,
+ __pyx_CyFunction_getsets,
+ &__pyx_CyFunctionType_type,
+ 0,
+ __pyx_FusedFunction_descr_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ 0,
+#endif
+};
+static int __pyx_FusedFunction_init(void) {
+ __pyx_FusedFunctionType = __Pyx_FetchCommonType(&__pyx_FusedFunctionType_type);
+ if (__pyx_FusedFunctionType == NULL) {
+ return -1;
+ }
+ return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_float(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_float, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_double(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_double, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_signed_char(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_signed_char, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_signed_short(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_signed_short, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_signed_int(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_signed_int, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_signed_long(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_signed_long, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_char(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_unsigned_char, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_short(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_unsigned_short, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_int(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_unsigned_int, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_unsigned_PY_LONG_LONG(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_unsigned_PY_LONG_LONG, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
+ const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
+ char* char_start = PyBytes_AS_STRING(bytes);
+ char* pos;
+ for (pos=char_start; pos < char_start+length; pos++) {
+ if (character == pos[0]) return 1;
+ }
+ return 0;
+}
+
+static PyObject *__pyx_memview_get_float(const char *itemp) {
+ return (PyObject *) PyFloat_FromDouble(*(float *) itemp);
+}
+static int __pyx_memview_set_float(const char *itemp, PyObject *obj) {
+ float value = __pyx_PyFloat_AsFloat(obj);
+ if ((value == (float)-1) && PyErr_Occurred())
+ return 0;
+ *(float *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) {
+ const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(unsigned int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(unsigned int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(unsigned int),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *x) {
+ const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(unsigned int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (unsigned int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(unsigned int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(unsigned int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, long, PyLong_AsLong(x))
+ } else if (sizeof(unsigned int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ unsigned int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (unsigned int) -1;
+ }
+ } else {
+ unsigned int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (unsigned int) -1;
+ val = __Pyx_PyInt_As_unsigned_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to unsigned int");
+ return (unsigned int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to unsigned int");
+ return (unsigned int) -1;
+}
+
+static PyObject *__pyx_memview_get_double(const char *itemp) {
+ return (PyObject *) PyFloat_FromDouble(*(double *) itemp);
+}
+static int __pyx_memview_set_double(const char *itemp, PyObject *obj) {
+ double value = __pyx_PyFloat_AsDouble(obj);
+ if ((value == (double)-1) && PyErr_Occurred())
+ return 0;
+ *(double *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_signed__char(signed char value) {
+ const signed char neg_one = (signed char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(signed char) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(signed char) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(signed char) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(signed char) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(signed char) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(signed char),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE signed char __Pyx_PyInt_As_signed__char(PyObject *x) {
+ const signed char neg_one = (signed char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(signed char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(signed char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (signed char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(signed char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(signed char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(signed char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(signed char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(signed char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(signed char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(signed char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(signed char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(signed char, long, PyLong_AsLong(x))
+ } else if (sizeof(signed char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(signed char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ signed char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (signed char) -1;
+ }
+ } else {
+ signed char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (signed char) -1;
+ val = __Pyx_PyInt_As_signed__char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to signed char");
+ return (signed char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to signed char");
+ return (signed char) -1;
+}
+
+static PyObject *__pyx_memview_get_signed_char(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_signed__char(*(signed char *) itemp);
+}
+static int __pyx_memview_set_signed_char(const char *itemp, PyObject *obj) {
+ signed char value = __Pyx_PyInt_As_signed__char(obj);
+ if ((value == (signed char)-1) && PyErr_Occurred())
+ return 0;
+ *(signed char *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_signed__short(signed short value) {
+ const signed short neg_one = (signed short) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(signed short) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(signed short) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(signed short) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(signed short) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(signed short) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(signed short),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE signed short __Pyx_PyInt_As_signed__short(PyObject *x) {
+ const signed short neg_one = (signed short) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(signed short) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(signed short, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (signed short) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(signed short, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(signed short) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(signed short, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(signed short) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(signed short, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(signed short, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(signed short, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(signed short) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(signed short, long, PyLong_AsLong(x))
+ } else if (sizeof(signed short) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(signed short, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ signed short val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (signed short) -1;
+ }
+ } else {
+ signed short val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (signed short) -1;
+ val = __Pyx_PyInt_As_signed__short(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to signed short");
+ return (signed short) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to signed short");
+ return (signed short) -1;
+}
+
+static PyObject *__pyx_memview_get_signed_short(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_signed__short(*(signed short *) itemp);
+}
+static int __pyx_memview_set_signed_short(const char *itemp, PyObject *obj) {
+ signed short value = __Pyx_PyInt_As_signed__short(obj);
+ if ((value == (signed short)-1) && PyErr_Occurred())
+ return 0;
+ *(signed short *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_signed__int(signed int value) {
+ const signed int neg_one = (signed int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(signed int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(signed int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(signed int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(signed int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(signed int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(signed int),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE signed int __Pyx_PyInt_As_signed__int(PyObject *x) {
+ const signed int neg_one = (signed int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(signed int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(signed int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (signed int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(signed int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(signed int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(signed int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(signed int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(signed int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(signed int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(signed int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(signed int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(signed int, long, PyLong_AsLong(x))
+ } else if (sizeof(signed int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(signed int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ signed int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (signed int) -1;
+ }
+ } else {
+ signed int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (signed int) -1;
+ val = __Pyx_PyInt_As_signed__int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to signed int");
+ return (signed int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to signed int");
+ return (signed int) -1;
+}
+
+static PyObject *__pyx_memview_get_signed_int(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_signed__int(*(signed int *) itemp);
+}
+static int __pyx_memview_set_signed_int(const char *itemp, PyObject *obj) {
+ signed int value = __Pyx_PyInt_As_signed__int(obj);
+ if ((value == (signed int)-1) && PyErr_Occurred())
+ return 0;
+ *(signed int *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_signed__long(signed long value) {
+ const signed long neg_one = (signed long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(signed long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(signed long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(signed long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(signed long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(signed long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(signed long),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE signed long __Pyx_PyInt_As_signed__long(PyObject *x) {
+ const signed long neg_one = (signed long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(signed long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(signed long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (signed long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(signed long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(signed long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(signed long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(signed long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(signed long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(signed long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(signed long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(signed long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(signed long, long, PyLong_AsLong(x))
+ } else if (sizeof(signed long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(signed long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ signed long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (signed long) -1;
+ }
+ } else {
+ signed long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (signed long) -1;
+ val = __Pyx_PyInt_As_signed__long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to signed long");
+ return (signed long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to signed long");
+ return (signed long) -1;
+}
+
+static PyObject *__pyx_memview_get_signed_long(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_signed__long(*(signed long *) itemp);
+}
+static int __pyx_memview_set_signed_long(const char *itemp, PyObject *obj) {
+ signed long value = __Pyx_PyInt_As_signed__long(obj);
+ if ((value == (signed long)-1) && PyErr_Occurred())
+ return 0;
+ *(signed long *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_char(unsigned char value) {
+ const unsigned char neg_one = (unsigned char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(unsigned char) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned char) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(unsigned char) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(unsigned char) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned char) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(unsigned char),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE unsigned char __Pyx_PyInt_As_unsigned_char(PyObject *x) {
+ const unsigned char neg_one = (unsigned char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(unsigned char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (unsigned char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(unsigned char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(unsigned char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(unsigned char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(unsigned char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, long, PyLong_AsLong(x))
+ } else if (sizeof(unsigned char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ unsigned char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (unsigned char) -1;
+ }
+ } else {
+ unsigned char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (unsigned char) -1;
+ val = __Pyx_PyInt_As_unsigned_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to unsigned char");
+ return (unsigned char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to unsigned char");
+ return (unsigned char) -1;
+}
+
+static PyObject *__pyx_memview_get_unsigned_char(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_unsigned_char(*(unsigned char *) itemp);
+}
+static int __pyx_memview_set_unsigned_char(const char *itemp, PyObject *obj) {
+ unsigned char value = __Pyx_PyInt_As_unsigned_char(obj);
+ if ((value == (unsigned char)-1) && PyErr_Occurred())
+ return 0;
+ *(unsigned char *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_short(unsigned short value) {
+ const unsigned short neg_one = (unsigned short) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(unsigned short) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned short) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(unsigned short) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(unsigned short) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned short) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(unsigned short),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE unsigned short __Pyx_PyInt_As_unsigned_short(PyObject *x) {
+ const unsigned short neg_one = (unsigned short) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(unsigned short) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned short, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (unsigned short) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned short, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(unsigned short) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned short, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(unsigned short) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned short, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned short, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(unsigned short, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(unsigned short) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned short, long, PyLong_AsLong(x))
+ } else if (sizeof(unsigned short) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned short, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ unsigned short val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (unsigned short) -1;
+ }
+ } else {
+ unsigned short val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (unsigned short) -1;
+ val = __Pyx_PyInt_As_unsigned_short(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to unsigned short");
+ return (unsigned short) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to unsigned short");
+ return (unsigned short) -1;
+}
+
+static PyObject *__pyx_memview_get_unsigned_short(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_unsigned_short(*(unsigned short *) itemp);
+}
+static int __pyx_memview_set_unsigned_short(const char *itemp, PyObject *obj) {
+ unsigned short value = __Pyx_PyInt_As_unsigned_short(obj);
+ if ((value == (unsigned short)-1) && PyErr_Occurred())
+ return 0;
+ *(unsigned short *) itemp = value;
+ return 1;
+}
+
+static PyObject *__pyx_memview_get_unsigned_int(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_unsigned_int(*(unsigned int *) itemp);
+}
+static int __pyx_memview_set_unsigned_int(const char *itemp, PyObject *obj) {
+ unsigned int value = __Pyx_PyInt_As_unsigned_int(obj);
+ if ((value == (unsigned int)-1) && PyErr_Occurred())
+ return 0;
+ *(unsigned int *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_PY_LONG_LONG(unsigned PY_LONG_LONG value) {
+ const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(unsigned PY_LONG_LONG) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(unsigned PY_LONG_LONG) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(unsigned PY_LONG_LONG),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_As_unsigned_PY_LONG_LONG(PyObject *x) {
+ const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(unsigned PY_LONG_LONG) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (unsigned PY_LONG_LONG) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(unsigned PY_LONG_LONG) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, long, PyLong_AsLong(x))
+ } else if (sizeof(unsigned PY_LONG_LONG) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned PY_LONG_LONG, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ unsigned PY_LONG_LONG val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (unsigned PY_LONG_LONG) -1;
+ }
+ } else {
+ unsigned PY_LONG_LONG val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (unsigned PY_LONG_LONG) -1;
+ val = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to unsigned PY_LONG_LONG");
+ return (unsigned PY_LONG_LONG) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to unsigned PY_LONG_LONG");
+ return (unsigned PY_LONG_LONG) -1;
+}
+
+static PyObject *__pyx_memview_get_unsigned_PY_LONG_LONG(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_unsigned_PY_LONG_LONG(*(unsigned PY_LONG_LONG *) itemp);
+}
+static int __pyx_memview_set_unsigned_PY_LONG_LONG(const char *itemp, PyObject *obj) {
+ unsigned PY_LONG_LONG value = __Pyx_PyInt_As_unsigned_PY_LONG_LONG(obj);
+ if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())
+ return 0;
+ *(unsigned PY_LONG_LONG *) itemp = value;
+ return 1;
+}
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/math/combo/combo.pyx b/silx/math/combo/combo.pyx
new file mode 100644
index 0000000..0390bce
--- /dev/null
+++ b/silx/math/combo/combo.pyx
@@ -0,0 +1,238 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module provides combination of statistics as single operation.
+
+For now it provides min/max (and optionally positive min) and indices
+of first occurences (i.e., argmin/argmax) in a single pass.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "20/12/2016"
+
+cimport cython
+
+# Replacement from libc.math cimport isnan
+# which is not available on Windows for Python2.7
+cdef extern from "isnan.h":
+ bint isnan(double x) nogil
+
+import numpy
+
+
+ctypedef fused _number:
+ float
+ double
+ signed char
+ signed short
+ signed int
+ signed long
+ unsigned char
+ unsigned short
+ unsigned int
+ unsigned long long
+
+
+class _MinMaxResult(object):
+ """Object storing result from :func:`min_max`"""
+
+ def __init__(self, minimum, min_pos, maximum,
+ argmin, argmin_pos, argmax):
+ self._minimum = minimum
+ self._min_positive = min_pos
+ self._maximum = maximum
+
+ self._argmin = argmin
+ self._argmin_positive = argmin_pos
+ self._argmax = argmax
+
+ minimum = property(
+ lambda self: self._minimum,
+ doc="Minimum value of the array")
+ maximum = property(
+ lambda self: self._maximum,
+ doc="Maximum value of the array")
+
+ argmin = property(
+ lambda self: self._argmin,
+ doc="Index of the first occurence of the minimum value")
+ argmax = property(
+ lambda self: self._argmax,
+ doc="Index of the first occurence of the maximum value")
+
+ min_positive = property(
+ lambda self: self._min_positive,
+ doc="""Strictly positive minimum value
+
+ It is None if no value is strictly positive.
+ """)
+ argmin_positive = property(
+ lambda self: self._argmin_positive,
+ doc="""Index of the strictly positive minimum value.
+
+ It is None if no value is strictly positive.
+ It is the index of the first occurence.""")
+
+ def __getitem__(self, key):
+ if key == 0:
+ return self.minimum
+ elif key == 1:
+ return self.maximum
+ else:
+ raise IndexError("Index out of range")
+
+
+@cython.initializedcheck(False)
+@cython.boundscheck(False)
+@cython.wraparound(False)
+def _min_max(_number[::1] data, bint min_positive=False):
+ """See :func:`min_max` for documentation."""
+ cdef:
+ _number value, minimum, minpos, maximum
+ unsigned int length
+ unsigned int index = 0
+ unsigned int min_index = 0
+ unsigned int min_pos_index = 0
+ unsigned int max_index = 0
+
+ length = len(data)
+
+ if length == 0:
+ raise ValueError('Zero-size array')
+
+ with nogil:
+ # Init starting values
+ value = data[0]
+ minimum = value
+ maximum = value
+ if min_positive and value > 0:
+ min_pos = value
+ else:
+ min_pos = 0
+
+ if _number in cython.floating:
+ # For floating, loop until first not NaN value
+ for index in range(length):
+ value = data[index]
+ if not isnan(value):
+ minimum = value
+ min_index = index
+ maximum = value
+ max_index = index
+ break
+
+ if not min_positive:
+ for index in range(index, length):
+ value = data[index]
+ if value > maximum:
+ maximum = value
+ max_index = index
+ elif value < minimum:
+ minimum = value
+ min_index = index
+
+ else:
+ # Loop until min_pos is defined
+ for index in range(index, length):
+ value = data[index]
+ if value > maximum:
+ maximum = value
+ max_index = index
+ elif value < minimum:
+ minimum = value
+ min_index = index
+
+ if value > 0:
+ min_pos = value
+ min_pos_index = index
+ break
+
+ # Loop until the end
+ for index in range(index+1, length):
+ value = data[index]
+ if value > maximum:
+ maximum = value
+ max_index = index
+ else:
+ if value < minimum:
+ minimum = value
+ min_index = index
+
+ if value > 0 and value < min_pos:
+ min_pos = value
+ min_pos_index = index
+
+ return _MinMaxResult(minimum,
+ min_pos if min_pos > 0 else None,
+ maximum,
+ min_index,
+ min_pos_index if min_pos > 0 else None,
+ max_index)
+
+
+def min_max(data not None, bint min_positive=False):
+ """Returns min, max and optionally strictly positive min of data.
+
+ It also computes the indices of first occurence of min/max.
+
+ NaNs are ignored while computing min/max unless all data is NaNs,
+ in which case returned min/max are NaNs.
+
+ Examples:
+
+ >>> import numpy
+ >>> data = numpy.arange(10)
+
+ Usage as a function returning min and max:
+
+ >>> min_, max_ = min_max(data)
+
+ Usage as a function returning a result object to access all information:
+
+ >>> result = min_max(data) # Do not get positive min
+ >>> result.minimum, result.argmin
+ 0, 0
+ >>> result.maximum, result.argmax
+ 9, 10
+ >>> result.min_positive, result.argmin_positive # Not computed
+ None, None
+
+ Getting strictly positive min information:
+
+ >>> result = min_max(data, min_positive=True)
+ >>> result.min_positive, result.argmin_positive # Computed
+ 1, 1
+
+ :param data: Array-like dataset
+ :param bool min_positive: True to compute the positive min and argmin
+ Default: False.
+ :returns: An object with minimum, maximum and min_positive attributes
+ and the indices of first occurence in the flattened data:
+ argmin, argmax and argmin_positive attributes.
+ If all data is <= 0 or min_positive argument is False, then
+ min_positive and argmin_positive are None.
+ :raises: ValueError if data is empty
+ """
+ return _min_max(numpy.ascontiguousarray(data).ravel(), min_positive)
diff --git a/silx/math/combo/isnan.h b/silx/math/combo/isnan.h
new file mode 100644
index 0000000..9ef86ce
--- /dev/null
+++ b/silx/math/combo/isnan.h
@@ -0,0 +1,45 @@
+# /*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+/* This header provides a compatible isnan function across platforms.
+
+ VisualStudio 2008 (i.e., Python2.7) provides a _isnan method and no isnan.
+
+ Usage from cython:
+
+ cdef extern from "isnan.h":
+ bint isnan(double x) nogil
+*/
+
+#ifndef __ISNAN_H__
+#define __ISNAN_H__
+
+#include <math.h>
+
+#if (defined (_MSC_VER) && _MSC_VER < 1800)
+#include <float.h>
+
+#define isnan(v) _isnan(v)
+#endif
+
+#endif /*__ISNAN_H__*/ \ No newline at end of file
diff --git a/silx/math/fit/__init__.py b/silx/math/fit/__init__.py
new file mode 100644
index 0000000..29e6a9e
--- /dev/null
+++ b/silx/math/fit/__init__.py
@@ -0,0 +1,39 @@
+# 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.
+#
+# ############################################################################*/
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "22/06/2016"
+
+
+from .leastsq import leastsq, chisq_alpha_beta
+from .leastsq import \
+ CFREE, CPOSITIVE, CQUOTED, CFIXED, \
+ CFACTOR, CDELTA, CSUM
+
+from .functions import *
+from .filters import *
+from .peaks import peak_search, guess_fwhm
+from .fitmanager import FitManager
+from .fittheory import FitTheory
diff --git a/silx/math/fit/bgtheories.py b/silx/math/fit/bgtheories.py
new file mode 100644
index 0000000..3cdac98
--- /dev/null
+++ b/silx/math/fit/bgtheories.py
@@ -0,0 +1,440 @@
+# coding: utf-8
+#/*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+########################################################################### */
+"""This modules defines a set of background model functions and associated
+estimation functions in a format that can be imported into a
+:class:`silx.math.fit.FitManager` object.
+
+A background function is a function that you want to add to a regular fit
+function prior to fitting the sum of both functions. This is useful, for
+instance, if you need to fit multiple gaussian peaks in an array of
+measured data points when the measurement is polluted by a background signal.
+
+The models include common background models such as a constant value or a
+linear background.
+
+It also includes background computation filters - *strip* and *snip* - that
+can extract a more complex low-curvature background signal from a signal with
+peaks having higher curvatures.
+
+The source code of this module can serve as a template for defining your
+own fit background theories. The minimal skeleton of such a theory definition
+file is::
+
+ from silx.math.fit.fittheory import FitTheory
+
+ def bgfunction1(x, y0, …):
+ bg_signal = …
+ return bg_signal
+
+ def estimation_function1(x, y):
+ …
+ estimated_params = …
+ constraints = …
+ return estimated_params, constraints
+
+ THEORY = {
+ 'bg_theory_name1': FitTheory(
+ description='Description of theory 1',
+ function=bgfunction1,
+ parameters=('param name 1', 'param name 2', …),
+ estimate=estimation_function1,
+ configure=configuration_function1,
+ derivative=derivative_function1,
+ is_background=True),
+ 'theory_name_2': …,
+ }
+"""
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+from collections import OrderedDict
+import numpy
+from silx.math.fit.filters import strip, snip1d,\
+ savitsky_golay
+from silx.math.fit.fittheory import FitTheory
+
+CONFIG = {
+ "SmoothingFlag": False,
+ "SmoothingWidth": 5,
+ "AnchorsFlag": False,
+ "AnchorsList": [],
+ "StripWidth": 2,
+ "StripIterations": 5000,
+ "StripThresholdFactor": 1.0,
+ "SnipWidth": 16,
+ "EstimatePolyOnStrip": True
+}
+
+# to avoid costly computations when parameters stay the same
+_BG_STRIP_OLDY = numpy.array([])
+_BG_STRIP_OLDPARS = [0, 0]
+_BG_STRIP_OLDBG = numpy.array([])
+
+_BG_SNIP_OLDY = numpy.array([])
+_BG_SNIP_OLDWIDTH = None
+_BG_SNIP_OLDBG = numpy.array([])
+
+
+_BG_OLD_ANCHORS = []
+_BG_OLD_ANCHORS_FLAG = None
+
+_BG_SMOOTH_OLDWIDTH = None
+_BG_SMOOTH_OLDFLAG = None
+
+
+def _convert_anchors_to_indices(x):
+ """Anchors stored in CONFIG["AnchorsList"] are abscissa.
+ Convert then to indices (take first index where x >= anchor),
+ then return the list of indices.
+
+ :param x: Original array of abscissa
+ :return: List of indices of anchors in x array.
+ If CONFIG['AnchorsFlag'] is False or None, or if the list
+ of indices is empty, return None.
+ """
+ # convert anchor X abscissa to index
+ if CONFIG['AnchorsFlag'] and CONFIG['AnchorsList'] is not None:
+ anchors_indices = []
+ for anchor_x in CONFIG['AnchorsList']:
+ if anchor_x <= x[0]:
+ continue
+ # take the first index where x > anchor_x
+ indices = numpy.nonzero(x >= anchor_x)[0]
+ if len(indices):
+ anchors_indices.append(min(indices))
+ if not len(anchors_indices):
+ anchors_indices = None
+ else:
+ anchors_indices = None
+
+ return anchors_indices
+
+
+def strip_bg(x, y0, width, niter):
+ """Extract and return the strip bg from y0.
+
+ Use anchors coordinates in CONFIG["AnchorsList"] if flag
+ CONFIG["AnchorsFlag"] is True. Convert anchors from x coordinate
+ to array index prior to passing it to silx.math.fit.filters.strip
+
+ :param x: Abscissa array
+ :param x: Ordinate array (data values at x positions)
+ :param width: strip width
+ :param niter: strip niter
+ """
+ global _BG_STRIP_OLDY
+ global _BG_STRIP_OLDPARS
+ global _BG_STRIP_OLDBG
+ global _BG_SMOOTH_OLDWIDTH
+ global _BG_SMOOTH_OLDFLAG
+ global _BG_OLD_ANCHORS
+ global _BG_OLD_ANCHORS_FLAG
+
+ parameters_changed =\
+ _BG_STRIP_OLDPARS != [width, niter] or\
+ _BG_SMOOTH_OLDWIDTH != CONFIG["SmoothingWidth"] or\
+ _BG_SMOOTH_OLDFLAG != CONFIG["SmoothingFlag"] or\
+ _BG_OLD_ANCHORS_FLAG != CONFIG["AnchorsFlag"] or\
+ _BG_OLD_ANCHORS != CONFIG["AnchorsList"]
+
+ # same parameters
+ if not parameters_changed:
+ # same data
+ if numpy.sum(_BG_STRIP_OLDY == y0) == len(y0):
+ # same result
+ return _BG_STRIP_OLDBG
+
+ _BG_STRIP_OLDY = y0
+ _BG_STRIP_OLDPARS = [width, niter]
+ _BG_SMOOTH_OLDWIDTH = CONFIG["SmoothingWidth"]
+ _BG_SMOOTH_OLDFLAG = CONFIG["SmoothingFlag"]
+ _BG_OLD_ANCHORS = CONFIG["AnchorsList"]
+ _BG_OLD_ANCHORS_FLAG = CONFIG["AnchorsFlag"]
+
+ y1 = savitsky_golay(y0, CONFIG["SmoothingWidth"]) if CONFIG["SmoothingFlag"] else y0
+
+ anchors_indices = _convert_anchors_to_indices(x)
+
+ background = strip(y1,
+ w=width,
+ niterations=niter,
+ factor=CONFIG["StripThresholdFactor"],
+ anchors=anchors_indices)
+
+ _BG_STRIP_OLDBG = background
+
+ return background
+
+
+def snip_bg(x, y0, width):
+ """Compute the snip bg for y0"""
+ global _BG_SNIP_OLDY
+ global _BG_SNIP_OLDWIDTH
+ global _BG_SNIP_OLDBG
+ global _BG_SMOOTH_OLDWIDTH
+ global _BG_SMOOTH_OLDFLAG
+ global _BG_OLD_ANCHORS
+ global _BG_OLD_ANCHORS_FLAG
+
+ parameters_changed =\
+ _BG_SNIP_OLDWIDTH != width or\
+ _BG_SMOOTH_OLDWIDTH != CONFIG["SmoothingWidth"] or\
+ _BG_SMOOTH_OLDFLAG != CONFIG["SmoothingFlag"] or\
+ _BG_OLD_ANCHORS_FLAG != CONFIG["AnchorsFlag"] or\
+ _BG_OLD_ANCHORS != CONFIG["AnchorsList"]
+
+ # same parameters
+ if not parameters_changed:
+ # same data
+ if numpy.sum(_BG_SNIP_OLDY == y0) == len(y0):
+ # same result
+ return _BG_SNIP_OLDBG
+
+ _BG_SNIP_OLDY = y0
+ _BG_SNIP_OLDWIDTH = width
+ _BG_SMOOTH_OLDWIDTH = CONFIG["SmoothingWidth"]
+ _BG_SMOOTH_OLDFLAG = CONFIG["SmoothingFlag"]
+ _BG_OLD_ANCHORS = CONFIG["AnchorsList"]
+ _BG_OLD_ANCHORS_FLAG = CONFIG["AnchorsFlag"]
+
+ y1 = savitsky_golay(y0, CONFIG["SmoothingWidth"]) if CONFIG["SmoothingFlag"] else y0
+
+ anchors_indices = _convert_anchors_to_indices(x)
+
+ if anchors_indices is None or not len(anchors_indices):
+ anchors_indices = [0, len(y1) - 1]
+
+ background = numpy.zeros_like(y1)
+ previous_anchor = 0
+ for anchor_index in anchors_indices:
+ if (anchor_index > previous_anchor) and (anchor_index < len(y1)):
+ background[previous_anchor:anchor_index] =\
+ snip1d(y1[previous_anchor:anchor_index],
+ width)
+ previous_anchor = anchor_index
+
+ if previous_anchor < len(y1):
+ background[previous_anchor:] = snip1d(y1[previous_anchor:],
+ width)
+
+ _BG_SNIP_OLDBG = background
+
+ return background
+
+
+def estimate_linear(x, y):
+ """
+ Estimate the linear parameters (constant, slope) of a y signal.
+
+ Strip peaks, then perform a linear regression.
+ """
+ bg = strip_bg(x, y,
+ width=CONFIG["StripWidth"],
+ niter=CONFIG["StripIterations"])
+ n = float(len(bg))
+ Sy = numpy.sum(bg)
+ Sx = float(numpy.sum(x))
+ Sxx = float(numpy.sum(x * x))
+ Sxy = float(numpy.sum(x * bg))
+
+ deno = n * Sxx - (Sx * Sx)
+ if deno != 0:
+ bg = (Sxx * Sy - Sx * Sxy) / deno
+ slope = (n * Sxy - Sx * Sy) / deno
+ else:
+ bg = 0.0
+ slope = 0.0
+ estimated_par = [bg, slope]
+ # code = 0: FREE
+ constraints = [[0, 0, 0], [0, 0, 0]]
+ return estimated_par, constraints
+
+
+def estimate_strip(x, y):
+ """Estimation function for strip parameters.
+
+ Return parameters as defined in CONFIG dict,
+ set constraints to FIXED.
+ """
+ estimated_par = [CONFIG["StripWidth"],
+ CONFIG["StripIterations"]]
+ constraints = numpy.zeros((len(estimated_par), 3), numpy.float)
+ # code = 3: FIXED
+ constraints[0][0] = 3
+ constraints[1][0] = 3
+ return estimated_par, constraints
+
+
+def estimate_snip(x, y):
+ """Estimation function for snip parameters.
+
+ Return parameters as defined in CONFIG dict,
+ set constraints to FIXED.
+ """
+ estimated_par = [CONFIG["SnipWidth"]]
+ constraints = numpy.zeros((len(estimated_par), 3), numpy.float)
+ # code = 3: FIXED
+ constraints[0][0] = 3
+ return estimated_par, constraints
+
+
+def poly(x, y, *pars):
+ """Order n polynomial.
+ The order of the polynomial is defined by the number of
+ coefficients (``*pars``).
+
+ """
+ p = numpy.poly1d(pars)
+ return p(x)
+
+
+def estimate_poly(x, y, deg=2):
+ """Estimate polynomial coefficients.
+
+ """
+ # extract bg signal with strip, to estimate polynomial on background
+ if CONFIG["EstimatePolyOnStrip"]:
+ y = strip_bg(x, y,
+ CONFIG["StripWidth"],
+ CONFIG["StripIterations"])
+ pcoeffs = numpy.polyfit(x, y, deg)
+ cons = numpy.zeros((deg + 1, 3), numpy.float)
+ return pcoeffs, cons
+
+
+def estimate_quadratic_poly(x, y):
+ """Estimate quadratic polynomial coefficients.
+ """
+ return estimate_poly(x, y, deg=2)
+
+
+def estimate_cubic_poly(x, y):
+ """Estimate cubic polynomial coefficients.
+ """
+ return estimate_poly(x, y, deg=3)
+
+
+def estimate_quartic_poly(x, y):
+ """Estimate degree 4 polynomial coefficients.
+ """
+ return estimate_poly(x, y, deg=4)
+
+
+def estimate_quintic_poly(x, y):
+ """Estimate degree 5 polynomial coefficients.
+ """
+ return estimate_poly(x, y, deg=5)
+
+
+def configure(**kw):
+ """Update the CONFIG dict
+ """
+ # inspect **kw to find known keys, update them in CONFIG
+ for key in CONFIG:
+ if key in kw:
+ CONFIG[key] = kw[key]
+
+ return CONFIG
+
+
+THEORY = OrderedDict(
+ (('No Background',
+ FitTheory(
+ description="No background function",
+ function=lambda x, y0: numpy.zeros_like(x),
+ parameters=[],
+ is_background=True)),
+ ('Constant',
+ FitTheory(
+ description='Constant background',
+ function=lambda x, y0, c: c * numpy.ones_like(x),
+ parameters=['Constant', ],
+ estimate=lambda x, y: ([min(y)], [[0, 0, 0]]),
+ is_background=True)),
+ ('Linear',
+ FitTheory(
+ description="Linear background, parameters 'Constant' and"
+ " 'Slope'",
+ function=lambda x, y0, a, b: a + b * x,
+ parameters=['Constant', 'Slope'],
+ estimate=estimate_linear,
+ configure=configure,
+ is_background=True)),
+ ('Strip',
+ FitTheory(
+ description="Compute background using a strip filter\n"
+ "Parameters 'StripWidth', 'StripIterations'",
+ function=strip_bg,
+ parameters=['StripWidth', 'StripIterations'],
+ estimate=estimate_strip,
+ configure=configure,
+ is_background=True)),
+ ('Snip',
+ FitTheory(
+ description="Compute background using a snip filter\n"
+ "Parameter 'SnipWidth'",
+ function=snip_bg,
+ parameters=['SnipWidth'],
+ estimate=estimate_snip,
+ configure=configure,
+ is_background=True)),
+ ('Degree 2 Polynomial',
+ FitTheory(
+ description="Quadratic polynomial background, Parameters "
+ "'a', 'b' and 'c'\ny = a*x^2 + b*x +c",
+ function=poly,
+ parameters=['a', 'b', 'c'],
+ estimate=estimate_quadratic_poly,
+ configure=configure,
+ is_background=True)),
+ ('Degree 3 Polynomial',
+ FitTheory(
+ description="Cubic polynomial background, Parameters "
+ "'a', 'b', 'c' and 'd'\n"
+ "y = a*x^3 + b*x^2 + c*x + d",
+ function=poly,
+ parameters=['a', 'b', 'c', 'd'],
+ estimate=estimate_cubic_poly,
+ configure=configure,
+ is_background=True)),
+ ('Degree 4 Polynomial',
+ FitTheory(
+ description="Quartic polynomial background\n"
+ "y = a*x^4 + b*x^3 + c*x^2 + d*x + e",
+ function=poly,
+ parameters=['a', 'b', 'c', 'd', 'e'],
+ estimate=estimate_quartic_poly,
+ configure=configure,
+ is_background=True)),
+ ('Degree 5 Polynomial',
+ FitTheory(
+ description="Quaintic polynomial background\n"
+ "y = a*x^5 + b*x^4 + c*x^3 + d*x^2 + e*x + f",
+ function=poly,
+ parameters=['a', 'b', 'c', 'd', 'e', 'f'],
+ estimate=estimate_quintic_poly,
+ configure=configure,
+ is_background=True))))
diff --git a/silx/math/fit/filters/filters.c b/silx/math/fit/filters/filters.c
new file mode 100644
index 0000000..fd83ee7
--- /dev/null
+++ b/silx/math/fit/filters/filters.c
@@ -0,0 +1,20519 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__filters
+#define __PYX_HAVE_API__filters
+#include "filters.h"
+#include "pythread.h"
+#include "string.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+ "filters.pyx",
+ "stringsource",
+};
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static void __Pyx_RaiseBufferIndexError(int axis);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static PyObject *__pyx_memview_get_double(const char *itemp);
+static int __pyx_memview_set_double(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static PyObject *__pyx_memview_get_long(const char *itemp);
+static int __pyx_memview_set_long(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_double(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_long(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'filters_wrapper' */
+
+/* Module declarations from 'filters' */
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_long = { "long", NULL, sizeof(long), { 0 }, 0, IS_UNSIGNED(long) ? 'U' : 'I', IS_UNSIGNED(long), 0 };
+#define __Pyx_MODULE_NAME "filters"
+int __pyx_module_is_main_filters = 0;
+
+/* Implementation of 'filters' */
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_pf_7filters_strip(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_w, PyObject *__pyx_v_niterations, PyObject *__pyx_v_factor, PyObject *__pyx_v_anchors); /* proto */
+static PyObject *__pyx_pf_7filters_2snip1d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_snip_width); /* proto */
+static PyObject *__pyx_pf_7filters_4snip2d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_snip_width); /* proto */
+static PyObject *__pyx_pf_7filters_6snip3d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_snip_width); /* proto */
+static PyObject *__pyx_pf_7filters_8savitsky_golay(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_npoints); /* proto */
+static PyObject *__pyx_pf_7filters_10smooth1d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data); /* proto */
+static PyObject *__pyx_pf_7filters_12smooth2d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data); /* proto */
+static PyObject *__pyx_pf_7filters_14smooth3d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_C[] = "C";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_c[] = "c";
+static char __pyx_k_w[] = "w";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_nx[] = "nx";
+static char __pyx_k_ny[] = "ny";
+static char __pyx_k_nz[] = "nz";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k_int[] = "int_";
+static char __pyx_k_len[] = "__len__";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_copy[] = "copy";
+static char __pyx_k_data[] = "data";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_empty[] = "empty";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_nrows[] = "nrows";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_order[] = "order";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_strip[] = "strip";
+static char __pyx_k_data_c[] = "data_c";
+static char __pyx_k_factor[] = "factor";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_logger[] = "_logger";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_output[] = "output";
+static char __pyx_k_snip1d[] = "snip1d";
+static char __pyx_k_snip2d[] = "snip2d";
+static char __pyx_k_snip3d[] = "snip3d";
+static char __pyx_k_status[] = "status";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_anchors[] = "anchors";
+static char __pyx_k_asarray[] = "asarray";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_filters[] = "filters";
+static char __pyx_k_float64[] = "float64";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_input_c[] = "input_c";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_logging[] = "logging";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_ndarray[] = "ndarray";
+static char __pyx_k_npoints[] = "npoints";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_P_Knobel[] = "P. Knobel";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_ncolumns[] = "ncolumns";
+static char __pyx_k_smooth1d[] = "smooth1d";
+static char __pyx_k_smooth2d[] = "smooth2d";
+static char __pyx_k_smooth3d[] = "smooth3d";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_anchors_c[] = "anchors_c";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_getLogger[] = "getLogger";
+static char __pyx_k_22_06_2016[] = "22/06/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_data_shape[] = "data_shape";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_snip_width[] = "snip_width";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_basicConfig[] = "basicConfig";
+static char __pyx_k_len_anchors[] = "len_anchors";
+static char __pyx_k_niterations[] = "niterations";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_savitsky_golay[] = "savitsky_golay";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_or_a_numpy_array[] = "or a numpy array";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_or_a_2D_numpy_array[] = "or a 2D numpy array";
+static char __pyx_k_or_a_3D_numpy_array[] = "or a 3D numpy array";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_than_3_and_smaller_than_100[] = "than 3 and smaller than 100.";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_This_module_provides_background[] = "This module provides background extraction functions and smoothing\nfunctions. These functions are extracted from PyMca module SpecFitFuns.\n\nIndex of background extraction functions:\n------------------------------------------\n\n - :func:`strip`\n - :func:`snip1d`\n - :func:`snip2d`\n - :func:`snip3d`\n\nSmoothing functions:\n--------------------\n\n - :func:`savitsky_golay`\n - :func:`smooth1d`\n - :func:`smooth2d`\n - :func:`smooth3d`\n\nAPI documentation:\n-------------------\n\n";
+static char __pyx_k_data_must_be_a_2D_sequence_list[] = "data must be a 2D sequence (list, tuple) ";
+static char __pyx_k_data_must_be_a_3D_sequence_list[] = "data must be a 3D sequence (list, tuple) ";
+static char __pyx_k_mntdirect__scisoft_users_tvince[] = "/mntdirect/_scisoft/users/tvincent/src/silx/silx/math/fit/filters/filters.pyx";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_Smoothing_failed_Check_that_npoi[] = "Smoothing failed. Check that npoints is greater ";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_data_array_must_be_2_dimensional[] = "data array must be 2-dimensional";
+static char __pyx_k_data_array_must_be_3_dimensional[] = "data array must be 3-dimensional";
+static char __pyx_k_data_must_be_a_sequence_list_tup[] = "data must be a sequence (list, tuple) ";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static PyObject *__pyx_kp_s_22_06_2016;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_n_s_C;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_kp_s_P_Knobel;
+static PyObject *__pyx_kp_s_Smoothing_failed_Check_that_npoi;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_anchors;
+static PyObject *__pyx_n_s_anchors_c;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_asarray;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_basicConfig;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_copy;
+static PyObject *__pyx_n_s_data;
+static PyObject *__pyx_kp_s_data_array_must_be_2_dimensional;
+static PyObject *__pyx_kp_s_data_array_must_be_3_dimensional;
+static PyObject *__pyx_n_s_data_c;
+static PyObject *__pyx_kp_s_data_must_be_a_2D_sequence_list;
+static PyObject *__pyx_kp_s_data_must_be_a_3D_sequence_list;
+static PyObject *__pyx_kp_s_data_must_be_a_sequence_list_tup;
+static PyObject *__pyx_n_s_data_shape;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_empty;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_factor;
+static PyObject *__pyx_n_s_filters;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float64;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_n_s_getLogger;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_input_c;
+static PyObject *__pyx_n_s_int;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_len;
+static PyObject *__pyx_n_s_len_anchors;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_logger;
+static PyObject *__pyx_n_s_logging;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_kp_s_mntdirect__scisoft_users_tvince;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_n_s_ncolumns;
+static PyObject *__pyx_n_s_ndarray;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_niterations;
+static PyObject *__pyx_n_s_npoints;
+static PyObject *__pyx_n_s_nrows;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_nx;
+static PyObject *__pyx_n_s_ny;
+static PyObject *__pyx_n_s_nz;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_kp_s_or_a_2D_numpy_array;
+static PyObject *__pyx_kp_s_or_a_3D_numpy_array;
+static PyObject *__pyx_kp_s_or_a_numpy_array;
+static PyObject *__pyx_n_s_order;
+static PyObject *__pyx_n_s_output;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_savitsky_golay;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_smooth1d;
+static PyObject *__pyx_n_s_smooth2d;
+static PyObject *__pyx_n_s_smooth3d;
+static PyObject *__pyx_n_s_snip1d;
+static PyObject *__pyx_n_s_snip2d;
+static PyObject *__pyx_n_s_snip3d;
+static PyObject *__pyx_n_s_snip_width;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_status;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_strip;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_kp_s_than_3_and_smaller_than_100;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_n_s_w;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_float_1_0;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_5;
+static PyObject *__pyx_int_1000;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__21;
+static PyObject *__pyx_slice__22;
+static PyObject *__pyx_slice__23;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__27;
+static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__31;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_tuple__35;
+static PyObject *__pyx_tuple__37;
+static PyObject *__pyx_tuple__39;
+static PyObject *__pyx_tuple__41;
+static PyObject *__pyx_tuple__42;
+static PyObject *__pyx_tuple__43;
+static PyObject *__pyx_tuple__44;
+static PyObject *__pyx_tuple__45;
+static PyObject *__pyx_codeobj__26;
+static PyObject *__pyx_codeobj__28;
+static PyObject *__pyx_codeobj__30;
+static PyObject *__pyx_codeobj__32;
+static PyObject *__pyx_codeobj__34;
+static PyObject *__pyx_codeobj__36;
+static PyObject *__pyx_codeobj__38;
+static PyObject *__pyx_codeobj__40;
+
+/* "filters.pyx":62
+ *
+ *
+ * def strip(data, w=1, niterations=1000, factor=1.0, anchors=None): # <<<<<<<<<<<<<<
+ * """Extract background from data using the strip algorithm, as explained at
+ * http://pymca.sourceforge.net/stripbackground.html.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7filters_1strip(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_7filters_strip[] = "strip(data, w=1, niterations=1000, factor=1.0, anchors=None)\nExtract background from data using the strip algorithm, as explained at\n http://pymca.sourceforge.net/stripbackground.html.\n\n In its simplest implementation it is just as an iterative procedure\n depending on two parameters. These parameters are the strip background\n width ``w``, and the number of iterations. At each iteration, if the\n contents of channel ``i``, ``y(i)``, is above the average of the contents\n of the channels at ``w`` channels of distance, ``y(i-w)`` and\n ``y(i+w)``, ``y(i)`` is replaced by the average.\n At the end of the process we are left with something that resembles a spectrum\n in which the peaks have been stripped.\n\n :param data: Data array\n :type data: numpy.ndarray\n :param w: Strip width\n :param niterations: number of iterations\n :param factor: scaling factor applied to the average of ``y(i-w)`` and\n ``y(i+w)`` before comparing to ``y(i)``\n :param anchors: Array of anchors, indices of points that will not be\n modified during the stripping procedure.\n :return: Data with peaks stripped away\n ";
+static PyMethodDef __pyx_mdef_7filters_1strip = {"strip", (PyCFunction)__pyx_pw_7filters_1strip, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7filters_strip};
+static PyObject *__pyx_pw_7filters_1strip(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ PyObject *__pyx_v_w = 0;
+ PyObject *__pyx_v_niterations = 0;
+ PyObject *__pyx_v_factor = 0;
+ PyObject *__pyx_v_anchors = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("strip (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_w,&__pyx_n_s_niterations,&__pyx_n_s_factor,&__pyx_n_s_anchors,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[1] = ((PyObject *)__pyx_int_1);
+ values[2] = ((PyObject *)__pyx_int_1000);
+ values[3] = ((PyObject *)__pyx_float_1_0);
+ values[4] = ((PyObject *)Py_None);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_w);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_niterations);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_factor);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_anchors);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "strip") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = values[0];
+ __pyx_v_w = values[1];
+ __pyx_v_niterations = values[2];
+ __pyx_v_factor = values[3];
+ __pyx_v_anchors = values[4];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("strip", 0, 1, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("filters.strip", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_7filters_strip(__pyx_self, __pyx_v_data, __pyx_v_w, __pyx_v_niterations, __pyx_v_factor, __pyx_v_anchors);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7filters_strip(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_w, PyObject *__pyx_v_niterations, PyObject *__pyx_v_factor, PyObject *__pyx_v_anchors) {
+ __Pyx_memviewslice __pyx_v_input_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_output = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_anchors_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_data_shape = NULL;
+ PyObject *__pyx_v_len_anchors = NULL;
+ CYTHON_UNUSED int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ __Pyx_memviewslice __pyx_t_12 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_13;
+ long __pyx_t_14;
+ double __pyx_t_15;
+ long __pyx_t_16;
+ Py_ssize_t __pyx_t_17;
+ int __pyx_t_18;
+ long __pyx_t_19;
+ Py_ssize_t __pyx_t_20;
+ PyObject *__pyx_t_21 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("strip", 0);
+
+ /* "filters.pyx":90
+ * long[::1] anchors_c
+ *
+ * if not isinstance(data, numpy.ndarray): # <<<<<<<<<<<<<<
+ * if not hasattr(data, "__len__"):
+ * raise TypeError("data must be a sequence (list, tuple) " +
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = PyObject_IsInstance(__pyx_v_data, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = ((!(__pyx_t_3 != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":91
+ *
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__"): # <<<<<<<<<<<<<<
+ * raise TypeError("data must be a sequence (list, tuple) " +
+ * "or a numpy array")
+ */
+ __pyx_t_4 = PyObject_HasAttr(__pyx_v_data, __pyx_n_s_len); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((!(__pyx_t_4 != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "filters.pyx":92
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__"):
+ * raise TypeError("data must be a sequence (list, tuple) " + # <<<<<<<<<<<<<<
+ * "or a numpy array")
+ * data_shape = (len(data), )
+ */
+ __pyx_t_2 = PyNumber_Add(__pyx_kp_s_data_must_be_a_sequence_list_tup, __pyx_kp_s_or_a_numpy_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "filters.pyx":94
+ * raise TypeError("data must be a sequence (list, tuple) " +
+ * "or a numpy array")
+ * data_shape = (len(data), ) # <<<<<<<<<<<<<<
+ * else:
+ * data_shape = data.shape
+ */
+ __pyx_t_5 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_v_data_shape = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":96
+ * data_shape = (len(data), )
+ * else:
+ * data_shape = data.shape # <<<<<<<<<<<<<<
+ *
+ * input_c = numpy.array(data,
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_data_shape = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "filters.pyx":98
+ * data_shape = data.shape
+ *
+ * input_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "filters.pyx":99
+ *
+ * input_c = numpy.array(data,
+ * copy=True, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_copy, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":100
+ * input_c = numpy.array(data,
+ * copy=True,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ *
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_float64); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":98
+ * data_shape = data.shape
+ *
+ * input_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "filters.pyx":101
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * output = numpy.empty(shape=(input_c.size,),
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_reshape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_8);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_input_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "filters.pyx":103
+ * order='C').reshape(-1)
+ *
+ * output = numpy.empty(shape=(input_c.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_empty); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyDict_New(); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_input_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_shape, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":104
+ *
+ * output = numpy.empty(shape=(input_c.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * if anchors is not None and len(anchors):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_dtype, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "filters.pyx":103
+ * order='C').reshape(-1)
+ *
+ * output = numpy.empty(shape=(input_c.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_empty_tuple, __pyx_t_8); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_2);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 103; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_output = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "filters.pyx":106
+ * dtype=numpy.float64)
+ *
+ * if anchors is not None and len(anchors): # <<<<<<<<<<<<<<
+ * # numpy.int_ is the same as C long (http://docs.scipy.org/doc/numpy/user/basics.types.html)
+ * anchors_c = numpy.array(anchors,
+ */
+ __pyx_t_4 = (__pyx_v_anchors != Py_None);
+ __pyx_t_11 = (__pyx_t_4 != 0);
+ if (__pyx_t_11) {
+ } else {
+ __pyx_t_3 = __pyx_t_11;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_5 = PyObject_Length(__pyx_v_anchors); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_11 = (__pyx_t_5 != 0);
+ __pyx_t_3 = __pyx_t_11;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_3) {
+
+ /* "filters.pyx":108
+ * if anchors is not None and len(anchors):
+ * # numpy.int_ is the same as C long (http://docs.scipy.org/doc/numpy/user/basics.types.html)
+ * anchors_c = numpy.array(anchors, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.int_,
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_array); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_anchors);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_anchors);
+ __Pyx_GIVEREF(__pyx_v_anchors);
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "filters.pyx":109
+ * # numpy.int_ is the same as C long (http://docs.scipy.org/doc/numpy/user/basics.types.html)
+ * anchors_c = numpy.array(anchors,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.int_,
+ * order='C')
+ */
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":110
+ * anchors_c = numpy.array(anchors,
+ * copy=False,
+ * dtype=numpy.int_, # <<<<<<<<<<<<<<
+ * order='C')
+ * len_anchors = anchors_c.size
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_int); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":108
+ * if anchors is not None and len(anchors):
+ * # numpy.int_ is the same as C long (http://docs.scipy.org/doc/numpy/user/basics.types.html)
+ * anchors_c = numpy.array(anchors, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.int_,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_12 = __Pyx_PyObject_to_MemoryviewSlice_dc_long(__pyx_t_7);
+ if (unlikely(!__pyx_t_12.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_anchors_c = __pyx_t_12;
+ __pyx_t_12.memview = NULL;
+ __pyx_t_12.data = NULL;
+
+ /* "filters.pyx":112
+ * dtype=numpy.int_,
+ * order='C')
+ * len_anchors = anchors_c.size # <<<<<<<<<<<<<<
+ * else:
+ * # Make a dummy length-1 array, because if I use shape=(0,) I get the error
+ */
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_anchors_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_long, (int (*)(char *, PyObject *)) __pyx_memview_set_long, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_len_anchors = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":116
+ * # Make a dummy length-1 array, because if I use shape=(0,) I get the error
+ * # IndexError: Out of bounds on buffer access (axis 0)
+ * anchors_c = numpy.empty(shape=(1,), # <<<<<<<<<<<<<<
+ * dtype=numpy.int_)
+ * len_anchors = 0
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_tuple__2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":117
+ * # IndexError: Out of bounds on buffer access (axis 0)
+ * anchors_c = numpy.empty(shape=(1,),
+ * dtype=numpy.int_) # <<<<<<<<<<<<<<
+ * len_anchors = 0
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_int); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "filters.pyx":116
+ * # Make a dummy length-1 array, because if I use shape=(0,) I get the error
+ * # IndexError: Out of bounds on buffer access (axis 0)
+ * anchors_c = numpy.empty(shape=(1,), # <<<<<<<<<<<<<<
+ * dtype=numpy.int_)
+ * len_anchors = 0
+ */
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_12 = __Pyx_PyObject_to_MemoryviewSlice_dc_long(__pyx_t_8);
+ if (unlikely(!__pyx_t_12.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_anchors_c = __pyx_t_12;
+ __pyx_t_12.memview = NULL;
+ __pyx_t_12.data = NULL;
+
+ /* "filters.pyx":118
+ * anchors_c = numpy.empty(shape=(1,),
+ * dtype=numpy.int_)
+ * len_anchors = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_v_len_anchors = __pyx_int_0;
+ }
+ __pyx_L5:;
+
+ /* "filters.pyx":121
+ *
+ *
+ * status = filters_wrapper.strip(&input_c[0], input_c.size, # <<<<<<<<<<<<<<
+ * factor, niterations, w,
+ * &anchors_c[0], len_anchors, &output[0])
+ */
+ __pyx_t_5 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_5 < 0) {
+ __pyx_t_5 += __pyx_v_input_c.shape[0];
+ if (unlikely(__pyx_t_5 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_5 >= __pyx_v_input_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = __pyx_memoryview_fromslice(__pyx_v_input_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_14 = __Pyx_PyInt_As_long(__pyx_t_6); if (unlikely((__pyx_t_14 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "filters.pyx":122
+ *
+ * status = filters_wrapper.strip(&input_c[0], input_c.size,
+ * factor, niterations, w, # <<<<<<<<<<<<<<
+ * &anchors_c[0], len_anchors, &output[0])
+ *
+ */
+ __pyx_t_15 = __pyx_PyFloat_AsDouble(__pyx_v_factor); if (unlikely((__pyx_t_15 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_16 = __Pyx_PyInt_As_long(__pyx_v_niterations); if (unlikely((__pyx_t_16 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_v_w); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":123
+ * status = filters_wrapper.strip(&input_c[0], input_c.size,
+ * factor, niterations, w,
+ * &anchors_c[0], len_anchors, &output[0]) # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(output).reshape(data_shape)
+ */
+ __pyx_t_17 = 0;
+ __pyx_t_18 = -1;
+ if (__pyx_t_17 < 0) {
+ __pyx_t_17 += __pyx_v_anchors_c.shape[0];
+ if (unlikely(__pyx_t_17 < 0)) __pyx_t_18 = 0;
+ } else if (unlikely(__pyx_t_17 >= __pyx_v_anchors_c.shape[0])) __pyx_t_18 = 0;
+ if (unlikely(__pyx_t_18 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_18);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_19 = __Pyx_PyInt_As_long(__pyx_v_len_anchors); if (unlikely((__pyx_t_19 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_20 = 0;
+ __pyx_t_18 = -1;
+ if (__pyx_t_20 < 0) {
+ __pyx_t_20 += __pyx_v_output.shape[0];
+ if (unlikely(__pyx_t_20 < 0)) __pyx_t_18 = 0;
+ } else if (unlikely(__pyx_t_20 >= __pyx_v_output.shape[0])) __pyx_t_18 = 0;
+ if (unlikely(__pyx_t_18 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_18);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "filters.pyx":121
+ *
+ *
+ * status = filters_wrapper.strip(&input_c[0], input_c.size, # <<<<<<<<<<<<<<
+ * factor, niterations, w,
+ * &anchors_c[0], len_anchors, &output[0])
+ */
+ __pyx_v_status = strip((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_input_c.data) + __pyx_t_5)) )))), __pyx_t_14, __pyx_t_15, __pyx_t_16, __pyx_t_13, (&(*((long *) ( /* dim=0 */ ((char *) (((long *) __pyx_v_anchors_c.data) + __pyx_t_17)) )))), __pyx_t_19, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_output.data) + __pyx_t_20)) )))));
+
+ /* "filters.pyx":125
+ * &anchors_c[0], len_anchors, &output[0])
+ *
+ * return numpy.asarray(output).reshape(data_shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_asarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_output, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_8);
+ } else {
+ __pyx_t_21 = PyTuple_New(1+1); if (unlikely(!__pyx_t_21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_21);
+ PyTuple_SET_ITEM(__pyx_t_21, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_21, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_21, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_reshape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_data_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_21 = PyTuple_New(1+1); if (unlikely(!__pyx_t_21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_21);
+ PyTuple_SET_ITEM(__pyx_t_21, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ __Pyx_INCREF(__pyx_v_data_shape);
+ PyTuple_SET_ITEM(__pyx_t_21, 0+1, __pyx_v_data_shape);
+ __Pyx_GIVEREF(__pyx_v_data_shape);
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_21, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "filters.pyx":62
+ *
+ *
+ * def strip(data, w=1, niterations=1000, factor=1.0, anchors=None): # <<<<<<<<<<<<<<
+ * """Extract background from data using the strip algorithm, as explained at
+ * http://pymca.sourceforge.net/stripbackground.html.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_12, 1);
+ __Pyx_XDECREF(__pyx_t_21);
+ __Pyx_AddTraceback("filters.strip", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_input_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_output, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_anchors_c, 1);
+ __Pyx_XDECREF(__pyx_v_data_shape);
+ __Pyx_XDECREF(__pyx_v_len_anchors);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "filters.pyx":128
+ *
+ *
+ * def snip1d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 1D data vector by clipping peaks.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7filters_3snip1d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_7filters_2snip1d[] = "snip1d(data, snip_width)\nEstimate the baseline (background) of a 1D data vector by clipping peaks.\n\n Implementation of the algorithm SNIP in 1D is described in *Miroslav\n Morhac et al. Nucl. Instruments and Methods in Physics Research A401\n (1997) 113-132*.\n\n The original idea for 1D and the low-statistics-digital-filter (lsdf) come\n from *C.G. Ryan et al. Nucl. Instruments and Methods in Physics Research\n B34 (1988) 396-402*.\n\n :param data: Data array, preferably 1D and of type *numpy.float64*.\n Else, the data array will be flattened and converted to\n *dtype=numpy.float64* prior to applying the snip filter.\n :type data: numpy.ndarray\n :param snip_width: Width of the snip operator, in number of samples.\n A sample will be iteratively compared to it's neighbors up to a\n distance of ``snip_width`` samples. This parameters has a direct\n influence on the speed of the algorithm.\n :type width: int\n :return: Baseline of the input array, as an array of the same shape.\n :rtype: numpy.ndarray\n ";
+static PyMethodDef __pyx_mdef_7filters_3snip1d = {"snip1d", (PyCFunction)__pyx_pw_7filters_3snip1d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7filters_2snip1d};
+static PyObject *__pyx_pw_7filters_3snip1d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ PyObject *__pyx_v_snip_width = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("snip1d (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_snip_width,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_snip_width)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("snip1d", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "snip1d") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_data = values[0];
+ __pyx_v_snip_width = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("snip1d", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("filters.snip1d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_7filters_2snip1d(__pyx_self, __pyx_v_data, __pyx_v_snip_width);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7filters_2snip1d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_snip_width) {
+ __Pyx_memviewslice __pyx_v_data_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_data_shape = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_10;
+ int __pyx_t_11;
+ PyObject *__pyx_t_12 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("snip1d", 0);
+
+ /* "filters.pyx":154
+ * double[::1] data_c
+ *
+ * if not isinstance(data, numpy.ndarray): # <<<<<<<<<<<<<<
+ * if not hasattr(data, "__len__"):
+ * raise TypeError("data must be a sequence (list, tuple) " +
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = PyObject_IsInstance(__pyx_v_data, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = ((!(__pyx_t_3 != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":155
+ *
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__"): # <<<<<<<<<<<<<<
+ * raise TypeError("data must be a sequence (list, tuple) " +
+ * "or a numpy array")
+ */
+ __pyx_t_4 = PyObject_HasAttr(__pyx_v_data, __pyx_n_s_len); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((!(__pyx_t_4 != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "filters.pyx":156
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__"):
+ * raise TypeError("data must be a sequence (list, tuple) " + # <<<<<<<<<<<<<<
+ * "or a numpy array")
+ * data_shape = (len(data), )
+ */
+ __pyx_t_2 = PyNumber_Add(__pyx_kp_s_data_must_be_a_sequence_list_tup, __pyx_kp_s_or_a_numpy_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "filters.pyx":158
+ * raise TypeError("data must be a sequence (list, tuple) " +
+ * "or a numpy array")
+ * data_shape = (len(data), ) # <<<<<<<<<<<<<<
+ * else:
+ * data_shape = data.shape
+ */
+ __pyx_t_5 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_v_data_shape = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":160
+ * data_shape = (len(data), )
+ * else:
+ * data_shape = data.shape # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_data_shape = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "filters.pyx":162
+ * data_shape = data.shape
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "filters.pyx":163
+ *
+ * data_c = numpy.array(data,
+ * copy=True, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_copy, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":164
+ * data_c = numpy.array(data,
+ * copy=True,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ *
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_float64); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":162
+ * data_shape = data.shape
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "filters.pyx":165
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.snip1d(&data_c[0], data_c.size, snip_width)
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_reshape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_8);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_data_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "filters.pyx":167
+ * order='C').reshape(-1)
+ *
+ * filters_wrapper.snip1d(&data_c[0], data_c.size, snip_width) # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(data_c).reshape(data_shape)
+ */
+ __pyx_t_5 = 0;
+ __pyx_t_10 = -1;
+ if (__pyx_t_5 < 0) {
+ __pyx_t_5 += __pyx_v_data_c.shape[0];
+ if (unlikely(__pyx_t_5 < 0)) __pyx_t_10 = 0;
+ } else if (unlikely(__pyx_t_5 >= __pyx_v_data_c.shape[0])) __pyx_t_10 = 0;
+ if (unlikely(__pyx_t_10 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_10);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_10 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_v_snip_width); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ snip1d((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data_c.data) + __pyx_t_5)) )))), __pyx_t_10, __pyx_t_11);
+
+ /* "filters.pyx":169
+ * filters_wrapper.snip1d(&data_c[0], data_c.size, snip_width)
+ *
+ * return numpy.asarray(data_c).reshape(data_shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_asarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_GOTREF(__pyx_t_8);
+ } else {
+ __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_12, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_reshape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_data_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ __Pyx_INCREF(__pyx_v_data_shape);
+ PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_v_data_shape);
+ __Pyx_GIVEREF(__pyx_v_data_shape);
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_12, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "filters.pyx":128
+ *
+ *
+ * def snip1d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 1D data vector by clipping peaks.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __Pyx_XDECREF(__pyx_t_12);
+ __Pyx_AddTraceback("filters.snip1d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data_c, 1);
+ __Pyx_XDECREF(__pyx_v_data_shape);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "filters.pyx":172
+ *
+ *
+ * def snip2d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 2D data signal by clipping peaks.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7filters_5snip2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_7filters_4snip2d[] = "snip2d(data, snip_width)\nEstimate the baseline (background) of a 2D data signal by clipping peaks.\n\n Implementation of the algorithm SNIP in 2D described in\n *Miroslav Morhac et al. Nucl. Instruments and Methods in Physics Research\n A401 (1997) 113-132.*\n\n :param data: 2D array\n :type data: numpy.ndarray\n :param width: Width of the snip operator, in number of samples. A wider\n snip operator will result in a smoother result (lower frequency peaks\n will be clipped), and a longer computation time.\n :type width: int\n :return: Baseline of the input array, as an array of the same shape.\n :rtype: numpy.ndarray\n ";
+static PyMethodDef __pyx_mdef_7filters_5snip2d = {"snip2d", (PyCFunction)__pyx_pw_7filters_5snip2d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7filters_4snip2d};
+static PyObject *__pyx_pw_7filters_5snip2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ PyObject *__pyx_v_snip_width = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("snip2d (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_snip_width,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_snip_width)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("snip2d", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "snip2d") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_data = values[0];
+ __pyx_v_snip_width = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("snip2d", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("filters.snip2d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_7filters_4snip2d(__pyx_self, __pyx_v_data, __pyx_v_snip_width);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7filters_4snip2d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_snip_width) {
+ __Pyx_memviewslice __pyx_v_data_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_nrows = NULL;
+ PyObject *__pyx_v_ncolumns = NULL;
+ PyObject *__pyx_v_data_shape = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_t_13;
+ PyObject *__pyx_t_14 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("snip2d", 0);
+
+ /* "filters.pyx":191
+ * double[::1] data_c
+ *
+ * if not isinstance(data, numpy.ndarray): # <<<<<<<<<<<<<<
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__"):
+ * raise TypeError("data must be a 2D sequence (list, tuple) " +
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = PyObject_IsInstance(__pyx_v_data, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = ((!(__pyx_t_3 != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":192
+ *
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__"): # <<<<<<<<<<<<<<
+ * raise TypeError("data must be a 2D sequence (list, tuple) " +
+ * "or a 2D numpy array")
+ */
+ __pyx_t_3 = PyObject_HasAttr(__pyx_v_data, __pyx_n_s_len); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = ((!(__pyx_t_3 != 0)) != 0);
+ if (!__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = PyObject_HasAttr(__pyx_t_2, __pyx_n_s_len); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_3 = ((!(__pyx_t_5 != 0)) != 0);
+ __pyx_t_4 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":193
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__"):
+ * raise TypeError("data must be a 2D sequence (list, tuple) " + # <<<<<<<<<<<<<<
+ * "or a 2D numpy array")
+ * nrows = len(data)
+ */
+ __pyx_t_2 = PyNumber_Add(__pyx_kp_s_data_must_be_a_2D_sequence_list, __pyx_kp_s_or_a_2D_numpy_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "filters.pyx":195
+ * raise TypeError("data must be a 2D sequence (list, tuple) " +
+ * "or a 2D numpy array")
+ * nrows = len(data) # <<<<<<<<<<<<<<
+ * ncolumns = len(data[0])
+ * data_shape = (len(data), len(data[0]))
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_v_nrows = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "filters.pyx":196
+ * "or a 2D numpy array")
+ * nrows = len(data)
+ * ncolumns = len(data[0]) # <<<<<<<<<<<<<<
+ * data_shape = (len(data), len(data[0]))
+ *
+ */
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_6 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_v_ncolumns = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "filters.pyx":197
+ * nrows = len(data)
+ * ncolumns = len(data[0])
+ * data_shape = (len(data), len(data[0])) # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = 0;
+ __pyx_v_data_shape = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":200
+ *
+ * else:
+ * data_shape = data.shape # <<<<<<<<<<<<<<
+ * nrows = data_shape[0]
+ * if len(data_shape) == 2:
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_data_shape = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":201
+ * else:
+ * data_shape = data.shape
+ * nrows = data_shape[0] # <<<<<<<<<<<<<<
+ * if len(data_shape) == 2:
+ * ncolumns = data_shape[1]
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_nrows = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":202
+ * data_shape = data.shape
+ * nrows = data_shape[0]
+ * if len(data_shape) == 2: # <<<<<<<<<<<<<<
+ * ncolumns = data_shape[1]
+ * else:
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data_shape); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = ((__pyx_t_6 == 2) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":203
+ * nrows = data_shape[0]
+ * if len(data_shape) == 2:
+ * ncolumns = data_shape[1] # <<<<<<<<<<<<<<
+ * else:
+ * raise TypeError("data array must be 2-dimensional")
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_ncolumns = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":205
+ * ncolumns = data_shape[1]
+ * else:
+ * raise TypeError("data array must be 2-dimensional") # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ }
+ __pyx_L3:;
+
+ /* "filters.pyx":207
+ * raise TypeError("data array must be 2-dimensional")
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+
+ /* "filters.pyx":208
+ *
+ * data_c = numpy.array(data,
+ * copy=True, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_copy, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":209
+ * data_c = numpy.array(data,
+ * copy=True,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ *
+ */
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_float64); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":207
+ * raise TypeError("data array must be 2-dimensional")
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "filters.pyx":210
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.snip2d(&data_c[0], nrows, ncolumns, snip_width)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_reshape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_9);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_data_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "filters.pyx":212
+ * order='C').reshape(-1)
+ *
+ * filters_wrapper.snip2d(&data_c[0], nrows, ncolumns, snip_width) # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(data_c).reshape(data_shape)
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_6 < 0) {
+ __pyx_t_6 += __pyx_v_data_c.shape[0];
+ if (unlikely(__pyx_t_6 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_6 >= __pyx_v_data_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_v_nrows); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_ncolumns); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_v_snip_width); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ snip2d((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data_c.data) + __pyx_t_6)) )))), __pyx_t_11, __pyx_t_12, __pyx_t_13);
+
+ /* "filters.pyx":214
+ * filters_wrapper.snip2d(&data_c[0], nrows, ncolumns, snip_width)
+ *
+ * return numpy.asarray(data_c).reshape(data_shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_asarray); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_14 = PyTuple_New(1+1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_14, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_14, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_reshape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_data_shape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ } else {
+ __pyx_t_14 = PyTuple_New(1+1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ __Pyx_INCREF(__pyx_v_data_shape);
+ PyTuple_SET_ITEM(__pyx_t_14, 0+1, __pyx_v_data_shape);
+ __Pyx_GIVEREF(__pyx_v_data_shape);
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_14, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L0;
+
+ /* "filters.pyx":172
+ *
+ *
+ * def snip2d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 2D data signal by clipping peaks.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_AddTraceback("filters.snip2d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data_c, 1);
+ __Pyx_XDECREF(__pyx_v_nrows);
+ __Pyx_XDECREF(__pyx_v_ncolumns);
+ __Pyx_XDECREF(__pyx_v_data_shape);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "filters.pyx":217
+ *
+ *
+ * def snip3d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 3D data signal by clipping peaks.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7filters_7snip3d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_7filters_6snip3d[] = "snip3d(data, snip_width)\nEstimate the baseline (background) of a 3D data signal by clipping peaks.\n\n Implementation of the algorithm SNIP in 2D described in\n *Miroslav Morhac et al. Nucl. Instruments and Methods in Physics Research\n A401 (1997) 113-132.*\n\n :param data: 3D array\n :type data: numpy.ndarray\n :param width: Width of the snip operator, in number of samples. A wider\n snip operator will result in a smoother result (lower frequency peaks\n will be clipped), and a longer computation time.\n :type width: int\n\n :return: Baseline of the input array, as an array of the same shape.\n :rtype: numpy.ndarray\n ";
+static PyMethodDef __pyx_mdef_7filters_7snip3d = {"snip3d", (PyCFunction)__pyx_pw_7filters_7snip3d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7filters_6snip3d};
+static PyObject *__pyx_pw_7filters_7snip3d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ PyObject *__pyx_v_snip_width = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("snip3d (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_snip_width,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_snip_width)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("snip3d", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "snip3d") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_data = values[0];
+ __pyx_v_snip_width = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("snip3d", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("filters.snip3d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_7filters_6snip3d(__pyx_self, __pyx_v_data, __pyx_v_snip_width);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7filters_6snip3d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_snip_width) {
+ __Pyx_memviewslice __pyx_v_data_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_nx = NULL;
+ PyObject *__pyx_v_ny = NULL;
+ PyObject *__pyx_v_nz = NULL;
+ PyObject *__pyx_v_data_shape = NULL;
+ CYTHON_UNUSED PyObject *__pyx_v_nrows = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_t_13;
+ int __pyx_t_14;
+ PyObject *__pyx_t_15 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("snip3d", 0);
+
+ /* "filters.pyx":237
+ * double[::1] data_c
+ *
+ * if not isinstance(data, numpy.ndarray): # <<<<<<<<<<<<<<
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\
+ * not hasattr(data[0][0], "__len__"):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = PyObject_IsInstance(__pyx_v_data, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = ((!(__pyx_t_3 != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":238
+ *
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\ # <<<<<<<<<<<<<<
+ * not hasattr(data[0][0], "__len__"):
+ * raise TypeError("data must be a 3D sequence (list, tuple) " +
+ */
+ __pyx_t_3 = PyObject_HasAttr(__pyx_v_data, __pyx_n_s_len); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = ((!(__pyx_t_3 != 0)) != 0);
+ if (!__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = PyObject_HasAttr(__pyx_t_2, __pyx_n_s_len); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_3 = ((!(__pyx_t_5 != 0)) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_4 = __pyx_t_3;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "filters.pyx":239
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\
+ * not hasattr(data[0][0], "__len__"): # <<<<<<<<<<<<<<
+ * raise TypeError("data must be a 3D sequence (list, tuple) " +
+ * "or a 3D numpy array")
+ */
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_3 = PyObject_HasAttr(__pyx_t_1, __pyx_n_s_len); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_5 = ((!(__pyx_t_3 != 0)) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":240
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\
+ * not hasattr(data[0][0], "__len__"):
+ * raise TypeError("data must be a 3D sequence (list, tuple) " + # <<<<<<<<<<<<<<
+ * "or a 3D numpy array")
+ * nx = len(data)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_kp_s_data_must_be_a_3D_sequence_list, __pyx_kp_s_or_a_3D_numpy_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "filters.pyx":242
+ * raise TypeError("data must be a 3D sequence (list, tuple) " +
+ * "or a 3D numpy array")
+ * nx = len(data) # <<<<<<<<<<<<<<
+ * ny = len(data[0])
+ * nz = len(data[0][0])
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_nx = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "filters.pyx":243
+ * "or a 3D numpy array")
+ * nx = len(data)
+ * ny = len(data[0]) # <<<<<<<<<<<<<<
+ * nz = len(data[0][0])
+ * data_shape = (len(data), len(data[0]), len(data[0][0]))
+ */
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_ny = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "filters.pyx":244
+ * nx = len(data)
+ * ny = len(data[0])
+ * nz = len(data[0][0]) # <<<<<<<<<<<<<<
+ * data_shape = (len(data), len(data[0]), len(data[0][0]))
+ * else:
+ */
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_v_nz = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "filters.pyx":245
+ * ny = len(data[0])
+ * nz = len(data[0][0])
+ * data_shape = (len(data), len(data[0]), len(data[0][0])) # <<<<<<<<<<<<<<
+ * else:
+ * data_shape = data.shape
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_7, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_6 = PyObject_Length(__pyx_t_8); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = 0;
+ __pyx_t_8 = 0;
+ __pyx_v_data_shape = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":247
+ * data_shape = (len(data), len(data[0]), len(data[0][0]))
+ * else:
+ * data_shape = data.shape # <<<<<<<<<<<<<<
+ * nrows = data_shape[0]
+ * if len(data_shape) == 3:
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_data_shape = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":248
+ * else:
+ * data_shape = data.shape
+ * nrows = data_shape[0] # <<<<<<<<<<<<<<
+ * if len(data_shape) == 3:
+ * nx = data_shape[0]
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_nrows = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":249
+ * data_shape = data.shape
+ * nrows = data_shape[0]
+ * if len(data_shape) == 3: # <<<<<<<<<<<<<<
+ * nx = data_shape[0]
+ * ny = data_shape[1]
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data_shape); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = ((__pyx_t_6 == 3) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":250
+ * nrows = data_shape[0]
+ * if len(data_shape) == 3:
+ * nx = data_shape[0] # <<<<<<<<<<<<<<
+ * ny = data_shape[1]
+ * nz = data_shape[2]
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_nx = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":251
+ * if len(data_shape) == 3:
+ * nx = data_shape[0]
+ * ny = data_shape[1] # <<<<<<<<<<<<<<
+ * nz = data_shape[2]
+ * else:
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_ny = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":252
+ * nx = data_shape[0]
+ * ny = data_shape[1]
+ * nz = data_shape[2] # <<<<<<<<<<<<<<
+ * else:
+ * raise TypeError("data array must be 3-dimensional")
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_nz = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":254
+ * nz = data_shape[2]
+ * else:
+ * raise TypeError("data array must be 3-dimensional") # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L8:;
+ }
+ __pyx_L3:;
+
+ /* "filters.pyx":256
+ * raise TypeError("data array must be 3-dimensional")
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "filters.pyx":257
+ *
+ * data_c = numpy.array(data,
+ * copy=True, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_copy, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":258
+ * data_c = numpy.array(data,
+ * copy=True,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_float64); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":256
+ * raise TypeError("data array must be 3-dimensional")
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_7, __pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":259
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.snip3d(&data_c[0], nx, ny, nz, snip_width)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_reshape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_9);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_data_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "filters.pyx":261
+ * order='C').reshape(-1)
+ *
+ * filters_wrapper.snip3d(&data_c[0], nx, ny, nz, snip_width) # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(data_c).reshape(data_shape)
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_6 < 0) {
+ __pyx_t_6 += __pyx_v_data_c.shape[0];
+ if (unlikely(__pyx_t_6 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_6 >= __pyx_v_data_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_v_nx); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_ny); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_v_nz); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_14 = __Pyx_PyInt_As_int(__pyx_v_snip_width); if (unlikely((__pyx_t_14 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ snip3d((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data_c.data) + __pyx_t_6)) )))), __pyx_t_11, __pyx_t_12, __pyx_t_13, __pyx_t_14);
+
+ /* "filters.pyx":263
+ * filters_wrapper.snip3d(&data_c[0], nx, ny, nz, snip_width)
+ *
+ * return numpy.asarray(data_c).reshape(data_shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_asarray); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_15, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_reshape); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_v_data_shape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ } else {
+ __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ __Pyx_INCREF(__pyx_v_data_shape);
+ PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_v_data_shape);
+ __Pyx_GIVEREF(__pyx_v_data_shape);
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_15, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_r = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L0;
+
+ /* "filters.pyx":217
+ *
+ *
+ * def snip3d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 3D data signal by clipping peaks.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_AddTraceback("filters.snip3d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data_c, 1);
+ __Pyx_XDECREF(__pyx_v_nx);
+ __Pyx_XDECREF(__pyx_v_ny);
+ __Pyx_XDECREF(__pyx_v_nz);
+ __Pyx_XDECREF(__pyx_v_data_shape);
+ __Pyx_XDECREF(__pyx_v_nrows);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "filters.pyx":266
+ *
+ *
+ * def savitsky_golay(data, npoints=5): # <<<<<<<<<<<<<<
+ * """Smooth a curve using a Savitsky-Golay filter.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7filters_9savitsky_golay(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_7filters_8savitsky_golay[] = "savitsky_golay(data, npoints=5)\nSmooth a curve using a Savitsky-Golay filter.\n\n :param data: Input data\n :type data: 1D numpy array\n :param npoints: Size of the smoothing operator in number of samples\n Must be between 3 and 100.\n :return: Smoothed data\n ";
+static PyMethodDef __pyx_mdef_7filters_9savitsky_golay = {"savitsky_golay", (PyCFunction)__pyx_pw_7filters_9savitsky_golay, METH_VARARGS|METH_KEYWORDS, __pyx_doc_7filters_8savitsky_golay};
+static PyObject *__pyx_pw_7filters_9savitsky_golay(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ PyObject *__pyx_v_npoints = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("savitsky_golay (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_npoints,0};
+ PyObject* values[2] = {0,0};
+ values[1] = ((PyObject *)__pyx_int_5);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_npoints);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "savitsky_golay") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = values[0];
+ __pyx_v_npoints = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("savitsky_golay", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("filters.savitsky_golay", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_7filters_8savitsky_golay(__pyx_self, __pyx_v_data, __pyx_v_npoints);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7filters_8savitsky_golay(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_npoints) {
+ __Pyx_memviewslice __pyx_v_data_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_output = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ __Pyx_memviewslice __pyx_t_6 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_7 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ long __pyx_t_10;
+ Py_ssize_t __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_t_13;
+ PyObject *__pyx_t_14 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("savitsky_golay", 0);
+
+ /* "filters.pyx":279
+ * double[::1] output
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "filters.pyx":280
+ *
+ * data_c = numpy.array(data,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":279
+ * double[::1] output
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "filters.pyx":281
+ * data_c = numpy.array(data,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * output = numpy.empty(shape=(data_c.size,),
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_5);
+ if (unlikely(!__pyx_t_6.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_data_c = __pyx_t_6;
+ __pyx_t_6.memview = NULL;
+ __pyx_t_6.data = NULL;
+
+ /* "filters.pyx":283
+ * order='C').reshape(-1)
+ *
+ * output = numpy.empty(shape=(data_c.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_size); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_shape, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":284
+ *
+ * output = numpy.empty(shape=(data_c.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = filters_wrapper.SavitskyGolay(&data_c[0], data_c.size,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "filters.pyx":283
+ * order='C').reshape(-1)
+ *
+ * output = numpy.empty(shape=(data_c.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_2);
+ if (unlikely(!__pyx_t_7.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_v_output = __pyx_t_7;
+ __pyx_t_7.memview = NULL;
+ __pyx_t_7.data = NULL;
+
+ /* "filters.pyx":286
+ * dtype=numpy.float64)
+ *
+ * status = filters_wrapper.SavitskyGolay(&data_c[0], data_c.size, # <<<<<<<<<<<<<<
+ * npoints, &output[0])
+ *
+ */
+ __pyx_t_8 = 0;
+ __pyx_t_9 = -1;
+ if (__pyx_t_8 < 0) {
+ __pyx_t_8 += __pyx_v_data_c.shape[0];
+ if (unlikely(__pyx_t_8 < 0)) __pyx_t_9 = 0;
+ } else if (unlikely(__pyx_t_8 >= __pyx_v_data_c.shape[0])) __pyx_t_9 = 0;
+ if (unlikely(__pyx_t_9 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_9);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_2 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_10 = __Pyx_PyInt_As_long(__pyx_t_5); if (unlikely((__pyx_t_10 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "filters.pyx":287
+ *
+ * status = filters_wrapper.SavitskyGolay(&data_c[0], data_c.size,
+ * npoints, &output[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_9 = __Pyx_PyInt_As_int(__pyx_v_npoints); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_11 = 0;
+ __pyx_t_12 = -1;
+ if (__pyx_t_11 < 0) {
+ __pyx_t_11 += __pyx_v_output.shape[0];
+ if (unlikely(__pyx_t_11 < 0)) __pyx_t_12 = 0;
+ } else if (unlikely(__pyx_t_11 >= __pyx_v_output.shape[0])) __pyx_t_12 = 0;
+ if (unlikely(__pyx_t_12 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_12);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "filters.pyx":286
+ * dtype=numpy.float64)
+ *
+ * status = filters_wrapper.SavitskyGolay(&data_c[0], data_c.size, # <<<<<<<<<<<<<<
+ * npoints, &output[0])
+ *
+ */
+ __pyx_v_status = SavitskyGolay((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data_c.data) + __pyx_t_8)) )))), __pyx_t_10, __pyx_t_9, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_output.data) + __pyx_t_11)) )))));
+
+ /* "filters.pyx":289
+ * npoints, &output[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * _logger.error("Smoothing failed. Check that npoints is greater " +
+ * "than 3 and smaller than 100.")
+ */
+ __pyx_t_13 = (__pyx_v_status != 0);
+ if (__pyx_t_13) {
+
+ /* "filters.pyx":290
+ *
+ * if status:
+ * _logger.error("Smoothing failed. Check that npoints is greater " + # <<<<<<<<<<<<<<
+ * "than 3 and smaller than 100.")
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_error); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyNumber_Add(__pyx_kp_s_Smoothing_failed_Check_that_npoi, __pyx_kp_s_than_3_and_smaller_than_100); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "filters.pyx":293
+ * "than 3 and smaller than 100.")
+ *
+ * return numpy.asarray(output).reshape(data.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_memoryview_fromslice(__pyx_v_output, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_14 = PyTuple_New(1+1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_14, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_14, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_reshape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_14 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_14 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_14)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_14);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_14) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_14); __Pyx_GIVEREF(__pyx_t_14); __pyx_t_14 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "filters.pyx":266
+ *
+ *
+ * def savitsky_golay(data, npoints=5): # <<<<<<<<<<<<<<
+ * """Smooth a curve using a Savitsky-Golay filter.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_AddTraceback("filters.savitsky_golay", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_output, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "filters.pyx":296
+ *
+ *
+ * def smooth1d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 1D data.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7filters_11smooth1d(PyObject *__pyx_self, PyObject *__pyx_v_data); /*proto*/
+static char __pyx_doc_7filters_10smooth1d[] = "smooth1d(data)\nSimple smoothing for 1D data.\n\n For a data array :math:`y` of length :math:`n`, the smoothed array\n :math:`ys` is calculated as a weighted average of neighboring samples:\n\n :math:`ys_0 = 0.75 y_0 + 0.25 y_1`\n\n :math:`ys_i = 0.25 (y_{i-1} + 2 y_i + y_{i+1})` for :math:`0 < i < n-1`\n\n :math:`ys_{n-1} = 0.25 y_{n-2} + 0.75 y_{n-1}`\n\n\n :param data: 1D\302\240data array\n :type data: numpy.ndarray\n :return: Smoothed data\n :rtype: numpy.ndarray(dtype=numpy.float64)\n ";
+static PyMethodDef __pyx_mdef_7filters_11smooth1d = {"smooth1d", (PyCFunction)__pyx_pw_7filters_11smooth1d, METH_O, __pyx_doc_7filters_10smooth1d};
+static PyObject *__pyx_pw_7filters_11smooth1d(PyObject *__pyx_self, PyObject *__pyx_v_data) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("smooth1d (wrapper)", 0);
+ __pyx_r = __pyx_pf_7filters_10smooth1d(__pyx_self, ((PyObject *)__pyx_v_data));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7filters_10smooth1d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data) {
+ __Pyx_memviewslice __pyx_v_data_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_data_shape = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("smooth1d", 0);
+
+ /* "filters.pyx":317
+ * double[::1] data_c
+ *
+ * if not isinstance(data, numpy.ndarray): # <<<<<<<<<<<<<<
+ * if not hasattr(data, "__len__"):
+ * raise TypeError("data must be a sequence (list, tuple) " +
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = PyObject_IsInstance(__pyx_v_data, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = ((!(__pyx_t_3 != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":318
+ *
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__"): # <<<<<<<<<<<<<<
+ * raise TypeError("data must be a sequence (list, tuple) " +
+ * "or a numpy array")
+ */
+ __pyx_t_4 = PyObject_HasAttr(__pyx_v_data, __pyx_n_s_len); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((!(__pyx_t_4 != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "filters.pyx":319
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__"):
+ * raise TypeError("data must be a sequence (list, tuple) " + # <<<<<<<<<<<<<<
+ * "or a numpy array")
+ * data_shape = (len(data), )
+ */
+ __pyx_t_2 = PyNumber_Add(__pyx_kp_s_data_must_be_a_sequence_list_tup, __pyx_kp_s_or_a_numpy_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "filters.pyx":321
+ * raise TypeError("data must be a sequence (list, tuple) " +
+ * "or a numpy array")
+ * data_shape = (len(data), ) # <<<<<<<<<<<<<<
+ * else:
+ * data_shape = data.shape
+ */
+ __pyx_t_5 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_v_data_shape = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":323
+ * data_shape = (len(data), )
+ * else:
+ * data_shape = data.shape # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_data_shape = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "filters.pyx":325
+ * data_shape = data.shape
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "filters.pyx":326
+ *
+ * data_c = numpy.array(data,
+ * copy=True, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_copy, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":327
+ * data_c = numpy.array(data,
+ * copy=True,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ *
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_float64); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":325
+ * data_shape = data.shape
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "filters.pyx":328
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.smooth1d(&data_c[0], data_c.size)
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_reshape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_8);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_data_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "filters.pyx":330
+ * order='C').reshape(-1)
+ *
+ * filters_wrapper.smooth1d(&data_c[0], data_c.size) # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(data_c).reshape(data_shape)
+ */
+ __pyx_t_5 = 0;
+ __pyx_t_10 = -1;
+ if (__pyx_t_5 < 0) {
+ __pyx_t_5 += __pyx_v_data_c.shape[0];
+ if (unlikely(__pyx_t_5 < 0)) __pyx_t_10 = 0;
+ } else if (unlikely(__pyx_t_5 >= __pyx_v_data_c.shape[0])) __pyx_t_10 = 0;
+ if (unlikely(__pyx_t_10 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_10);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_10 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_10 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ smooth1d((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data_c.data) + __pyx_t_5)) )))), __pyx_t_10);
+
+ /* "filters.pyx":332
+ * filters_wrapper.smooth1d(&data_c[0], data_c.size)
+ *
+ * return numpy.asarray(data_c).reshape(data_shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_asarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_GOTREF(__pyx_t_8);
+ } else {
+ __pyx_t_11 = PyTuple_New(1+1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_11, 0+1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_11, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_reshape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_data_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_11 = PyTuple_New(1+1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ __Pyx_INCREF(__pyx_v_data_shape);
+ PyTuple_SET_ITEM(__pyx_t_11, 0+1, __pyx_v_data_shape);
+ __Pyx_GIVEREF(__pyx_v_data_shape);
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_11, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "filters.pyx":296
+ *
+ *
+ * def smooth1d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 1D data.
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("filters.smooth1d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data_c, 1);
+ __Pyx_XDECREF(__pyx_v_data_shape);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "filters.pyx":335
+ *
+ *
+ * def smooth2d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 2D data:
+ * :func:`smooth1d` is applied succesively along both axis
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7filters_13smooth2d(PyObject *__pyx_self, PyObject *__pyx_v_data); /*proto*/
+static char __pyx_doc_7filters_12smooth2d[] = "smooth2d(data)\nSimple smoothing for 2D data:\n :func:`smooth1d` is applied succesively along both axis\n\n :param data: 2D\302\240data array\n :type data: numpy.ndarray\n :return: Smoothed data\n :rtype: numpy.ndarray(dtype=numpy.float64)\n ";
+static PyMethodDef __pyx_mdef_7filters_13smooth2d = {"smooth2d", (PyCFunction)__pyx_pw_7filters_13smooth2d, METH_O, __pyx_doc_7filters_12smooth2d};
+static PyObject *__pyx_pw_7filters_13smooth2d(PyObject *__pyx_self, PyObject *__pyx_v_data) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("smooth2d (wrapper)", 0);
+ __pyx_r = __pyx_pf_7filters_12smooth2d(__pyx_self, ((PyObject *)__pyx_v_data));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7filters_12smooth2d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data) {
+ __Pyx_memviewslice __pyx_v_data_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_nrows = NULL;
+ PyObject *__pyx_v_ncolumns = NULL;
+ PyObject *__pyx_v_data_shape = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ int __pyx_t_12;
+ PyObject *__pyx_t_13 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("smooth2d", 0);
+
+ /* "filters.pyx":347
+ * double[::1] data_c
+ *
+ * if not isinstance(data, numpy.ndarray): # <<<<<<<<<<<<<<
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__"):
+ * raise TypeError("data must be a 2D sequence (list, tuple) " +
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = PyObject_IsInstance(__pyx_v_data, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = ((!(__pyx_t_3 != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":348
+ *
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__"): # <<<<<<<<<<<<<<
+ * raise TypeError("data must be a 2D sequence (list, tuple) " +
+ * "or a 2D numpy array")
+ */
+ __pyx_t_3 = PyObject_HasAttr(__pyx_v_data, __pyx_n_s_len); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 348; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = ((!(__pyx_t_3 != 0)) != 0);
+ if (!__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 348; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = PyObject_HasAttr(__pyx_t_2, __pyx_n_s_len); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 348; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_3 = ((!(__pyx_t_5 != 0)) != 0);
+ __pyx_t_4 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":349
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__"):
+ * raise TypeError("data must be a 2D sequence (list, tuple) " + # <<<<<<<<<<<<<<
+ * "or a 2D numpy array")
+ * nrows = len(data)
+ */
+ __pyx_t_2 = PyNumber_Add(__pyx_kp_s_data_must_be_a_2D_sequence_list, __pyx_kp_s_or_a_2D_numpy_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_1, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "filters.pyx":351
+ * raise TypeError("data must be a 2D sequence (list, tuple) " +
+ * "or a 2D numpy array")
+ * nrows = len(data) # <<<<<<<<<<<<<<
+ * ncolumns = len(data[0])
+ * data_shape = (len(data), len(data[0]))
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_v_nrows = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "filters.pyx":352
+ * "or a 2D numpy array")
+ * nrows = len(data)
+ * ncolumns = len(data[0]) # <<<<<<<<<<<<<<
+ * data_shape = (len(data), len(data[0]))
+ *
+ */
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_6 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_v_ncolumns = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "filters.pyx":353
+ * nrows = len(data)
+ * ncolumns = len(data[0])
+ * data_shape = (len(data), len(data[0])) # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = 0;
+ __pyx_v_data_shape = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":356
+ *
+ * else:
+ * data_shape = data.shape # <<<<<<<<<<<<<<
+ * nrows = data_shape[0]
+ * if len(data_shape) == 2:
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_data_shape = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":357
+ * else:
+ * data_shape = data.shape
+ * nrows = data_shape[0] # <<<<<<<<<<<<<<
+ * if len(data_shape) == 2:
+ * ncolumns = data_shape[1]
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_nrows = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":358
+ * data_shape = data.shape
+ * nrows = data_shape[0]
+ * if len(data_shape) == 2: # <<<<<<<<<<<<<<
+ * ncolumns = data_shape[1]
+ * else:
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data_shape); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = ((__pyx_t_6 == 2) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":359
+ * nrows = data_shape[0]
+ * if len(data_shape) == 2:
+ * ncolumns = data_shape[1] # <<<<<<<<<<<<<<
+ * else:
+ * raise TypeError("data array must be 2-dimensional")
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_ncolumns = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":361
+ * ncolumns = data_shape[1]
+ * else:
+ * raise TypeError("data array must be 2-dimensional") # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ }
+ __pyx_L3:;
+
+ /* "filters.pyx":363
+ * raise TypeError("data array must be 2-dimensional")
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+
+ /* "filters.pyx":364
+ *
+ * data_c = numpy.array(data,
+ * copy=True, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_copy, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":365
+ * data_c = numpy.array(data,
+ * copy=True,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ *
+ */
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_float64); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_dtype, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":363
+ * raise TypeError("data array must be 2-dimensional")
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_7, __pyx_t_2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "filters.pyx":366
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.smooth2d(&data_c[0], nrows, ncolumns)
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_reshape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_9);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_data_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "filters.pyx":368
+ * order='C').reshape(-1)
+ *
+ * filters_wrapper.smooth2d(&data_c[0], nrows, ncolumns) # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(data_c).reshape(data_shape)
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_6 < 0) {
+ __pyx_t_6 += __pyx_v_data_c.shape[0];
+ if (unlikely(__pyx_t_6 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_6 >= __pyx_v_data_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_v_nrows); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_ncolumns); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ smooth2d((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data_c.data) + __pyx_t_6)) )))), __pyx_t_11, __pyx_t_12);
+
+ /* "filters.pyx":370
+ * filters_wrapper.smooth2d(&data_c[0], nrows, ncolumns)
+ *
+ * return numpy.asarray(data_c).reshape(data_shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_asarray); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_13 = PyTuple_New(1+1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_13, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_13, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_reshape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_data_shape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ } else {
+ __pyx_t_13 = PyTuple_New(1+1); if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_13);
+ PyTuple_SET_ITEM(__pyx_t_13, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ __Pyx_INCREF(__pyx_v_data_shape);
+ PyTuple_SET_ITEM(__pyx_t_13, 0+1, __pyx_v_data_shape);
+ __Pyx_GIVEREF(__pyx_v_data_shape);
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_13, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L0;
+
+ /* "filters.pyx":335
+ *
+ *
+ * def smooth2d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 2D data:
+ * :func:`smooth1d` is applied succesively along both axis
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_13);
+ __Pyx_AddTraceback("filters.smooth2d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data_c, 1);
+ __Pyx_XDECREF(__pyx_v_nrows);
+ __Pyx_XDECREF(__pyx_v_ncolumns);
+ __Pyx_XDECREF(__pyx_v_data_shape);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "filters.pyx":373
+ *
+ *
+ * def smooth3d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 3D data:
+ * :func:`smooth2d` is applied on each 2D slice of the data volume along all
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_7filters_15smooth3d(PyObject *__pyx_self, PyObject *__pyx_v_data); /*proto*/
+static char __pyx_doc_7filters_14smooth3d[] = "smooth3d(data)\nSimple smoothing for 3D data:\n :func:`smooth2d` is applied on each 2D slice of the data volume along all\n 3 axis\n\n :param data: 2D\302\240data array\n :type data: numpy.ndarray\n :return: Smoothed data\n :rtype: numpy.ndarray(dtype=numpy.float64)\n ";
+static PyMethodDef __pyx_mdef_7filters_15smooth3d = {"smooth3d", (PyCFunction)__pyx_pw_7filters_15smooth3d, METH_O, __pyx_doc_7filters_14smooth3d};
+static PyObject *__pyx_pw_7filters_15smooth3d(PyObject *__pyx_self, PyObject *__pyx_v_data) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("smooth3d (wrapper)", 0);
+ __pyx_r = __pyx_pf_7filters_14smooth3d(__pyx_self, ((PyObject *)__pyx_v_data));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_7filters_14smooth3d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data) {
+ __Pyx_memviewslice __pyx_v_data_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_nx = NULL;
+ PyObject *__pyx_v_ny = NULL;
+ PyObject *__pyx_v_nz = NULL;
+ PyObject *__pyx_v_data_shape = NULL;
+ CYTHON_UNUSED PyObject *__pyx_v_nrows = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_t_13;
+ PyObject *__pyx_t_14 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("smooth3d", 0);
+
+ /* "filters.pyx":386
+ * double[::1] data_c
+ *
+ * if not isinstance(data, numpy.ndarray): # <<<<<<<<<<<<<<
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\
+ * not hasattr(data[0][0], "__len__"):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = PyObject_IsInstance(__pyx_v_data, __pyx_t_2); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = ((!(__pyx_t_3 != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":387
+ *
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\ # <<<<<<<<<<<<<<
+ * not hasattr(data[0][0], "__len__"):
+ * raise TypeError("data must be a 3D sequence (list, tuple) " +
+ */
+ __pyx_t_3 = PyObject_HasAttr(__pyx_v_data, __pyx_n_s_len); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = ((!(__pyx_t_3 != 0)) != 0);
+ if (!__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_5 = PyObject_HasAttr(__pyx_t_2, __pyx_n_s_len); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_3 = ((!(__pyx_t_5 != 0)) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_4 = __pyx_t_3;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "filters.pyx":388
+ * if not isinstance(data, numpy.ndarray):
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\
+ * not hasattr(data[0][0], "__len__"): # <<<<<<<<<<<<<<
+ * raise TypeError("data must be a 3D sequence (list, tuple) " +
+ * "or a 3D numpy array")
+ */
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_2, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_3 = PyObject_HasAttr(__pyx_t_1, __pyx_n_s_len); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 388; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_5 = ((!(__pyx_t_3 != 0)) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":389
+ * if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\
+ * not hasattr(data[0][0], "__len__"):
+ * raise TypeError("data must be a 3D sequence (list, tuple) " + # <<<<<<<<<<<<<<
+ * "or a 3D numpy array")
+ * nx = len(data)
+ */
+ __pyx_t_1 = PyNumber_Add(__pyx_kp_s_data_must_be_a_3D_sequence_list, __pyx_kp_s_or_a_3D_numpy_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "filters.pyx":391
+ * raise TypeError("data must be a 3D sequence (list, tuple) " +
+ * "or a 3D numpy array")
+ * nx = len(data) # <<<<<<<<<<<<<<
+ * ny = len(data[0])
+ * nz = len(data[0][0])
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 391; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 391; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_nx = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "filters.pyx":392
+ * "or a 3D numpy array")
+ * nx = len(data)
+ * ny = len(data[0]) # <<<<<<<<<<<<<<
+ * nz = len(data[0][0])
+ * data_shape = (len(data), len(data[0]), len(data[0][0]))
+ */
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_ny = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "filters.pyx":393
+ * nx = len(data)
+ * ny = len(data[0])
+ * nz = len(data[0][0]) # <<<<<<<<<<<<<<
+ * data_shape = (len(data), len(data[0]), len(data[0][0]))
+ * else:
+ */
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_v_nz = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "filters.pyx":394
+ * ny = len(data[0])
+ * nz = len(data[0][0])
+ * data_shape = (len(data), len(data[0]), len(data[0][0])) # <<<<<<<<<<<<<<
+ * else:
+ * data_shape = data.shape
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_6 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_GetItemInt(__pyx_t_7, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_6 = PyObject_Length(__pyx_t_8); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyInt_FromSsize_t(__pyx_t_6); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_7 = PyTuple_New(3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_7, 2, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = 0;
+ __pyx_t_8 = 0;
+ __pyx_v_data_shape = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":396
+ * data_shape = (len(data), len(data[0]), len(data[0][0]))
+ * else:
+ * data_shape = data.shape # <<<<<<<<<<<<<<
+ * nrows = data_shape[0]
+ * if len(data_shape) == 3:
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_data_shape = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":397
+ * else:
+ * data_shape = data.shape
+ * nrows = data_shape[0] # <<<<<<<<<<<<<<
+ * if len(data_shape) == 3:
+ * nx = data_shape[0]
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_nrows = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":398
+ * data_shape = data.shape
+ * nrows = data_shape[0]
+ * if len(data_shape) == 3: # <<<<<<<<<<<<<<
+ * nx = data_shape[0]
+ * ny = data_shape[1]
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_data_shape); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = ((__pyx_t_6 == 3) != 0);
+ if (__pyx_t_4) {
+
+ /* "filters.pyx":399
+ * nrows = data_shape[0]
+ * if len(data_shape) == 3:
+ * nx = data_shape[0] # <<<<<<<<<<<<<<
+ * ny = data_shape[1]
+ * nz = data_shape[2]
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_nx = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":400
+ * if len(data_shape) == 3:
+ * nx = data_shape[0]
+ * ny = data_shape[1] # <<<<<<<<<<<<<<
+ * nz = data_shape[2]
+ * else:
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_ny = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "filters.pyx":401
+ * nx = data_shape[0]
+ * ny = data_shape[1]
+ * nz = data_shape[2] # <<<<<<<<<<<<<<
+ * else:
+ * raise TypeError("data array must be 3-dimensional")
+ */
+ __pyx_t_7 = __Pyx_GetItemInt(__pyx_v_data_shape, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_nz = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "filters.pyx":403
+ * nz = data_shape[2]
+ * else:
+ * raise TypeError("data array must be 3-dimensional") # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L8:;
+ }
+ __pyx_L3:;
+
+ /* "filters.pyx":405
+ * raise TypeError("data array must be 3-dimensional")
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "filters.pyx":406
+ *
+ * data_c = numpy.array(data,
+ * copy=True, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_copy, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":407
+ * data_c = numpy.array(data,
+ * copy=True,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_float64); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":405
+ * raise TypeError("data array must be 3-dimensional")
+ *
+ * data_c = numpy.array(data, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_7, __pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 405; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":408
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.smooth3d(&data_c[0], nx, ny, nz)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_reshape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_9);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_data_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "filters.pyx":410
+ * order='C').reshape(-1)
+ *
+ * filters_wrapper.smooth3d(&data_c[0], nx, ny, nz) # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(data_c).reshape(data_shape)
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_6 < 0) {
+ __pyx_t_6 += __pyx_v_data_c.shape[0];
+ if (unlikely(__pyx_t_6 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_6 >= __pyx_v_data_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_v_nx); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_v_ny); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_v_nz); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ smooth3d((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_data_c.data) + __pyx_t_6)) )))), __pyx_t_11, __pyx_t_12, __pyx_t_13);
+
+ /* "filters.pyx":412
+ * filters_wrapper.smooth3d(&data_c[0], nx, ny, nz)
+ *
+ * return numpy.asarray(data_c).reshape(data_shape) # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_asarray); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_data_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_7); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_14 = PyTuple_New(1+1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_14, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_14, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_reshape); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_v_data_shape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ } else {
+ __pyx_t_14 = PyTuple_New(1+1); if (unlikely(!__pyx_t_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_14);
+ PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ __Pyx_INCREF(__pyx_v_data_shape);
+ PyTuple_SET_ITEM(__pyx_t_14, 0+1, __pyx_v_data_shape);
+ __Pyx_GIVEREF(__pyx_v_data_shape);
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_14, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_r = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L0;
+
+ /* "filters.pyx":373
+ *
+ *
+ * def smooth3d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 3D data:
+ * :func:`smooth2d` is applied on each 2D slice of the data volume along all
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_14);
+ __Pyx_AddTraceback("filters.smooth3d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_data_c, 1);
+ __Pyx_XDECREF(__pyx_v_nx);
+ __Pyx_XDECREF(__pyx_v_ny);
+ __Pyx_XDECREF(__pyx_v_nz);
+ __Pyx_XDECREF(__pyx_v_data_shape);
+ __Pyx_XDECREF(__pyx_v_nrows);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__21);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__21);
+ __Pyx_GIVEREF(__pyx_slice__21);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__22); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__23);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__23);
+ __Pyx_GIVEREF(__pyx_slice__23);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "filters.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "filters.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "filters.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "filters._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "filters",
+ __pyx_k_This_module_provides_background, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_22_06_2016, __pyx_k_22_06_2016, sizeof(__pyx_k_22_06_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_n_s_C, __pyx_k_C, sizeof(__pyx_k_C), 0, 0, 1, 1},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_kp_s_P_Knobel, __pyx_k_P_Knobel, sizeof(__pyx_k_P_Knobel), 0, 0, 1, 0},
+ {&__pyx_kp_s_Smoothing_failed_Check_that_npoi, __pyx_k_Smoothing_failed_Check_that_npoi, sizeof(__pyx_k_Smoothing_failed_Check_that_npoi), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_anchors, __pyx_k_anchors, sizeof(__pyx_k_anchors), 0, 0, 1, 1},
+ {&__pyx_n_s_anchors_c, __pyx_k_anchors_c, sizeof(__pyx_k_anchors_c), 0, 0, 1, 1},
+ {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+ {&__pyx_n_s_asarray, __pyx_k_asarray, sizeof(__pyx_k_asarray), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_basicConfig, __pyx_k_basicConfig, sizeof(__pyx_k_basicConfig), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_copy, __pyx_k_copy, sizeof(__pyx_k_copy), 0, 0, 1, 1},
+ {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1},
+ {&__pyx_kp_s_data_array_must_be_2_dimensional, __pyx_k_data_array_must_be_2_dimensional, sizeof(__pyx_k_data_array_must_be_2_dimensional), 0, 0, 1, 0},
+ {&__pyx_kp_s_data_array_must_be_3_dimensional, __pyx_k_data_array_must_be_3_dimensional, sizeof(__pyx_k_data_array_must_be_3_dimensional), 0, 0, 1, 0},
+ {&__pyx_n_s_data_c, __pyx_k_data_c, sizeof(__pyx_k_data_c), 0, 0, 1, 1},
+ {&__pyx_kp_s_data_must_be_a_2D_sequence_list, __pyx_k_data_must_be_a_2D_sequence_list, sizeof(__pyx_k_data_must_be_a_2D_sequence_list), 0, 0, 1, 0},
+ {&__pyx_kp_s_data_must_be_a_3D_sequence_list, __pyx_k_data_must_be_a_3D_sequence_list, sizeof(__pyx_k_data_must_be_a_3D_sequence_list), 0, 0, 1, 0},
+ {&__pyx_kp_s_data_must_be_a_sequence_list_tup, __pyx_k_data_must_be_a_sequence_list_tup, sizeof(__pyx_k_data_must_be_a_sequence_list_tup), 0, 0, 1, 0},
+ {&__pyx_n_s_data_shape, __pyx_k_data_shape, sizeof(__pyx_k_data_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_factor, __pyx_k_factor, sizeof(__pyx_k_factor), 0, 0, 1, 1},
+ {&__pyx_n_s_filters, __pyx_k_filters, sizeof(__pyx_k_filters), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 0, 1, 1},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_n_s_getLogger, __pyx_k_getLogger, sizeof(__pyx_k_getLogger), 0, 0, 1, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_input_c, __pyx_k_input_c, sizeof(__pyx_k_input_c), 0, 0, 1, 1},
+ {&__pyx_n_s_int, __pyx_k_int, sizeof(__pyx_k_int), 0, 0, 1, 1},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_len, __pyx_k_len, sizeof(__pyx_k_len), 0, 0, 1, 1},
+ {&__pyx_n_s_len_anchors, __pyx_k_len_anchors, sizeof(__pyx_k_len_anchors), 0, 0, 1, 1},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_logger, __pyx_k_logger, sizeof(__pyx_k_logger), 0, 0, 1, 1},
+ {&__pyx_n_s_logging, __pyx_k_logging, sizeof(__pyx_k_logging), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_k_mntdirect__scisoft_users_tvince, sizeof(__pyx_k_mntdirect__scisoft_users_tvince), 0, 0, 1, 0},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_n_s_ncolumns, __pyx_k_ncolumns, sizeof(__pyx_k_ncolumns), 0, 0, 1, 1},
+ {&__pyx_n_s_ndarray, __pyx_k_ndarray, sizeof(__pyx_k_ndarray), 0, 0, 1, 1},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_niterations, __pyx_k_niterations, sizeof(__pyx_k_niterations), 0, 0, 1, 1},
+ {&__pyx_n_s_npoints, __pyx_k_npoints, sizeof(__pyx_k_npoints), 0, 0, 1, 1},
+ {&__pyx_n_s_nrows, __pyx_k_nrows, sizeof(__pyx_k_nrows), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_nx, __pyx_k_nx, sizeof(__pyx_k_nx), 0, 0, 1, 1},
+ {&__pyx_n_s_ny, __pyx_k_ny, sizeof(__pyx_k_ny), 0, 0, 1, 1},
+ {&__pyx_n_s_nz, __pyx_k_nz, sizeof(__pyx_k_nz), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_kp_s_or_a_2D_numpy_array, __pyx_k_or_a_2D_numpy_array, sizeof(__pyx_k_or_a_2D_numpy_array), 0, 0, 1, 0},
+ {&__pyx_kp_s_or_a_3D_numpy_array, __pyx_k_or_a_3D_numpy_array, sizeof(__pyx_k_or_a_3D_numpy_array), 0, 0, 1, 0},
+ {&__pyx_kp_s_or_a_numpy_array, __pyx_k_or_a_numpy_array, sizeof(__pyx_k_or_a_numpy_array), 0, 0, 1, 0},
+ {&__pyx_n_s_order, __pyx_k_order, sizeof(__pyx_k_order), 0, 0, 1, 1},
+ {&__pyx_n_s_output, __pyx_k_output, sizeof(__pyx_k_output), 0, 0, 1, 1},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+ {&__pyx_n_s_savitsky_golay, __pyx_k_savitsky_golay, sizeof(__pyx_k_savitsky_golay), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_smooth1d, __pyx_k_smooth1d, sizeof(__pyx_k_smooth1d), 0, 0, 1, 1},
+ {&__pyx_n_s_smooth2d, __pyx_k_smooth2d, sizeof(__pyx_k_smooth2d), 0, 0, 1, 1},
+ {&__pyx_n_s_smooth3d, __pyx_k_smooth3d, sizeof(__pyx_k_smooth3d), 0, 0, 1, 1},
+ {&__pyx_n_s_snip1d, __pyx_k_snip1d, sizeof(__pyx_k_snip1d), 0, 0, 1, 1},
+ {&__pyx_n_s_snip2d, __pyx_k_snip2d, sizeof(__pyx_k_snip2d), 0, 0, 1, 1},
+ {&__pyx_n_s_snip3d, __pyx_k_snip3d, sizeof(__pyx_k_snip3d), 0, 0, 1, 1},
+ {&__pyx_n_s_snip_width, __pyx_k_snip_width, sizeof(__pyx_k_snip_width), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_status, __pyx_k_status, sizeof(__pyx_k_status), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_strip, __pyx_k_strip, sizeof(__pyx_k_strip), 0, 0, 1, 1},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_kp_s_than_3_and_smaller_than_100, __pyx_k_than_3_and_smaller_than_100, sizeof(__pyx_k_than_3_and_smaller_than_100), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "filters.pyx":101
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * output = numpy.empty(shape=(input_c.size,),
+ */
+ __pyx_tuple_ = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "filters.pyx":116
+ * # Make a dummy length-1 array, because if I use shape=(0,) I get the error
+ * # IndexError: Out of bounds on buffer access (axis 0)
+ * anchors_c = numpy.empty(shape=(1,), # <<<<<<<<<<<<<<
+ * dtype=numpy.int_)
+ * len_anchors = 0
+ */
+ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "filters.pyx":165
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.snip1d(&data_c[0], data_c.size, snip_width)
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "filters.pyx":205
+ * ncolumns = data_shape[1]
+ * else:
+ * raise TypeError("data array must be 2-dimensional") # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_data_array_must_be_2_dimensional); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "filters.pyx":210
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.snip2d(&data_c[0], nrows, ncolumns, snip_width)
+ */
+ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "filters.pyx":254
+ * nz = data_shape[2]
+ * else:
+ * raise TypeError("data array must be 3-dimensional") # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_data_array_must_be_3_dimensional); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+
+ /* "filters.pyx":259
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.snip3d(&data_c[0], nx, ny, nz, snip_width)
+ */
+ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__7);
+ __Pyx_GIVEREF(__pyx_tuple__7);
+
+ /* "filters.pyx":281
+ * data_c = numpy.array(data,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * output = numpy.empty(shape=(data_c.size,),
+ */
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "filters.pyx":328
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.smooth1d(&data_c[0], data_c.size)
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "filters.pyx":361
+ * ncolumns = data_shape[1]
+ * else:
+ * raise TypeError("data array must be 2-dimensional") # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_data_array_must_be_2_dimensional); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+
+ /* "filters.pyx":366
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.smooth2d(&data_c[0], nrows, ncolumns)
+ */
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+
+ /* "filters.pyx":403
+ * nz = data_shape[2]
+ * else:
+ * raise TypeError("data array must be 3-dimensional") # <<<<<<<<<<<<<<
+ *
+ * data_c = numpy.array(data,
+ */
+ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_data_array_must_be_3_dimensional); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__12);
+ __Pyx_GIVEREF(__pyx_tuple__12);
+
+ /* "filters.pyx":408
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ *
+ * filters_wrapper.smooth3d(&data_c[0], nx, ny, nz)
+ */
+ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__13);
+ __Pyx_GIVEREF(__pyx_tuple__13);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__14);
+ __Pyx_GIVEREF(__pyx_tuple__14);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__19);
+ __Pyx_GIVEREF(__pyx_tuple__19);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__21 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__21)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__21);
+ __Pyx_GIVEREF(__pyx_slice__21);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__22 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__22)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__22);
+ __Pyx_GIVEREF(__pyx_slice__22);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__23 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__23)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__23);
+ __Pyx_GIVEREF(__pyx_slice__23);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__24);
+ __Pyx_GIVEREF(__pyx_tuple__24);
+
+ /* "filters.pyx":62
+ *
+ *
+ * def strip(data, w=1, niterations=1000, factor=1.0, anchors=None): # <<<<<<<<<<<<<<
+ * """Extract background from data using the strip algorithm, as explained at
+ * http://pymca.sourceforge.net/stripbackground.html.
+ */
+ __pyx_tuple__25 = PyTuple_Pack(11, __pyx_n_s_data, __pyx_n_s_w, __pyx_n_s_niterations, __pyx_n_s_factor, __pyx_n_s_anchors, __pyx_n_s_input_c, __pyx_n_s_output, __pyx_n_s_anchors_c, __pyx_n_s_data_shape, __pyx_n_s_len_anchors, __pyx_n_s_status); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__25);
+ __Pyx_GIVEREF(__pyx_tuple__25);
+ __pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(5, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_strip, 62, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":128
+ *
+ *
+ * def snip1d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 1D data vector by clipping peaks.
+ *
+ */
+ __pyx_tuple__27 = PyTuple_Pack(4, __pyx_n_s_data, __pyx_n_s_snip_width, __pyx_n_s_data_c, __pyx_n_s_data_shape); if (unlikely(!__pyx_tuple__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__27);
+ __Pyx_GIVEREF(__pyx_tuple__27);
+ __pyx_codeobj__28 = (PyObject*)__Pyx_PyCode_New(2, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_snip1d, 128, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":172
+ *
+ *
+ * def snip2d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 2D data signal by clipping peaks.
+ *
+ */
+ __pyx_tuple__29 = PyTuple_Pack(6, __pyx_n_s_data, __pyx_n_s_snip_width, __pyx_n_s_data_c, __pyx_n_s_nrows, __pyx_n_s_ncolumns, __pyx_n_s_data_shape); if (unlikely(!__pyx_tuple__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__29);
+ __Pyx_GIVEREF(__pyx_tuple__29);
+ __pyx_codeobj__30 = (PyObject*)__Pyx_PyCode_New(2, 0, 6, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__29, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_snip2d, 172, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__30)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":217
+ *
+ *
+ * def snip3d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 3D data signal by clipping peaks.
+ *
+ */
+ __pyx_tuple__31 = PyTuple_Pack(8, __pyx_n_s_data, __pyx_n_s_snip_width, __pyx_n_s_data_c, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nz, __pyx_n_s_data_shape, __pyx_n_s_nrows); if (unlikely(!__pyx_tuple__31)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__31);
+ __Pyx_GIVEREF(__pyx_tuple__31);
+ __pyx_codeobj__32 = (PyObject*)__Pyx_PyCode_New(2, 0, 8, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__31, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_snip3d, 217, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":266
+ *
+ *
+ * def savitsky_golay(data, npoints=5): # <<<<<<<<<<<<<<
+ * """Smooth a curve using a Savitsky-Golay filter.
+ *
+ */
+ __pyx_tuple__33 = PyTuple_Pack(5, __pyx_n_s_data, __pyx_n_s_npoints, __pyx_n_s_data_c, __pyx_n_s_output, __pyx_n_s_status); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__33);
+ __Pyx_GIVEREF(__pyx_tuple__33);
+ __pyx_codeobj__34 = (PyObject*)__Pyx_PyCode_New(2, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__33, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_savitsky_golay, 266, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__34)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":296
+ *
+ *
+ * def smooth1d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 1D data.
+ *
+ */
+ __pyx_tuple__35 = PyTuple_Pack(3, __pyx_n_s_data, __pyx_n_s_data_c, __pyx_n_s_data_shape); if (unlikely(!__pyx_tuple__35)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__35);
+ __Pyx_GIVEREF(__pyx_tuple__35);
+ __pyx_codeobj__36 = (PyObject*)__Pyx_PyCode_New(1, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__35, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_smooth1d, 296, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__36)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":335
+ *
+ *
+ * def smooth2d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 2D data:
+ * :func:`smooth1d` is applied succesively along both axis
+ */
+ __pyx_tuple__37 = PyTuple_Pack(5, __pyx_n_s_data, __pyx_n_s_data_c, __pyx_n_s_nrows, __pyx_n_s_ncolumns, __pyx_n_s_data_shape); if (unlikely(!__pyx_tuple__37)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__37);
+ __Pyx_GIVEREF(__pyx_tuple__37);
+ __pyx_codeobj__38 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_smooth2d, 335, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__38)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":373
+ *
+ *
+ * def smooth3d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 3D data:
+ * :func:`smooth2d` is applied on each 2D slice of the data volume along all
+ */
+ __pyx_tuple__39 = PyTuple_Pack(7, __pyx_n_s_data, __pyx_n_s_data_c, __pyx_n_s_nx, __pyx_n_s_ny, __pyx_n_s_nz, __pyx_n_s_data_shape, __pyx_n_s_nrows); if (unlikely(!__pyx_tuple__39)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__39);
+ __Pyx_GIVEREF(__pyx_tuple__39);
+ __pyx_codeobj__40 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__39, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_smooth3d, 373, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__40)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__41 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__41)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__41);
+ __Pyx_GIVEREF(__pyx_tuple__41);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__42 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__42)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__42);
+ __Pyx_GIVEREF(__pyx_tuple__42);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__43 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__43)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__43);
+ __Pyx_GIVEREF(__pyx_tuple__43);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__44 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__44)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__44);
+ __Pyx_GIVEREF(__pyx_tuple__44);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__45 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__45)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__45);
+ __Pyx_GIVEREF(__pyx_tuple__45);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_float_1_0 = PyFloat_FromDouble(1.0); if (unlikely(!__pyx_float_1_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1000 = PyInt_FromLong(1000); if (unlikely(!__pyx_int_1000)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initfilters(void); /*proto*/
+PyMODINIT_FUNC initfilters(void)
+#else
+PyMODINIT_FUNC PyInit_filters(void); /*proto*/
+PyMODINIT_FUNC PyInit_filters(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_filters(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("filters", __pyx_methods, __pyx_k_This_module_provides_background, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_filters) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "filters")) {
+ if (unlikely(PyDict_SetItemString(modules, "filters", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "filters.pyx":48
+ * """
+ *
+ * __authors__ = ["P. Knobel"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "22/06/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_P_Knobel);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_P_Knobel);
+ __Pyx_GIVEREF(__pyx_kp_s_P_Knobel);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":49
+ *
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "22/06/2016"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":50
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT"
+ * __date__ = "22/06/2016" # <<<<<<<<<<<<<<
+ *
+ * import logging
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_22_06_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "filters.pyx":52
+ * __date__ = "22/06/2016"
+ *
+ * import logging # <<<<<<<<<<<<<<
+ * import numpy
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":53
+ *
+ * import logging
+ * import numpy # <<<<<<<<<<<<<<
+ *
+ * logging.basicConfig()
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":55
+ * import numpy
+ *
+ * logging.basicConfig() # <<<<<<<<<<<<<<
+ * _logger = logging.getLogger(__name__)
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_basicConfig); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":56
+ *
+ * logging.basicConfig()
+ * _logger = logging.getLogger(__name__) # <<<<<<<<<<<<<<
+ *
+ * cimport cython
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_getLogger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_name_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logger, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":62
+ *
+ *
+ * def strip(data, w=1, niterations=1000, factor=1.0, anchors=None): # <<<<<<<<<<<<<<
+ * """Extract background from data using the strip algorithm, as explained at
+ * http://pymca.sourceforge.net/stripbackground.html.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7filters_1strip, NULL, __pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_strip, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":128
+ *
+ *
+ * def snip1d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 1D data vector by clipping peaks.
+ *
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7filters_3snip1d, NULL, __pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_snip1d, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":172
+ *
+ *
+ * def snip2d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 2D data signal by clipping peaks.
+ *
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7filters_5snip2d, NULL, __pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_snip2d, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":217
+ *
+ *
+ * def snip3d(data, snip_width): # <<<<<<<<<<<<<<
+ * """Estimate the baseline (background) of a 3D data signal by clipping peaks.
+ *
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7filters_7snip3d, NULL, __pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_snip3d, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":266
+ *
+ *
+ * def savitsky_golay(data, npoints=5): # <<<<<<<<<<<<<<
+ * """Smooth a curve using a Savitsky-Golay filter.
+ *
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7filters_9savitsky_golay, NULL, __pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_savitsky_golay, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":296
+ *
+ *
+ * def smooth1d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 1D data.
+ *
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7filters_11smooth1d, NULL, __pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_smooth1d, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":335
+ *
+ *
+ * def smooth2d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 2D data:
+ * :func:`smooth1d` is applied succesively along both axis
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7filters_13smooth2d, NULL, __pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_smooth2d, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":373
+ *
+ *
+ * def smooth3d(data): # <<<<<<<<<<<<<<
+ * """Simple smoothing for 3D data:
+ * :func:`smooth2d` is applied on each 2D slice of the data volume along all
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_7filters_15smooth3d, NULL, __pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_smooth3d, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "filters.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * #/[inserted by cython to avoid comment start]*##########################################################################
+ * # Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__41, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__42, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__43, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__44, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__45, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init filters", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init filters");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static void __Pyx_RaiseBufferIndexError(int axis) {
+ PyErr_Format(PyExc_IndexError,
+ "Out of bounds on buffer access (axis %d)", axis);
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+static PyObject *__pyx_memview_get_double(const char *itemp) {
+ return (PyObject *) PyFloat_FromDouble(*(double *) itemp);
+}
+static int __pyx_memview_set_double(const char *itemp, PyObject *obj) {
+ double value = __pyx_PyFloat_AsDouble(obj);
+ if ((value == (double)-1) && PyErr_Occurred())
+ return 0;
+ *(double *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static PyObject *__pyx_memview_get_long(const char *itemp) {
+ return (PyObject *) __Pyx_PyInt_From_long(*(long *) itemp);
+}
+static int __pyx_memview_set_long(const char *itemp, PyObject *obj) {
+ long value = __Pyx_PyInt_As_long(obj);
+ if ((value == (long)-1) && PyErr_Occurred())
+ return 0;
+ *(long *) itemp = value;
+ return 1;
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_double(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_double, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_long(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_long, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/math/fit/filters/filters.pyx b/silx/math/fit/filters/filters.pyx
new file mode 100644
index 0000000..9887ad7
--- /dev/null
+++ b/silx/math/fit/filters/filters.pyx
@@ -0,0 +1,412 @@
+# coding: utf-8
+#/*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+#############################################################################*/
+"""This module provides background extraction functions and smoothing
+functions. These functions are extracted from PyMca module SpecFitFuns.
+
+Index of background extraction functions:
+------------------------------------------
+
+ - :func:`strip`
+ - :func:`snip1d`
+ - :func:`snip2d`
+ - :func:`snip3d`
+
+Smoothing functions:
+--------------------
+
+ - :func:`savitsky_golay`
+ - :func:`smooth1d`
+ - :func:`smooth2d`
+ - :func:`smooth3d`
+
+API documentation:
+-------------------
+
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "22/06/2016"
+
+import logging
+import numpy
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+cimport cython
+cimport filters_wrapper
+
+
+def strip(data, w=1, niterations=1000, factor=1.0, anchors=None):
+ """Extract background from data using the strip algorithm, as explained at
+ http://pymca.sourceforge.net/stripbackground.html.
+
+ In its simplest implementation it is just as an iterative procedure
+ depending on two parameters. These parameters are the strip background
+ 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.
+
+ :param data: Data array
+ :type data: numpy.ndarray
+ :param w: Strip width
+ :param niterations: number of iterations
+ :param factor: scaling factor applied to the average of ``y(i-w)`` and
+ ``y(i+w)`` before comparing to ``y(i)``
+ :param anchors: Array of anchors, indices of points that will not be
+ modified during the stripping procedure.
+ :return: Data with peaks stripped away
+ """
+ cdef:
+ double[::1] input_c
+ double[::1] output
+ long[::1] anchors_c
+
+ if not isinstance(data, numpy.ndarray):
+ if not hasattr(data, "__len__"):
+ raise TypeError("data must be a sequence (list, tuple) " +
+ "or a numpy array")
+ data_shape = (len(data), )
+ else:
+ data_shape = data.shape
+
+ input_c = numpy.array(data,
+ copy=True,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+
+ output = numpy.empty(shape=(input_c.size,),
+ dtype=numpy.float64)
+
+ if anchors is not None and len(anchors):
+ # numpy.int_ is the same as C long (http://docs.scipy.org/doc/numpy/user/basics.types.html)
+ anchors_c = numpy.array(anchors,
+ copy=False,
+ dtype=numpy.int_,
+ order='C')
+ len_anchors = anchors_c.size
+ else:
+ # Make a dummy length-1 array, because if I use shape=(0,) I get the error
+ # IndexError: Out of bounds on buffer access (axis 0)
+ anchors_c = numpy.empty(shape=(1,),
+ dtype=numpy.int_)
+ len_anchors = 0
+
+
+ status = filters_wrapper.strip(&input_c[0], input_c.size,
+ factor, niterations, w,
+ &anchors_c[0], len_anchors, &output[0])
+
+ return numpy.asarray(output).reshape(data_shape)
+
+
+def snip1d(data, snip_width):
+ """Estimate the baseline (background) of a 1D data vector by clipping peaks.
+
+ Implementation of the algorithm SNIP in 1D is described in *Miroslav
+ Morhac et al. Nucl. Instruments and Methods in Physics Research A401
+ (1997) 113-132*.
+
+ The original idea for 1D and the low-statistics-digital-filter (lsdf) come
+ from *C.G. Ryan et al. Nucl. Instruments and Methods in Physics Research
+ B34 (1988) 396-402*.
+
+ :param data: Data array, preferably 1D and of type *numpy.float64*.
+ Else, the data array will be flattened and converted to
+ *dtype=numpy.float64* prior to applying the snip filter.
+ :type data: numpy.ndarray
+ :param snip_width: Width of the snip operator, in number of samples.
+ A sample will be iteratively compared to it's neighbors up to a
+ distance of ``snip_width`` samples. This parameters has a direct
+ influence on the speed of the algorithm.
+ :type width: int
+ :return: Baseline of the input array, as an array of the same shape.
+ :rtype: numpy.ndarray
+ """
+ cdef:
+ double[::1] data_c
+
+ if not isinstance(data, numpy.ndarray):
+ if not hasattr(data, "__len__"):
+ raise TypeError("data must be a sequence (list, tuple) " +
+ "or a numpy array")
+ data_shape = (len(data), )
+ else:
+ data_shape = data.shape
+
+ data_c = numpy.array(data,
+ copy=True,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+
+ filters_wrapper.snip1d(&data_c[0], data_c.size, snip_width)
+
+ return numpy.asarray(data_c).reshape(data_shape)
+
+
+def snip2d(data, snip_width):
+ """Estimate the baseline (background) of a 2D data signal by clipping peaks.
+
+ Implementation of the algorithm SNIP in 2D described in
+ *Miroslav Morhac et al. Nucl. Instruments and Methods in Physics Research
+ A401 (1997) 113-132.*
+
+ :param data: 2D array
+ :type data: numpy.ndarray
+ :param width: Width of the snip operator, in number of samples. A wider
+ snip operator will result in a smoother result (lower frequency peaks
+ will be clipped), and a longer computation time.
+ :type width: int
+ :return: Baseline of the input array, as an array of the same shape.
+ :rtype: numpy.ndarray
+ """
+ cdef:
+ double[::1] data_c
+
+ if not isinstance(data, numpy.ndarray):
+ if not hasattr(data, "__len__") or not hasattr(data[0], "__len__"):
+ raise TypeError("data must be a 2D sequence (list, tuple) " +
+ "or a 2D numpy array")
+ nrows = len(data)
+ ncolumns = len(data[0])
+ data_shape = (len(data), len(data[0]))
+
+ else:
+ data_shape = data.shape
+ nrows = data_shape[0]
+ if len(data_shape) == 2:
+ ncolumns = data_shape[1]
+ else:
+ raise TypeError("data array must be 2-dimensional")
+
+ data_c = numpy.array(data,
+ copy=True,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+
+ filters_wrapper.snip2d(&data_c[0], nrows, ncolumns, snip_width)
+
+ return numpy.asarray(data_c).reshape(data_shape)
+
+
+def snip3d(data, snip_width):
+ """Estimate the baseline (background) of a 3D data signal by clipping peaks.
+
+ Implementation of the algorithm SNIP in 2D described in
+ *Miroslav Morhac et al. Nucl. Instruments and Methods in Physics Research
+ A401 (1997) 113-132.*
+
+ :param data: 3D array
+ :type data: numpy.ndarray
+ :param width: Width of the snip operator, in number of samples. A wider
+ snip operator will result in a smoother result (lower frequency peaks
+ will be clipped), and a longer computation time.
+ :type width: int
+
+ :return: Baseline of the input array, as an array of the same shape.
+ :rtype: numpy.ndarray
+ """
+ cdef:
+ double[::1] data_c
+
+ if not isinstance(data, numpy.ndarray):
+ if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\
+ not hasattr(data[0][0], "__len__"):
+ raise TypeError("data must be a 3D sequence (list, tuple) " +
+ "or a 3D numpy array")
+ nx = len(data)
+ ny = len(data[0])
+ nz = len(data[0][0])
+ data_shape = (len(data), len(data[0]), len(data[0][0]))
+ else:
+ data_shape = data.shape
+ nrows = data_shape[0]
+ if len(data_shape) == 3:
+ nx = data_shape[0]
+ ny = data_shape[1]
+ nz = data_shape[2]
+ else:
+ raise TypeError("data array must be 3-dimensional")
+
+ data_c = numpy.array(data,
+ copy=True,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+
+ filters_wrapper.snip3d(&data_c[0], nx, ny, nz, snip_width)
+
+ return numpy.asarray(data_c).reshape(data_shape)
+
+
+def savitsky_golay(data, npoints=5):
+ """Smooth a curve using a Savitsky-Golay filter.
+
+ :param data: Input data
+ :type data: 1D numpy array
+ :param npoints: Size of the smoothing operator in number of samples
+ Must be between 3 and 100.
+ :return: Smoothed data
+ """
+ cdef:
+ double[::1] data_c
+ double[::1] output
+
+ data_c = numpy.array(data,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+
+ output = numpy.empty(shape=(data_c.size,),
+ dtype=numpy.float64)
+
+ status = filters_wrapper.SavitskyGolay(&data_c[0], data_c.size,
+ npoints, &output[0])
+
+ if status:
+ _logger.error("Smoothing failed. Check that npoints is greater " +
+ "than 3 and smaller than 100.")
+
+ return numpy.asarray(output).reshape(data.shape)
+
+
+def smooth1d(data):
+ """Simple smoothing for 1D data.
+
+ For a data array :math:`y` of length :math:`n`, the smoothed array
+ :math:`ys` is calculated as a weighted average of neighboring samples:
+
+ :math:`ys_0 = 0.75 y_0 + 0.25 y_1`
+
+ :math:`ys_i = 0.25 (y_{i-1} + 2 y_i + y_{i+1})` for :math:`0 < i < n-1`
+
+ :math:`ys_{n-1} = 0.25 y_{n-2} + 0.75 y_{n-1}`
+
+
+ :param data: 1D data array
+ :type data: numpy.ndarray
+ :return: Smoothed data
+ :rtype: numpy.ndarray(dtype=numpy.float64)
+ """
+ cdef:
+ double[::1] data_c
+
+ if not isinstance(data, numpy.ndarray):
+ if not hasattr(data, "__len__"):
+ raise TypeError("data must be a sequence (list, tuple) " +
+ "or a numpy array")
+ data_shape = (len(data), )
+ else:
+ data_shape = data.shape
+
+ data_c = numpy.array(data,
+ copy=True,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+
+ filters_wrapper.smooth1d(&data_c[0], data_c.size)
+
+ return numpy.asarray(data_c).reshape(data_shape)
+
+
+def smooth2d(data):
+ """Simple smoothing for 2D data:
+ :func:`smooth1d` is applied succesively along both axis
+
+ :param data: 2D data array
+ :type data: numpy.ndarray
+ :return: Smoothed data
+ :rtype: numpy.ndarray(dtype=numpy.float64)
+ """
+ cdef:
+ double[::1] data_c
+
+ if not isinstance(data, numpy.ndarray):
+ if not hasattr(data, "__len__") or not hasattr(data[0], "__len__"):
+ raise TypeError("data must be a 2D sequence (list, tuple) " +
+ "or a 2D numpy array")
+ nrows = len(data)
+ ncolumns = len(data[0])
+ data_shape = (len(data), len(data[0]))
+
+ else:
+ data_shape = data.shape
+ nrows = data_shape[0]
+ if len(data_shape) == 2:
+ ncolumns = data_shape[1]
+ else:
+ raise TypeError("data array must be 2-dimensional")
+
+ data_c = numpy.array(data,
+ copy=True,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+
+ filters_wrapper.smooth2d(&data_c[0], nrows, ncolumns)
+
+ return numpy.asarray(data_c).reshape(data_shape)
+
+
+def smooth3d(data):
+ """Simple smoothing for 3D data:
+ :func:`smooth2d` is applied on each 2D slice of the data volume along all
+ 3 axis
+
+ :param data: 2D data array
+ :type data: numpy.ndarray
+ :return: Smoothed data
+ :rtype: numpy.ndarray(dtype=numpy.float64)
+ """
+ cdef:
+ double[::1] data_c
+
+ if not isinstance(data, numpy.ndarray):
+ if not hasattr(data, "__len__") or not hasattr(data[0], "__len__") or\
+ not hasattr(data[0][0], "__len__"):
+ raise TypeError("data must be a 3D sequence (list, tuple) " +
+ "or a 3D numpy array")
+ nx = len(data)
+ ny = len(data[0])
+ nz = len(data[0][0])
+ data_shape = (len(data), len(data[0]), len(data[0][0]))
+ else:
+ data_shape = data.shape
+ nrows = data_shape[0]
+ if len(data_shape) == 3:
+ nx = data_shape[0]
+ ny = data_shape[1]
+ nz = data_shape[2]
+ else:
+ raise TypeError("data array must be 3-dimensional")
+
+ data_c = numpy.array(data,
+ copy=True,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+
+ filters_wrapper.smooth3d(&data_c[0], nx, ny, nz)
+
+ return numpy.asarray(data_c).reshape(data_shape)
diff --git a/silx/math/fit/filters/filters_wrapper.pxd b/silx/math/fit/filters/filters_wrapper.pxd
new file mode 100644
index 0000000..e4f7c72
--- /dev/null
+++ b/silx/math/fit/filters/filters_wrapper.pxd
@@ -0,0 +1,71 @@
+# 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.
+#
+#############################################################################*/
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "22/06/2016"
+
+cimport cython
+
+cdef extern from "filters.h":
+ void snip1d(double *data,
+ int size,
+ int width)
+
+ void snip2d(double *data,
+ int nrows,
+ int ncolumns,
+ int width)
+
+ void snip3d(double *data,
+ int nx,
+ int ny,
+ int nz,
+ int width)
+
+ int strip(double* input,
+ long len_input,
+ double c,
+ long niter,
+ int deltai,
+ long* anchors,
+ long len_anchors,
+ double* output)
+
+ int SavitskyGolay(double* input,
+ long len_input,
+ int npoints,
+ double* output)
+
+ void smooth1d(double *data,
+ int size)
+
+ void smooth2d(double *data,
+ int size0,
+ int size1)
+
+ void smooth3d(double *data,
+ int size0,
+ int size1,
+ int size2)
diff --git a/silx/math/fit/filters/include/filters.h b/silx/math/fit/filters/include/filters.h
new file mode 100644
index 0000000..48e7e52
--- /dev/null
+++ b/silx/math/fit/filters/include/filters.h
@@ -0,0 +1,45 @@
+/*##########################################################################
+# 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.
+#
+# ############################################################################*/
+
+#ifndef FITFILTERSH
+#define FITFILTERS_H
+
+/* Background functions */
+void snip1d(double *data, int size, int width);
+//void snip1d_multiple(double *data, int n_channels, int snip_width, int n_spectra);
+void snip2d(double *data, int nrows, int ncolumns, int width);
+void snip3d(double *data, int nx, int ny, int nz, int width);
+
+int strip(double* input, long len_input, double c, long niter, int deltai,
+ long* anchors, long len_anchors, double* output);
+
+/* Smoothing functions */
+
+int SavitskyGolay(double* input, long len_input, int npoints, double* output);
+
+void smooth1d(double *data, int size);
+void smooth2d(double *data, int size0, int size1);
+void smooth3d(double *data, int size0, int size1, int size2);
+
+
+#endif /* #define FITFILTERS_H */
diff --git a/silx/math/fit/filters/src/smoothnd.c b/silx/math/fit/filters/src/smoothnd.c
new file mode 100644
index 0000000..cb96961
--- /dev/null
+++ b/silx/math/fit/filters/src/smoothnd.c
@@ -0,0 +1,317 @@
+#/*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+#############################################################################*/
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+#define MAX_SAVITSKY_GOLAY_WIDTH 101
+#define MIN_SAVITSKY_GOLAY_WIDTH 3
+
+/* Wrapped functions */
+void smooth1d(double *data, int size);
+void smooth2d(double *data, int size0, int size1);
+void smooth3d(double *data, int size0, int size1, int size2);
+int SavitskyGolay(double* input, long len_input, int npoints, double* output);
+
+/* Internal functions */
+long index2d(long row_idx, long col_idx, long ncols);
+long index3d(long x_idx, long y_idx, long z_idx, long ny, long nz);
+void smooth1d_rows(double *data, long nrows, long ncols);
+void smooth1d_cols(double *data, long nrows, long ncols);
+void smooth1d_x(double *data, long nx, long ny, long nz);
+void smooth1d_y(double *data, long nx, long ny, long nz);
+void smooth1d_z(double *data, long nx, long ny, long nz);
+void smooth2d_yzslice(double *data, long nx, long ny, long nz);
+void smooth2d_xzslice(double *data, long nx, long ny, long nz);
+void smooth2d_xyslice(double *data, long nx, long ny, long nz);
+
+
+/* Simple smoothing of a 1D array */
+void smooth1d(double *data, int size)
+{
+ long i;
+ double prev_sample;
+ double next_sample;
+
+ if (size < 3)
+ {
+ return;
+ }
+ prev_sample = data[0];
+ for (i=0; i<(size-1); i++)
+ {
+ next_sample = 0.25 * (prev_sample + 2 * data[i] + data[i+1]);
+ prev_sample = data[i];
+ data[i] = next_sample;
+ }
+ data[size-1] = 0.25 * prev_sample + 0.75 * data[size-1];
+ return;
+}
+
+/* Smoothing of a 2D array*/
+void smooth2d(double *data, int nrows, int ncols)
+{
+ /* smooth the first dimension (rows) */
+ smooth1d_rows(data, nrows, ncols);
+
+ /* smooth the 2nd dimension */
+ smooth1d_cols(data, nrows, ncols);
+}
+
+/* Smoothing of a 3D array */
+void smooth3d(double *data, int nx, int ny, int nz)
+{
+ smooth2d_xyslice(data, nx, ny, nz);
+ smooth2d_xzslice(data, nx, ny, nz);
+ smooth2d_yzslice(data, nx, ny, nz);
+}
+
+/* 1D Savitsky-Golay smoothing */
+int SavitskyGolay(double* input, long len_input, int npoints, double* output)
+{
+
+ //double dpoints = 5.;
+ double coeff[MAX_SAVITSKY_GOLAY_WIDTH];
+ int i, j, m;
+ double dhelp, den;
+ double *data;
+
+ memcpy(output, input, len_input * sizeof(double));
+
+ if (!(npoints % 2)) npoints +=1;
+
+ if((npoints < MIN_SAVITSKY_GOLAY_WIDTH) || (len_input < npoints) || \
+ (npoints > MAX_SAVITSKY_GOLAY_WIDTH))
+ {
+ /* do not smooth data */
+ return 1;
+ }
+
+ /* calculate the coefficients */
+ m = (int) (npoints/2);
+ den = (double) ((2*m-1) * (2*m+1) * (2*m + 3));
+ for (i=0; i<= m; i++){
+ coeff[m+i] = (double) (3 * (3*m*m + 3*m - 1 - 5*i*i ));
+ coeff[m-i] = coeff[m+i];
+ }
+
+ /* simple smoothing at the beginning */
+ for (j=0; j<=(int)(npoints/3); j++)
+ {
+ smooth1d(output, m);
+ }
+
+ /* simple smoothing at the end */
+ for (j=0; j<=(int)(npoints/3); j++)
+ {
+ smooth1d((output+len_input-m-1), m);
+ }
+
+ /*one does not need the whole spectrum buffer, but code is clearer */
+ data = (double *) malloc(len_input * sizeof(double));
+ memcpy(data, output, len_input * sizeof(double));
+
+ /* the actual SG smoothing in the middle */
+ for (i=m; i<(len_input-m); i++){
+ dhelp = 0;
+ for (j=-m;j<=m;j++) {
+ dhelp += coeff[m+j] * (*(data+i+j));
+ }
+ if(dhelp > 0.0){
+ *(output+i) = dhelp / den;
+ }
+ }
+ free(data);
+ return (0);
+}
+
+/*********************/
+/* Utility functions */
+/*********************/
+
+long index2d(long row_idx, long col_idx, long ncols)
+{
+ return (row_idx*ncols+col_idx);
+}
+
+/* Apply smooth 1d on all rows in a 2D array*/
+void smooth1d_rows(double *data, long nrows, long ncols)
+{
+ long row_idx;
+
+ for (row_idx=0; row_idx < nrows; row_idx++)
+ {
+ smooth1d(&data[row_idx * ncols], ncols);
+ }
+}
+
+/* Apply smooth 1d on all columns in a 2D array*/
+void smooth1d_cols(double *data, long nrows, long ncols)
+{
+ long row_idx, col_idx;
+ long this_idx2d, next_idx2d;
+ double prev_sample;
+ double next_sample;
+
+ for (col_idx=0; col_idx < ncols; col_idx++)
+ {
+ prev_sample = data[index2d(0, col_idx, ncols)];
+ for (row_idx=0; row_idx<(nrows-1); row_idx++)
+ {
+ this_idx2d = index2d(row_idx, col_idx, ncols);
+ next_idx2d = index2d(row_idx+1, col_idx, ncols);
+
+ next_sample = 0.25 * (prev_sample + \
+ 2 * data[this_idx2d] + \
+ data[next_idx2d]);
+ prev_sample = data[this_idx2d];
+ data[this_idx2d] = next_sample;
+ }
+
+ this_idx2d = index2d(nrows-1, col_idx, ncols);
+ data[this_idx2d] = 0.25 * prev_sample + 0.75 * data[this_idx2d];
+ }
+}
+
+long index3d(long x_idx, long y_idx, long z_idx, long ny, long nz)
+{
+ return ((x_idx*ny + y_idx) * nz + z_idx);
+}
+
+/* Apply smooth 1d along first dimension in a 3D array*/
+void smooth1d_x(double *data, long nx, long ny, long nz)
+{
+ long x_idx, y_idx, z_idx;
+ long this_idx3d, next_idx3d;
+ double prev_sample;
+ double next_sample;
+
+ for (y_idx=0; y_idx < ny; y_idx++)
+ {
+ for (z_idx=0; z_idx < nz; z_idx++)
+ {
+ prev_sample = data[index3d(0, y_idx, z_idx, ny, nz)];
+ for (x_idx=0; x_idx<(nx-1); x_idx++)
+ {
+ this_idx3d = index3d(x_idx, y_idx, z_idx, ny, nz);
+ next_idx3d = index3d(x_idx+1, y_idx, z_idx, ny, nz);
+
+ next_sample = 0.25 * (prev_sample + \
+ 2 * data[this_idx3d] + \
+ data[next_idx3d]);
+ prev_sample = data[this_idx3d];
+ data[this_idx3d] = next_sample;
+ }
+
+ this_idx3d = index3d(nx-1, y_idx, z_idx, ny, nz);
+ data[this_idx3d] = 0.25 * prev_sample + 0.75 * data[this_idx3d];
+ }
+ }
+}
+
+/* Apply smooth 1d along second dimension in a 3D array*/
+void smooth1d_y(double *data, long nx, long ny, long nz)
+{
+ long x_idx, y_idx, z_idx;
+ long this_idx3d, next_idx3d;
+ double prev_sample;
+ double next_sample;
+
+ for (x_idx=0; x_idx < nx; x_idx++)
+ {
+ for (z_idx=0; z_idx < nz; z_idx++)
+ {
+ prev_sample = data[index3d(x_idx, 0, z_idx, ny, nz)];
+ for (y_idx=0; y_idx<(ny-1); y_idx++)
+ {
+ this_idx3d = index3d(x_idx, y_idx, z_idx, ny, nz);
+ next_idx3d = index3d(x_idx, y_idx+1, z_idx, ny, nz);
+
+ next_sample = 0.25 * (prev_sample + \
+ 2 * data[this_idx3d] + \
+ data[next_idx3d]);
+ prev_sample = data[this_idx3d];
+ data[this_idx3d] = next_sample;
+ }
+
+ this_idx3d = index3d(x_idx, ny-1, z_idx, ny, nz);
+ data[this_idx3d] = 0.25 * prev_sample + 0.75 * data[this_idx3d];
+ }
+ }
+}
+
+/* Apply smooth 1d along third dimension in a 3D array*/
+void smooth1d_z(double *data, long nx, long ny, long nz)
+{
+ long x_idx, y_idx;
+ long idx3d_first_sample;
+
+ for (x_idx=0; x_idx < nx; x_idx++)
+ {
+ for (y_idx=0; y_idx < ny; y_idx++)
+ {
+ idx3d_first_sample = index3d(x_idx, y_idx, 0, ny, nz);
+ /*We can use regular 1D smoothing function because z samples
+ are contiguous in memory*/
+ smooth1d(&data[idx3d_first_sample], nz);
+ }
+ }
+}
+
+/* 2D smoothing of a YZ slice in a 3D volume*/
+void smooth2d_yzslice(double *data, long nx, long ny, long nz)
+{
+ long x_idx;
+ long slice_size = ny * nz;
+
+ /* a YZ slice is a "normal" 2D array of memory-contiguous data*/
+ for (x_idx=0; x_idx < nx; x_idx++)
+ {
+ smooth2d(&data[x_idx*slice_size], ny, nz);
+ }
+}
+
+/* 2D smoothing of a XZ slice in a 3D volume*/
+void smooth2d_xzslice(double *data, long nx, long ny, long nz)
+{
+
+ /* smooth along the first dimension */
+ smooth1d_x(data, nx, ny, nz);
+
+ /* smooth along the third dimension */
+ smooth1d_z(data, nx, ny, nz);
+}
+
+/* 2D smoothing of a XY slice in a 3D volume*/
+void smooth2d_xyslice(double *data, long nx, long ny, long nz)
+{
+ /* smooth along the first dimension */
+ smooth1d_x(data, nx, ny, nz);
+
+ /* smooth along the second dimension */
+ smooth1d_y(data, nx, ny, nz);
+}
+
diff --git a/silx/math/fit/filters/src/snip1d.c b/silx/math/fit/filters/src/snip1d.c
new file mode 100644
index 0000000..994a272
--- /dev/null
+++ b/silx/math/fit/filters/src/snip1d.c
@@ -0,0 +1,149 @@
+#/*##########################################################################
+# Copyright (c) 2004-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.
+#
+#############################################################################*/
+/*
+ Implementation of the algorithm SNIP in 1D described in
+ Miroslav Morhac et al. Nucl. Instruments and Methods in Physics Research A401 (1997) 113-132.
+
+ The original idea for 1D and the low-statistics-digital-filter (lsdf) come from
+ C.G. Ryan et al. Nucl. Instruments and Methods in Physics Research B34 (1988) 396-402.
+*/
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+void lls(double *data, int size);
+void lls_inv(double *data, int size);
+void snip1d(double *data, int n_channels, int snip_width);
+void snip1d_multiple(double *data, int n_channels, int snip_width, int n_spectra);
+void lsdf(double *data, int size, int fwhm, double f, double A, double M, double ratio);
+
+void lls(double *data, int size)
+{
+ int i;
+ for (i=0; i< size; i++)
+ {
+ data[i] = log(log(sqrt(data[i]+1.0)+1.0)+1.0);
+ }
+}
+
+void lls_inv(double *data, int size)
+{
+ int i;
+ double tmp;
+ for (i=0; i< size; i++)
+ {
+ /* slightly different than the published formula because
+ with the original formula:
+
+ tmp = exp(exp(data[i]-1.0)-1.0);
+ data[i] = tmp * tmp - 1.0;
+
+ one does not recover the original data */
+
+ tmp = exp(exp(data[i])-1.0)-1.0;
+ data[i] = tmp * tmp - 1.0;
+ }
+}
+
+void lsdf(double *data, int size, int fwhm, double f, double A, double M, double ratio)
+{
+ int channel, i, j;
+ double L, R, S;
+ int width;
+ double dhelp;
+
+ width = (int) (f * fwhm);
+ for (channel=width; channel<(size-width); channel++)
+ {
+ i = width;
+ while(i>0)
+ {
+ L=0;
+ R=0;
+ for(j=channel-i; j<channel; j++)
+ {
+ L += data[j];
+ }
+ for(j=channel+1; j<channel+i; j++)
+ {
+ R += data[j];
+ }
+ S = data[channel] + L + R;
+ if (S<M)
+ {
+ data[channel] = S /(2*i+1);
+ break;
+ }
+ dhelp = (R+1)/(L+1);
+ if ((dhelp < ratio) && (dhelp > (1/ratio)))
+ {
+ if (S<(A*sqrt(data[channel])))
+ {
+ data[channel] = S /(2*i+1);
+ break;
+ }
+ }
+ i=i-1;
+ }
+ }
+}
+
+
+void snip1d(double *data, int n_channels, int snip_width)
+{
+ snip1d_multiple(data, n_channels, snip_width, 1);
+}
+
+void snip1d_multiple(double *data, int n_channels, int snip_width, int n_spectra)
+{
+ int i;
+ int j;
+ int p;
+ int offset;
+ double *w;
+
+ i = (int) (0.5 * snip_width);
+ /* lsdf(data, size, i, 1.5, 75., 10., 1.3); */
+
+ w = (double *) malloc(n_channels * sizeof(double));
+
+ for (j=0; j < n_spectra; j++)
+ {
+ offset = j * n_channels;
+ for (p = snip_width; p > 0; p--)
+ {
+ for (i=p; i<(n_channels - p); i++)
+ {
+ w[i] = MIN(data[i + offset], 0.5*(data[i + offset - p] + data[ i + offset + p]));
+ }
+ for (i=p; i<(n_channels - p); i++)
+ {
+ data[i+offset] = w[i];
+ }
+ }
+ }
+ free(w);
+}
diff --git a/silx/math/fit/filters/src/snip2d.c b/silx/math/fit/filters/src/snip2d.c
new file mode 100644
index 0000000..235759c
--- /dev/null
+++ b/silx/math/fit/filters/src/snip2d.c
@@ -0,0 +1,96 @@
+#/*##########################################################################
+#
+# The PyMca X-Ray Fluorescence Toolkit
+#
+# Copyright (c) 2004-2014 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# 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.
+#
+#############################################################################*/
+/*
+ Implementation of the algorithm SNIP in 2D described in
+ Miroslav Morhac et al. Nucl. Instruments and Methods in Physics Research A401 (1997) 113-132.
+*/
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+void lls(double *data, int size);
+void lls_inv(double *data, int size);
+
+void snip2d(double *data, int nrows, int ncolumns, int width)
+{
+ int i, j;
+ int p;
+ int size;
+ double *w;
+ double P1, P2, P3, P4;
+ double S1, S2, S3, S4;
+ double dhelp;
+ int iminuspxncolumns; /* (i-p) * ncolumns */
+ int ixncolumns; /* i * ncolumns */
+ int ipluspxncolumns; /* (i+p) * ncolumns */
+
+ size = nrows * ncolumns;
+ w = (double *) malloc(size * sizeof(double));
+
+ for (p=width; p > 0; p--)
+ {
+ for (i=p; i<(nrows-p); i++)
+ {
+ iminuspxncolumns = (i-p) * ncolumns;
+ ixncolumns = i * ncolumns;
+ ipluspxncolumns = (i+p) * ncolumns;
+ for (j=p; j<(ncolumns-p); j++)
+ {
+ P4 = data[ iminuspxncolumns + (j-p)]; /* P4 = data[i-p][j-p] */
+ S4 = data[ iminuspxncolumns + j]; /* S4 = data[i-p][j] */
+ P2 = data[ iminuspxncolumns + (j+p)]; /* P2 = data[i-p][j+p] */
+ S3 = data[ ixncolumns + (j-p)]; /* S3 = data[i][j-p] */
+ S2 = data[ ixncolumns + (j+p)]; /* S2 = data[i][j+p] */
+ P3 = data[ ipluspxncolumns + (j-p)]; /* P3 = data[i+p][j-p] */
+ S1 = data[ ipluspxncolumns + j]; /* S1 = data[i+p][j] */
+ P1 = data[ ipluspxncolumns + (j+p)]; /* P1 = data[i+p][j+p] */
+ dhelp = 0.5*(P1+P3);
+ S1 = MAX(S1, dhelp) - dhelp;
+ dhelp = 0.5*(P1+P2);
+ S2 = MAX(S2, dhelp) - dhelp;
+ dhelp = 0.5*(P3+P4);
+ S3 = MAX(S3, dhelp) - dhelp;
+ dhelp = 0.5*(P2+P4);
+ S4 = MAX(S4, dhelp) - dhelp;
+ w[ixncolumns + j] = MIN(data[ixncolumns + j], 0.5 * (S1+S2+S3+S4) + 0.25 * (P1+P2+P3+P4));
+ }
+ }
+ for (i=p; i<(nrows-p); i++)
+ {
+ ixncolumns = i * ncolumns;
+ for (j=p; j<(ncolumns-p); j++)
+ {
+ data[ixncolumns + j] = w[ixncolumns + j];
+ }
+ }
+ }
+ free(w);
+}
diff --git a/silx/math/fit/filters/src/snip3d.c b/silx/math/fit/filters/src/snip3d.c
new file mode 100644
index 0000000..cf48ee4
--- /dev/null
+++ b/silx/math/fit/filters/src/snip3d.c
@@ -0,0 +1,186 @@
+#/*##########################################################################
+#
+# The PyMca X-Ray Fluorescence Toolkit
+#
+# Copyright (c) 2004-2014 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# 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.
+#
+#############################################################################*/
+/*
+ Implementation of the algorithm SNIP in 3D described in
+ Miroslav Morhac et al. Nucl. Instruments and Methods in Physics Research A401 (1997) 113-132.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+void lls(double *data, int size);
+void lls_inv(double *data, int size);
+
+void snip3d(double *data, int nx, int ny, int nz, int width)
+{
+ int i, j, k;
+ int p;
+ int size;
+ double *w;
+ double P1, P2, P3, P4, P5, P6, P7, P8;
+ double R1, R2, R3, R4, R5, R6;
+ double S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12;
+ double dhelp;
+ long ioffset;
+ long iplus;
+ long imin;
+ long joffset;
+ long jplus;
+ long jmin;
+
+ size = nx * ny * nz;
+ w = (double *) malloc(size * sizeof(double));
+
+ for (p=width; p > 0; p--)
+ {
+ for (i=p; i<(nx-p); i++)
+ {
+ ioffset = i * ny * nz;
+ iplus = (i + p) * ny * nz;
+ imin = (i - p) * ny * nz;
+ for (j=p; j<(ny-p); j++)
+ {
+ joffset = j * nz;
+ jplus = (j + p) * nz;
+ jmin = (j - p) * nz;
+ for (k=p; k<(nz-p); k++)
+ {
+ P1 = data[iplus + jplus + k-p]; /* P1 = data[i+p][j+p][k-p] */
+ P2 = data[imin + jplus + k-p]; /* P2 = data[i-p][j+p][k-p] */
+ P3 = data[iplus + jmin + k-p]; /* P3 = data[i+p][j-p][k-p] */
+ P4 = data[imin + jmin + k-p]; /* P4 = data[i-p][j-p][k-p] */
+ P5 = data[iplus + jplus + k+p]; /* P5 = data[i+p][j+p][k+p] */
+ P6 = data[imin + jplus + k+p]; /* P6 = data[i-p][j+p][k+p] */
+ P7 = data[imin + jmin + k+p]; /* P7 = data[i-p][j-p][k+p] */
+ P8 = data[iplus + jmin + k+p]; /* P8 = data[i+p][j-p][k+p] */
+
+ S1 = data[iplus + joffset + k-p]; /* S1 = data[i+p][j][k-p] */
+ S2 = data[ioffset + jmin + k-p]; /* S2 = data[i][j+p][k-p] */
+ S3 = data[imin + joffset + k-p]; /* S3 = data[i-p][j][k-p] */
+ S4 = data[ioffset + jmin + k-p]; /* S4 = data[i][j-p][k-p] */
+ S5 = data[imin + joffset + k+p]; /* S5 = data[i-p][j][k+p] */
+ S6 = data[ioffset + jplus + k+p]; /* S6 = data[i][j+p][k+p] */
+ S7 = data[imin + joffset + k+p]; /* S7 = data[i-p][j][k+p] */
+ S8 = data[ioffset + jmin + k+p]; /* S8 = data[i][j-p][k+p] */
+ S9 = data[imin + jplus + k]; /* S9 = data[i-p][j+p][k] */
+ S10 = data[imin + jmin + k]; /* S10 = data[i-p][j-p][k] */
+ S11 = data[iplus + jmin + k]; /* S11 = data[i+p][j-p][k] */
+ S12 = data[iplus + jplus + k]; /* S12 = data[i+p][j+p][k] */
+
+ R1 = data[ioffset + joffset + k-p]; /* R1 = data[i][j][k-p] */
+ R2 = data[ioffset + joffset + k+p]; /* R2 = data[i][j][k+p] */
+ R3 = data[imin + joffset + k]; /* R3 = data[i-p][j][k] */
+ R4 = data[iplus + joffset + k]; /* R4 = data[i+p][j][k] */
+ R5 = data[ioffset + jplus + k]; /* R5 = data[i][j+p][k] */
+ R6 = data[ioffset + jmin + k]; /* R6 = data[i][j-p][k] */
+
+ dhelp = 0.5*(P1+P3);
+ S1 = MAX(S1, dhelp) - dhelp;
+
+ dhelp = 0.5*(P1+P2);
+ S2 = MAX(S2, dhelp) - dhelp;
+
+ dhelp = 0.5*(P2+P4);
+ S3 = MAX(S3, dhelp) - dhelp;
+
+ dhelp = 0.5*(P3+P4);
+ S4 = MAX(S4, dhelp) - dhelp;
+
+ dhelp = 0.5*(P5+P8); /* Different from paper (P5+P7) but according to drawing */
+ S5 = MAX(S5, dhelp) - dhelp;
+
+ dhelp = 0.5*(P5+P6);
+ S6 = MAX(S6, dhelp) - dhelp;
+
+ dhelp = 0.5*(P6+P7); /* Different from paper (P6+P8) but according to drawing */
+ S7 = MAX(S7, dhelp) - dhelp;
+
+ dhelp = 0.5*(P7+P8);
+ S8 = MAX(S8, dhelp) - dhelp;
+
+ dhelp = 0.5*(P2+P6);
+ S9 = MAX(S9, dhelp) - dhelp;
+
+ dhelp = 0.5*(P4+P7); /* Different from paper (P4+P8) but according to drawing */
+ S10 = MAX(S10, dhelp) - dhelp;
+
+ dhelp = 0.5*(P3+P8); /* Different from paper (P1+P5) but according to drawing */
+ S11 = MAX(S11, dhelp) - dhelp;
+
+ dhelp = 0.5*(P1+P5); /* Different from paper (P3+P7) but according to drawing */
+ S12 = MAX(S12, dhelp) - dhelp;
+
+ /* The published formulae correspond to have:
+ P7 and P8 interchanged, and S11 and S12 interchanged
+ with respect to the published drawing */
+
+ dhelp = 0.5 * (S1+S2+S3+S4) + 0.25 * (P1+P2+P3+P4);
+ R1 = MAX(R1, dhelp) - dhelp;
+
+ dhelp = 0.5 * (S5+S6+S7+S8) + 0.25 * (P5+P6+P7+P8);
+ R2 = MAX(R2, dhelp) - dhelp;
+
+ dhelp = 0.5 * (S3+S7+S9+S10) + 0.25 * (P2+P4+P6+P7); /* Again same P7 and P8 change */
+ R3 = MAX(R3, dhelp) - dhelp;
+
+ dhelp = 0.5 * (S1+S5+S11+S12) + 0.25 * (P1+P3+P5+P8); /* Again same P7 and P8 change */
+ R4 = MAX(R4, dhelp) - dhelp;
+
+ dhelp = 0.5 * (S2+S6+S9+S12) + 0.25 * (P1+P2+P5+P6); /* Again same S11 and S12 change */
+ R5 = MAX(R5, dhelp) - dhelp;
+
+ dhelp = 0.5 * (S4+S8+S10+S11) + 0.25 * (P3+P4+P7+P8); /* Again same S11 and S12 change */
+ R6 = MAX(R6, dhelp) - dhelp;
+
+ dhelp = 0.5 * (R1 + R2 + R3 + R4 + R5 + R6) +\
+ 0.25 * (S1 + S2 + S3 + S4 + S5 + S6) +\
+ 0.25 * (S7 + S8 + S9 + S10 + S11 + S12) +\
+ 0.125 * (P1 + P2 + P3 + P4 + P5 + P6 + P7 + P8);
+ w[ioffset + joffset + k] = MIN(data[ioffset + joffset + k], dhelp);
+ }
+ }
+ }
+ for (i=p; i<(nx-p); i++)
+ {
+ ioffset = i * ny * nz;
+ for (j=p; j<(ny-p); j++)
+ {
+ joffset = j * nz;
+ for (k=p; k<(nz-p); j++)
+ {
+ data[ioffset + joffset + k] = w[ioffset + joffset + k];
+ }
+ }
+ }
+ }
+ free(w);
+}
diff --git a/silx/math/fit/filters/src/strip.c b/silx/math/fit/filters/src/strip.c
new file mode 100644
index 0000000..dec0742
--- /dev/null
+++ b/silx/math/fit/filters/src/strip.c
@@ -0,0 +1,118 @@
+#/*##########################################################################
+# Copyright (c) 2004-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.
+#
+#############################################################################*/
+/*
+ This file provides a background strip function, to isolate low frequency
+ background signal from a spectrum (and later substact it from the signal
+ to be left only with the peaks to be fitted).
+
+ It is adapted from PyMca source file "SpecFitFuns.c". The main difference
+ with the original code is that this code does not handle the python
+ wrapping, which is done elsewhere using cython.
+
+ Authors: V.A. Sole, P. Knobel
+ License: MIT
+ Last modified: 17/06/2016
+*/
+
+#include <string.h>
+
+#include <stdio.h>
+
+/* strip(double* input, double c, long niter, double* output)
+
+ The strip background is probably PyMca's most popular background model.
+
+ In its simplest implementation it is just as an iterative procedure depending
+ on two parameters. These parameters are the strip background width w, and the
+ strip background 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".
+
+ Parameters:
+
+ - input: Input data array
+ - c: scaling factor applied to the average of y(i-w) and y(i+w) before
+ comparing to y(i)
+ - niter: number of iterations
+ - deltai: operator width (in number of channels)
+ - anchors: Array of anchors, indices of points that will not be
+ modified during the stripping procedure.
+ - output: output array
+
+*/
+int strip(double* input, long len_input,
+ double c, long niter, int deltai,
+ long* anchors, long len_anchors,
+ double* output)
+{
+ long iter_index, array_index, anchor_index, anchor;
+ int anchor_nearby_flag;
+ double t_mean;
+
+ memcpy(output, input, len_input * sizeof(double));
+
+ if (deltai <=0) deltai = 1;
+
+ if (len_input < (2*deltai+1)) return(-1);
+
+ if (len_anchors > 0) {
+ for (iter_index = 0; iter_index < niter; iter_index++) {
+ for (array_index = deltai; array_index < len_input - deltai; array_index++) {
+ /* if index is within +- deltai of an anchor, don't do anything */
+ anchor_nearby_flag = 0;
+ for (anchor_index=0; anchor_index<len_anchors; anchor_index++)
+ {
+ anchor = anchors[anchor_index];
+ if (array_index > (anchor - deltai) && array_index < (anchor + deltai))
+ {
+ anchor_nearby_flag = 1;
+ break;
+ }
+ }
+ /* skip this array_index index */
+ if (anchor_nearby_flag) {
+ continue;
+ }
+
+ t_mean = 0.5 * (input[array_index-deltai] + input[array_index+deltai]);
+ if (input[array_index] > (t_mean * c))
+ output[array_index] = t_mean;
+ }
+ memcpy(input, output, len_input * sizeof(double));
+ }
+ }
+ else {
+ for (iter_index = 0; iter_index < niter; iter_index++) {
+ for (array_index=deltai; array_index < len_input - deltai; array_index++) {
+ t_mean = 0.5 * (input[array_index-deltai] + input[array_index+deltai]);
+
+ if (input[array_index] > (t_mean * c))
+ output[array_index] = t_mean;
+ }
+ memcpy(input, output, len_input * sizeof(double));
+ }
+ }
+ return(0);
+}
diff --git a/silx/math/fit/fitmanager.py b/silx/math/fit/fitmanager.py
new file mode 100644
index 0000000..4a12a24
--- /dev/null
+++ b/silx/math/fit/fitmanager.py
@@ -0,0 +1,1071 @@
+# coding: utf-8
+# /*#########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ##########################################################################*/
+"""
+This module provides a tool to perform advanced fitting. The actual fit relies
+on :func:`silx.math.fit.leastsq`.
+
+This module deals with:
+
+ - handling of the model functions (using a set of default functions or
+ loading custom user functions)
+ - handling of estimation function, that are used to determine the number
+ of parameters to be fitted for functions with unknown number of
+ parameters (such as the sum of a variable number of gaussian curves),
+ and find reasonable initial parameters for input to the iterative
+ fitting algorithm
+ - handling of custom derivative functions that can be passed as a
+ parameter to :func:`silx.math.fit.leastsq`
+ - providing different background models
+
+"""
+from collections import OrderedDict
+import logging
+import numpy
+from numpy.linalg.linalg import LinAlgError
+import os
+import sys
+
+from .filters import strip, smooth1d
+from .leastsq import leastsq
+from .fittheory import FitTheory
+from . import bgtheories
+
+
+__authors__ = ["V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+_logger = logging.getLogger(__name__)
+
+
+class FitManager(object):
+ """
+ Fit functions manager
+
+ :param x: Abscissa data. If ``None``, :attr:`xdata` is set to
+ ``numpy.array([0.0, 1.0, 2.0, ..., len(y)-1])``
+ :type x: Sequence or numpy array or None
+ :param y: The dependant data ``y = f(x)``. ``y`` must have the same
+ shape as ``x`` if ``x`` is not ``None``.
+ :type y: Sequence or numpy array or None
+ :param sigmay: The uncertainties in the ``ydata`` array. These can be
+ used as weights in the least-squares problem, if ``weight_flag``
+ is ``True``.
+ If ``None``, the uncertainties are assumed to be 1, unless
+ ``weight_flag`` is ``True``, in which case the square-root
+ of ``y`` is used.
+ :type sigmay: Sequence or numpy array or None
+ :param weight_flag: If this parameter is ``True`` and ``sigmay``
+ uncertainties are not specified, the square root of ``y`` is used
+ as weights in the least-squares problem. If ``False``, the
+ uncertainties are set to 1.
+ :type weight_flag: boolean
+ """
+ def __init__(self, x=None, y=None, sigmay=None, weight_flag=False):
+ """
+ """
+ self.fitconfig = {
+ 'WeightFlag': weight_flag,
+ 'fitbkg': 'No Background',
+ 'fittheory': None,
+ # Next few parameters are defined for compatibility with legacy theories
+ # which take the background as argument for their estimation function
+ 'StripWidth': 2,
+ 'StripIterations': 5000,
+ 'StripThresholdFactor': 1.0,
+ 'SmoothingFlag': False
+ }
+ """Dictionary of fit configuration parameters.
+ These parameters can be modified using the :meth:`configure` method.
+
+ Keys are:
+
+ - 'fitbkg': name of the function used for fitting a low frequency
+ background signal
+ - 'FwhmPoints': default full width at half maximum value for the
+ peaks'.
+ - 'Sensitivity': Sensitivity parameter for the peak detection
+ algorithm (:func:`silx.math.fit.peak_search`)
+ """
+
+ self.theories = OrderedDict()
+ """Dictionary of fit theories, defining functions to be fitted
+ to individual peaks.
+
+ Keys are descriptive theory names (e.g "Gaussians" or "Step up").
+ Values are :class:`silx.math.fit.fittheory.FitTheory` objects with
+ the following attributes:
+
+ - *"function"* is the fit function for an individual peak
+ - *"parameters"* is a sequence of parameter names
+ - *"estimate"* is the parameter estimation function
+ - *"configure"* is the function returning the configuration dict
+ for the theory in the format described in the :attr:` fitconfig`
+ documentation
+ - *"derivative"* (optional) is a custom derivative function, whose
+ signature is described in the documentation of
+ :func:`silx.math.fit.leastsq.leastsq`
+ (``model_deriv(xdata, parameters, index)``).
+ - *"description"* is a description string
+ """
+
+ self.selectedtheory = None
+ """Name of currently selected theory. This name matches a key in
+ :attr:`theories`."""
+
+ self.bgtheories = OrderedDict()
+ """Dictionary of background theories.
+
+ See :attr:`theories` for documentation on theories.
+ """
+
+ # Load default theories (constant, linear, strip)
+ self.loadbgtheories(bgtheories)
+
+ self.selectedbg = 'No Background'
+ """Name of currently selected background theory. This name must be
+ an existing key in :attr:`bgtheories`."""
+
+ self.fit_results = []
+ """This list stores detailed information about all fit parameters.
+ It is initialized in :meth:`estimate` and completed with final fit
+ values in :meth:`runfit`.
+
+ Each fit parameter is stored as a dictionary with following fields:
+
+ - 'name': Parameter name.
+ - 'estimation': Estimated value.
+ - 'group': Group number. Group 0 corresponds to the background
+ function parameters. Group ``n`` (for ``n>0``) corresponds to
+ the fit function parameters for the n-th peak.
+ - 'code': Constraint code
+
+ - 0 - FREE
+ - 1 - POSITIVE
+ - 2 - QUOTED
+ - 3 - FIXED
+ - 4 - FACTOR
+ - 5 - DELTA
+ - 6 - SUM
+
+ - 'cons1':
+
+ - Ignored if 'code' is FREE, POSITIVE or FIXED.
+ - Min value of the parameter if code is QUOTED
+ - Index of fitted parameter to which 'cons2' is related
+ if code is FACTOR, DELTA or SUM.
+
+ - 'cons2':
+
+ - Ignored if 'code' is FREE, POSITIVE or FIXED.
+ - Max value of the parameter if QUOTED
+ - Factor to apply to related parameter with index 'cons1' if
+ 'code' is FACTOR
+ - Difference with parameter with index 'cons1' if
+ 'code' is DELTA
+ - Sum obtained when adding parameter with index 'cons1' if
+ 'code' is SUM
+
+ - 'fitresult': Fitted value.
+ - 'sigma': Standard deviation for the parameter estimate
+ - 'xmin': Lower limit of the ``x`` data range on which the fit
+ was performed
+ - 'xmax': Upeer limit of the ``x`` data range on which the fit
+ was performed
+ """
+
+ self.parameter_names = []
+ """This list stores all fit parameter names: background function
+ parameters and fit function parameters for every peak. It is filled
+ in :meth:`estimate`.
+
+ It is the responsibility of the estimate function defined in
+ :attr:`theories` to determine how many parameters are needed,
+ based on how many peaks are detected and how many parameters are needed
+ to fit an individual peak.
+ """
+
+ self.setdata(x, y, sigmay)
+
+ ##################
+ # Public methods #
+ ##################
+ def addbackground(self, bgname, bgtheory):
+ """Add a new background theory to dictionary :attr:`bgtheories`.
+
+ :param bgname: String with the name describing the function
+ :param bgtheory: :class:`FitTheory` object
+ :type bgtheory: :class:`silx.math.fit.fittheory.FitTheory`
+ """
+ self.bgtheories[bgname] = bgtheory
+
+ def addtheory(self, name, theory=None,
+ function=None, parameters=None,
+ estimate=None, configure=None, derivative=None,
+ description=None, pymca_legacy=False):
+ """Add a new theory to dictionary :attr:`theories`.
+
+ You can pass a name and a :class:`FitTheory` object as arguments, or
+ alternatively provide all arguments necessary to instantiate a new
+ :class:`FitTheory` object.
+
+ See :meth:`loadtheories` for more information on estimation functions,
+ configuration functions and custom derivative functions.
+
+ :param name: String with the name describing the function
+ :param theory: :class:`FitTheory` object, defining a fit function and
+ associated information (estimation function, description…).
+ If this parameter is provided, all other parameters, except for
+ ``name``, are ignored.
+ :type theory: :class:`silx.math.fit.fittheory.FitTheory`
+ :param function function: Mandatory argument if ``theory`` is not provided.
+ See documentation for :attr:`silx.math.fit.fittheory.FitTheory.function`.
+ :param list[str] parameters: Mandatory argument if ``theory`` is not provided.
+ See documentation for :attr:`silx.math.fit.fittheory.FitTheory.parameters`.
+ :param function estimate: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.estimate`
+ :param function configure: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.configure`
+ :param function derivative: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.derivative`
+ :param str description: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.description`
+ :param config_widget: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.config_widget`
+ :param bool pymca_legacy: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.pymca_legacy`
+ """
+ if theory is not None:
+ self.theories[name] = theory
+
+ elif function is not None and parameters is not None:
+ self.theories[name] = FitTheory(
+ description=description,
+ function=function,
+ parameters=parameters,
+ estimate=estimate,
+ configure=configure,
+ derivative=derivative,
+ pymca_legacy=pymca_legacy
+ )
+
+ else:
+ raise TypeError("You must supply a FitTheory object or define " +
+ "a fit function and its parameters.")
+
+ def addbgtheory(self, name, theory=None,
+ function=None, parameters=None,
+ estimate=None, configure=None,
+ derivative=None, description=None):
+ """Add a new theory to dictionary :attr:`bgtheories`.
+
+ You can pass a name and a :class:`FitTheory` object as arguments, or
+ alternatively provide all arguments necessary to instantiate a new
+ :class:`FitTheory` object.
+
+ :param name: String with the name describing the function
+ :param theory: :class:`FitTheory` object, defining a fit function and
+ associated information (estimation function, description…).
+ If this parameter is provided, all other parameters, except for
+ ``name``, are ignored.
+ :type theory: :class:`silx.math.fit.fittheory.FitTheory`
+ :param function function: Mandatory argument if ``theory`` is not provided.
+ See documentation for :attr:`silx.math.fit.fittheory.FitTheory.function`.
+ :param list[str] parameters: Mandatory argument if ``theory`` is not provided.
+ See documentation for :attr:`silx.math.fit.fittheory.FitTheory.parameters`.
+ :param function estimate: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.estimate`
+ :param function configure: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.configure`
+ :param function derivative: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.derivative`
+ :param str description: See documentation for
+ :attr:`silx.math.fit.fittheory.FitTheory.description`
+ """
+ if theory is not None:
+ self.bgtheories[name] = theory
+
+ elif function is not None and parameters is not None:
+ self.bgtheories[name] = FitTheory(
+ description=description,
+ function=function,
+ parameters=parameters,
+ estimate=estimate,
+ configure=configure,
+ derivative=derivative,
+ is_background=True
+ )
+
+ else:
+ raise TypeError("You must supply a FitTheory object or define " +
+ "a background function and its parameters.")
+
+ def configure(self, **kw):
+ """Configure the current theory by filling or updating the
+ :attr:`fitconfig` dictionary.
+ Call the custom configuration function, if any. This allows the user
+ to modify the behavior of the custom fit function or the custom
+ estimate function.
+
+ This methods accepts only named parameters. All ``**kw`` parameters
+ are expected to be fields of :attr:`fitconfig` to be updated, unless
+ they have a special meaning for the custom configuration function
+ of the currently selected theory..
+
+ This method returns the modified config dictionary returned by the
+ custom configuration function.
+ """
+ # inspect **kw to find known keys, update them in self.fitconfig
+ for key in self.fitconfig:
+ if key in kw:
+ self.fitconfig[key] = kw[key]
+
+ # initialize dict with existing config dict
+ result = {}
+ result.update(self.fitconfig)
+
+ if "WeightFlag" in kw:
+ if kw["WeightFlag"]:
+ self.enableweight()
+ else:
+ self.disableweight()
+
+ if self.selectedtheory is None:
+ return result
+
+ # Apply custom configuration function
+ custom_config_fun = self.theories[self.selectedtheory].configure
+ if custom_config_fun is not None:
+ result.update(custom_config_fun(**kw))
+
+ custom_bg_config_fun = self.bgtheories[self.selectedbg].configure
+ if custom_bg_config_fun is not None:
+ result.update(custom_bg_config_fun(**kw))
+
+ # Update self.fitconfig with custom config
+ for key in self.fitconfig:
+ if key in result:
+ self.fitconfig[key] = result[key]
+
+ result.update(self.fitconfig)
+ return result
+
+ def estimate(self, callback=None):
+ """
+ Fill :attr:`fit_results` with an estimation of the fit parameters.
+
+ At first, the background parameters are estimated, if a background
+ model has been specified.
+ Then, a custom estimation function related to the model function is
+ called.
+
+ This process determines the number of needed fit parameters and
+ provides an initial estimation for them, to serve as an input for the
+ actual iterative fitting performed in :meth:`runfit`.
+
+ :param callback: Optional callback function, conforming to the
+ signature ``callback(data)`` with ``data`` being a dictionary.
+ This callback function is called before and after the estimation
+ process, and is given a dictionary containing the values of
+ :attr:`state` (``'Estimate in progress'`` or ``'Ready to Fit'``)
+ and :attr:`chisq`.
+ This is used for instance in :mod:`silx.gui.fit.FitWidget` to
+ update a widget displaying a status message.
+ :return: Estimated parameters
+ """
+ self.state = 'Estimate in progress'
+ self.chisq = None
+
+ if callback is not None:
+ callback(data={'chisq': self.chisq,
+ 'status': self.state})
+
+ CONS = {0: 'FREE',
+ 1: 'POSITIVE',
+ 2: 'QUOTED',
+ 3: 'FIXED',
+ 4: 'FACTOR',
+ 5: 'DELTA',
+ 6: 'SUM',
+ 7: 'IGNORE'}
+
+ xwork = self.xdata
+ ywork = self.ydata
+
+ # estimate the background
+ bg_params, bg_constraints = self.estimate_bkg(xwork, ywork)
+
+ # estimate the function
+ try:
+ fun_params, fun_constraints = self.estimate_fun(xwork, ywork)
+ except LinAlgError:
+ self.state = 'Estimate failed'
+ if callback is not None:
+ callback(data={'status': self.state})
+ raise
+
+ # build the names
+ self.parameter_names = []
+
+ for bg_param_name in self.bgtheories[self.selectedbg].parameters:
+ self.parameter_names.append(bg_param_name)
+
+ fun_param_names = self.theories[self.selectedtheory].parameters
+ param_index, peak_index = 0, 0
+ while param_index < len(fun_params):
+ peak_index += 1
+ for fun_param_name in fun_param_names:
+ self.parameter_names.append(fun_param_name + "%d" % peak_index)
+ param_index += 1
+
+ self.fit_results = []
+ nb_fun_params_per_group = len(fun_param_names)
+ group_number = 0
+ xmin = min(xwork)
+ xmax = max(xwork)
+ nb_bg_params = len(bg_params)
+ for (pindex, pname) in enumerate(self.parameter_names):
+ # First come background parameters
+ if pindex < nb_bg_params:
+ estimation_value = bg_params[pindex]
+ constraint_code = CONS[int(bg_constraints[pindex][0])]
+ cons1 = bg_constraints[pindex][1]
+ cons2 = bg_constraints[pindex][2]
+ # then come peak function parameters
+ else:
+ fun_param_index = pindex - nb_bg_params
+
+ # increment group_number for each new fitted peak
+ if (fun_param_index % nb_fun_params_per_group) == 0:
+ group_number += 1
+
+ estimation_value = fun_params[fun_param_index]
+ constraint_code = CONS[int(fun_constraints[fun_param_index][0])]
+ # cons1 is the index of another fit parameter. In the global
+ # fit_results, we must adjust the index to account for the bg
+ # params added to the start of the list.
+ cons1 = fun_constraints[fun_param_index][1]
+ if constraint_code in ["FACTOR", "DELTA", "SUM"]:
+ cons1 += nb_bg_params
+ cons2 = fun_constraints[fun_param_index][2]
+
+ self.fit_results.append({'name': pname,
+ 'estimation': estimation_value,
+ 'group': group_number,
+ 'code': constraint_code,
+ 'cons1': cons1,
+ 'cons2': cons2,
+ 'fitresult': 0.0,
+ 'sigma': 0.0,
+ 'xmin': xmin,
+ 'xmax': xmax})
+
+ self.state = 'Ready to Fit'
+ self.chisq = None
+ self.niter = 0
+
+ if callback is not None:
+ callback(data={'chisq': self.chisq,
+ 'status': self.state})
+ return numpy.append(bg_params, fun_params)
+
+ def fit(self):
+ """Convenience method to call :meth:`estimate` followed by :meth:`runfit`.
+
+ :return: Output of :meth:`runfit`"""
+ self.estimate()
+ return self.runfit()
+
+ def gendata(self, x=None, paramlist=None, estimated=False):
+ """Return a data array using the currently selected fit function
+ and the fitted parameters.
+
+ :param x: Independent variable where the function is calculated.
+ If ``None``, use :attr:`xdata`.
+ :param paramlist: List of dictionaries, each dictionary item being a
+ fit parameter. The dictionary's format is documented in
+ :attr:`fit_results`.
+ If ``None`` (default), use parameters from :attr:`fit_results`.
+ :param estimated: If *True*, use estimated parameters.
+ :return: :meth:`fitfunction` calculated for parameters whose code is
+ not set to ``"IGNORE"``.
+
+ This calculates :meth:`fitfunction` on `x` data using fit parameters
+ from a list of parameter dictionaries, if field ``code`` is not set
+ to ``"IGNORE"``.
+ """
+ if x is None:
+ x = self.xdata
+ if paramlist is None:
+ paramlist = self.fit_results
+ active_params = []
+ for param in paramlist:
+ if param['code'] not in ['IGNORE', 7]:
+ if not estimated:
+ active_params.append(param['fitresult'])
+ else:
+ active_params.append(param['estimation'])
+
+ newdata = self.fitfunction(numpy.array(x), *active_params)
+ return newdata
+
+ def get_estimation(self):
+ """Return the list of fit parameter names."""
+ if self.state not in ["Ready to fit", "Fit in progress", "Ready"]:
+ _logger.warning("get_estimation() called before estimate() completed")
+ return [param["estimation"] for param in self.fit_results]
+
+ def get_names(self):
+ """Return the list of fit parameter estimations."""
+ if self.state not in ["Ready to fit", "Fit in progress", "Ready"]:
+ msg = "get_names() called before estimate() completed, "
+ msg += "names are not populated at this stage"
+ _logger.warning(msg)
+ return [param["name"] for param in self.fit_results]
+
+ def get_fitted_parameters(self):
+ """Return the list of fitted parameters."""
+ if self.state not in ["Ready"]:
+ msg = "get_fitted_parameters() called before runfit() completed, "
+ msg += "results are not available a this stage"
+ _logger.warning(msg)
+ return [param["fitresult"] for param in self.fit_results]
+
+ def loadtheories(self, theories):
+ """Import user defined fit functions defined in an external Python
+ source file, and save them in :attr:`theories`.
+
+ An example of such a file can be found in the sources of
+ :mod:`silx.math.fit.fittheories`. It must contain a
+ dictionary named ``THEORY`` with the following structure::
+
+ THEORY = {
+ 'theory_name_1':
+ FitTheory(description='Description of theory 1',
+ function=fitfunction1,
+ parameters=('param name 1', 'param name 2', …),
+ estimate=estimation_function1,
+ configure=configuration_function1,
+ derivative=derivative_function1),
+ 'theory_name_2':
+ FitTheory(…),
+ }
+
+ See documentation of :mod:`silx.math.fit.fittheories` and
+ :mod:`silx.math.fit.fittheory` for more
+ information on designing your fit functions file.
+
+ This method can also load user defined functions in the legacy
+ format used in *PyMca*.
+
+ :param theories: Name of python source file, or module containing the
+ definition of fit functions.
+ :raise: ImportError if theories cannot be imported
+ """
+ from types import ModuleType
+ if isinstance(theories, ModuleType):
+ theories_module = theories
+ else:
+ # if theories is not a module, it must be a string
+ string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+ if not isinstance(theories, string_types):
+ raise ImportError("theory must be a python module, a module" +
+ "name or a python filename")
+ # if theories is a filename
+ if os.path.isfile(theories):
+ sys.path.append(os.path.dirname(theories))
+ f = os.path.basename(os.path.splitext(theories)[0])
+ theories_module = __import__(f)
+ # if theories is a module name
+ else:
+ theories_module = __import__(theories)
+
+ if hasattr(theories_module, "INIT"):
+ theories.INIT()
+
+ if not hasattr(theories_module, "THEORY"):
+ msg = "File %s does not contain a THEORY dictionary" % theories
+ raise ImportError(msg)
+
+ elif isinstance(theories_module.THEORY, dict):
+ # silx format for theory definition
+ for theory_name, fittheory in list(theories_module.THEORY.items()):
+ self.addtheory(theory_name, fittheory)
+ else:
+ self._load_legacy_theories(theories_module)
+
+ def loadbgtheories(self, theories):
+ """Import user defined background functions defined in an external Python
+ module (source file), and save them in :attr:`theories`.
+
+ An example of such a file can be found in the sources of
+ :mod:`silx.math.fit.fittheories`. It must contain a
+ dictionary named ``THEORY`` with the following structure::
+
+ THEORY = {
+ 'theory_name_1':
+ FitTheory(description='Description of theory 1',
+ function=fitfunction1,
+ parameters=('param name 1', 'param name 2', …),
+ estimate=estimation_function1,
+ configure=configuration_function1,
+ 'theory_name_2':
+ FitTheory(…),
+ }
+
+ See documentation of :mod:`silx.math.fit.bgtheories` and
+ :mod:`silx.math.fit.fittheory` for more
+ information on designing your background functions file.
+
+ :param theories: Module or name of python source file containing the
+ definition of background functions.
+ :raise: ImportError if theories cannot be imported
+ """
+ from types import ModuleType
+ if isinstance(theories, ModuleType):
+ theories_module = theories
+ else:
+ # if theories is not a module, it must be a string
+ string_types = (basestring,) if sys.version_info[0] == 2 else (str,) # noqa
+ if not isinstance(theories, string_types):
+ raise ImportError("theory must be a python module, a module" +
+ "name or a python filename")
+ # if theories is a filename
+ if os.path.isfile(theories):
+ sys.path.append(os.path.dirname(theories))
+ f = os.path.basename(os.path.splitext(theories)[0])
+ theories_module = __import__(f)
+ # if theories is a module name
+ else:
+ theories_module = __import__(theories)
+
+ if hasattr(theories_module, "INIT"):
+ theories.INIT()
+
+ if not hasattr(theories_module, "THEORY"):
+ msg = "File %s does not contain a THEORY dictionary" % theories
+ raise ImportError(msg)
+
+ elif isinstance(theories_module.THEORY, dict):
+ # silx format for theory definition
+ for theory_name, fittheory in list(theories_module.THEORY.items()):
+ self.addbgtheory(theory_name, fittheory)
+
+ def setbackground(self, theory):
+ """Choose a background type from within :attr:`bgtheories`.
+
+ This updates :attr:`selectedbg`.
+
+ :param theory: The name of the background to be used.
+ :raise: KeyError if ``theory`` is not a key of :attr:`bgtheories``.
+ """
+ if theory in self.bgtheories:
+ self.selectedbg = theory
+ else:
+ msg = "No theory with name %s in bgtheories.\n" % theory
+ msg += "Available theories: %s\n" % self.bgtheories.keys()
+ raise KeyError(msg)
+
+ # run configure to apply our fitconfig to the selected theory
+ # through its custom config function
+ self.configure(**self.fitconfig)
+
+ def setdata(self, x, y, sigmay=None, xmin=None, xmax=None):
+ """Set data attributes:
+
+ - ``xdata0``, ``ydata0`` and ``sigmay0`` store the initial data
+ and uncertainties. These attributes are not modified after
+ initialization.
+ - ``xdata``, ``ydata`` and ``sigmay`` store the data after
+ removing values where ``xdata < xmin`` or ``xdata > xmax``.
+ These attributes may be modified at a latter stage by filters.
+
+ :param x: Abscissa data. If ``None``, :attr:`xdata`` is set to
+ ``numpy.array([0.0, 1.0, 2.0, ..., len(y)-1])``
+ :type x: Sequence or numpy array or None
+ :param y: The dependant data ``y = f(x)``. ``y`` must have the same
+ shape as ``x`` if ``x`` is not ``None``.
+ :type y: Sequence or numpy array or None
+ :param sigmay: The uncertainties in the ``ydata`` array. These are
+ used as weights in the least-squares problem.
+ If ``None``, the uncertainties are assumed to be 1.
+ :type sigmay: Sequence or numpy array or None
+ :param xmin: Lower value of x values to use for fitting
+ :param xmax: Upper value of x values to use for fitting
+ """
+ if y is None:
+ self.xdata0 = numpy.array([], numpy.float)
+ self.ydata0 = numpy.array([], numpy.float)
+ # self.sigmay0 = numpy.array([], numpy.float)
+ self.xdata = numpy.array([], numpy.float)
+ self.ydata = numpy.array([], numpy.float)
+ # self.sigmay = numpy.array([], numpy.float)
+
+ else:
+ self.ydata0 = numpy.array(y)
+ self.ydata = numpy.array(y)
+ if x is None:
+ self.xdata0 = numpy.arange(len(self.ydata0))
+ self.xdata = numpy.arange(len(self.ydata0))
+ else:
+ self.xdata0 = numpy.array(x)
+ self.xdata = numpy.array(x)
+
+ # default weight
+ if sigmay is None:
+ self.sigmay0 = None
+ self.sigmay = numpy.sqrt(self.ydata) if self.fitconfig["WeightFlag"] else None
+ else:
+ self.sigmay0 = numpy.array(sigmay)
+ self.sigmay = numpy.array(sigmay) if self.fitconfig["WeightFlag"] else None
+
+ # take the data between limits, using boolean array indexing
+ if (xmin is not None or xmax is not None) and len(self.xdata):
+ xmin = xmin if xmin is not None else min(self.xdata)
+ xmax = xmax if xmax is not None else max(self.xdata)
+ bool_array = (self.xdata >= xmin) & (self.xdata <= xmax)
+ self.xdata = self.xdata[bool_array]
+ self.ydata = self.ydata[bool_array]
+ self.sigmay = self.sigmay[bool_array] if sigmay is not None else None
+
+ def enableweight(self):
+ """This method can be called to set :attr:`sigmay`. If :attr:`sigmay0` was filled with
+ actual uncertainties in :meth:`setdata`, use these values.
+ Else, use ``sqrt(self.ydata)``.
+ """
+ if self.sigmay0 is None:
+ self.sigmay = numpy.sqrt(self.ydata) if self.fitconfig["WeightFlag"] else None
+ else:
+ self.sigmay = self.sigmay0
+
+ def disableweight(self):
+ """This method can be called to set :attr:`sigmay` equal to ``None``.
+ As a result, :func:`leastsq` will consider that the weights in the
+ least square problem are 1 for all samples."""
+ self.sigmay = None
+
+ def settheory(self, theory):
+ """Pick a theory from :attr:`theories`.
+
+ :param theory: Name of the theory to be used.
+ :raise: KeyError if ``theory`` is not a key of :attr:`theories`.
+ """
+ if theory is None:
+ self.selectedtheory = None
+ elif theory in self.theories:
+ self.selectedtheory = theory
+ else:
+ msg = "No theory with name %s in theories.\n" % theory
+ msg += "Available theories: %s\n" % self.theories.keys()
+ raise KeyError(msg)
+
+ # run configure to apply our fitconfig to the selected theory
+ # through its custom config function
+ self.configure(**self.fitconfig)
+
+ def runfit(self, callback=None):
+ """Run the actual fitting and fill :attr:`fit_results` with fit results.
+
+ Before running this method, :attr:`fit_results` must already be
+ populated with a list of all parameters and their estimated values.
+ For this, run :meth:`estimate` beforehand.
+
+ :param callback: Optional callback function, conforming to the
+ signature ``callback(data)`` with ``data`` being a dictionary.
+ This callback function is called before and after the estimation
+ process, and is given a dictionary containing the values of
+ :attr:`state` (``'Fit in progress'`` or ``'Ready'``)
+ and :attr:`chisq`.
+ This is used for instance in :mod:`silx.gui.fit.FitWidget` to
+ update a widget displaying a status message.
+ :return: Tuple ``(fitted parameters, uncertainties, infodict)``.
+ *infodict* is the dictionary returned by
+ :func:`silx.math.fit.leastsq` when called with option
+ ``full_output=True``. Uncertainties is a sequence of uncertainty
+ values associated with each fitted parameter.
+ """
+ # self.dataupdate()
+
+ self.state = 'Fit in progress'
+ self.chisq = None
+
+ if callback is not None:
+ callback(data={'chisq': self.chisq,
+ 'status': self.state})
+
+ param_val = []
+ param_constraints = []
+ # Initial values are set to the ones computed in estimate()
+ for param in self.fit_results:
+ param_val.append(param['estimation'])
+ param_constraints.append([param['code'], param['cons1'], param['cons2']])
+
+ ywork = self.ydata
+
+
+ try:
+ params, covariance_matrix, infodict = leastsq(
+ self.fitfunction, # bg + actual model function
+ self.xdata, ywork, param_val,
+ sigma=self.sigmay,
+ constraints=param_constraints,
+ model_deriv=self.theories[self.selectedtheory].derivative,
+ full_output=True, left_derivative=True)
+ except LinAlgError:
+ self.state = 'Fit failed'
+ callback(data={'status': self.state})
+ raise
+
+ sigmas = infodict['uncertainties']
+
+ for i, param in enumerate(self.fit_results):
+ if param['code'] != 'IGNORE':
+ param['fitresult'] = params[i]
+ param['sigma'] = sigmas[i]
+
+ self.chisq = infodict["reduced_chisq"]
+ self.niter = infodict["niter"]
+ self.state = 'Ready'
+
+ if callback is not None:
+ callback(data={'chisq': self.chisq,
+ 'status': self.state})
+
+ return params, sigmas, infodict
+
+ ###################
+ # Private methods #
+ ###################
+ def fitfunction(self, x, *pars):
+ """Function to be fitted.
+
+ This is the sum of the selected background function plus
+ the selected fit model function.
+
+ :param x: Independent variable where the function is calculated.
+ :param pars: Sequence of all fit parameters. The first few parameters
+ are background parameters, then come the peak function parameters.
+ :return: Output of the fit function with ``x`` as input and ``pars``
+ as fit parameters.
+ """
+ result = numpy.zeros(numpy.shape(x), numpy.float)
+
+ if self.selectedbg is not None:
+ bg_pars_list = self.bgtheories[self.selectedbg].parameters
+ nb_bg_pars = len(bg_pars_list)
+
+ bgfun = self.bgtheories[self.selectedbg].function
+ result += bgfun(x, self.ydata, *pars[0:nb_bg_pars])
+ else:
+ nb_bg_pars = 0
+
+ selectedfun = self.theories[self.selectedtheory].function
+ result += selectedfun(x, *pars[nb_bg_pars:])
+
+ return result
+
+ def estimate_bkg(self, x, y):
+ """Estimate background parameters using the function defined in
+ the current fit configuration.
+
+ To change the selected background model, attribute :attr:`selectdbg`
+ must be changed using method :meth:`setbackground`.
+
+ The actual background function to be used is
+ referenced in :attr:`bgtheories`
+
+ :param x: Sequence of x data
+ :param y: sequence of y data
+ :return: Tuple of two sequences and one data array
+ ``(estimated_param, constraints, bg_data)``:
+
+ - ``estimated_param`` is a list of estimated values for each
+ background parameter.
+ - ``constraints`` is a 2D sequence of dimension ``(n_parameters, 3)``
+
+ - ``constraints[i][0]``: Constraint code.
+ See explanation about codes in :attr:`fit_results`
+
+ - ``constraints[i][1]``
+ See explanation about 'cons1' in :attr:`fit_results`
+ documentation.
+
+ - ``constraints[i][2]``
+ See explanation about 'cons2' in :attr:`fit_results`
+ documentation.
+ """
+ background_estimate_function = self.bgtheories[self.selectedbg].estimate
+ if background_estimate_function is not None:
+ return background_estimate_function(x, y)
+ else:
+ return [], []
+
+ def estimate_fun(self, x, y):
+ """Estimate fit parameters using the function defined in
+ the current fit configuration.
+
+ :param x: Sequence of x data
+ :param y: sequence of y data
+ :param bg: Background signal, to be subtracted from ``y`` before fitting.
+ :return: Tuple of two sequences ``(estimated_param, constraints)``:
+
+ - ``estimated_param`` is a list of estimated values for each
+ background parameter.
+ - ``constraints`` is a 2D sequence of dimension (n_parameters, 3)
+
+ - ``constraints[i][0]``: Constraint code.
+ See explanation about codes in :attr:`fit_results`
+
+ - ``constraints[i][1]``
+ See explanation about 'cons1' in :attr:`fit_results`
+ documentation.
+
+ - ``constraints[i][2]``
+ See explanation about 'cons2' in :attr:`fit_results`
+ documentation.
+ :raise: ``TypeError`` if estimation function is not callable
+
+ """
+ estimatefunction = self.theories[self.selectedtheory].estimate
+ if hasattr(estimatefunction, '__call__'):
+ if not self.theories[self.selectedtheory].pymca_legacy:
+ return estimatefunction(x, y)
+ else:
+ # legacy pymca estimate functions have a different signature
+ if self.fitconfig["fitbkg"] == "No Background":
+ bg = numpy.zeros_like(y)
+ else:
+ if self.fitconfig["SmoothingFlag"]:
+ y = smooth1d(y)
+ bg = strip(y,
+ w=self.fitconfig["StripWidth"],
+ niterations=self.fitconfig["StripIterations"],
+ factor=self.fitconfig["StripThresholdFactor"])
+ # fitconfig can be filled by user defined config function
+ xscaling = self.fitconfig.get('Xscaling', 1.0)
+ yscaling = self.fitconfig.get('Yscaling', 1.0)
+ return estimatefunction(x, y, bg, xscaling, yscaling)
+ else:
+ raise TypeError("Estimation function in attribute " +
+ "theories[%s]" % self.selectedtheory +
+ " must be callable.")
+
+ def _load_legacy_theories(self, theories_module):
+ """Load theories from a custom module in the old PyMca format.
+
+ See PyMca5.PyMcaMath.fitting.SpecfitFunctions for an example.
+ """
+ mandatory_attributes = ["THEORY", "PARAMETERS",
+ "FUNCTION", "ESTIMATE"]
+ err_msg = "Custom fit function file must define: "
+ err_msg += ", ".join(mandatory_attributes)
+ for attr in mandatory_attributes:
+ if not hasattr(theories_module, attr):
+ raise ImportError(err_msg)
+
+ derivative = theories_module.DERIVATIVE if hasattr(theories_module, "DERIVATIVE") else None
+ configure = theories_module.CONFIGURE if hasattr(theories_module, "CONFIGURE") else None
+ estimate = theories_module.ESTIMATE if hasattr(theories_module, "ESTIMATE") else None
+ if isinstance(theories_module.THEORY, (list, tuple)):
+ # multiple fit functions
+ for i in range(len(theories_module.THEORY)):
+ deriv = derivative[i] if derivative is not None else None
+ config = configure[i] if configure is not None else None
+ estim = estimate[i] if estimate is not None else None
+ self.addtheory(theories_module.THEORY[i],
+ FitTheory(
+ theories_module.FUNCTION[i],
+ theories_module.PARAMETERS[i],
+ estim,
+ config,
+ deriv,
+ pymca_legacy=True))
+ else:
+ # single fit function
+ self.addtheory(theories_module.THEORY,
+ FitTheory(
+ theories_module.FUNCTION,
+ theories_module.PARAMETERS,
+ estimate,
+ configure,
+ derivative,
+ pymca_legacy=True))
+
+
+def test():
+ from .functions import sum_gauss
+ from . import fittheories
+ from . import bgtheories
+
+ # Create synthetic data with a sum of gaussian functions
+ x = numpy.arange(1000).astype(numpy.float)
+
+ p = [1000, 100., 250,
+ 255, 690., 45,
+ 1500, 800.5, 95]
+ y = 0.5 * x + 13 + sum_gauss(x, *p)
+
+ # Fitting
+ fit = FitManager()
+ # more sensitivity necessary to resolve
+ # overlapping peaks at x=690 and x=800.5
+ fit.setdata(x=x, y=y)
+ fit.loadtheories(fittheories)
+ fit.settheory('Gaussians')
+ fit.loadbgtheories(bgtheories)
+ fit.setbackground('Linear')
+ fit.estimate()
+ fit.runfit()
+
+ print("Searched parameters = ", 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)
+
+ # Plot
+ constant, slope = dummy_list[:2]
+ p1 = dummy_list[2:]
+ print(p1)
+ y2 = slope * x + constant + sum_gauss(x, *p1)
+
+ try:
+ from silx.gui import qt
+ from silx.gui.plot.PlotWindow import PlotWindow
+ app = qt.QApplication([])
+ pw = PlotWindow(control=True)
+ pw.addCurve(x, y, "Original")
+ pw.addCurve(x, y2, "Fit result")
+ pw.legendsDockWidget.show()
+ pw.show()
+ app.exec_()
+ except ImportError:
+ _logger.warning("Could not import qt to display fit result as curve")
+
+
+if __name__ == "__main__":
+ test()
diff --git a/silx/math/fit/fittheories.py b/silx/math/fit/fittheories.py
new file mode 100644
index 0000000..bd3e1ce
--- /dev/null
+++ b/silx/math/fit/fittheories.py
@@ -0,0 +1,1374 @@
+# coding: utf-8
+#/*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+########################################################################### */
+"""This modules provides a set of fit functions and associated
+estimation functions in a format that can be imported into a
+:class:`silx.math.fit.FitManager` instance.
+
+These functions are well suited for fitting multiple gaussian shaped peaks
+typically found in spectroscopy data. The estimation functions are designed
+to detect how many peaks are present in the data, and provide an initial
+estimate for their height, their center location and their full-width
+at half maximum (fwhm).
+
+The limitation of these estimation algorithms is that only gaussians having a
+similar fwhm can be detected by the peak search algorithm.
+This *search fwhm* can be defined by the user, if
+he knows the characteristics of his data, or can be automatically estimated
+based on the fwhm of the largest peak in the data.
+
+The source code of this module can serve as template for defining your own
+fit functions.
+
+The functions to be imported by :meth:`FitManager.loadtheories` are defined by
+a dictionary :const:`THEORY`: with the following structure::
+
+ from silx.math.fit.fittheory import FitTheory
+
+ THEORY = {
+ 'theory_name_1': FitTheory(
+ description='Description of theory 1',
+ function=fitfunction1,
+ parameters=('param name 1', 'param name 2', …),
+ estimate=estimation_function1,
+ configure=configuration_function1,
+ derivative=derivative_function1),
+
+ 'theory_name_2': FitTheory(…),
+ }
+
+.. note::
+
+ Consider using an OrderedDict instead of a regular dictionary, when
+ defining your own theory dictionary, if the order matters to you.
+ This will likely be the case if you intend to load a selection of
+ functions in a GUI such as :class:`silx.gui.fit.FitManager`.
+
+Theory names can be customized (e.g. ``gauss, lorentz, splitgauss``…).
+
+The mandatory parameters for :class:`FitTheory` are ``function`` and
+``parameters``.
+
+You can also define an ``INIT`` function that will be executed by
+:meth:`FitManager.loadtheories`.
+
+See the documentation of :class:`silx.math.fit.fittheory.FitTheory`
+for more information.
+
+Module members:
+---------------
+"""
+import numpy
+from collections import OrderedDict
+import logging
+
+from silx.math.fit import functions
+from silx.math.fit.peaks import peak_search, guess_fwhm
+from silx.math.fit.filters import strip, savitsky_golay
+from silx.math.fit.leastsq import leastsq
+from silx.math.fit.fittheory import FitTheory
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+__authors__ = ["V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "06/01/2017"
+
+
+DEFAULT_CONFIG = {
+ 'NoConstraintsFlag': False,
+ 'PositiveFwhmFlag': True,
+ 'PositiveHeightAreaFlag': True,
+ 'SameFwhmFlag': False,
+ 'QuotedPositionFlag': False, # peak not outside data range
+ 'QuotedEtaFlag': False, # force 0 < eta < 1
+ # Peak detection
+ 'AutoScaling': False,
+ 'Yscaling': 1.0,
+ 'FwhmPoints': 8,
+ 'AutoFwhm': True,
+ 'Sensitivity': 2.5,
+ 'ForcePeakPresence': True,
+ # Hypermet
+ 'HypermetTails': 15,
+ 'QuotedFwhmFlag': 0,
+ 'MaxFwhm2InputRatio': 1.5,
+ 'MinFwhm2InputRatio': 0.4,
+ # short tail parameters
+ 'MinGaussArea4ShortTail': 50000.,
+ 'InitialShortTailAreaRatio': 0.050,
+ 'MaxShortTailAreaRatio': 0.100,
+ 'MinShortTailAreaRatio': 0.0010,
+ 'InitialShortTailSlopeRatio': 0.70,
+ 'MaxShortTailSlopeRatio': 2.00,
+ 'MinShortTailSlopeRatio': 0.50,
+ # long tail parameters
+ 'MinGaussArea4LongTail': 1000.0,
+ 'InitialLongTailAreaRatio': 0.050,
+ 'MaxLongTailAreaRatio': 0.300,
+ 'MinLongTailAreaRatio': 0.010,
+ 'InitialLongTailSlopeRatio': 20.0,
+ 'MaxLongTailSlopeRatio': 50.0,
+ 'MinLongTailSlopeRatio': 5.0,
+ # step tail
+ 'MinGaussHeight4StepTail': 5000.,
+ 'InitialStepTailHeightRatio': 0.002,
+ 'MaxStepTailHeightRatio': 0.0100,
+ 'MinStepTailHeightRatio': 0.0001,
+ # Hypermet constraints
+ # position in range [estimated position +- estimated fwhm/2]
+ 'HypermetQuotedPositionFlag': True,
+ 'DeltaPositionFwhmUnits': 0.5,
+ 'SameSlopeRatioFlag': 1,
+ 'SameAreaRatioFlag': 1,
+ # Strip bg removal
+ 'StripBackgroundFlag': True,
+ 'SmoothingFlag': True,
+ 'SmoothingWidth': 5,
+ 'StripWidth': 2,
+ 'StripIterations': 5000,
+ 'StripThresholdFactor': 1.0}
+"""This dictionary defines default configuration parameters that have effects
+on fit functions and estimation functions, mainly on fit constraints.
+This dictionary is accessible as attribute :attr:`FitTheories.config`,
+which can be modified by configuration functions defined in
+:const:`CONFIGURE`.
+"""
+
+CFREE = 0
+CPOSITIVE = 1
+CQUOTED = 2
+CFIXED = 3
+CFACTOR = 4
+CDELTA = 5
+CSUM = 6
+CIGNORED = 7
+
+
+class FitTheories(object):
+ """Class wrapping functions from :class:`silx.math.fit.functions`
+ and providing estimate functions for all of these fit functions."""
+ def __init__(self, config=None):
+ if config is None:
+ self.config = DEFAULT_CONFIG
+ else:
+ self.config = config
+
+ def ahypermet(self, x, *pars):
+ """
+ Wrapping of :func:`silx.math.fit.functions.sum_ahypermet` without
+ the tail flags in the function signature.
+
+ Depending on the value of `self.config['HypermetTails']`, one can
+ activate or deactivate the various terms of the hypermet function.
+
+ `self.config['HypermetTails']` must be an integer between 0 and 15.
+ It is a set of 4 binary flags, one for activating each one of the
+ hypermet terms: *gaussian function, short tail, long tail, step*.
+
+ For example, 15 can be expressed as ``1111`` in base 2, so a flag of
+ 15 means all terms are active.
+ """
+ g_term = self.config['HypermetTails'] & 1
+ st_term = (self.config['HypermetTails'] >> 1) & 1
+ lt_term = (self.config['HypermetTails'] >> 2) & 1
+ step_term = (self.config['HypermetTails'] >> 3) & 1
+ return functions.sum_ahypermet(x, *pars,
+ gaussian_term=g_term, st_term=st_term,
+ lt_term=lt_term, step_term=step_term)
+
+ def poly(self, x, *pars):
+ """Order n polynomial.
+ The order of the polynomial is defined by the number of
+ coefficients (``*pars``).
+
+ """
+ p = numpy.poly1d(pars)
+ return p(x)
+
+ @staticmethod
+ def estimate_poly(x, y, n=2):
+ """Estimate polynomial coefficients for a degree n polynomial.
+
+ """
+ pcoeffs = numpy.polyfit(x, y, n)
+ constraints = numpy.zeros((n + 1, 3), numpy.float)
+ return pcoeffs, constraints
+
+ def estimate_quadratic(self, x, y):
+ """Estimate quadratic coefficients
+
+ """
+ return self.estimate_poly(x, y, n=2)
+
+ def estimate_cubic(self, x, y):
+ """Estimate coefficients for a degree 3 polynomial
+
+ """
+ return self.estimate_poly(x, y, n=3)
+
+ def estimate_quartic(self, x, y):
+ """Estimate coefficients for a degree 4 polynomial
+
+ """
+ return self.estimate_poly(x, y, n=4)
+
+ def estimate_quintic(self, x, y):
+ """Estimate coefficients for a degree 5 polynomial
+
+ """
+ return self.estimate_poly(x, y, n=5)
+
+ def strip_bg(self, y):
+ """Return the strip background of y, using parameters from
+ :attr:`config` dictionary (*StripBackgroundFlag, StripWidth,
+ StripIterations, StripThresholdFactor*)"""
+ remove_strip_bg = self.config.get('StripBackgroundFlag', False)
+ if remove_strip_bg:
+ if self.config['SmoothingFlag']:
+ y = savitsky_golay(y, self.config['SmoothingWidth'])
+ strip_width = self.config['StripWidth']
+ strip_niterations = self.config['StripIterations']
+ strip_thr_factor = self.config['StripThresholdFactor']
+ return strip(y, w=strip_width,
+ niterations=strip_niterations,
+ factor=strip_thr_factor)
+ else:
+ return numpy.zeros_like(y)
+
+ def guess_yscaling(self, y):
+ """Estimate scaling for y prior to peak search.
+ A smoothing filter is applied to y to estimate the noise level
+ (chi-squared)
+
+ :param y: Data array
+ :return: Scaling factor
+ """
+ # ensure y is an array
+ yy = numpy.array(y, copy=False)
+
+ # smooth
+ convolution_kernel = numpy.ones(shape=(3,)) / 3.
+ ysmooth = numpy.convolve(y, convolution_kernel, mode="same")
+
+ # remove zeros
+ idx_array = numpy.fabs(y) > 0.0
+ yy = yy[idx_array]
+ ysmooth = ysmooth[idx_array]
+
+ # compute scaling factor
+ chisq = numpy.mean((yy - ysmooth)**2 / numpy.fabs(yy))
+ if chisq > 0:
+ return 1. / chisq
+ else:
+ return 1.0
+
+ def peak_search(self, y, fwhm, sensitivity):
+ """Search for peaks in y array, after padding the array and
+ multiplying its value by a scaling factor.
+
+ :param y: 1-D data array
+ :param int fwhm: Typical full width at half maximum for peaks,
+ in number of points. This parameter is used for to discriminate between
+ true peaks and background fluctuations.
+ :param float sensitivity: Sensitivity parameter. This is a threshold factor
+ for peak detection. Only peaks larger than the standard deviation
+ of the noise multiplied by this sensitivity parameter are detected.
+ :return: List of peak indices
+ """
+ # add padding
+ ysearch = numpy.ones((len(y) + 2 * fwhm,), numpy.float)
+ ysearch[0:fwhm] = y[0]
+ ysearch[-1:-fwhm - 1:-1] = y[len(y)-1]
+ ysearch[fwhm:fwhm + len(y)] = y[:]
+
+ scaling = self.guess_yscaling(y) if self.config["AutoScaling"] else self.config["Yscaling"]
+
+ if len(ysearch) > 1.5 * fwhm:
+ peaks = peak_search(scaling * ysearch,
+ fwhm=fwhm, sensitivity=sensitivity)
+ return [peak_index - fwhm for peak_index in peaks
+ if 0 <= peak_index - fwhm < len(y)]
+ else:
+ return []
+
+ def estimate_height_position_fwhm(self, x, y):
+ """Estimation of *Height, Position, FWHM* of peaks, for gaussian-like
+ curves.
+
+ This functions finds how many parameters are needed, based on the
+ number of peaks detected. Then it estimates the fit parameters
+ with a few iterations of fitting gaussian functions.
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each peak are:
+ *Height, Position, FWHM*.
+ Fit constraints depend on :attr:`config`.
+ """
+ fittedpar = []
+
+ bg = self.strip_bg(y)
+
+ if self.config['AutoFwhm']:
+ search_fwhm = guess_fwhm(y)
+ else:
+ search_fwhm = int(float(self.config['FwhmPoints']))
+ search_sens = float(self.config['Sensitivity'])
+
+ if search_fwhm < 3:
+ _logger.warning("Setting peak fwhm to 3 (lower limit)")
+ search_fwhm = 3
+ self.config['FwhmPoints'] = 3
+
+ if search_sens < 1:
+ _logger.warning("Setting peak search sensitivity to 1. " +
+ "(lower limit to filter out noise peaks)")
+ search_sens = 1
+ self.config['Sensitivity'] = 1
+
+ npoints = len(y)
+
+ # Find indices of peaks in data array
+ peaks = self.peak_search(y,
+ fwhm=search_fwhm,
+ sensitivity=search_sens)
+
+ if not len(peaks):
+ forcepeak = int(float(self.config.get('ForcePeakPresence', 0)))
+ if forcepeak:
+ delta = y - bg
+ # get index of global maximum
+ # (first one if several samples are equal to this value)
+ peaks = [numpy.nonzero(delta == delta.max())[0][0]]
+
+ # Find index of largest peak in peaks array
+ index_largest_peak = 0
+ if len(peaks) > 0:
+ # estimate fwhm as 5 * sampling interval
+ sig = 5 * abs(x[npoints - 1] - x[0]) / npoints
+ peakpos = x[int(peaks[0])]
+ if abs(peakpos) < 1.0e-16:
+ peakpos = 0.0
+ param = numpy.array(
+ [y[int(peaks[0])] - bg[int(peaks[0])], peakpos, sig])
+ height_largest_peak = param[0]
+ peak_index = 1
+ for i in peaks[1:]:
+ param2 = numpy.array(
+ [y[int(i)] - bg[int(i)], x[int(i)], sig])
+ param = numpy.concatenate((param, param2))
+ if param2[0] > height_largest_peak:
+ height_largest_peak = param2[0]
+ index_largest_peak = peak_index
+ peak_index += 1
+
+ # Subtract background
+ xw = x
+ yw = y - bg
+
+ cons = numpy.zeros((len(param), 3), numpy.float)
+
+ # peak height must be positive
+ cons[0:len(param):3, 0] = CPOSITIVE
+ # force peaks to stay around their position
+ cons[1:len(param):3, 0] = CQUOTED
+
+ # set possible peak range to estimated peak +- guessed fwhm
+ if len(xw) > search_fwhm:
+ fwhmx = numpy.fabs(xw[int(search_fwhm)] - xw[0])
+ cons[1:len(param):3, 1] = param[1:len(param):3] - 0.5 * fwhmx
+ cons[1:len(param):3, 2] = param[1:len(param):3] + 0.5 * fwhmx
+ else:
+ cons[1:len(param):3, 1] = min(xw) * numpy.ones(
+ (param[1:len(param):3]),
+ numpy.float)
+ cons[1:len(param):3, 2] = max(xw) * numpy.ones(
+ (param[1:len(param):3]),
+ numpy.float)
+
+ # ensure fwhm is positive
+ cons[2:len(param):3, 0] = CPOSITIVE
+
+ # run a quick iterative fit (4 iterations) to improve
+ # estimations
+ fittedpar, _, _ = leastsq(functions.sum_gauss, xw, yw, param,
+ max_iter=4, constraints=cons.tolist(),
+ full_output=True)
+
+ # set final constraints based on config parameters
+ cons = numpy.zeros((len(fittedpar), 3), numpy.float)
+ peak_index = 0
+ for i in range(len(peaks)):
+ # Setup height area constrains
+ if not self.config['NoConstraintsFlag']:
+ if self.config['PositiveHeightAreaFlag']:
+ cons[peak_index, 0] = CPOSITIVE
+ cons[peak_index, 1] = 0
+ cons[peak_index, 2] = 0
+ peak_index += 1
+
+ # Setup position constrains
+ if not self.config['NoConstraintsFlag']:
+ if self.config['QuotedPositionFlag']:
+ cons[peak_index, 0] = CQUOTED
+ cons[peak_index, 1] = min(x)
+ cons[peak_index, 2] = max(x)
+ peak_index += 1
+
+ # Setup positive FWHM constrains
+ if not self.config['NoConstraintsFlag']:
+ if self.config['PositiveFwhmFlag']:
+ cons[peak_index, 0] = CPOSITIVE
+ cons[peak_index, 1] = 0
+ cons[peak_index, 2] = 0
+ if self.config['SameFwhmFlag']:
+ if i != index_largest_peak:
+ cons[peak_index, 0] = CFACTOR
+ cons[peak_index, 1] = 3 * index_largest_peak + 2
+ cons[peak_index, 2] = 1.0
+ peak_index += 1
+
+ return fittedpar, cons
+
+ def estimate_agauss(self, x, y):
+ """Estimation of *Area, Position, FWHM* of peaks, for gaussian-like
+ curves.
+
+ This functions uses :meth:`estimate_height_position_fwhm`, then
+ converts the height parameters to area under the curve with the
+ formula ``area = sqrt(2*pi) * height * fwhm / (2 * sqrt(2 * log(2))``
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each peak are:
+ *Area, Position, FWHM*.
+ Fit constraints depend on :attr:`config`.
+ """
+ fittedpar, cons = self.estimate_height_position_fwhm(x, y)
+ # get the number of found peaks
+ npeaks = len(fittedpar) // 3
+ for i in range(npeaks):
+ height = fittedpar[3 * i]
+ fwhm = fittedpar[3 * i + 2]
+ # Replace height with area in fittedpar
+ fittedpar[3 * i] = numpy.sqrt(2 * numpy.pi) * height * fwhm / (
+ 2.0 * numpy.sqrt(2 * numpy.log(2)))
+ return fittedpar, cons
+
+ def estimate_alorentz(self, x, y):
+ """Estimation of *Area, Position, FWHM* of peaks, for Lorentzian
+ curves.
+
+ This functions uses :meth:`estimate_height_position_fwhm`, then
+ converts the height parameters to area under the curve with the
+ formula ``area = height * fwhm * 0.5 * pi``
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each peak are:
+ *Area, Position, FWHM*.
+ Fit constraints depend on :attr:`config`.
+ """
+ fittedpar, cons = self.estimate_height_position_fwhm(x, y)
+ # get the number of found peaks
+ npeaks = len(fittedpar) // 3
+ for i in range(npeaks):
+ height = fittedpar[3 * i]
+ fwhm = fittedpar[3 * i + 2]
+ # Replace height with area in fittedpar
+ fittedpar[3 * i] = (height * fwhm * 0.5 * numpy.pi)
+ return fittedpar, cons
+
+ def estimate_splitgauss(self, x, y):
+ """Estimation of *Height, Position, FWHM1, FWHM2* of peaks, for
+ asymmetric gaussian-like curves.
+
+ This functions uses :meth:`estimate_height_position_fwhm`, then
+ adds a second (identical) estimation of FWHM to the fit parameters
+ for each peak, and the corresponding constraint.
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each peak are:
+ *Height, Position, FWHM1, FWHM2*.
+ Fit constraints depend on :attr:`config`.
+ """
+ fittedpar, cons = self.estimate_height_position_fwhm(x, y)
+ # get the number of found peaks
+ npeaks = len(fittedpar) // 3
+ estimated_parameters = []
+ estimated_constraints = numpy.zeros((4 * npeaks, 3), numpy.float)
+ for i in range(npeaks):
+ for j in range(3):
+ estimated_parameters.append(fittedpar[3 * i + j])
+ # fwhm2 estimate = fwhm1
+ estimated_parameters.append(fittedpar[3 * i + 2])
+ # height
+ estimated_constraints[4 * i, 0] = cons[3 * i, 0]
+ estimated_constraints[4 * i, 1] = cons[3 * i, 1]
+ estimated_constraints[4 * i, 2] = cons[3 * i, 2]
+ # position
+ estimated_constraints[4 * i + 1, 0] = cons[3 * i + 1, 0]
+ estimated_constraints[4 * i + 1, 1] = cons[3 * i + 1, 1]
+ estimated_constraints[4 * i + 1, 2] = cons[3 * i + 1, 2]
+ # fwhm1
+ estimated_constraints[4 * i + 2, 0] = cons[3 * i + 2, 0]
+ estimated_constraints[4 * i + 2, 1] = cons[3 * i + 2, 1]
+ estimated_constraints[4 * i + 2, 2] = cons[3 * i + 2, 2]
+ # fwhm2
+ estimated_constraints[4 * i + 3, 0] = cons[3 * i + 2, 0]
+ estimated_constraints[4 * i + 3, 1] = cons[3 * i + 2, 1]
+ estimated_constraints[4 * i + 3, 2] = cons[3 * i + 2, 2]
+ if cons[3 * i + 2, 0] == CFACTOR:
+ # convert indices of related parameters
+ # (this happens if SameFwhmFlag == True)
+ estimated_constraints[4 * i + 2, 1] = \
+ int(cons[3 * i + 2, 1] / 3) * 4 + 2
+ estimated_constraints[4 * i + 3, 1] = \
+ int(cons[3 * i + 2, 1] / 3) * 4 + 3
+ return estimated_parameters, estimated_constraints
+
+ def estimate_pvoigt(self, x, y):
+ """Estimation of *Height, Position, FWHM, eta* of peaks, for
+ pseudo-Voigt curves.
+
+ Pseudo-Voigt are a sum of a gaussian curve *G(x)* and a lorentzian
+ curve *L(x)* with the same height, center, fwhm parameters:
+ ``y(x) = eta * G(x) + (1-eta) * L(x)``
+
+ This functions uses :meth:`estimate_height_position_fwhm`, then
+ adds a constant estimation of *eta* (0.5) to the fit parameters
+ for each peak, and the corresponding constraint.
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each peak are:
+ *Height, Position, FWHM, eta*.
+ Constraint for the eta parameter can be set to QUOTED (0.--1.)
+ by setting :attr:`config`['QuotedEtaFlag'] to ``True``.
+ If this is not the case, the constraint code is set to FREE.
+ """
+ fittedpar, cons = self.estimate_height_position_fwhm(x, y)
+ npeaks = len(fittedpar) // 3
+ newpar = []
+ newcons = numpy.zeros((4 * npeaks, 3), numpy.float)
+ # find out related parameters proper index
+ if not self.config['NoConstraintsFlag']:
+ if self.config['SameFwhmFlag']:
+ j = 0
+ # get the index of the free FWHM
+ for i in range(npeaks):
+ if cons[3 * i + 2, 0] != 4:
+ j = i
+ for i in range(npeaks):
+ if i != j:
+ cons[3 * i + 2, 1] = 4 * j + 2
+ for i in range(npeaks):
+ newpar.append(fittedpar[3 * i])
+ newpar.append(fittedpar[3 * i + 1])
+ newpar.append(fittedpar[3 * i + 2])
+ newpar.append(0.5)
+ # height
+ newcons[4 * i, 0] = cons[3 * i, 0]
+ newcons[4 * i, 1] = cons[3 * i, 1]
+ newcons[4 * i, 2] = cons[3 * i, 2]
+ # position
+ newcons[4 * i + 1, 0] = cons[3 * i + 1, 0]
+ newcons[4 * i + 1, 1] = cons[3 * i + 1, 1]
+ newcons[4 * i + 1, 2] = cons[3 * i + 1, 2]
+ # fwhm
+ newcons[4 * i + 2, 0] = cons[3 * i + 2, 0]
+ newcons[4 * i + 2, 1] = cons[3 * i + 2, 1]
+ newcons[4 * i + 2, 2] = cons[3 * i + 2, 2]
+ # Eta constrains
+ newcons[4 * i + 3, 0] = CFREE
+ newcons[4 * i + 3, 1] = 0
+ newcons[4 * i + 3, 2] = 0
+ if self.config['QuotedEtaFlag']:
+ newcons[4 * i + 3, 0] = CQUOTED
+ newcons[4 * i + 3, 1] = 0.0
+ newcons[4 * i + 3, 2] = 1.0
+ return newpar, newcons
+
+ def estimate_splitpvoigt(self, x, y):
+ """Estimation of *Height, Position, FWHM1, FWHM2, eta* of peaks, for
+ asymmetric pseudo-Voigt curves.
+
+ This functions uses :meth:`estimate_height_position_fwhm`, then
+ adds an identical FWHM2 parameter and a constant estimation of
+ *eta* (0.5) to the fit parameters for each peak, and the corresponding
+ constraints.
+
+ Constraint for the eta parameter can be set to QUOTED (0.--1.)
+ by setting :attr:`config`['QuotedEtaFlag'] to ``True``.
+ If this is not the case, the constraint code is set to FREE.
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each peak are:
+ *Height, Position, FWHM1, FWHM2, eta*.
+ """
+ fittedpar, cons = self.estimate_height_position_fwhm(x, y)
+ npeaks = len(fittedpar) // 3
+ newpar = []
+ newcons = numpy.zeros((5 * npeaks, 3), numpy.float)
+ # find out related parameters proper index
+ if not self.config['NoConstraintsFlag']:
+ if self.config['SameFwhmFlag']:
+ j = 0
+ # get the index of the free FWHM
+ for i in range(npeaks):
+ if cons[3 * i + 2, 0] != 4:
+ j = i
+ for i in range(npeaks):
+ if i != j:
+ cons[3 * i + 2, 1] = 4 * j + 2
+ for i in range(npeaks):
+ # height
+ newpar.append(fittedpar[3 * i])
+ # position
+ newpar.append(fittedpar[3 * i + 1])
+ # fwhm1
+ newpar.append(fittedpar[3 * i + 2])
+ # fwhm2 estimate equal to fwhm1
+ newpar.append(fittedpar[3 * i + 2])
+ # eta
+ newpar.append(0.5)
+ # constraint codes
+ # ----------------
+ # height
+ newcons[5 * i, 0] = cons[3 * i, 0]
+ # position
+ newcons[5 * i + 1, 0] = cons[3 * i + 1, 0]
+ # fwhm1
+ newcons[5 * i + 2, 0] = cons[3 * i + 2, 0]
+ # fwhm2
+ newcons[5 * i + 3, 0] = cons[3 * i + 2, 0]
+ # cons 1
+ # ------
+ newcons[5 * i, 1] = cons[3 * i, 1]
+ newcons[5 * i + 1, 1] = cons[3 * i + 1, 1]
+ newcons[5 * i + 2, 1] = cons[3 * i + 2, 1]
+ newcons[5 * i + 3, 1] = cons[3 * i + 2, 1]
+ # cons 2
+ # ------
+ newcons[5 * i, 2] = cons[3 * i, 2]
+ newcons[5 * i + 1, 2] = cons[3 * i + 1, 2]
+ newcons[5 * i + 2, 2] = cons[3 * i + 2, 2]
+ newcons[5 * i + 3, 2] = cons[3 * i + 2, 2]
+
+ if cons[3 * i + 2, 0] == CFACTOR:
+ # fwhm2 connstraint depends on fwhm1
+ newcons[5 * i + 3, 1] = newcons[5 * i + 2, 1] + 1
+ # eta constraints
+ newcons[5 * i + 4, 0] = CFREE
+ newcons[5 * i + 4, 1] = 0
+ newcons[5 * i + 4, 2] = 0
+ if self.config['QuotedEtaFlag']:
+ newcons[5 * i + 4, 0] = CQUOTED
+ newcons[5 * i + 4, 1] = 0.0
+ newcons[5 * i + 4, 2] = 1.0
+ return newpar, newcons
+
+ def estimate_apvoigt(self, x, y):
+ """Estimation of *Area, Position, FWHM1, eta* of peaks, for
+ pseudo-Voigt curves.
+
+ This functions uses :meth:`estimate_pvoigt`, then converts the height
+ parameter to area.
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each peak are:
+ *Area, Position, FWHM, eta*.
+ """
+ fittedpar, cons = self.estimate_pvoigt(x, y)
+ npeaks = len(fittedpar) // 4
+ # Assume 50% of the area is determined by the gaussian and 50% by
+ # the Lorentzian.
+ for i in range(npeaks):
+ height = fittedpar[4 * i]
+ fwhm = fittedpar[4 * i + 2]
+ fittedpar[4 * i] = 0.5 * (height * fwhm * 0.5 * numpy.pi) +\
+ 0.5 * (height * fwhm / (2.0 * numpy.sqrt(2 * numpy.log(2)))
+ ) * numpy.sqrt(2 * numpy.pi)
+ return fittedpar, cons
+
+ def estimate_ahypermet(self, x, y):
+ """Estimation of *area, position, fwhm, st_area_r, st_slope_r,
+ lt_area_r, lt_slope_r, step_height_r* of peaks, for hypermet curves.
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each peak are:
+ *area, position, fwhm, st_area_r, st_slope_r,
+ lt_area_r, lt_slope_r, step_height_r* .
+ """
+ yscaling = self.config.get('Yscaling', 1.0)
+ if yscaling == 0:
+ yscaling = 1.0
+ fittedpar, cons = self.estimate_height_position_fwhm(x, y)
+ npeaks = len(fittedpar) // 3
+ newpar = []
+ newcons = numpy.zeros((8 * npeaks, 3), numpy.float)
+ main_peak = 0
+ # find out related parameters proper index
+ if not self.config['NoConstraintsFlag']:
+ if self.config['SameFwhmFlag']:
+ j = 0
+ # get the index of the free FWHM
+ for i in range(npeaks):
+ if cons[3 * i + 2, 0] != 4:
+ j = i
+ for i in range(npeaks):
+ if i != j:
+ cons[3 * i + 2, 1] = 8 * j + 2
+ main_peak = j
+ for i in range(npeaks):
+ if fittedpar[3 * i] > fittedpar[3 * main_peak]:
+ main_peak = i
+
+ for i in range(npeaks):
+ height = fittedpar[3 * i]
+ position = fittedpar[3 * i + 1]
+ fwhm = fittedpar[3 * i + 2]
+ area = (height * fwhm / (2.0 * numpy.sqrt(2 * numpy.log(2)))
+ ) * numpy.sqrt(2 * numpy.pi)
+ # the gaussian parameters
+ newpar.append(area)
+ newpar.append(position)
+ newpar.append(fwhm)
+ # print "area, pos , fwhm = ",area,position,fwhm
+ # Avoid zero derivatives because of not calculating contribution
+ g_term = 1
+ st_term = 1
+ lt_term = 1
+ step_term = 1
+ if self.config['HypermetTails'] != 0:
+ g_term = self.config['HypermetTails'] & 1
+ st_term = (self.config['HypermetTails'] >> 1) & 1
+ lt_term = (self.config['HypermetTails'] >> 2) & 1
+ step_term = (self.config['HypermetTails'] >> 3) & 1
+ if g_term == 0:
+ # fix the gaussian parameters
+ newcons[8 * i, 0] = CFIXED
+ newcons[8 * i + 1, 0] = CFIXED
+ newcons[8 * i + 2, 0] = CFIXED
+ # the short tail parameters
+ if ((area * yscaling) <
+ self.config['MinGaussArea4ShortTail']) | \
+ (st_term == 0):
+ newpar.append(0.0)
+ newpar.append(0.0)
+ newcons[8 * i + 3, 0] = CFIXED
+ newcons[8 * i + 3, 1] = 0.0
+ newcons[8 * i + 3, 2] = 0.0
+ newcons[8 * i + 4, 0] = CFIXED
+ newcons[8 * i + 4, 1] = 0.0
+ newcons[8 * i + 4, 2] = 0.0
+ else:
+ newpar.append(self.config['InitialShortTailAreaRatio'])
+ newpar.append(self.config['InitialShortTailSlopeRatio'])
+ newcons[8 * i + 3, 0] = CQUOTED
+ newcons[8 * i + 3, 1] = self.config['MinShortTailAreaRatio']
+ newcons[8 * i + 3, 2] = self.config['MaxShortTailAreaRatio']
+ newcons[8 * i + 4, 0] = CQUOTED
+ newcons[8 * i + 4, 1] = self.config['MinShortTailSlopeRatio']
+ newcons[8 * i + 4, 2] = self.config['MaxShortTailSlopeRatio']
+ # the long tail parameters
+ if ((area * yscaling) <
+ self.config['MinGaussArea4LongTail']) | \
+ (lt_term == 0):
+ newpar.append(0.0)
+ newpar.append(0.0)
+ newcons[8 * i + 5, 0] = CFIXED
+ newcons[8 * i + 5, 1] = 0.0
+ newcons[8 * i + 5, 2] = 0.0
+ newcons[8 * i + 6, 0] = CFIXED
+ newcons[8 * i + 6, 1] = 0.0
+ newcons[8 * i + 6, 2] = 0.0
+ else:
+ newpar.append(self.config['InitialLongTailAreaRatio'])
+ newpar.append(self.config['InitialLongTailSlopeRatio'])
+ newcons[8 * i + 5, 0] = CQUOTED
+ newcons[8 * i + 5, 1] = self.config['MinLongTailAreaRatio']
+ newcons[8 * i + 5, 2] = self.config['MaxLongTailAreaRatio']
+ newcons[8 * i + 6, 0] = CQUOTED
+ newcons[8 * i + 6, 1] = self.config['MinLongTailSlopeRatio']
+ newcons[8 * i + 6, 2] = self.config['MaxLongTailSlopeRatio']
+ # the step parameters
+ if ((height * yscaling) <
+ self.config['MinGaussHeight4StepTail']) | \
+ (step_term == 0):
+ newpar.append(0.0)
+ newcons[8 * i + 7, 0] = CFIXED
+ newcons[8 * i + 7, 1] = 0.0
+ newcons[8 * i + 7, 2] = 0.0
+ else:
+ newpar.append(self.config['InitialStepTailHeightRatio'])
+ newcons[8 * i + 7, 0] = CQUOTED
+ newcons[8 * i + 7, 1] = self.config['MinStepTailHeightRatio']
+ newcons[8 * i + 7, 2] = self.config['MaxStepTailHeightRatio']
+ # if self.config['NoConstraintsFlag'] == 1:
+ # newcons=numpy.zeros((8*npeaks, 3),numpy.float)
+ if npeaks > 0:
+ if g_term:
+ if self.config['PositiveHeightAreaFlag']:
+ for i in range(npeaks):
+ newcons[8 * i, 0] = CPOSITIVE
+ if self.config['PositiveFwhmFlag']:
+ for i in range(npeaks):
+ newcons[8 * i + 2, 0] = CPOSITIVE
+ if self.config['SameFwhmFlag']:
+ for i in range(npeaks):
+ if i != main_peak:
+ newcons[8 * i + 2, 0] = CFACTOR
+ newcons[8 * i + 2, 1] = 8 * main_peak + 2
+ newcons[8 * i + 2, 2] = 1.0
+ if self.config['HypermetQuotedPositionFlag']:
+ for i in range(npeaks):
+ delta = self.config['DeltaPositionFwhmUnits'] * fwhm
+ newcons[8 * i + 1, 0] = CQUOTED
+ newcons[8 * i + 1, 1] = newpar[8 * i + 1] - delta
+ newcons[8 * i + 1, 2] = newpar[8 * i + 1] + delta
+ if self.config['SameSlopeRatioFlag']:
+ for i in range(npeaks):
+ if i != main_peak:
+ newcons[8 * i + 4, 0] = CFACTOR
+ newcons[8 * i + 4, 1] = 8 * main_peak + 4
+ newcons[8 * i + 4, 2] = 1.0
+ newcons[8 * i + 6, 0] = CFACTOR
+ newcons[8 * i + 6, 1] = 8 * main_peak + 6
+ newcons[8 * i + 6, 2] = 1.0
+ if self.config['SameAreaRatioFlag']:
+ for i in range(npeaks):
+ if i != main_peak:
+ newcons[8 * i + 3, 0] = CFACTOR
+ newcons[8 * i + 3, 1] = 8 * main_peak + 3
+ newcons[8 * i + 3, 2] = 1.0
+ newcons[8 * i + 5, 0] = CFACTOR
+ newcons[8 * i + 5, 1] = 8 * main_peak + 5
+ newcons[8 * i + 5, 2] = 1.0
+ return newpar, newcons
+
+ def estimate_stepdown(self, x, y):
+ """Estimation of parameters for stepdown curves.
+
+ The functions estimates gaussian parameters for the derivative of
+ the data, takes the largest gaussian peak and uses its estimated
+ parameters to define the center of the step and its fwhm. The
+ estimated amplitude returned is simply ``max(y) - min(y)``.
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit newconstraints.
+ Parameters to be estimated for each stepdown are:
+ *height, centroid, fwhm* .
+ """
+ crappyfilter = [-0.25, -0.75, 0.0, 0.75, 0.25]
+ cutoff = len(crappyfilter) // 2
+ y_deriv = numpy.convolve(y,
+ crappyfilter,
+ mode="valid")
+
+ # make the derivative's peak have the same amplitude as the step
+ if max(y_deriv) > 0:
+ y_deriv = y_deriv * max(y) / max(y_deriv)
+
+ fittedpar, newcons = self.estimate_height_position_fwhm(
+ x[cutoff:-cutoff], y_deriv)
+
+ data_amplitude = max(y) - min(y)
+
+ # use parameters from largest gaussian found
+ if len(fittedpar):
+ npeaks = len(fittedpar) // 3
+ largest_index = 0
+ largest = [data_amplitude,
+ fittedpar[3 * largest_index + 1],
+ fittedpar[3 * largest_index + 2]]
+ for i in range(npeaks):
+ if fittedpar[3 * i] > largest[0]:
+ largest_index = i
+ largest = [data_amplitude,
+ fittedpar[3 * largest_index + 1],
+ fittedpar[3 * largest_index + 2]]
+ else:
+ # no peak was found
+ largest = [data_amplitude, # height
+ x[len(x)//2], # center: middle of x range
+ self.config["FwhmPoints"] * (x[1] - x[0])] # fwhm: default value
+
+ # Setup constrains
+ newcons = numpy.zeros((3, 3), numpy.float)
+ if not self.config['NoConstraintsFlag']:
+ # Setup height constrains
+ if self.config['PositiveHeightAreaFlag']:
+ newcons[0, 0] = CPOSITIVE
+ newcons[0, 1] = 0
+ newcons[0, 2] = 0
+
+ # Setup position constrains
+ if self.config['QuotedPositionFlag']:
+ newcons[1, 0] = CQUOTED
+ newcons[1, 1] = min(x)
+ newcons[1, 2] = max(x)
+
+ # Setup positive FWHM constrains
+ if self.config['PositiveFwhmFlag']:
+ newcons[2, 0] = CPOSITIVE
+ newcons[2, 1] = 0
+ newcons[2, 2] = 0
+
+ return largest, newcons
+
+ def estimate_slit(self, x, y):
+ """Estimation of parameters for slit curves.
+
+ The functions estimates stepup and stepdown parameters for the largest
+ steps, and uses them for calculating the center (middle between stepup
+ and stepdown), the height (maximum amplitude in data), the fwhm
+ (distance between the up- and down-step centers) and the beamfwhm
+ (average of FWHM for up- and down-step).
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each slit are:
+ *height, position, fwhm, beamfwhm* .
+ """
+ largestup, cons = self.estimate_stepup(x, y)
+ largestdown, cons = self.estimate_stepdown(x, y)
+ fwhm = numpy.fabs(largestdown[1] - largestup[1])
+ beamfwhm = 0.5 * (largestup[2] + largestdown[1])
+ beamfwhm = min(beamfwhm, fwhm / 10.0)
+ beamfwhm = max(beamfwhm, (max(x) - min(x)) * 3.0 / len(x))
+
+ y_minus_bg = y - self.strip_bg(y)
+ height = max(y_minus_bg)
+
+ i1 = numpy.nonzero(y_minus_bg >= 0.5 * height)[0]
+ xx = numpy.take(x, i1)
+ position = (xx[0] + xx[-1]) / 2.0
+ fwhm = xx[-1] - xx[0]
+ largest = [height, position, fwhm, beamfwhm]
+ cons = numpy.zeros((4, 3), numpy.float)
+ # Setup constrains
+ if not self.config['NoConstraintsFlag']:
+ # Setup height constrains
+ if self.config['PositiveHeightAreaFlag']:
+ cons[0, 0] = CPOSITIVE
+ cons[0, 1] = 0
+ cons[0, 2] = 0
+
+ # Setup position constrains
+ if self.config['QuotedPositionFlag']:
+ cons[1, 0] = CQUOTED
+ cons[1, 1] = min(x)
+ cons[1, 2] = max(x)
+
+ # Setup positive FWHM constrains
+ if self.config['PositiveFwhmFlag']:
+ cons[2, 0] = CPOSITIVE
+ cons[2, 1] = 0
+ cons[2, 2] = 0
+
+ # Setup positive FWHM constrains
+ if self.config['PositiveFwhmFlag']:
+ cons[3, 0] = CPOSITIVE
+ cons[3, 1] = 0
+ cons[3, 2] = 0
+ return largest, cons
+
+ def estimate_stepup(self, x, y):
+ """Estimation of parameters for a single step up curve.
+
+ The functions estimates gaussian parameters for the derivative of
+ the data, takes the largest gaussian peak and uses its estimated
+ parameters to define the center of the step and its fwhm. The
+ estimated amplitude returned is simply ``max(y) - min(y)``.
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ Parameters to be estimated for each stepup are:
+ *height, centroid, fwhm* .
+ """
+ crappyfilter = [0.25, 0.75, 0.0, -0.75, -0.25]
+ cutoff = len(crappyfilter) // 2
+ y_deriv = numpy.convolve(y, crappyfilter, mode="valid")
+ if max(y_deriv) > 0:
+ y_deriv = y_deriv * max(y) / max(y_deriv)
+
+ fittedpar, cons = self.estimate_height_position_fwhm(
+ x[cutoff:-cutoff], y_deriv)
+
+ # for height, use the data amplitude after removing the background
+ data_amplitude = max(y) - min(y)
+
+ # find params of the largest gaussian found
+ if len(fittedpar):
+ npeaks = len(fittedpar) // 3
+ largest_index = 0
+ largest = [data_amplitude,
+ fittedpar[3 * largest_index + 1],
+ fittedpar[3 * largest_index + 2]]
+ for i in range(npeaks):
+ if fittedpar[3 * i] > largest[0]:
+ largest_index = i
+ largest = [fittedpar[3 * largest_index],
+ fittedpar[3 * largest_index + 1],
+ fittedpar[3 * largest_index + 2]]
+ else:
+ # no peak was found
+ largest = [data_amplitude, # height
+ x[len(x)//2], # center: middle of x range
+ self.config["FwhmPoints"] * (x[1] - x[0])] # fwhm: default value
+
+ newcons = numpy.zeros((3, 3), numpy.float)
+ # Setup constrains
+ if not self.config['NoConstraintsFlag']:
+ # Setup height constraints
+ if self.config['PositiveHeightAreaFlag']:
+ newcons[0, 0] = CPOSITIVE
+ newcons[0, 1] = 0
+ newcons[0, 2] = 0
+
+ # Setup position constraints
+ if self.config['QuotedPositionFlag']:
+ newcons[1, 0] = CQUOTED
+ newcons[1, 1] = min(x)
+ newcons[1, 2] = max(x)
+
+ # Setup positive FWHM constraints
+ if self.config['PositiveFwhmFlag']:
+ newcons[2, 0] = CPOSITIVE
+ newcons[2, 1] = 0
+ newcons[2, 2] = 0
+
+ return largest, newcons
+
+ def estimate_periodic_gauss(self, x, y):
+ """Estimation of parameters for periodic gaussian curves:
+ *number of peaks, distance between peaks, height, position of the
+ first peak, fwhm*
+
+ The functions detects all peaks, then computes the parameters the
+ following way:
+
+ - *distance*: average of distances between detected peaks
+ - *height*: average height of detected peaks
+ - *fwhm*: fwhm of the highest peak (in number of samples) if
+ field ``'AutoFwhm'`` in :attr:`config` is ``True``, else take
+ the default value (field ``'FwhmPoints'`` in :attr:`config`)
+
+ :param x: Array of abscissa values
+ :param y: Array of ordinate values (``y = f(x)``)
+ :return: Tuple of estimated fit parameters and fit constraints.
+ """
+ yscaling = self.config.get('Yscaling', 1.0)
+ if yscaling == 0:
+ yscaling = 1.0
+
+ bg = self.strip_bg(y)
+
+ if self.config['AutoFwhm']:
+ search_fwhm = guess_fwhm(y)
+ else:
+ search_fwhm = int(float(self.config['FwhmPoints']))
+ search_sens = float(self.config['Sensitivity'])
+
+ if search_fwhm < 3:
+ search_fwhm = 3
+
+ if search_sens < 1:
+ search_sens = 1
+
+ if len(y) > 1.5 * search_fwhm:
+ peaks = peak_search(yscaling * y, fwhm=search_fwhm,
+ sensitivity=search_sens)
+ else:
+ peaks = []
+ npeaks = len(peaks)
+ if not npeaks:
+ fittedpar = []
+ cons = numpy.zeros((len(fittedpar), 3), numpy.float)
+ return fittedpar, cons
+
+ fittedpar = [0.0, 0.0, 0.0, 0.0, 0.0]
+
+ # The number of peaks
+ fittedpar[0] = npeaks
+
+ # The separation between peaks in x units
+ delta = 0.0
+ height = 0.0
+ for i in range(npeaks):
+ height += y[int(peaks[i])] - bg[int(peaks[i])]
+ if i != npeaks - 1:
+ delta += (x[int(peaks[i + 1])] - x[int(peaks[i])])
+
+ # delta between peaks
+ if npeaks > 1:
+ fittedpar[1] = delta / (npeaks - 1)
+
+ # starting height
+ fittedpar[2] = height / npeaks
+
+ # position of the first peak
+ fittedpar[3] = x[int(peaks[0])]
+
+ # Estimate the fwhm
+ fittedpar[4] = search_fwhm
+
+ # setup constraints
+ cons = numpy.zeros((5, 3), numpy.float)
+ cons[0, 0] = CFIXED # the number of gaussians
+ if npeaks == 1:
+ cons[1, 0] = CFIXED # the delta between peaks
+ else:
+ cons[1, 0] = CFREE
+ j = 2
+ # Setup height area constrains
+ if not self.config['NoConstraintsFlag']:
+ if self.config['PositiveHeightAreaFlag']:
+ # POSITIVE = 1
+ cons[j, 0] = CPOSITIVE
+ cons[j, 1] = 0
+ cons[j, 2] = 0
+ j += 1
+
+ # Setup position constrains
+ if not self.config['NoConstraintsFlag']:
+ if self.config['QuotedPositionFlag']:
+ # QUOTED = 2
+ cons[j, 0] = CQUOTED
+ cons[j, 1] = min(x)
+ cons[j, 2] = max(x)
+ j += 1
+
+ # Setup positive FWHM constrains
+ if not self.config['NoConstraintsFlag']:
+ if self.config['PositiveFwhmFlag']:
+ # POSITIVE=1
+ cons[j, 0] = CPOSITIVE
+ cons[j, 1] = 0
+ cons[j, 2] = 0
+ j += 1
+ return fittedpar, cons
+
+ def configure(self, **kw):
+ """Add new / unknown keyword arguments to :attr:`config`,
+ update entries in :attr:`config` if the parameter name is a existing
+ key.
+
+ :param kw: Dictionary of keyword arguments.
+ :return: Configuration dictionary :attr:`config`
+ """
+ if not kw.keys():
+ return self.config
+ for key in kw.keys():
+ notdone = 1
+ # take care of lower / upper case problems ...
+ for config_key in self.config.keys():
+ if config_key.lower() == key.lower():
+ self.config[config_key] = kw[key]
+ notdone = 0
+ if notdone:
+ self.config[key] = kw[key]
+ return self.config
+
+fitfuns = FitTheories()
+
+THEORY = OrderedDict((
+ ('Gaussians',
+ FitTheory(description='Gaussian functions',
+ function=functions.sum_gauss,
+ parameters=('Height', 'Position', 'FWHM'),
+ estimate=fitfuns.estimate_height_position_fwhm,
+ configure=fitfuns.configure)),
+ ('Lorentz',
+ FitTheory(description='Lorentzian functions',
+ function=functions.sum_lorentz,
+ parameters=('Height', 'Position', 'FWHM'),
+ estimate=fitfuns.estimate_height_position_fwhm,
+ configure=fitfuns.configure)),
+ ('Area Gaussians',
+ FitTheory(description='Gaussian functions (area)',
+ function=functions.sum_agauss,
+ parameters=('Area', 'Position', 'FWHM'),
+ estimate=fitfuns.estimate_agauss,
+ configure=fitfuns.configure)),
+ ('Area Lorentz',
+ FitTheory(description='Lorentzian functions (area)',
+ function=functions.sum_alorentz,
+ parameters=('Area', 'Position', 'FWHM'),
+ estimate=fitfuns.estimate_alorentz,
+ configure=fitfuns.configure)),
+ ('Pseudo-Voigt Line',
+ FitTheory(description='Pseudo-Voigt functions',
+ function=functions.sum_pvoigt,
+ parameters=('Height', 'Position', 'FWHM', 'Eta'),
+ estimate=fitfuns.estimate_pvoigt,
+ configure=fitfuns.configure)),
+ ('Area Pseudo-Voigt',
+ FitTheory(description='Pseudo-Voigt functions (area)',
+ function=functions.sum_apvoigt,
+ parameters=('Area', 'Position', 'FWHM', 'Eta'),
+ estimate=fitfuns.estimate_apvoigt,
+ configure=fitfuns.configure)),
+ ('Split Gaussian',
+ FitTheory(description='Asymmetric gaussian functions',
+ function=functions.sum_splitgauss,
+ parameters=('Height', 'Position', 'LowFWHM',
+ 'HighFWHM'),
+ estimate=fitfuns.estimate_splitgauss,
+ configure=fitfuns.configure)),
+ ('Split Lorentz',
+ FitTheory(description='Asymmetric lorentzian functions',
+ function=functions.sum_splitlorentz,
+ parameters=('Height', 'Position', 'LowFWHM', 'HighFWHM'),
+ estimate=fitfuns.estimate_splitgauss,
+ configure=fitfuns.configure)),
+ ('Split Pseudo-Voigt',
+ FitTheory(description='Asymmetric pseudo-Voigt functions',
+ function=functions.sum_splitpvoigt,
+ parameters=('Height', 'Position', 'LowFWHM',
+ 'HighFWHM', 'Eta'),
+ estimate=fitfuns.estimate_splitpvoigt,
+ configure=fitfuns.configure)),
+ ('Step Down',
+ FitTheory(description='Step down function',
+ function=functions.sum_stepdown,
+ parameters=('Height', 'Position', 'FWHM'),
+ estimate=fitfuns.estimate_stepdown,
+ configure=fitfuns.configure)),
+ ('Step Up',
+ FitTheory(description='Step up function',
+ function=functions.sum_stepup,
+ parameters=('Height', 'Position', 'FWHM'),
+ estimate=fitfuns.estimate_stepup,
+ configure=fitfuns.configure)),
+ ('Slit',
+ FitTheory(description='Slit function',
+ function=functions.sum_slit,
+ parameters=('Height', 'Position', 'FWHM', 'BeamFWHM'),
+ estimate=fitfuns.estimate_slit,
+ configure=fitfuns.configure)),
+ ('Atan',
+ FitTheory(description='Arctan step up function',
+ function=functions.atan_stepup,
+ parameters=('Height', 'Position', 'Width'),
+ estimate=fitfuns.estimate_stepup,
+ configure=fitfuns.configure)),
+ ('Hypermet',
+ FitTheory(description='Hypermet functions',
+ function=fitfuns.ahypermet, # customized version of functions.sum_ahypermet
+ parameters=('G_Area', 'Position', 'FWHM', 'ST_Area',
+ 'ST_Slope', 'LT_Area', 'LT_Slope', 'Step_H'),
+ estimate=fitfuns.estimate_ahypermet,
+ configure=fitfuns.configure)),
+ # ('Periodic Gaussians',
+ # FitTheory(description='Periodic gaussian functions',
+ # function=functions.periodic_gauss,
+ # parameters=('N', 'Delta', 'Height', 'Position', 'FWHM'),
+ # estimate=fitfuns.estimate_periodic_gauss,
+ # configure=fitfuns.configure))
+ ('Degree 2 Polynomial',
+ FitTheory(description='Degree 2 polynomial'
+ '\ny = a*x^2 + b*x +c',
+ function=fitfuns.poly,
+ parameters=['a', 'b', 'c'],
+ estimate=fitfuns.estimate_quadratic)),
+ ('Degree 3 Polynomial',
+ FitTheory(description='Degree 3 polynomial'
+ '\ny = a*x^3 + b*x^2 + c*x + d',
+ function=fitfuns.poly,
+ parameters=['a', 'b', 'c', 'd'],
+ estimate=fitfuns.estimate_cubic)),
+ ('Degree 4 Polynomial',
+ FitTheory(description='Degree 4 polynomial'
+ '\ny = a*x^4 + b*x^3 + c*x^2 + d*x + e',
+ function=fitfuns.poly,
+ parameters=['a', 'b', 'c', 'd', 'e'],
+ estimate=fitfuns.estimate_quartic)),
+ ('Degree 5 Polynomial',
+ FitTheory(description='Degree 5 polynomial'
+ '\ny = a*x^5 + b*x^4 + c*x^3 + d*x^2 + e*x + f',
+ function=fitfuns.poly,
+ parameters=['a', 'b', 'c', 'd', 'e', 'f'],
+ estimate=fitfuns.estimate_quintic)),
+))
+"""Dictionary of fit theories: fit functions and their associated estimation
+function, parameters list, configuration function and description.
+"""
+
+
+def test(a):
+ from silx.math.fit import fitmanager
+ x = numpy.arange(1000).astype(numpy.float)
+ p = [1500, 100., 50.0,
+ 1500, 700., 50.0]
+ y_synthetic = functions.sum_gauss(x, *p) + 1
+
+ fit = fitmanager.FitManager(x, y_synthetic)
+ fit.addtheory('Gaussians', functions.sum_gauss, ['Height', 'Position', 'FWHM'],
+ a.estimate_height_position_fwhm)
+ fit.settheory('Gaussians')
+ fit.setbackground('Linear')
+
+ fit.estimate()
+ fit.runfit()
+
+ y_fit = fit.gendata()
+
+ print("Fit parameter names: %s" % str(fit.get_names()))
+ print("Theoretical parameters: %s" % str(numpy.append([1, 0], p)))
+ print("Fitted parameters: %s" % str(fit.get_fitted_parameters()))
+
+ try:
+ from silx.gui import qt
+ from silx.gui.plot import plot1D
+ app = qt.QApplication([])
+
+ # Offset of 1 to see the difference in log scale
+ plot1D(x, (y_synthetic + 1, y_fit), "Input data + 1, Fit")
+
+ app.exec_()
+ except ImportError:
+ _logger.warning("Unable to load qt binding, can't plot results.")
+
+
+if __name__ == "__main__":
+ test(fitfuns)
diff --git a/silx/math/fit/fittheory.py b/silx/math/fit/fittheory.py
new file mode 100644
index 0000000..17441ac
--- /dev/null
+++ b/silx/math/fit/fittheory.py
@@ -0,0 +1,161 @@
+# coding: utf-8
+#/*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+########################################################################### */
+"""
+This module defines the :class:`FitTheory` object that is used by
+:class:`silx.math.fit.FitManager` to define fit functions and background
+models.
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "09/08/2016"
+
+
+class FitTheory(object):
+ """This class defines a fit theory, which consists of:
+
+ - a model function, the actual function to be fitted
+ - parameters names
+ - an estimation function, that return the estimated initial parameters
+ that serve as input for :func:`silx.math.fit.leastsq`
+ - an optional configuration function, that can be used to modify
+ configuration parameters to alter the behavior of the fit function
+ and the estimation function
+ - an optional derivative function, that replaces the default model
+ derivative used in :func:`silx.math.fit.leastsq`
+ """
+ def __init__(self, function, parameters,
+ estimate=None, configure=None, derivative=None,
+ description=None, pymca_legacy=False, is_background=False):
+ """
+ :param function function: Actual function. See documentation for
+ :attr:`function`.
+ :param list[str] parameters: List of parameter names for the function.
+ See documentation for :attr:`parameters`.
+ :param function estimate: Optional estimation function.
+ See documentation for :attr:`estimate`
+ :param function configure: Optional configuration function.
+ See documentation for :attr:`configure`
+ :param function derivative: Optional custom derivative function.
+ See documentation for :attr:`derivative`
+ :param str description: Optional description string.
+ See documentation for :attr:`description`
+ :param bool pymca_legacy: Flag to indicate that the theory is a PyMca
+ legacy theory. See documentation for :attr:`pymca_legacy`
+ :param bool is_background: Flag to indicate that the theory is a
+ background theory. This has implications regarding the function's
+ signature, as explained in the documentation for :attr:`function`.
+ """
+ self.function = function
+ """Regular fit functions must have the signature *f(x, \*params) -> y*,
+ where *x* is a 1D array of values for the independent variable,
+ *params* are the parameters to be fitted and *y* is the output array
+ that we want to have the best fit to a series of data points.
+
+ Background functions used by :class:`FitManager` must have a slightly
+ different signature: *f(x, y0, \*params) -> bg*, where *y0* is the
+ array of original data points and *bg* is the background signal that
+ we want to subtract from the data array prior to fitting the regular
+ fit function.
+
+ The number of parameters must be the same as in :attr:`parameters`, or
+ a multiple of this number if the function is defined as a sum of a
+ variable number of base functions and if :attr:`estimate` is designed
+ to be able to estimate the number of needed base functions.
+ """
+
+ self.parameters = parameters
+ """List of parameters names.
+
+ This list can contain the minimum number of parameters, if the
+ function takes a variable number of parameters,
+ and if the estimation function is responsible for finding the number
+ of required parameters """
+
+ self.estimate = estimate
+ """The estimation function should have the following signature::
+
+ f(x, y) -> (estimated_param, constraints)
+
+ Parameters:
+
+ - ``x`` is a sequence of values for the independent variable
+ - ``y`` is a sequence of the same length as ``x`` containing the
+ data to be fitted
+
+ Return values:
+
+ - ``estimated_param`` is a sequence of estimated fit parameters to
+ be used as initial values for an iterative fit.
+ - ``constraints`` is a sequence of shape *(n, 3)*, where *n* is the
+ number of estimated parameters, containing the constraints for each
+ parameter to be fitted. See :func:`silx.math.fit.leastsq` for more
+ explanations about constraints."""
+ if estimate is None:
+ self.estimate = self.default_estimate
+
+ self.configure = configure
+ """The optional configuration function must conform to the signature
+ ``f(**kw) -> dict`` (i.e it must accept any named argument and
+ return a dictionary).
+ It can be used to modify configuration parameters to alter the
+ behavior of the fit function and the estimation function."""
+
+ self.derivative = derivative
+ """The optional derivative function must conform to the signature
+ ``model_deriv(xdata, parameters, index)``, where parameters is a
+ sequence with the current values of the fitting parameters, index is
+ the fitting parameter index for which the the derivative has to be
+ provided in the supplied array of xdata points."""
+
+ self.description = description
+ """Optional description string for this particular fit theory."""
+
+ self.pymca_legacy = pymca_legacy
+ """This attribute can be set to *True* to indicate that the theory
+ is a PyMca legacy theory.
+
+ This tells :mod:`silx.math.fit.fitmanager` that the signature of
+ the estimate function is::
+
+ f(x, y, bg, xscaling, yscaling) -> (estimated_param, constraints)
+ """
+
+ self.is_background = is_background
+ """Flag to indicate that the theory is background theory.
+
+ A background function is an secondary function that needs to be added
+ to the main fit function to better fit the original data.
+ If this flag is set to *True*, modules using this theory are informed
+ that :attr:`function` has the signature *f(x, y0, \*params) -> bg*,
+ instead of the usual fit function signature."""
+
+ def default_estimate(self, x=None, y=None, bg=None):
+ """Default estimate function. Return an array of *ones* as the
+ initial estimated parameters, and set all constraints to zero
+ (FREE)"""
+ estimated_parameters = [1. for _ in self.parameters]
+ estimated_constraints = [[0, 0, 0] for _ in self.parameters]
+ return estimated_parameters, estimated_constraints
diff --git a/silx/math/fit/functions/functions.c b/silx/math/fit/functions/functions.c
new file mode 100644
index 0000000..21c6911
--- /dev/null
+++ b/silx/math/fit/functions/functions.c
@@ -0,0 +1,27541 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__functions
+#define __PYX_HAVE_API__functions
+#include "functions.h"
+#include "pythread.h"
+#include "string.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+ "functions.pyx",
+ "stringsource",
+};
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static void __Pyx_RaiseBufferIndexError(int axis);
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static PyObject *__pyx_memview_get_double(const char *itemp);
+static int __pyx_memview_set_double(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_double(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'functions_wrapper' */
+
+/* Module declarations from 'functions' */
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 };
+#define __Pyx_MODULE_NAME "functions"
+int __pyx_module_is_main_functions = 0;
+
+/* Implementation of 'functions' */
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_pf_9functions_erf(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x); /* proto */
+static PyObject *__pyx_pf_9functions_2erfc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x); /* proto */
+static PyObject *__pyx_pf_9functions_4sum_gauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_6sum_agauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_8sum_fastagauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_10sum_splitgauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_12sum_apvoigt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_14sum_pvoigt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_16sum_splitpvoigt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_18sum_lorentz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_20sum_alorentz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_22sum_splitlorentz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_24sum_stepdown(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_26sum_stepup(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_28sum_slit(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_30sum_ahypermet(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_gaussian_term, PyObject *__pyx_v_st_term, PyObject *__pyx_v_lt_term, PyObject *__pyx_v_step_term, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_32sum_fastahypermet(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_gaussian_term, PyObject *__pyx_v_st_term, PyObject *__pyx_v_lt_term, PyObject *__pyx_v_step_term, PyObject *__pyx_v_params); /* proto */
+static PyObject *__pyx_pf_9functions_34atan_stepup(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c); /* proto */
+static PyObject *__pyx_pf_9functions_36periodic_gauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_pars); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_C[] = "C";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_a[] = "a";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_c[] = "c";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_x[] = "x";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_pi[] = "pi";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k_erf[] = "erf";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_x_c[] = "x_c";
+static char __pyx_k_y_c[] = "y_c";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_copy[] = "copy";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_erfc[] = "erfc";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_pars[] = "pars";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_empty[] = "empty";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_float[] = "float";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_order[] = "order";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_zeros[] = "zeros";
+static char __pyx_k_arctan[] = "arctan";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_logger[] = "_logger";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_params[] = "params";
+static char __pyx_k_status[] = "status";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_asarray[] = "asarray";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_float64[] = "float64";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_len_dim[] = "len_dim";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_logging[] = "logging";
+static char __pyx_k_lt_term[] = "lt_term";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_newpars[] = "newpars";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_st_term[] = "st_term";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_P_Knobel[] = "P. Knobel";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_params_c[] = "params_c";
+static char __pyx_k_sum_slit[] = "sum_slit";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_functions[] = "functions";
+static char __pyx_k_getLogger[] = "getLogger";
+static char __pyx_k_step_term[] = "step_term";
+static char __pyx_k_sum_gauss[] = "sum_gauss";
+static char __pyx_k_17_06_2016[] = "17/06/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_sum_agauss[] = "sum_agauss";
+static char __pyx_k_sum_pvoigt[] = "sum_pvoigt";
+static char __pyx_k_sum_stepup[] = "sum_stepup";
+static char __pyx_k_tail_flags[] = "tail_flags";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_atan_stepup[] = "atan_stepup";
+static char __pyx_k_basicConfig[] = "basicConfig";
+static char __pyx_k_sum_apvoigt[] = "sum_apvoigt";
+static char __pyx_k_sum_lorentz[] = "sum_lorentz";
+static char __pyx_k_sum_alorentz[] = "sum_alorentz";
+static char __pyx_k_sum_stepdown[] = "sum_stepdown";
+static char __pyx_k_gaussian_term[] = "gaussian_term";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_sum_ahypermet[] = "sum_ahypermet";
+static char __pyx_k_periodic_gauss[] = "periodic_gauss";
+static char __pyx_k_sum_fastagauss[] = "sum_fastagauss";
+static char __pyx_k_sum_splitgauss[] = "sum_splitgauss";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_sum_splitpvoigt[] = "sum_splitpvoigt";
+static char __pyx_k_sum_splitlorentz[] = "sum_splitlorentz";
+static char __pyx_k_sum_fastahypermet[] = "sum_fastahypermet";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_No_parameters_specified[] = "No parameters specified. ";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_Cannot_compute_erf_for_an_empty[] = "Cannot compute erf for an empty array";
+static char __pyx_k_mntdirect__scisoft_users_tvince[] = "/mntdirect/_scisoft/users/tvincent/src/silx/silx/math/fit/functions/functions.pyx";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_At_least_3_parameters_are_requir[] = "At least 3 parameters are required.";
+static char __pyx_k_At_least_4_parameters_are_requir[] = "At least 4 parameters are required.";
+static char __pyx_k_At_least_5_parameters_are_requir[] = "At least 5 parameters are required.";
+static char __pyx_k_At_least_8_parameters_are_requir[] = "At least 8 parameters are required.";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_compute_erfc_for_an_empty[] = "Cannot compute erfc for an empty array";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_No_gaussian_parameters_specified[] = "No gaussian parameters specified. ";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_This_module_provides_fit_functio[] = "This module provides fit functions.\n\nList of fit functions:\n-----------------------\n\n - :func:`sum_gauss`\n - :func:`sum_agauss`\n - :func:`sum_splitgauss`\n - :func:`sum_fastagauss`\n\n - :func:`sum_apvoigt`\n - :func:`sum_pvoigt`\n - :func:`sum_splitpvoigt`\n\n - :func:`sum_lorentz`\n - :func:`sum_alorentz`\n - :func:`sum_splitlorentz`\n\n - :func:`sum_stepdown`\n - :func:`sum_stepup`\n - :func:`sum_slit`\n\n - :func:`sum_ahypermet`\n - :func:`sum_fastahypermet`\n\nFull documentation:\n-------------------\n\n";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_Wrong_number_of_parameters_for_f[] = "Wrong number of parameters for function";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static PyObject *__pyx_kp_s_17_06_2016;
+static PyObject *__pyx_kp_s_At_least_3_parameters_are_requir;
+static PyObject *__pyx_kp_s_At_least_4_parameters_are_requir;
+static PyObject *__pyx_kp_s_At_least_5_parameters_are_requir;
+static PyObject *__pyx_kp_s_At_least_8_parameters_are_requir;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_n_s_C;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_compute_erf_for_an_empty;
+static PyObject *__pyx_kp_s_Cannot_compute_erfc_for_an_empty;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_kp_s_No_gaussian_parameters_specified;
+static PyObject *__pyx_kp_s_No_parameters_specified;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_kp_s_P_Knobel;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_kp_s_Wrong_number_of_parameters_for_f;
+static PyObject *__pyx_n_s_a;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_arctan;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_asarray;
+static PyObject *__pyx_n_s_atan_stepup;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_b;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_basicConfig;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_copy;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_empty;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_erf;
+static PyObject *__pyx_n_s_erfc;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float;
+static PyObject *__pyx_n_s_float64;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_n_s_functions;
+static PyObject *__pyx_n_s_gaussian_term;
+static PyObject *__pyx_n_s_getLogger;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_i;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_len_dim;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_logger;
+static PyObject *__pyx_n_s_logging;
+static PyObject *__pyx_n_s_lt_term;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_kp_s_mntdirect__scisoft_users_tvince;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_newpars;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_n_s_order;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_n_s_params;
+static PyObject *__pyx_n_s_params_c;
+static PyObject *__pyx_n_s_pars;
+static PyObject *__pyx_n_s_periodic_gauss;
+static PyObject *__pyx_n_s_pi;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_st_term;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_status;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_step_term;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_sum_agauss;
+static PyObject *__pyx_n_s_sum_ahypermet;
+static PyObject *__pyx_n_s_sum_alorentz;
+static PyObject *__pyx_n_s_sum_apvoigt;
+static PyObject *__pyx_n_s_sum_fastagauss;
+static PyObject *__pyx_n_s_sum_fastahypermet;
+static PyObject *__pyx_n_s_sum_gauss;
+static PyObject *__pyx_n_s_sum_lorentz;
+static PyObject *__pyx_n_s_sum_pvoigt;
+static PyObject *__pyx_n_s_sum_slit;
+static PyObject *__pyx_n_s_sum_splitgauss;
+static PyObject *__pyx_n_s_sum_splitlorentz;
+static PyObject *__pyx_n_s_sum_splitpvoigt;
+static PyObject *__pyx_n_s_sum_stepdown;
+static PyObject *__pyx_n_s_sum_stepup;
+static PyObject *__pyx_n_s_tail_flags;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_n_s_x;
+static PyObject *__pyx_n_s_x_c;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_n_s_y_c;
+static PyObject *__pyx_n_s_zeros;
+static PyObject *__pyx_float_0_5;
+static PyObject *__pyx_float_1_0;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_3;
+static PyObject *__pyx_int_4;
+static PyObject *__pyx_int_8;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__50;
+static PyObject *__pyx_slice__59;
+static PyObject *__pyx_slice__60;
+static PyObject *__pyx_slice__61;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__26;
+static PyObject *__pyx_tuple__27;
+static PyObject *__pyx_tuple__28;
+static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__30;
+static PyObject *__pyx_tuple__31;
+static PyObject *__pyx_tuple__32;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_tuple__34;
+static PyObject *__pyx_tuple__35;
+static PyObject *__pyx_tuple__36;
+static PyObject *__pyx_tuple__37;
+static PyObject *__pyx_tuple__38;
+static PyObject *__pyx_tuple__39;
+static PyObject *__pyx_tuple__40;
+static PyObject *__pyx_tuple__41;
+static PyObject *__pyx_tuple__42;
+static PyObject *__pyx_tuple__43;
+static PyObject *__pyx_tuple__44;
+static PyObject *__pyx_tuple__45;
+static PyObject *__pyx_tuple__46;
+static PyObject *__pyx_tuple__47;
+static PyObject *__pyx_tuple__48;
+static PyObject *__pyx_tuple__49;
+static PyObject *__pyx_tuple__51;
+static PyObject *__pyx_tuple__52;
+static PyObject *__pyx_tuple__53;
+static PyObject *__pyx_tuple__54;
+static PyObject *__pyx_tuple__55;
+static PyObject *__pyx_tuple__56;
+static PyObject *__pyx_tuple__57;
+static PyObject *__pyx_tuple__58;
+static PyObject *__pyx_tuple__62;
+static PyObject *__pyx_tuple__63;
+static PyObject *__pyx_tuple__65;
+static PyObject *__pyx_tuple__67;
+static PyObject *__pyx_tuple__69;
+static PyObject *__pyx_tuple__71;
+static PyObject *__pyx_tuple__73;
+static PyObject *__pyx_tuple__75;
+static PyObject *__pyx_tuple__77;
+static PyObject *__pyx_tuple__79;
+static PyObject *__pyx_tuple__81;
+static PyObject *__pyx_tuple__83;
+static PyObject *__pyx_tuple__85;
+static PyObject *__pyx_tuple__87;
+static PyObject *__pyx_tuple__89;
+static PyObject *__pyx_tuple__91;
+static PyObject *__pyx_tuple__93;
+static PyObject *__pyx_tuple__95;
+static PyObject *__pyx_tuple__97;
+static PyObject *__pyx_tuple__99;
+static PyObject *__pyx_tuple__101;
+static PyObject *__pyx_tuple__102;
+static PyObject *__pyx_tuple__103;
+static PyObject *__pyx_tuple__104;
+static PyObject *__pyx_tuple__105;
+static PyObject *__pyx_codeobj__64;
+static PyObject *__pyx_codeobj__66;
+static PyObject *__pyx_codeobj__68;
+static PyObject *__pyx_codeobj__70;
+static PyObject *__pyx_codeobj__72;
+static PyObject *__pyx_codeobj__74;
+static PyObject *__pyx_codeobj__76;
+static PyObject *__pyx_codeobj__78;
+static PyObject *__pyx_codeobj__80;
+static PyObject *__pyx_codeobj__82;
+static PyObject *__pyx_codeobj__84;
+static PyObject *__pyx_codeobj__86;
+static PyObject *__pyx_codeobj__88;
+static PyObject *__pyx_codeobj__90;
+static PyObject *__pyx_codeobj__92;
+static PyObject *__pyx_codeobj__94;
+static PyObject *__pyx_codeobj__96;
+static PyObject *__pyx_codeobj__98;
+static PyObject *__pyx_codeobj__100;
+
+/* "functions.pyx":68
+ *
+ *
+ * def erf(x): # <<<<<<<<<<<<<<
+ * """Return the gaussian error function
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_1erf(PyObject *__pyx_self, PyObject *__pyx_v_x); /*proto*/
+static char __pyx_doc_9functions_erf[] = "erf(x)\nReturn the gaussian error function\n\n :param x: Independant variable where the gaussian error function is\n calculated\n :type x: numpy.ndarray or scalar\n :return: Gaussian error function ``y=erf(x)``\n :raise: IndexError if ``x`` is an empty array\n ";
+static PyMethodDef __pyx_mdef_9functions_1erf = {"erf", (PyCFunction)__pyx_pw_9functions_1erf, METH_O, __pyx_doc_9functions_erf};
+static PyObject *__pyx_pw_9functions_1erf(PyObject *__pyx_self, PyObject *__pyx_v_x) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("erf (wrapper)", 0);
+ __pyx_r = __pyx_pf_9functions_erf(__pyx_self, ((PyObject *)__pyx_v_x));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_erf(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_len_dim = NULL;
+ CYTHON_UNUSED int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_11 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_12;
+ Py_ssize_t __pyx_t_13;
+ int __pyx_t_14;
+ PyObject *__pyx_t_15 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("erf", 0);
+ __Pyx_INCREF(__pyx_v_x);
+
+ /* "functions.pyx":83
+ *
+ * # force list into numpy array
+ * if not hasattr(x, "shape"): # <<<<<<<<<<<<<<
+ * x = numpy.asarray(x)
+ *
+ */
+ __pyx_t_1 = PyObject_HasAttr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":84
+ * # force list into numpy array
+ * if not hasattr(x, "shape"):
+ * x = numpy.asarray(x) # <<<<<<<<<<<<<<
+ *
+ * for len_dim in x.shape:
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_x); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF_SET(__pyx_v_x, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "functions.pyx":86
+ * x = numpy.asarray(x)
+ *
+ * for len_dim in x.shape: # <<<<<<<<<<<<<<
+ * if len_dim == 0:
+ * raise IndexError("Cannot compute erf for an empty array")
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_5 = __pyx_t_3; __Pyx_INCREF(__pyx_t_5); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = Py_TYPE(__pyx_t_5)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_5))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_5)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_3); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_3); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_8(__pyx_t_5);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_len_dim, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "functions.pyx":87
+ *
+ * for len_dim in x.shape:
+ * if len_dim == 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Cannot compute erf for an empty array")
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_len_dim, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 87; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":88
+ * for len_dim in x.shape:
+ * if len_dim == 0:
+ * raise IndexError("Cannot compute erf for an empty array") # <<<<<<<<<<<<<<
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":86
+ * x = numpy.asarray(x)
+ *
+ * for len_dim in x.shape: # <<<<<<<<<<<<<<
+ * if len_dim == 0:
+ * raise IndexError("Cannot compute erf for an empty array")
+ */
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":90
+ * raise IndexError("Cannot compute erf for an empty array")
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64)
+ *
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_reshape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_9);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_x_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":91
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.erf_array(&x_c[0], x_c.size, &y_c[0])
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_empty); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_5 = __pyx_memoryview_fromslice(__pyx_v_x_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_dtype, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_empty_tuple, __pyx_t_9); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_11 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_3);
+ if (unlikely(!__pyx_t_11.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_y_c = __pyx_t_11;
+ __pyx_t_11.memview = NULL;
+ __pyx_t_11.data = NULL;
+
+ /* "functions.pyx":93
+ * y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64)
+ *
+ * status = functions_wrapper.erf_array(&x_c[0], x_c.size, &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_7 = 0;
+ __pyx_t_12 = -1;
+ if (__pyx_t_7 < 0) {
+ __pyx_t_7 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_7 < 0)) __pyx_t_12 = 0;
+ } else if (unlikely(__pyx_t_7 >= __pyx_v_x_c.shape[0])) __pyx_t_12 = 0;
+ if (unlikely(__pyx_t_12 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_12);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_x_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_size); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_t_9); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = -1;
+ if (__pyx_t_13 < 0) {
+ __pyx_t_13 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_13 < 0)) __pyx_t_14 = 0;
+ } else if (unlikely(__pyx_t_13 >= __pyx_v_y_c.shape[0])) __pyx_t_14 = 0;
+ if (unlikely(__pyx_t_14 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_14);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_status = erf_array((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_7)) )))), __pyx_t_12, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_13)) )))));
+
+ /* "functions.pyx":95
+ * status = functions_wrapper.erf_array(&x_c[0], x_c.size, &y_c[0])
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_15, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_15 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_15 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_15)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_15);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_15) {
+ __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_9);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_15); __Pyx_GIVEREF(__pyx_t_15); __pyx_t_15 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":68
+ *
+ *
+ * def erf(x): # <<<<<<<<<<<<<<
+ * """Return the gaussian error function
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_9);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_AddTraceback("functions.erf", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XDECREF(__pyx_v_len_dim);
+ __Pyx_XDECREF(__pyx_v_x);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":98
+ *
+ *
+ * def erfc(x): # <<<<<<<<<<<<<<
+ * """Return the gaussian complementary error function
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_3erfc(PyObject *__pyx_self, PyObject *__pyx_v_x); /*proto*/
+static char __pyx_doc_9functions_2erfc[] = "erfc(x)\nReturn the gaussian complementary error function\n\n :param x: Independant variable where the gaussian complementary error\n function is calculated\n :type x: numpy.ndarray or scalar\n :return: Gaussian complementary error function ``y=erfc(x)``\n :type rtype: numpy.ndarray\n :raise: IndexError if ``x`` is an empty array\n ";
+static PyMethodDef __pyx_mdef_9functions_3erfc = {"erfc", (PyCFunction)__pyx_pw_9functions_3erfc, METH_O, __pyx_doc_9functions_2erfc};
+static PyObject *__pyx_pw_9functions_3erfc(PyObject *__pyx_self, PyObject *__pyx_v_x) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("erfc (wrapper)", 0);
+ __pyx_r = __pyx_pf_9functions_2erfc(__pyx_self, ((PyObject *)__pyx_v_x));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_2erfc(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_len_dim = NULL;
+ CYTHON_UNUSED int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_11 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_12;
+ Py_ssize_t __pyx_t_13;
+ int __pyx_t_14;
+ PyObject *__pyx_t_15 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("erfc", 0);
+ __Pyx_INCREF(__pyx_v_x);
+
+ /* "functions.pyx":113
+ *
+ * # force list into numpy array
+ * if not hasattr(x, "shape"): # <<<<<<<<<<<<<<
+ * x = numpy.asarray(x)
+ *
+ */
+ __pyx_t_1 = PyObject_HasAttr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":114
+ * # force list into numpy array
+ * if not hasattr(x, "shape"):
+ * x = numpy.asarray(x) # <<<<<<<<<<<<<<
+ *
+ * for len_dim in x.shape:
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_x); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF_SET(__pyx_v_x, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "functions.pyx":116
+ * x = numpy.asarray(x)
+ *
+ * for len_dim in x.shape: # <<<<<<<<<<<<<<
+ * if len_dim == 0:
+ * raise IndexError("Cannot compute erfc for an empty array")
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_5 = __pyx_t_3; __Pyx_INCREF(__pyx_t_5); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = Py_TYPE(__pyx_t_5)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_5))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_5)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_3); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_7); __Pyx_INCREF(__pyx_t_3); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_5, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_8(__pyx_t_5);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_len_dim, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "functions.pyx":117
+ *
+ * for len_dim in x.shape:
+ * if len_dim == 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Cannot compute erfc for an empty array")
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_len_dim, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":118
+ * for len_dim in x.shape:
+ * if len_dim == 0:
+ * raise IndexError("Cannot compute erfc for an empty array") # <<<<<<<<<<<<<<
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":116
+ * x = numpy.asarray(x)
+ *
+ * for len_dim in x.shape: # <<<<<<<<<<<<<<
+ * if len_dim == 0:
+ * raise IndexError("Cannot compute erfc for an empty array")
+ */
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":120
+ * raise IndexError("Cannot compute erfc for an empty array")
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64)
+ *
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_reshape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_9);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_x_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":121
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.erfc_array(&x_c[0], x_c.size, &y_c[0])
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_empty); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_5 = __pyx_memoryview_fromslice(__pyx_v_x_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_dtype, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_empty_tuple, __pyx_t_9); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_11 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_3);
+ if (unlikely(!__pyx_t_11.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_y_c = __pyx_t_11;
+ __pyx_t_11.memview = NULL;
+ __pyx_t_11.data = NULL;
+
+ /* "functions.pyx":123
+ * y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64)
+ *
+ * status = functions_wrapper.erfc_array(&x_c[0], x_c.size, &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_7 = 0;
+ __pyx_t_12 = -1;
+ if (__pyx_t_7 < 0) {
+ __pyx_t_7 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_7 < 0)) __pyx_t_12 = 0;
+ } else if (unlikely(__pyx_t_7 >= __pyx_v_x_c.shape[0])) __pyx_t_12 = 0;
+ if (unlikely(__pyx_t_12 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_12);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_x_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_size); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_12 = __Pyx_PyInt_As_int(__pyx_t_9); if (unlikely((__pyx_t_12 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_13 = 0;
+ __pyx_t_14 = -1;
+ if (__pyx_t_13 < 0) {
+ __pyx_t_13 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_13 < 0)) __pyx_t_14 = 0;
+ } else if (unlikely(__pyx_t_13 >= __pyx_v_y_c.shape[0])) __pyx_t_14 = 0;
+ if (unlikely(__pyx_t_14 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_14);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_status = erfc_array((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_7)) )))), __pyx_t_12, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_13)) )))));
+
+ /* "functions.pyx":125
+ * status = functions_wrapper.erfc_array(&x_c[0], x_c.size, &y_c[0])
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_15, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_15 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_15 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_15)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_15);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_15) {
+ __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_9);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_15); __Pyx_GIVEREF(__pyx_t_15); __pyx_t_15 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":98
+ *
+ *
+ * def erfc(x): # <<<<<<<<<<<<<<
+ * """Return the gaussian complementary error function
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_9);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_AddTraceback("functions.erfc", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XDECREF(__pyx_v_len_dim);
+ __Pyx_XDECREF(__pyx_v_x);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":128
+ *
+ *
+ * def sum_gauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(height, centroid, fwhm)*,
+ * where:
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_5sum_gauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_4sum_gauss[] = "sum_gauss(x, *params)\nReturn a sum of gaussian functions defined by *(height, centroid, fwhm)*,\n where:\n\n - *height* is the peak amplitude\n - *centroid* is the peak x-coordinate\n - *fwhm* is the full-width at half maximum\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of gaussian parameters (length must be a multiple\n of 3):\n *(height1, centroid1, fwhm1, height2, centroid2, fwhm2,...)*\n :return: Array of sum of gaussian functions at each ``x`` coordinate.\n ";
+static PyMethodDef __pyx_mdef_9functions_5sum_gauss = {"sum_gauss", (PyCFunction)__pyx_pw_9functions_5sum_gauss, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_4sum_gauss};
+static PyObject *__pyx_pw_9functions_5sum_gauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_gauss (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_gauss") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_gauss", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_gauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_4sum_gauss(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_4sum_gauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_gauss", 0);
+
+ /* "functions.pyx":148
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No gaussian parameters specified. " +
+ * "At least 3 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":149
+ *
+ * if not len(params):
+ * raise IndexError("No gaussian parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 3 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_gaussian_parameters_specified, __pyx_kp_s_At_least_3_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":153
+ *
+ * # ensure float64 (double) type and 1D contiguous data layout in memory
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":154
+ * # ensure float64 (double) type and 1D contiguous data layout in memory
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":155
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":153
+ *
+ * # ensure float64 (double) type and 1D contiguous data layout in memory
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":156
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":157
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":158
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":159
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":157
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":160
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":161
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":162
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_gauss(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":161
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":165
+ *
+ * status = functions_wrapper.sum_gauss(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":166
+ * status = functions_wrapper.sum_gauss(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":167
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":164
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_gauss( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_gauss((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":169
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":170
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * # reshape y_c to match original, possibly unusual, data shape
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":173
+ *
+ * # reshape y_c to match original, possibly unusual, data shape
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":128
+ *
+ *
+ * def sum_gauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(height, centroid, fwhm)*,
+ * where:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_gauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":176
+ *
+ *
+ * def sum_agauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ * where:
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_7sum_agauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_6sum_agauss[] = "sum_agauss(x, *params)\nReturn a sum of gaussian functions defined by *(area, centroid, fwhm)*,\n where:\n\n - *area* is the area underneath the peak\n - *centroid* is the peak x-coordinate\n - *fwhm* is the full-width at half maximum\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of gaussian parameters (length must be a multiple\n of 3):\n *(area1, centroid1, fwhm1, area2, centroid2, fwhm2,...)*\n :return: Array of sum of gaussian functions at each ``x`` coordinate.\n ";
+static PyMethodDef __pyx_mdef_9functions_7sum_agauss = {"sum_agauss", (PyCFunction)__pyx_pw_9functions_7sum_agauss, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_6sum_agauss};
+static PyObject *__pyx_pw_9functions_7sum_agauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_agauss (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_agauss") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_agauss", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_agauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_6sum_agauss(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_6sum_agauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_agauss", 0);
+
+ /* "functions.pyx":196
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No gaussian parameters specified. " +
+ * "At least 3 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":197
+ *
+ * if not len(params):
+ * raise IndexError("No gaussian parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 3 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_gaussian_parameters_specified, __pyx_kp_s_At_least_3_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":200
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":201
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":202
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":200
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":203
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":204
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":205
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":206
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":204
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":207
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":208
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":209
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_agauss(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":208
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":212
+ *
+ * status = functions_wrapper.sum_agauss(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":213
+ * status = functions_wrapper.sum_agauss(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":214
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":211
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_agauss( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_agauss((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":216
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":217
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":219
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":176
+ *
+ *
+ * def sum_agauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ * where:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_agauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":222
+ *
+ *
+ * def sum_fastagauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ * where:
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_9sum_fastagauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_8sum_fastagauss[] = "sum_fastagauss(x, *params)\nReturn a sum of gaussian functions defined by *(area, centroid, fwhm)*,\n where:\n\n - *area* is the area underneath the peak\n - *centroid* is the peak x-coordinate\n - *fwhm* is the full-width at half maximum\n\n This implementation differs from :func:`sum_agauss` by the usage of a\n lookup table with precalculated exponential values. This might speed up\n the computation for large numbers of individual gaussian functions.\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of gaussian parameters (length must be a multiple\n of 3):\n *(area1, centroid1, fwhm1, area2, centroid2, fwhm2,...)*\n :return: Array of sum of gaussian functions at each ``x`` coordinate.\n ";
+static PyMethodDef __pyx_mdef_9functions_9sum_fastagauss = {"sum_fastagauss", (PyCFunction)__pyx_pw_9functions_9sum_fastagauss, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_8sum_fastagauss};
+static PyObject *__pyx_pw_9functions_9sum_fastagauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_fastagauss (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_fastagauss") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_fastagauss", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_fastagauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_8sum_fastagauss(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_8sum_fastagauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_fastagauss", 0);
+
+ /* "functions.pyx":246
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No gaussian parameters specified. " +
+ * "At least 3 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":247
+ *
+ * if not len(params):
+ * raise IndexError("No gaussian parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 3 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_gaussian_parameters_specified, __pyx_kp_s_At_least_3_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":250
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":251
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":252
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 252; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":250
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":253
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":254
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":255
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":256
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":254
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":257
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":258
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":259
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_fastagauss(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":258
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":262
+ *
+ * status = functions_wrapper.sum_fastagauss(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":263
+ * status = functions_wrapper.sum_fastagauss(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":264
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":261
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_fastagauss( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_fastagauss((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":266
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":267
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":269
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":222
+ *
+ *
+ * def sum_fastagauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ * where:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_fastagauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":272
+ *
+ *
+ * def sum_splitgauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm1, fwhm2)*,
+ * where:
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_11sum_splitgauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_10sum_splitgauss[] = "sum_splitgauss(x, *params)\nReturn a sum of gaussian functions defined by *(area, centroid, fwhm1, fwhm2)*,\n where:\n\n - *height* is the peak amplitude\n - *centroid* is the peak x-coordinate\n - *fwhm1* is the full-width at half maximum for the distribution\n when ``x < centroid``\n - *fwhm2* is the full-width at half maximum for the distribution\n when ``x > centroid``\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of gaussian parameters (length must be a multiple\n of 4):\n *(height1, centroid1, fwhm11, fwhm21, height2, centroid2, fwhm12, fwhm22,...)*\n :return: Array of sum of split gaussian functions at each ``x`` coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_11sum_splitgauss = {"sum_splitgauss", (PyCFunction)__pyx_pw_9functions_11sum_splitgauss, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_10sum_splitgauss};
+static PyObject *__pyx_pw_9functions_11sum_splitgauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_splitgauss (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_splitgauss") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_splitgauss", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_splitgauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_10sum_splitgauss(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_10sum_splitgauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_splitgauss", 0);
+
+ /* "functions.pyx":295
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No gaussian parameters specified. " +
+ * "At least 4 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":296
+ *
+ * if not len(params):
+ * raise IndexError("No gaussian parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 4 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_gaussian_parameters_specified, __pyx_kp_s_At_least_4_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":299
+ * "At least 4 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":300
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":301
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":299
+ * "At least 4 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":302
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":303
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":304
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":305
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":303
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":306
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":307
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":308
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_splitgauss(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":307
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":311
+ *
+ * status = functions_wrapper.sum_splitgauss(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":312
+ * status = functions_wrapper.sum_splitgauss(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":313
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":310
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_splitgauss( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_splitgauss((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":315
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":316
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":318
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":272
+ *
+ *
+ * def sum_splitgauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm1, fwhm2)*,
+ * where:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_splitgauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":321
+ *
+ *
+ * def sum_apvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of pseudo-Voigt functions, defined by *(area, centroid, fwhm,
+ * eta)*.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_13sum_apvoigt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_12sum_apvoigt[] = "sum_apvoigt(x, *params)\nReturn a sum of pseudo-Voigt functions, defined by *(area, centroid, fwhm,\n eta)*.\n\n The pseudo-Voigt profile ``PV(x)`` is an approximation of the Voigt\n profile using a linear combination of a Gaussian curve ``G(x)`` and a\n Lorentzian curve ``L(x)`` instead of their convolution.\n\n - *area* is the area underneath both G(x) and L(x)\n - *centroid* is the peak x-coordinate for both functions\n - *fwhm* is the full-width at half maximum of both functions\n - *eta* is the Lorentz factor: PV(x) = eta * L(x) + (1 - eta) * G(x)\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of pseudo-Voigt parameters (length must be a multiple\n of 4):\n *(area1, centroid1, fwhm1, eta1, area2, centroid2, fwhm2, eta2,...)*\n :return: Array of sum of pseudo-Voigt functions at each ``x`` coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_13sum_apvoigt = {"sum_apvoigt", (PyCFunction)__pyx_pw_9functions_13sum_apvoigt, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_12sum_apvoigt};
+static PyObject *__pyx_pw_9functions_13sum_apvoigt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_apvoigt (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_apvoigt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_apvoigt", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_apvoigt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_12sum_apvoigt(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_12sum_apvoigt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_apvoigt", 0);
+
+ /* "functions.pyx":346
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 4 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":347
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 4 parameters are required.")
+ * x_c = numpy.array(x,
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_4_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":349
+ * raise IndexError("No parameters specified. " +
+ * "At least 4 parameters are required.")
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":350
+ * "At least 4 parameters are required.")
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":351
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":349
+ * raise IndexError("No parameters specified. " +
+ * "At least 4 parameters are required.")
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":352
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":353
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":354
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":355
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":353
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":356
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":357
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":358
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_apvoigt(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":357
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":361
+ *
+ * status = functions_wrapper.sum_apvoigt(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":362
+ * status = functions_wrapper.sum_apvoigt(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":363
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":360
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_apvoigt( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_apvoigt((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":365
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":366
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":368
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":321
+ *
+ *
+ * def sum_apvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of pseudo-Voigt functions, defined by *(area, centroid, fwhm,
+ * eta)*.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_apvoigt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":371
+ *
+ *
+ * def sum_pvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of pseudo-Voigt functions, defined by *(height, centroid,
+ * fwhm, eta)*.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_15sum_pvoigt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_14sum_pvoigt[] = "sum_pvoigt(x, *params)\nReturn a sum of pseudo-Voigt functions, defined by *(height, centroid,\n fwhm, eta)*.\n\n The pseudo-Voigt profile ``PV(x)`` is an approximation of the Voigt\n profile using a linear combination of a Gaussian curve ``G(x)`` and a\n Lorentzian curve ``L(x)`` instead of their convolution.\n\n - *height* is the peak amplitude of G(x) and L(x)\n - *centroid* is the peak x-coordinate for both functions\n - *fwhm* is the full-width at half maximum of both functions\n - *eta* is the Lorentz factor: PV(x) = eta * L(x) + (1 - eta) * G(x)\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of pseudo-Voigt parameters (length must be a multiple\n of 4):\n *(height1, centroid1, fwhm1, eta1, height2, centroid2, fwhm2, eta2,...)*\n :return: Array of sum of pseudo-Voigt functions at each ``x`` coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_15sum_pvoigt = {"sum_pvoigt", (PyCFunction)__pyx_pw_9functions_15sum_pvoigt, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_14sum_pvoigt};
+static PyObject *__pyx_pw_9functions_15sum_pvoigt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_pvoigt (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_pvoigt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_pvoigt", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_pvoigt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_14sum_pvoigt(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_14sum_pvoigt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_pvoigt", 0);
+
+ /* "functions.pyx":396
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 4 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":397
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 4 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_4_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":400
+ * "At least 4 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":401
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":402
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":400
+ * "At least 4 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":403
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":404
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":405
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":406
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":404
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":407
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":408
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":409
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_pvoigt(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":408
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":412
+ *
+ * status = functions_wrapper.sum_pvoigt(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":413
+ * status = functions_wrapper.sum_pvoigt(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":414
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":411
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_pvoigt( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_pvoigt((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":416
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":417
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":419
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":371
+ *
+ *
+ * def sum_pvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of pseudo-Voigt functions, defined by *(height, centroid,
+ * fwhm, eta)*.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_pvoigt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":422
+ *
+ *
+ * def sum_splitpvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of split pseudo-Voigt functions, defined by *(height,
+ * centroid, fwhm1, fwhm2, eta)*.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_17sum_splitpvoigt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_16sum_splitpvoigt[] = "sum_splitpvoigt(x, *params)\nReturn a sum of split pseudo-Voigt functions, defined by *(height,\n centroid, fwhm1, fwhm2, eta)*.\n\n The pseudo-Voigt profile ``PV(x)`` is an approximation of the Voigt\n profile using a linear combination of a Gaussian curve ``G(x)`` and a\n Lorentzian curve ``L(x)`` instead of their convolution.\n\n - *height* is the peak amplitudefor G(x) and L(x)\n - *centroid* is the peak x-coordinate for both functions\n - *fwhm1* is the full-width at half maximum of both functions\n when ``x < centroid``\n - *fwhm2* is the full-width at half maximum of both functions\n when ``x > centroid``\n - *eta* is the Lorentz factor: PV(x) = eta * L(x) + (1 - eta) * G(x)\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of pseudo-Voigt parameters (length must be a multiple\n of 5):\n *(height1, centroid1, fwhm11, fwhm21, eta1,...)*\n :return: Array of sum of split pseudo-Voigt functions at each ``x``\n coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_17sum_splitpvoigt = {"sum_splitpvoigt", (PyCFunction)__pyx_pw_9functions_17sum_splitpvoigt, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_16sum_splitpvoigt};
+static PyObject *__pyx_pw_9functions_17sum_splitpvoigt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_splitpvoigt (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_splitpvoigt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_splitpvoigt", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_splitpvoigt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_16sum_splitpvoigt(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_16sum_splitpvoigt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_splitpvoigt", 0);
+
+ /* "functions.pyx":451
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 5 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":452
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 5 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_5_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":455
+ * "At least 5 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":456
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":457
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":455
+ * "At least 5 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":458
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":459
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":460
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":461
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":459
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":462
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":463
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":464
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_splitpvoigt(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":463
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":467
+ *
+ * status = functions_wrapper.sum_splitpvoigt(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":468
+ * status = functions_wrapper.sum_splitpvoigt(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":469
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":466
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_splitpvoigt( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_splitpvoigt((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":471
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":472
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":474
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 474; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":422
+ *
+ *
+ * def sum_splitpvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of split pseudo-Voigt functions, defined by *(height,
+ * centroid, fwhm1, fwhm2, eta)*.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_splitpvoigt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":477
+ *
+ *
+ * def sum_lorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ * defined by *(height, centroid, fwhm)*.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_19sum_lorentz(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_18sum_lorentz[] = "sum_lorentz(x, *params)\nReturn a sum of Lorentz distributions, also known as Cauchy distribution,\n defined by *(height, centroid, fwhm)*.\n\n - *height* is the peak amplitude\n - *centroid* is the peak x-coordinate\n - *fwhm* is the full-width at half maximum\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of Lorentz parameters (length must be a multiple\n of 3):\n *(height1, centroid1, fwhm1,...)*\n :return: Array of sum Lorentz functions at each ``x``\n coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_19sum_lorentz = {"sum_lorentz", (PyCFunction)__pyx_pw_9functions_19sum_lorentz, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_18sum_lorentz};
+static PyObject *__pyx_pw_9functions_19sum_lorentz(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_lorentz (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_lorentz") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_lorentz", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_lorentz", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_18sum_lorentz(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_18sum_lorentz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_lorentz", 0);
+
+ /* "functions.pyx":498
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 3 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":499
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 3 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_3_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":502
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":503
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":504
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":502
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":505
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":506
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":507
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":508
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 508; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 508; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":506
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":509
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 509; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 509; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 509; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":510
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":511
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_lorentz(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 511; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":510
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":514
+ *
+ * status = functions_wrapper.sum_lorentz(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":515
+ * status = functions_wrapper.sum_lorentz(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":516
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 516; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":513
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_lorentz( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_lorentz((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":518
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":519
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":521
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":477
+ *
+ *
+ * def sum_lorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ * defined by *(height, centroid, fwhm)*.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_lorentz", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":524
+ *
+ *
+ * def sum_alorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ * defined by *(area, centroid, fwhm)*.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_21sum_alorentz(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_20sum_alorentz[] = "sum_alorentz(x, *params)\nReturn a sum of Lorentz distributions, also known as Cauchy distribution,\n defined by *(area, centroid, fwhm)*.\n\n - *area* is the area underneath the peak\n - *centroid* is the peak x-coordinate for both functions\n - *fwhm* is the full-width at half maximum\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of Lorentz parameters (length must be a multiple\n of 3):\n *(area1, centroid1, fwhm1,...)*\n :return: Array of sum of Lorentz functions at each ``x``\n coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_21sum_alorentz = {"sum_alorentz", (PyCFunction)__pyx_pw_9functions_21sum_alorentz, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_20sum_alorentz};
+static PyObject *__pyx_pw_9functions_21sum_alorentz(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_alorentz (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_alorentz") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_alorentz", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_alorentz", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_20sum_alorentz(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_20sum_alorentz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_alorentz", 0);
+
+ /* "functions.pyx":545
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 3 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":546
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 3 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_3_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":549
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":550
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":551
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 551; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 551; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":549
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 549; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":552
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":553
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":554
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":555
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":553
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":556
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":557
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":558
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_alorentz(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":557
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":561
+ *
+ * status = functions_wrapper.sum_alorentz(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":562
+ * status = functions_wrapper.sum_alorentz(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 562; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":563
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":560
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_alorentz( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_alorentz((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":565
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":566
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 566; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 566; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":568
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":524
+ *
+ *
+ * def sum_alorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ * defined by *(area, centroid, fwhm)*.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_alorentz", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":571
+ *
+ *
+ * def sum_splitlorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of split Lorentz distributions,
+ * defined by *(height, centroid, fwhm1, fwhm2)*.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_23sum_splitlorentz(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_22sum_splitlorentz[] = "sum_splitlorentz(x, *params)\nReturn a sum of split Lorentz distributions,\n defined by *(height, centroid, fwhm1, fwhm2)*.\n\n - *height* is the peak amplitude\n - *centroid* is the peak x-coordinate for both functions\n - *fwhm1* is the full-width at half maximum for ``x < centroid``\n - *fwhm2* is the full-width at half maximum for ``x > centroid``\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of Lorentz parameters (length must be a multiple\n of 4):\n *(height1, centroid1, fwhm11, fwhm21...)*\n :return: Array of sum of Lorentz functions at each ``x``\n coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_23sum_splitlorentz = {"sum_splitlorentz", (PyCFunction)__pyx_pw_9functions_23sum_splitlorentz, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_22sum_splitlorentz};
+static PyObject *__pyx_pw_9functions_23sum_splitlorentz(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_splitlorentz (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_splitlorentz") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_splitlorentz", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_splitlorentz", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_22sum_splitlorentz(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_22sum_splitlorentz(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_splitlorentz", 0);
+
+ /* "functions.pyx":593
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 4 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 593; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":594
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 4 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_4_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":597
+ * "At least 4 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":598
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":599
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":597
+ * "At least 4 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":600
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":601
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":602
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":603
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":601
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":604
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":605
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":606
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_splitlorentz(
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 606; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 606; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":605
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":609
+ *
+ * status = functions_wrapper.sum_splitlorentz(
+ * &x_c[0], x.size, # <<<<<<<<<<<<<<
+ * &params_c[0], params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":610
+ * status = functions_wrapper.sum_splitlorentz(
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 610; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 610; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 610; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 610; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":611
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 611; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":608
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_splitlorentz( # <<<<<<<<<<<<<<
+ * &x_c[0], x.size,
+ * &params_c[0], params_c.size,
+ */
+ __pyx_v_status = sum_splitlorentz((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":613
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":614
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__34, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":616
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":571
+ *
+ *
+ * def sum_splitlorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of split Lorentz distributions,
+ * defined by *(height, centroid, fwhm1, fwhm2)*.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_splitlorentz", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":619
+ *
+ *
+ * def sum_stepdown(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of stepdown functions.
+ * defined by *(height, centroid, fwhm)*.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_25sum_stepdown(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_24sum_stepdown[] = "sum_stepdown(x, *params)\nReturn a sum of stepdown functions.\n defined by *(height, centroid, fwhm)*.\n\n - *height* is the step's amplitude\n - *centroid* is the step's x-coordinate\n - *fwhm* is the full-width at half maximum for the derivative,\n which is a measure of the *sharpness* of the step-down's edge\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of stepdown parameters (length must be a multiple\n of 3):\n *(height1, centroid1, fwhm1,...)*\n :return: Array of sum of stepdown functions at each ``x``\n coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_25sum_stepdown = {"sum_stepdown", (PyCFunction)__pyx_pw_9functions_25sum_stepdown, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_24sum_stepdown};
+static PyObject *__pyx_pw_9functions_25sum_stepdown(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_stepdown (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_stepdown") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_stepdown", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_stepdown", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_24sum_stepdown(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_24sum_stepdown(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_stepdown", 0);
+
+ /* "functions.pyx":641
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 3 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":642
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 3 parameters are required.")
+ * x_c = numpy.array(x,
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_3_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 642; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 642; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 642; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 642; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":644
+ * raise IndexError("No parameters specified. " +
+ * "At least 3 parameters are required.")
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":645
+ * "At least 3 parameters are required.")
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":646
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":644
+ * raise IndexError("No parameters specified. " +
+ * "At least 3 parameters are required.")
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":647
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__35, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":648
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":649
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":650
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":648
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":651
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__36, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":652
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":653
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_stepdown(&x_c[0],
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 653; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":652
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":655
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_stepdown(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 655; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":656
+ *
+ * status = functions_wrapper.sum_stepdown(&x_c[0],
+ * x.size, # <<<<<<<<<<<<<<
+ * &params_c[0],
+ * params_c.size,
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":657
+ * status = functions_wrapper.sum_stepdown(&x_c[0],
+ * x.size,
+ * &params_c[0], # <<<<<<<<<<<<<<
+ * params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":658
+ * x.size,
+ * &params_c[0],
+ * params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 658; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":659
+ * &params_c[0],
+ * params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 659; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":655
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_stepdown(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_v_status = sum_stepdown((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":661
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":662
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__37, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":664
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 664; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":619
+ *
+ *
+ * def sum_stepdown(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of stepdown functions.
+ * defined by *(height, centroid, fwhm)*.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_stepdown", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":667
+ *
+ *
+ * def sum_stepup(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of stepup functions.
+ * defined by *(height, centroid, fwhm)*.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_27sum_stepup(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_26sum_stepup[] = "sum_stepup(x, *params)\nReturn a sum of stepup functions.\n defined by *(height, centroid, fwhm)*.\n\n - *height* is the step's amplitude\n - *centroid* is the step's x-coordinate\n - *fwhm* is the full-width at half maximum for the derivative,\n which is a measure of the *sharpness* of the step-up's edge\n\n :param x: Independant variable where the gaussians are calculated\n :type x: numpy.ndarray\n :param params: Array of stepup parameters (length must be a multiple\n of 3):\n *(height1, centroid1, fwhm1,...)*\n :return: Array of sum of stepup functions at each ``x``\n coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_27sum_stepup = {"sum_stepup", (PyCFunction)__pyx_pw_9functions_27sum_stepup, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_26sum_stepup};
+static PyObject *__pyx_pw_9functions_27sum_stepup(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_stepup (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_stepup") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_stepup", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_stepup", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_26sum_stepup(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_26sum_stepup(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_stepup", 0);
+
+ /* "functions.pyx":689
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 3 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 689; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":690
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 3 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_3_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 690; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 690; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 690; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 690; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":693
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":694
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":695
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 695; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 695; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":693
+ * "At least 3 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":696
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 696; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__38, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 696; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 696; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":697
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":698
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":699
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 699; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 699; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":697
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":700
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 700; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__39, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 700; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 700; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":701
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":702
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_stepup(&x_c[0],
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 702; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 702; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":701
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 701; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":704
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_stepup(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 704; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":705
+ *
+ * status = functions_wrapper.sum_stepup(&x_c[0],
+ * x.size, # <<<<<<<<<<<<<<
+ * &params_c[0],
+ * params_c.size,
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":706
+ * status = functions_wrapper.sum_stepup(&x_c[0],
+ * x.size,
+ * &params_c[0], # <<<<<<<<<<<<<<
+ * params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 706; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":707
+ * x.size,
+ * &params_c[0],
+ * params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":708
+ * &params_c[0],
+ * params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":704
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_stepup(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_v_status = sum_stepup((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":710
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":711
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__40, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 711; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 711; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":713
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 713; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":667
+ *
+ *
+ * def sum_stepup(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of stepup functions.
+ * defined by *(height, centroid, fwhm)*.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_stepup", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":716
+ *
+ *
+ * def sum_slit(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of slit functions.
+ * defined by *(height, position, fwhm, beamfwhm)*.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_29sum_slit(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_28sum_slit[] = "sum_slit(x, *params)\nReturn a sum of slit functions.\n defined by *(height, position, fwhm, beamfwhm)*.\n\n - *height* is the slit's amplitude\n - *position* is the center of the slit's x-coordinate\n - *fwhm* is the full-width at half maximum of the slit\n - *beamfwhm* is the full-width at half maximum of the\n derivative, which is a measure of the *sharpness*\n of the edges of the slit\n\n :param x: Independant variable where the slits are calculated\n :type x: numpy.ndarray\n :param params: Array of slit parameters (length must be a multiple\n of 4):\n *(height1, centroid1, fwhm1, beamfwhm1,...)*\n :return: Array of sum of slit functions at each ``x``\n coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_29sum_slit = {"sum_slit", (PyCFunction)__pyx_pw_9functions_29sum_slit, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_28sum_slit};
+static PyObject *__pyx_pw_9functions_29sum_slit(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_slit (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_slit") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_slit", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_slit", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_28sum_slit(__pyx_self, __pyx_v_x, __pyx_v_params);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_28sum_slit(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_slit", 0);
+
+ /* "functions.pyx":740
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 4 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":741
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 4 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_4_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":744
+ * "At least 4 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":745
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":746
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":744
+ * "At least 4 parameters are required.")
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":747
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 747; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__41, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 747; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 747; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":748
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":749
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":750
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 750; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 750; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":748
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":751
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__42, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":752
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":753
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_slit(&x_c[0],
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 753; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 753; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":752
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 752; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":755
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_slit(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 755; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":756
+ *
+ * status = functions_wrapper.sum_slit(&x_c[0],
+ * x.size, # <<<<<<<<<<<<<<
+ * &params_c[0],
+ * params_c.size,
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 756; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 756; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":757
+ * status = functions_wrapper.sum_slit(&x_c[0],
+ * x.size,
+ * &params_c[0], # <<<<<<<<<<<<<<
+ * params_c.size,
+ * &y_c[0])
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 757; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":758
+ * x.size,
+ * &params_c[0],
+ * params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0])
+ *
+ */
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":759
+ * &params_c[0],
+ * params_c.size,
+ * &y_c[0]) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":755
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_slit(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_v_status = sum_slit((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))));
+
+ /* "functions.pyx":761
+ * &y_c[0])
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":762
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__43, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":764
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 764; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":716
+ *
+ *
+ * def sum_slit(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of slit functions.
+ * defined by *(height, position, fwhm, beamfwhm)*.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_slit", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":767
+ *
+ *
+ * def sum_ahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True, lt_term=True, step_term=True):
+ * """Return a sum of ahypermet functions.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_31sum_ahypermet(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_30sum_ahypermet[] = "sum_ahypermet(x, *params, gaussian_term=True, st_term=True, lt_term=True, step_term=True)\nReturn a sum of ahypermet functions.\n defined by *(area, position, fwhm, st_area_r, st_slope_r, lt_area_r,\n lt_slope_r, step_height_r)*.\n\n - *area* is the area underneath the gaussian peak\n - *position* is the center of the various peaks and the position of\n the step down\n - *fwhm* is the full-width at half maximum of the terms\n - *st_area_r* is factor between the gaussian area and the area of the\n short tail term\n - *st_slope_r* is a ratio related to the slope of the short tail\n in the low ``x`` values (the lower, the steeper)\n - *lt_area_r* is ratio between the gaussian area and the area of the\n long tail term\n - *lt_slope_r* is a ratio related to the slope of the long tail\n in the low ``x`` values (the lower, the steeper)\n - *step_height_r* is the ratio between the height of the step down\n and the gaussian height\n\n A hypermet function is a sum of four functions (terms):\n\n - a gaussian term\n - a long tail term\n - a short tail term\n - a step down term\n\n :param x: Independant variable where the hypermets are calculated\n :type x: numpy.ndarray\n :param params: Array of hypermet parameters (length must be a multiple\n of 8):\n *(area1, position1, fwhm1, st_area_r1, st_slope_r1, lt_area_r1,\n lt_slope_r1, step_height_r1...)*\n :param gaussian_term: If ``True``, enable gaussian term. Default ``True``\n :param st_term: If ``True``, enable gaussian term. Default ``True``\n :param lt_term: If ``True``, enable gaussian term. Default ``True``\n :param step_term: If ``True``, enable gaussian term. Default ``True``\n :return: Array of sum of hypermet functions at each ``x`` coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_31sum_ahypermet = {"sum_ahypermet", (PyCFunction)__pyx_pw_9functions_31sum_ahypermet, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_30sum_ahypermet};
+static PyObject *__pyx_pw_9functions_31sum_ahypermet(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_gaussian_term = 0;
+ PyObject *__pyx_v_st_term = 0;
+ PyObject *__pyx_v_lt_term = 0;
+ PyObject *__pyx_v_step_term = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_ahypermet (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_gaussian_term,&__pyx_n_s_st_term,&__pyx_n_s_lt_term,&__pyx_n_s_step_term,0};
+ PyObject* values[5] = {0,0,0,0,0};
+
+ /* "functions.pyx":768
+ *
+ * def sum_ahypermet(x, *params,
+ * gaussian_term=True, st_term=True, lt_term=True, step_term=True): # <<<<<<<<<<<<<<
+ * """Return a sum of ahypermet functions.
+ * defined by *(area, position, fwhm, st_area_r, st_slope_r, lt_area_r,
+ */
+ values[1] = ((PyObject *)Py_True);
+ values[2] = ((PyObject *)Py_True);
+ values[3] = ((PyObject *)Py_True);
+ values[4] = ((PyObject *)Py_True);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (kw_args > 0 && likely(kw_args <= 4)) {
+ Py_ssize_t index;
+ for (index = 1; index < 5 && kw_args > 0; index++) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, *__pyx_pyargnames[index]);
+ if (value) { values[index] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_ahypermet") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ __pyx_v_gaussian_term = values[1];
+ __pyx_v_st_term = values[2];
+ __pyx_v_lt_term = values[3];
+ __pyx_v_step_term = values[4];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_ahypermet", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_ahypermet", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_30sum_ahypermet(__pyx_self, __pyx_v_x, __pyx_v_gaussian_term, __pyx_v_st_term, __pyx_v_lt_term, __pyx_v_step_term, __pyx_v_params);
+
+ /* "functions.pyx":767
+ *
+ *
+ * def sum_ahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True, lt_term=True, step_term=True):
+ * """Return a sum of ahypermet functions.
+ */
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_30sum_ahypermet(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_gaussian_term, PyObject *__pyx_v_st_term, PyObject *__pyx_v_lt_term, PyObject *__pyx_v_step_term, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_tail_flags = NULL;
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_ahypermet", 0);
+
+ /* "functions.pyx":812
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 8 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 812; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":813
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 8 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_8_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":817
+ *
+ * # Sum binary flags to activate various terms of the equation
+ * tail_flags = 1 if gaussian_term else 0 # <<<<<<<<<<<<<<
+ * if st_term:
+ * tail_flags += 2
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_gaussian_term); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_t_3 = __pyx_int_1;
+ } else {
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ }
+ __pyx_v_tail_flags = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "functions.pyx":818
+ * # Sum binary flags to activate various terms of the equation
+ * tail_flags = 1 if gaussian_term else 0
+ * if st_term: # <<<<<<<<<<<<<<
+ * tail_flags += 2
+ * if lt_term:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_st_term); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 818; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":819
+ * tail_flags = 1 if gaussian_term else 0
+ * if st_term:
+ * tail_flags += 2 # <<<<<<<<<<<<<<
+ * if lt_term:
+ * tail_flags += 4
+ */
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_tail_flags, __pyx_int_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_tail_flags, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "functions.pyx":820
+ * if st_term:
+ * tail_flags += 2
+ * if lt_term: # <<<<<<<<<<<<<<
+ * tail_flags += 4
+ * if step_term:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_lt_term); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 820; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":821
+ * tail_flags += 2
+ * if lt_term:
+ * tail_flags += 4 # <<<<<<<<<<<<<<
+ * if step_term:
+ * tail_flags += 8
+ */
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_tail_flags, __pyx_int_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_tail_flags, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "functions.pyx":822
+ * if lt_term:
+ * tail_flags += 4
+ * if step_term: # <<<<<<<<<<<<<<
+ * tail_flags += 8
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_step_term); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":823
+ * tail_flags += 4
+ * if step_term:
+ * tail_flags += 8 # <<<<<<<<<<<<<<
+ *
+ * x_c = numpy.array(x,
+ */
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_tail_flags, __pyx_int_8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_tail_flags, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "functions.pyx":825
+ * tail_flags += 8
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 825; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 825; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 825; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 825; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":826
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 825; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":827
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 825; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 825; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":825
+ * tail_flags += 8
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 825; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":828
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__44, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":829
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":830
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":831
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":829
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":832
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__45, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":833
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":834
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_ahypermet(&x_c[0],
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":833
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":836
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_ahypermet(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":837
+ *
+ * status = functions_wrapper.sum_ahypermet(&x_c[0],
+ * x.size, # <<<<<<<<<<<<<<
+ * &params_c[0],
+ * params_c.size,
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":838
+ * status = functions_wrapper.sum_ahypermet(&x_c[0],
+ * x.size,
+ * &params_c[0], # <<<<<<<<<<<<<<
+ * params_c.size,
+ * &y_c[0],
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":839
+ * x.size,
+ * &params_c[0],
+ * params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0],
+ * tail_flags)
+ */
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":840
+ * &params_c[0],
+ * params_c.size,
+ * &y_c[0], # <<<<<<<<<<<<<<
+ * tail_flags)
+ *
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":841
+ * params_c.size,
+ * &y_c[0],
+ * tail_flags) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_tail_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":836
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_ahypermet(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_v_status = sum_ahypermet((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))), __pyx_t_15);
+
+ /* "functions.pyx":843
+ * tail_flags)
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":844
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__46, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":846
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 846; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":767
+ *
+ *
+ * def sum_ahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True, lt_term=True, step_term=True):
+ * """Return a sum of ahypermet functions.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_ahypermet", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XDECREF(__pyx_v_tail_flags);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":849
+ *
+ *
+ * def sum_fastahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True,
+ * lt_term=True, step_term=True):
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_33sum_fastahypermet(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_32sum_fastahypermet[] = "sum_fastahypermet(x, *params, gaussian_term=True, st_term=True, lt_term=True, step_term=True)\nReturn a sum of hypermet functions defined by *(area, position, fwhm,\n st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r)*.\n\n - *area* is the area underneath the gaussian peak\n - *position* is the center of the various peaks and the position of\n the step down\n - *fwhm* is the full-width at half maximum of the terms\n - *st_area_r* is factor between the gaussian area and the area of the\n short tail term\n - *st_slope_r* is a parameter related to the slope of the short tail\n in the low ``x`` values (the lower, the steeper)\n - *lt_area_r* is factor between the gaussian area and the area of the\n long tail term\n - *lt_slope_r* is a parameter related to the slope of the long tail\n in the low ``x`` values (the lower, the steeper)\n - *step_height_r* is the factor between the height of the step down\n and the gaussian height\n\n A hypermet function is a sum of four functions (terms):\n\n - a gaussian term\n - a long tail term\n - a short tail term\n - a step down term\n\n This function differs from :func:`sum_ahypermet` by the use of a lookup\n table for calculating exponentials. This offers better performance when\n calculating many functions for large ``x`` arrays.\n\n :param x: Independant variable where the hypermets are calculated\n :type x: numpy.ndarray\n :param params: Array of hypermet parameters (length must be a multiple\n of 8):\n *(area1, position1, fwhm1, st_area_r1, st_slope_r1, lt_area_r1,\n lt_slope_r1, step_height_r1...)*\n :param gaussian_term: If ``True``, enable gaussian term. Default ``True``\n :param st_term: If ``True``, enable gaussian term. Default ``True``\n :param lt_term: If ``True``, enable gaussian term. Default ``True``\n :param step_t""erm: If ``True``, enable gaussian term. Default ``True``\n :return: Array of sum of hypermet functions at each ``x`` coordinate\n ";
+static PyMethodDef __pyx_mdef_9functions_33sum_fastahypermet = {"sum_fastahypermet", (PyCFunction)__pyx_pw_9functions_33sum_fastahypermet, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_32sum_fastahypermet};
+static PyObject *__pyx_pw_9functions_33sum_fastahypermet(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_gaussian_term = 0;
+ PyObject *__pyx_v_st_term = 0;
+ PyObject *__pyx_v_lt_term = 0;
+ PyObject *__pyx_v_step_term = 0;
+ PyObject *__pyx_v_params = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sum_fastahypermet (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_params = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_params)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_params);
+ } else {
+ __pyx_v_params = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_gaussian_term,&__pyx_n_s_st_term,&__pyx_n_s_lt_term,&__pyx_n_s_step_term,0};
+ PyObject* values[5] = {0,0,0,0,0};
+
+ /* "functions.pyx":850
+ *
+ * def sum_fastahypermet(x, *params,
+ * gaussian_term=True, st_term=True, # <<<<<<<<<<<<<<
+ * lt_term=True, step_term=True):
+ * """Return a sum of hypermet functions defined by *(area, position, fwhm,
+ */
+ values[1] = ((PyObject *)Py_True);
+ values[2] = ((PyObject *)Py_True);
+
+ /* "functions.pyx":851
+ * def sum_fastahypermet(x, *params,
+ * gaussian_term=True, st_term=True,
+ * lt_term=True, step_term=True): # <<<<<<<<<<<<<<
+ * """Return a sum of hypermet functions defined by *(area, position, fwhm,
+ * st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r)*.
+ */
+ values[3] = ((PyObject *)Py_True);
+ values[4] = ((PyObject *)Py_True);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (kw_args > 0 && likely(kw_args <= 4)) {
+ Py_ssize_t index;
+ for (index = 1; index < 5 && kw_args > 0; index++) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, *__pyx_pyargnames[index]);
+ if (value) { values[index] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "sum_fastahypermet") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ __pyx_v_gaussian_term = values[1];
+ __pyx_v_st_term = values[2];
+ __pyx_v_lt_term = values[3];
+ __pyx_v_step_term = values[4];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("sum_fastahypermet", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_params); __pyx_v_params = 0;
+ __Pyx_AddTraceback("functions.sum_fastahypermet", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_32sum_fastahypermet(__pyx_self, __pyx_v_x, __pyx_v_gaussian_term, __pyx_v_st_term, __pyx_v_lt_term, __pyx_v_step_term, __pyx_v_params);
+
+ /* "functions.pyx":849
+ *
+ *
+ * def sum_fastahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True,
+ * lt_term=True, step_term=True):
+ */
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_params);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_32sum_fastahypermet(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_gaussian_term, PyObject *__pyx_v_st_term, PyObject *__pyx_v_lt_term, PyObject *__pyx_v_step_term, PyObject *__pyx_v_params) {
+ __Pyx_memviewslice __pyx_v_x_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_params_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *__pyx_v_tail_flags = NULL;
+ int __pyx_v_status;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ __Pyx_memviewslice __pyx_t_8 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_9 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_10 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ int __pyx_t_15;
+ PyObject *__pyx_t_16 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sum_fastahypermet", 0);
+
+ /* "functions.pyx":898
+ * double[::1] y_c
+ *
+ * if not len(params): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 8 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_params); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":899
+ *
+ * if not len(params):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 8 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_8_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":903
+ *
+ * # Sum binary flags to activate various terms of the equation
+ * tail_flags = 1 if gaussian_term else 0 # <<<<<<<<<<<<<<
+ * if st_term:
+ * tail_flags += 2
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_gaussian_term); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_t_3 = __pyx_int_1;
+ } else {
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ }
+ __pyx_v_tail_flags = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "functions.pyx":904
+ * # Sum binary flags to activate various terms of the equation
+ * tail_flags = 1 if gaussian_term else 0
+ * if st_term: # <<<<<<<<<<<<<<
+ * tail_flags += 2
+ * if lt_term:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_st_term); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 904; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":905
+ * tail_flags = 1 if gaussian_term else 0
+ * if st_term:
+ * tail_flags += 2 # <<<<<<<<<<<<<<
+ * if lt_term:
+ * tail_flags += 4
+ */
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_tail_flags, __pyx_int_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_tail_flags, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "functions.pyx":906
+ * if st_term:
+ * tail_flags += 2
+ * if lt_term: # <<<<<<<<<<<<<<
+ * tail_flags += 4
+ * if step_term:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_lt_term); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":907
+ * tail_flags += 2
+ * if lt_term:
+ * tail_flags += 4 # <<<<<<<<<<<<<<
+ * if step_term:
+ * tail_flags += 8
+ */
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_tail_flags, __pyx_int_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_tail_flags, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "functions.pyx":908
+ * if lt_term:
+ * tail_flags += 4
+ * if step_term: # <<<<<<<<<<<<<<
+ * tail_flags += 8
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_step_term); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":909
+ * tail_flags += 4
+ * if step_term:
+ * tail_flags += 8 # <<<<<<<<<<<<<<
+ *
+ * # TODO (maybe):
+ */
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_tail_flags, __pyx_int_8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_tail_flags, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "functions.pyx":918
+ * # lt_slope_r (params[8*i + 6]) and lt_term.
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+
+ /* "functions.pyx":919
+ *
+ * x_c = numpy.array(x,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":920
+ * x_c = numpy.array(x,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":918
+ * # lt_slope_r (params[8*i + 6]) and lt_term.
+ *
+ * x_c = numpy.array(x, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":921
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_tuple__47, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_8.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_x_c = __pyx_t_8;
+ __pyx_t_8.memview = NULL;
+ __pyx_t_8.data = NULL;
+
+ /* "functions.pyx":922
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_params);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_params);
+ __Pyx_GIVEREF(__pyx_v_params);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "functions.pyx":923
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params,
+ * copy=False, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_False) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":924
+ * params_c = numpy.array(params,
+ * copy=False,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":922
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * params_c = numpy.array(params, # <<<<<<<<<<<<<<
+ * copy=False,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":925
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__48, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_6);
+ if (unlikely(!__pyx_t_9.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_params_c = __pyx_t_9;
+ __pyx_t_9.memview = NULL;
+ __pyx_t_9.data = NULL;
+
+ /* "functions.pyx":926
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_shape, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":927
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * status = functions_wrapper.sum_fastahypermet(&x_c[0],
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":926
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * y_c = numpy.empty(shape=(x.size,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_10 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_7);
+ if (unlikely(!__pyx_t_10.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_y_c = __pyx_t_10;
+ __pyx_t_10.memview = NULL;
+ __pyx_t_10.data = NULL;
+
+ /* "functions.pyx":929
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_fastahypermet(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_t_1 = 0;
+ __pyx_t_11 = -1;
+ if (__pyx_t_1 < 0) {
+ __pyx_t_1 += __pyx_v_x_c.shape[0];
+ if (unlikely(__pyx_t_1 < 0)) __pyx_t_11 = 0;
+ } else if (unlikely(__pyx_t_1 >= __pyx_v_x_c.shape[0])) __pyx_t_11 = 0;
+ if (unlikely(__pyx_t_11 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_11);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":930
+ *
+ * status = functions_wrapper.sum_fastahypermet(&x_c[0],
+ * x.size, # <<<<<<<<<<<<<<
+ * &params_c[0],
+ * params_c.size,
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = __Pyx_PyInt_As_int(__pyx_t_7); if (unlikely((__pyx_t_11 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 930; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "functions.pyx":931
+ * status = functions_wrapper.sum_fastahypermet(&x_c[0],
+ * x.size,
+ * &params_c[0], # <<<<<<<<<<<<<<
+ * params_c.size,
+ * &y_c[0],
+ */
+ __pyx_t_12 = 0;
+ __pyx_t_13 = -1;
+ if (__pyx_t_12 < 0) {
+ __pyx_t_12 += __pyx_v_params_c.shape[0];
+ if (unlikely(__pyx_t_12 < 0)) __pyx_t_13 = 0;
+ } else if (unlikely(__pyx_t_12 >= __pyx_v_params_c.shape[0])) __pyx_t_13 = 0;
+ if (unlikely(__pyx_t_13 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_13);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":932
+ * x.size,
+ * &params_c[0],
+ * params_c.size, # <<<<<<<<<<<<<<
+ * &y_c[0],
+ * tail_flags)
+ */
+ __pyx_t_7 = __pyx_memoryview_fromslice(__pyx_v_params_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_13 = __Pyx_PyInt_As_int(__pyx_t_6); if (unlikely((__pyx_t_13 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "functions.pyx":933
+ * &params_c[0],
+ * params_c.size,
+ * &y_c[0], # <<<<<<<<<<<<<<
+ * tail_flags)
+ *
+ */
+ __pyx_t_14 = 0;
+ __pyx_t_15 = -1;
+ if (__pyx_t_14 < 0) {
+ __pyx_t_14 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_14 < 0)) __pyx_t_15 = 0;
+ } else if (unlikely(__pyx_t_14 >= __pyx_v_y_c.shape[0])) __pyx_t_15 = 0;
+ if (unlikely(__pyx_t_15 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_15);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":934
+ * params_c.size,
+ * &y_c[0],
+ * tail_flags) # <<<<<<<<<<<<<<
+ *
+ * if status:
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_tail_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 934; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":929
+ * dtype=numpy.float64)
+ *
+ * status = functions_wrapper.sum_fastahypermet(&x_c[0], # <<<<<<<<<<<<<<
+ * x.size,
+ * &params_c[0],
+ */
+ __pyx_v_status = sum_fastahypermet((&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_x_c.data) + __pyx_t_1)) )))), __pyx_t_11, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_params_c.data) + __pyx_t_12)) )))), __pyx_t_13, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_14)) )))), __pyx_t_15);
+
+ /* "functions.pyx":936
+ * tail_flags)
+ *
+ * if status: # <<<<<<<<<<<<<<
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ */
+ __pyx_t_2 = (__pyx_v_status != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":937
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__49, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":939
+ * raise IndexError("Wrong number of parameters for function")
+ *
+ * return numpy.asarray(y_c).reshape(x.shape) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_asarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_7 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_7);
+ } else {
+ __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_16, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":849
+ *
+ *
+ * def sum_fastahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True,
+ * lt_term=True, step_term=True):
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_10, 1);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_AddTraceback("functions.sum_fastahypermet", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_x_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_params_c, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XDECREF(__pyx_v_tail_flags);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":942
+ *
+ *
+ * def atan_stepup(x, a, b, c): # <<<<<<<<<<<<<<
+ * """
+ * Step up function using an inverse tangent.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_35atan_stepup(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_34atan_stepup[] = "atan_stepup(x, a, b, c)\n\n Step up function using an inverse tangent.\n\n :param x: Independant variable where the function is calculated\n :type x: numpy array\n :param a: Height of the step up\n :param b: Center of the step up\n :param c: Parameter related to the slope of the step. A lower ``c``\n value yields a sharper step.\n :return: ``a * (0.5 + (arctan((x - b) / c) / pi))``\n :rtype: numpy array\n ";
+static PyMethodDef __pyx_mdef_9functions_35atan_stepup = {"atan_stepup", (PyCFunction)__pyx_pw_9functions_35atan_stepup, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_34atan_stepup};
+static PyObject *__pyx_pw_9functions_35atan_stepup(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_a = 0;
+ PyObject *__pyx_v_b = 0;
+ PyObject *__pyx_v_c = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("atan_stepup (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_a,&__pyx_n_s_b,&__pyx_n_s_c,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_a)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("atan_stepup", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_b)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("atan_stepup", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_c)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("atan_stepup", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "atan_stepup") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_x = values[0];
+ __pyx_v_a = values[1];
+ __pyx_v_b = values[2];
+ __pyx_v_c = values[3];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("atan_stepup", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("functions.atan_stepup", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_34atan_stepup(__pyx_self, __pyx_v_x, __pyx_v_a, __pyx_v_b, __pyx_v_c);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_34atan_stepup(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("atan_stepup", 0);
+ __Pyx_INCREF(__pyx_v_x);
+
+ /* "functions.pyx":955
+ * :rtype: numpy array
+ * """
+ * if not hasattr(x, "shape"): # <<<<<<<<<<<<<<
+ * x = numpy.array(x)
+ * return a * (0.5 + (numpy.arctan((1.0 * x - b) / c) / numpy.pi))
+ */
+ __pyx_t_1 = PyObject_HasAttr(__pyx_v_x, __pyx_n_s_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 955; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":956
+ * """
+ * if not hasattr(x, "shape"):
+ * x = numpy.array(x) # <<<<<<<<<<<<<<
+ * return a * (0.5 + (numpy.arctan((1.0 * x - b) / c) / numpy.pi))
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_x); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 956; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF_SET(__pyx_v_x, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "functions.pyx":957
+ * if not hasattr(x, "shape"):
+ * x = numpy.array(x)
+ * return a * (0.5 + (numpy.arctan((1.0 * x - b) / c) / numpy.pi)) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_arctan); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyNumber_Multiply(__pyx_float_1_0, __pyx_v_x); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = PyNumber_Subtract(__pyx_t_5, __pyx_v_b); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyNumber_Divide(__pyx_t_4, __pyx_v_c); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_pi); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyNumber_Divide(__pyx_t_3, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyNumber_Add(__pyx_float_0_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyNumber_Multiply(__pyx_v_a, __pyx_t_7); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 957; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_r = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":942
+ *
+ *
+ * def atan_stepup(x, a, b, c): # <<<<<<<<<<<<<<
+ * """
+ * Step up function using an inverse tangent.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("functions.atan_stepup", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_x);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "functions.pyx":960
+ *
+ *
+ * def periodic_gauss(x, *pars): # <<<<<<<<<<<<<<
+ * """
+ * Return a sum of gaussian functions defined by
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_9functions_37periodic_gauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_9functions_36periodic_gauss[] = "periodic_gauss(x, *pars)\n\n Return a sum of gaussian functions defined by\n *(npeaks, delta, height, centroid, fwhm)*,\n where:\n\n - *npeaks* is the number of gaussians peaks\n - *delta* is the constant distance between 2 peaks\n - *height* is the peak amplitude of all the gaussians\n - *centroid* is the peak x-coordinate of the first gaussian\n - *fwhm* is the full-width at half maximum for all the gaussians\n\n :param x: Independant variable where the function is calculated\n :param pars: *(npeaks, delta, height, centroid, fwhm)*\n :return: Sum of ``npeaks`` gaussians\n ";
+static PyMethodDef __pyx_mdef_9functions_37periodic_gauss = {"periodic_gauss", (PyCFunction)__pyx_pw_9functions_37periodic_gauss, METH_VARARGS|METH_KEYWORDS, __pyx_doc_9functions_36periodic_gauss};
+static PyObject *__pyx_pw_9functions_37periodic_gauss(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_x = 0;
+ PyObject *__pyx_v_pars = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("periodic_gauss (wrapper)", 0);
+ if (PyTuple_GET_SIZE(__pyx_args) > 1) {
+ __pyx_v_pars = PyTuple_GetSlice(__pyx_args, 1, PyTuple_GET_SIZE(__pyx_args));
+ if (unlikely(!__pyx_v_pars)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_v_pars);
+ } else {
+ __pyx_v_pars = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
+ }
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ default:
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ const Py_ssize_t used_pos_args = (pos_args < 1) ? pos_args : 1;
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, used_pos_args, "periodic_gauss") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) < 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_x = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("periodic_gauss", 0, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_DECREF(__pyx_v_pars); __pyx_v_pars = 0;
+ __Pyx_AddTraceback("functions.periodic_gauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_9functions_36periodic_gauss(__pyx_self, __pyx_v_x, __pyx_v_pars);
+
+ /* function exit code */
+ __Pyx_XDECREF(__pyx_v_pars);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_9functions_36periodic_gauss(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_x, PyObject *__pyx_v_pars) {
+ PyObject *__pyx_v_newpars = NULL;
+ PyObject *__pyx_v_i = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *(*__pyx_t_9)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("periodic_gauss", 0);
+
+ /* "functions.pyx":977
+ * """
+ *
+ * if not len(pars): # <<<<<<<<<<<<<<
+ * raise IndexError("No parameters specified. " +
+ * "At least 5 parameters are required.")
+ */
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_pars); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "functions.pyx":978
+ *
+ * if not len(pars):
+ * raise IndexError("No parameters specified. " + # <<<<<<<<<<<<<<
+ * "At least 5 parameters are required.")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_No_parameters_specified, __pyx_kp_s_At_least_5_parameters_are_requir); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "functions.pyx":981
+ * "At least 5 parameters are required.")
+ *
+ * newpars = numpy.zeros((pars[0], 3), numpy.float) # <<<<<<<<<<<<<<
+ * for i in range(int(pars[0])):
+ * newpars[i, 0] = pars[2]
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_GetItemInt_Tuple(__pyx_v_pars, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_int_3);
+ PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_int_3);
+ __Pyx_GIVEREF(__pyx_int_3);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ __pyx_t_1 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_1 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_1, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 981; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_newpars = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "functions.pyx":982
+ *
+ * newpars = numpy.zeros((pars[0], 3), numpy.float)
+ * for i in range(int(pars[0])): # <<<<<<<<<<<<<<
+ * newpars[i, 0] = pars[2]
+ * newpars[i, 1] = pars[3] + i * pars[1]
+ */
+ __pyx_t_3 = __Pyx_GetItemInt_Tuple(__pyx_v_pars, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = PyNumber_Int(__pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (likely(PyList_CheckExact(__pyx_t_5)) || PyTuple_CheckExact(__pyx_t_5)) {
+ __pyx_t_3 = __pyx_t_5; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ __pyx_t_9 = NULL;
+ } else {
+ __pyx_t_1 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_9)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_1 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_5); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_5); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_9(__pyx_t_3);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "functions.pyx":983
+ * newpars = numpy.zeros((pars[0], 3), numpy.float)
+ * for i in range(int(pars[0])):
+ * newpars[i, 0] = pars[2] # <<<<<<<<<<<<<<
+ * newpars[i, 1] = pars[3] + i * pars[1]
+ * newpars[:, 2] = pars[4]
+ */
+ __pyx_t_5 = __Pyx_GetItemInt_Tuple(__pyx_v_pars, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 983; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_i);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_i);
+ __Pyx_GIVEREF(__pyx_v_i);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ if (unlikely(PyObject_SetItem(__pyx_v_newpars, __pyx_t_8, __pyx_t_5) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 983; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "functions.pyx":984
+ * for i in range(int(pars[0])):
+ * newpars[i, 0] = pars[2]
+ * newpars[i, 1] = pars[3] + i * pars[1] # <<<<<<<<<<<<<<
+ * newpars[:, 2] = pars[4]
+ * return sum_gauss(x, newpars)
+ */
+ __pyx_t_5 = __Pyx_GetItemInt_Tuple(__pyx_v_pars, 3, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = __Pyx_GetItemInt_Tuple(__pyx_v_pars, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_7 = PyNumber_Multiply(__pyx_v_i, __pyx_t_8); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyNumber_Add(__pyx_t_5, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_INCREF(__pyx_v_i);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_i);
+ __Pyx_GIVEREF(__pyx_v_i);
+ __Pyx_INCREF(__pyx_int_1);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_int_1);
+ __Pyx_GIVEREF(__pyx_int_1);
+ if (unlikely(PyObject_SetItem(__pyx_v_newpars, __pyx_t_7, __pyx_t_8) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "functions.pyx":985
+ * newpars[i, 0] = pars[2]
+ * newpars[i, 1] = pars[3] + i * pars[1]
+ * newpars[:, 2] = pars[4] # <<<<<<<<<<<<<<
+ * return sum_gauss(x, newpars)
+ */
+ __pyx_t_8 = __Pyx_GetItemInt_Tuple(__pyx_v_pars, 4, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_8);
+ if (unlikely(PyObject_SetItem(__pyx_v_newpars, __pyx_tuple__51, __pyx_t_8) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "functions.pyx":982
+ *
+ * newpars = numpy.zeros((pars[0], 3), numpy.float)
+ * for i in range(int(pars[0])): # <<<<<<<<<<<<<<
+ * newpars[i, 0] = pars[2]
+ * newpars[i, 1] = pars[3] + i * pars[1]
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "functions.pyx":986
+ * newpars[i, 1] = pars[3] + i * pars[1]
+ * newpars[:, 2] = pars[4]
+ * return sum_gauss(x, newpars) # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_sum_gauss); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_7 = NULL;
+ __pyx_t_1 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ __pyx_t_1 = 1;
+ }
+ }
+ __pyx_t_5 = PyTuple_New(2+__pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_x);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_1, __pyx_v_x);
+ __Pyx_GIVEREF(__pyx_v_x);
+ __Pyx_INCREF(__pyx_v_newpars);
+ PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_1, __pyx_v_newpars);
+ __Pyx_GIVEREF(__pyx_v_newpars);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "functions.pyx":960
+ *
+ *
+ * def periodic_gauss(x, *pars): # <<<<<<<<<<<<<<
+ * """
+ * Return a sum of gaussian functions defined by
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("functions.periodic_gauss", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_newpars);
+ __Pyx_XDECREF(__pyx_v_i);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__52, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__53, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__54, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__55, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__56, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__57, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__58, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__59);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__59);
+ __Pyx_GIVEREF(__pyx_slice__59);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__60); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__61);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__61);
+ __Pyx_GIVEREF(__pyx_slice__61);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__62, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "functions.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "functions.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "functions.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "functions._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "functions",
+ __pyx_k_This_module_provides_fit_functio, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_17_06_2016, __pyx_k_17_06_2016, sizeof(__pyx_k_17_06_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_At_least_3_parameters_are_requir, __pyx_k_At_least_3_parameters_are_requir, sizeof(__pyx_k_At_least_3_parameters_are_requir), 0, 0, 1, 0},
+ {&__pyx_kp_s_At_least_4_parameters_are_requir, __pyx_k_At_least_4_parameters_are_requir, sizeof(__pyx_k_At_least_4_parameters_are_requir), 0, 0, 1, 0},
+ {&__pyx_kp_s_At_least_5_parameters_are_requir, __pyx_k_At_least_5_parameters_are_requir, sizeof(__pyx_k_At_least_5_parameters_are_requir), 0, 0, 1, 0},
+ {&__pyx_kp_s_At_least_8_parameters_are_requir, __pyx_k_At_least_8_parameters_are_requir, sizeof(__pyx_k_At_least_8_parameters_are_requir), 0, 0, 1, 0},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_n_s_C, __pyx_k_C, sizeof(__pyx_k_C), 0, 0, 1, 1},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_compute_erf_for_an_empty, __pyx_k_Cannot_compute_erf_for_an_empty, sizeof(__pyx_k_Cannot_compute_erf_for_an_empty), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_compute_erfc_for_an_empty, __pyx_k_Cannot_compute_erfc_for_an_empty, sizeof(__pyx_k_Cannot_compute_erfc_for_an_empty), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_kp_s_No_gaussian_parameters_specified, __pyx_k_No_gaussian_parameters_specified, sizeof(__pyx_k_No_gaussian_parameters_specified), 0, 0, 1, 0},
+ {&__pyx_kp_s_No_parameters_specified, __pyx_k_No_parameters_specified, sizeof(__pyx_k_No_parameters_specified), 0, 0, 1, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_kp_s_P_Knobel, __pyx_k_P_Knobel, sizeof(__pyx_k_P_Knobel), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Wrong_number_of_parameters_for_f, __pyx_k_Wrong_number_of_parameters_for_f, sizeof(__pyx_k_Wrong_number_of_parameters_for_f), 0, 0, 1, 0},
+ {&__pyx_n_s_a, __pyx_k_a, sizeof(__pyx_k_a), 0, 0, 1, 1},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_arctan, __pyx_k_arctan, sizeof(__pyx_k_arctan), 0, 0, 1, 1},
+ {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+ {&__pyx_n_s_asarray, __pyx_k_asarray, sizeof(__pyx_k_asarray), 0, 0, 1, 1},
+ {&__pyx_n_s_atan_stepup, __pyx_k_atan_stepup, sizeof(__pyx_k_atan_stepup), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_b, __pyx_k_b, sizeof(__pyx_k_b), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_basicConfig, __pyx_k_basicConfig, sizeof(__pyx_k_basicConfig), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_copy, __pyx_k_copy, sizeof(__pyx_k_copy), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_erf, __pyx_k_erf, sizeof(__pyx_k_erf), 0, 0, 1, 1},
+ {&__pyx_n_s_erfc, __pyx_k_erfc, sizeof(__pyx_k_erfc), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_float, __pyx_k_float, sizeof(__pyx_k_float), 0, 0, 1, 1},
+ {&__pyx_n_s_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 0, 1, 1},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_n_s_functions, __pyx_k_functions, sizeof(__pyx_k_functions), 0, 0, 1, 1},
+ {&__pyx_n_s_gaussian_term, __pyx_k_gaussian_term, sizeof(__pyx_k_gaussian_term), 0, 0, 1, 1},
+ {&__pyx_n_s_getLogger, __pyx_k_getLogger, sizeof(__pyx_k_getLogger), 0, 0, 1, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_len_dim, __pyx_k_len_dim, sizeof(__pyx_k_len_dim), 0, 0, 1, 1},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_logger, __pyx_k_logger, sizeof(__pyx_k_logger), 0, 0, 1, 1},
+ {&__pyx_n_s_logging, __pyx_k_logging, sizeof(__pyx_k_logging), 0, 0, 1, 1},
+ {&__pyx_n_s_lt_term, __pyx_k_lt_term, sizeof(__pyx_k_lt_term), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_k_mntdirect__scisoft_users_tvince, sizeof(__pyx_k_mntdirect__scisoft_users_tvince), 0, 0, 1, 0},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_newpars, __pyx_k_newpars, sizeof(__pyx_k_newpars), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_n_s_order, __pyx_k_order, sizeof(__pyx_k_order), 0, 0, 1, 1},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_n_s_params, __pyx_k_params, sizeof(__pyx_k_params), 0, 0, 1, 1},
+ {&__pyx_n_s_params_c, __pyx_k_params_c, sizeof(__pyx_k_params_c), 0, 0, 1, 1},
+ {&__pyx_n_s_pars, __pyx_k_pars, sizeof(__pyx_k_pars), 0, 0, 1, 1},
+ {&__pyx_n_s_periodic_gauss, __pyx_k_periodic_gauss, sizeof(__pyx_k_periodic_gauss), 0, 0, 1, 1},
+ {&__pyx_n_s_pi, __pyx_k_pi, sizeof(__pyx_k_pi), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_st_term, __pyx_k_st_term, sizeof(__pyx_k_st_term), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_status, __pyx_k_status, sizeof(__pyx_k_status), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_step_term, __pyx_k_step_term, sizeof(__pyx_k_step_term), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_agauss, __pyx_k_sum_agauss, sizeof(__pyx_k_sum_agauss), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_ahypermet, __pyx_k_sum_ahypermet, sizeof(__pyx_k_sum_ahypermet), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_alorentz, __pyx_k_sum_alorentz, sizeof(__pyx_k_sum_alorentz), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_apvoigt, __pyx_k_sum_apvoigt, sizeof(__pyx_k_sum_apvoigt), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_fastagauss, __pyx_k_sum_fastagauss, sizeof(__pyx_k_sum_fastagauss), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_fastahypermet, __pyx_k_sum_fastahypermet, sizeof(__pyx_k_sum_fastahypermet), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_gauss, __pyx_k_sum_gauss, sizeof(__pyx_k_sum_gauss), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_lorentz, __pyx_k_sum_lorentz, sizeof(__pyx_k_sum_lorentz), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_pvoigt, __pyx_k_sum_pvoigt, sizeof(__pyx_k_sum_pvoigt), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_slit, __pyx_k_sum_slit, sizeof(__pyx_k_sum_slit), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_splitgauss, __pyx_k_sum_splitgauss, sizeof(__pyx_k_sum_splitgauss), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_splitlorentz, __pyx_k_sum_splitlorentz, sizeof(__pyx_k_sum_splitlorentz), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_splitpvoigt, __pyx_k_sum_splitpvoigt, sizeof(__pyx_k_sum_splitpvoigt), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_stepdown, __pyx_k_sum_stepdown, sizeof(__pyx_k_sum_stepdown), 0, 0, 1, 1},
+ {&__pyx_n_s_sum_stepup, __pyx_k_sum_stepup, sizeof(__pyx_k_sum_stepup), 0, 0, 1, 1},
+ {&__pyx_n_s_tail_flags, __pyx_k_tail_flags, sizeof(__pyx_k_tail_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1},
+ {&__pyx_n_s_x_c, __pyx_k_x_c, sizeof(__pyx_k_x_c), 0, 0, 1, 1},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {&__pyx_n_s_y_c, __pyx_k_y_c, sizeof(__pyx_k_y_c), 0, 0, 1, 1},
+ {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 982; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "functions.pyx":88
+ * for len_dim in x.shape:
+ * if len_dim == 0:
+ * raise IndexError("Cannot compute erf for an empty array") # <<<<<<<<<<<<<<
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1)
+ */
+ __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_Cannot_compute_erf_for_an_empty); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "functions.pyx":90
+ * raise IndexError("Cannot compute erf for an empty array")
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64)
+ *
+ */
+ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "functions.pyx":118
+ * for len_dim in x.shape:
+ * if len_dim == 0:
+ * raise IndexError("Cannot compute erfc for an empty array") # <<<<<<<<<<<<<<
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1)
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_Cannot_compute_erfc_for_an_empty); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "functions.pyx":120
+ * raise IndexError("Cannot compute erfc for an empty array")
+ *
+ * x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64)
+ *
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "functions.pyx":156
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "functions.pyx":160
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+
+ /* "functions.pyx":170
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * # reshape y_c to match original, possibly unusual, data shape
+ */
+ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__7);
+ __Pyx_GIVEREF(__pyx_tuple__7);
+
+ /* "functions.pyx":203
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "functions.pyx":207
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "functions.pyx":217
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+
+ /* "functions.pyx":253
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+
+ /* "functions.pyx":257
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__12);
+ __Pyx_GIVEREF(__pyx_tuple__12);
+
+ /* "functions.pyx":267
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__13);
+ __Pyx_GIVEREF(__pyx_tuple__13);
+
+ /* "functions.pyx":302
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__14 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__14);
+ __Pyx_GIVEREF(__pyx_tuple__14);
+
+ /* "functions.pyx":306
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+
+ /* "functions.pyx":316
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 316; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+
+ /* "functions.pyx":352
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+
+ /* "functions.pyx":356
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+
+ /* "functions.pyx":366
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__19);
+ __Pyx_GIVEREF(__pyx_tuple__19);
+
+ /* "functions.pyx":403
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 403; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+
+ /* "functions.pyx":407
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__21 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__21);
+ __Pyx_GIVEREF(__pyx_tuple__21);
+
+ /* "functions.pyx":417
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__22);
+ __Pyx_GIVEREF(__pyx_tuple__22);
+
+ /* "functions.pyx":458
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__23 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__23);
+ __Pyx_GIVEREF(__pyx_tuple__23);
+
+ /* "functions.pyx":462
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__24);
+ __Pyx_GIVEREF(__pyx_tuple__24);
+
+ /* "functions.pyx":472
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 472; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__25);
+ __Pyx_GIVEREF(__pyx_tuple__25);
+
+ /* "functions.pyx":505
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__26 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__26);
+ __Pyx_GIVEREF(__pyx_tuple__26);
+
+ /* "functions.pyx":509
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__27 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 509; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__27);
+ __Pyx_GIVEREF(__pyx_tuple__27);
+
+ /* "functions.pyx":519
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__28);
+ __Pyx_GIVEREF(__pyx_tuple__28);
+
+ /* "functions.pyx":552
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__29 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__29);
+ __Pyx_GIVEREF(__pyx_tuple__29);
+
+ /* "functions.pyx":556
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__30 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__30)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__30);
+ __Pyx_GIVEREF(__pyx_tuple__30);
+
+ /* "functions.pyx":566
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__31)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 566; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__31);
+ __Pyx_GIVEREF(__pyx_tuple__31);
+
+ /* "functions.pyx":600
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__32 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 600; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__32);
+ __Pyx_GIVEREF(__pyx_tuple__32);
+
+ /* "functions.pyx":604
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__33 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__33);
+ __Pyx_GIVEREF(__pyx_tuple__33);
+
+ /* "functions.pyx":614
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__34 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__34)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__34);
+ __Pyx_GIVEREF(__pyx_tuple__34);
+
+ /* "functions.pyx":647
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__35 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__35)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__35);
+ __Pyx_GIVEREF(__pyx_tuple__35);
+
+ /* "functions.pyx":651
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__36 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__36)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__36);
+ __Pyx_GIVEREF(__pyx_tuple__36);
+
+ /* "functions.pyx":662
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__37 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__37)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 662; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__37);
+ __Pyx_GIVEREF(__pyx_tuple__37);
+
+ /* "functions.pyx":696
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__38 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__38)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 696; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__38);
+ __Pyx_GIVEREF(__pyx_tuple__38);
+
+ /* "functions.pyx":700
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__39 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__39)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 700; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__39);
+ __Pyx_GIVEREF(__pyx_tuple__39);
+
+ /* "functions.pyx":711
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__40 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__40)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 711; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__40);
+ __Pyx_GIVEREF(__pyx_tuple__40);
+
+ /* "functions.pyx":747
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__41 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__41)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 747; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__41);
+ __Pyx_GIVEREF(__pyx_tuple__41);
+
+ /* "functions.pyx":751
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__42 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__42)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__42);
+ __Pyx_GIVEREF(__pyx_tuple__42);
+
+ /* "functions.pyx":762
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__43 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__43)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__43);
+ __Pyx_GIVEREF(__pyx_tuple__43);
+
+ /* "functions.pyx":828
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__44 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__44);
+ __Pyx_GIVEREF(__pyx_tuple__44);
+
+ /* "functions.pyx":832
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__45 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__45)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__45);
+ __Pyx_GIVEREF(__pyx_tuple__45);
+
+ /* "functions.pyx":844
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__46 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__46);
+ __Pyx_GIVEREF(__pyx_tuple__46);
+
+ /* "functions.pyx":921
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * params_c = numpy.array(params,
+ * copy=False,
+ */
+ __pyx_tuple__47 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__47)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__47);
+ __Pyx_GIVEREF(__pyx_tuple__47);
+
+ /* "functions.pyx":925
+ * copy=False,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * y_c = numpy.empty(shape=(x.size,),
+ * dtype=numpy.float64)
+ */
+ __pyx_tuple__48 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__48)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__48);
+ __Pyx_GIVEREF(__pyx_tuple__48);
+
+ /* "functions.pyx":937
+ *
+ * if status:
+ * raise IndexError("Wrong number of parameters for function") # <<<<<<<<<<<<<<
+ *
+ * return numpy.asarray(y_c).reshape(x.shape)
+ */
+ __pyx_tuple__49 = PyTuple_Pack(1, __pyx_kp_s_Wrong_number_of_parameters_for_f); if (unlikely(!__pyx_tuple__49)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 937; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__49);
+ __Pyx_GIVEREF(__pyx_tuple__49);
+
+ /* "functions.pyx":985
+ * newpars[i, 0] = pars[2]
+ * newpars[i, 1] = pars[3] + i * pars[1]
+ * newpars[:, 2] = pars[4] # <<<<<<<<<<<<<<
+ * return sum_gauss(x, newpars)
+ */
+ __pyx_slice__50 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__50)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__50);
+ __Pyx_GIVEREF(__pyx_slice__50);
+ __pyx_tuple__51 = PyTuple_Pack(2, __pyx_slice__50, __pyx_int_2); if (unlikely(!__pyx_tuple__51)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__51);
+ __Pyx_GIVEREF(__pyx_tuple__51);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__52 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__52)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__52);
+ __Pyx_GIVEREF(__pyx_tuple__52);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__53 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__53)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__53);
+ __Pyx_GIVEREF(__pyx_tuple__53);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__54 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__54)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__54);
+ __Pyx_GIVEREF(__pyx_tuple__54);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__55 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__55)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__55);
+ __Pyx_GIVEREF(__pyx_tuple__55);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__56 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__56)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__56);
+ __Pyx_GIVEREF(__pyx_tuple__56);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__57 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__57)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__57);
+ __Pyx_GIVEREF(__pyx_tuple__57);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__58 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__58)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__58);
+ __Pyx_GIVEREF(__pyx_tuple__58);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__59 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__59)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__59);
+ __Pyx_GIVEREF(__pyx_slice__59);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__60 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__60)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__60);
+ __Pyx_GIVEREF(__pyx_slice__60);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__61 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__61)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__61);
+ __Pyx_GIVEREF(__pyx_slice__61);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__62 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__62)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__62);
+ __Pyx_GIVEREF(__pyx_tuple__62);
+
+ /* "functions.pyx":68
+ *
+ *
+ * def erf(x): # <<<<<<<<<<<<<<
+ * """Return the gaussian error function
+ *
+ */
+ __pyx_tuple__63 = PyTuple_Pack(5, __pyx_n_s_x, __pyx_n_s_x_c, __pyx_n_s_y_c, __pyx_n_s_len_dim, __pyx_n_s_status); if (unlikely(!__pyx_tuple__63)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__63);
+ __Pyx_GIVEREF(__pyx_tuple__63);
+ __pyx_codeobj__64 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__63, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_erf, 68, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__64)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":98
+ *
+ *
+ * def erfc(x): # <<<<<<<<<<<<<<
+ * """Return the gaussian complementary error function
+ *
+ */
+ __pyx_tuple__65 = PyTuple_Pack(5, __pyx_n_s_x, __pyx_n_s_x_c, __pyx_n_s_y_c, __pyx_n_s_len_dim, __pyx_n_s_status); if (unlikely(!__pyx_tuple__65)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__65);
+ __Pyx_GIVEREF(__pyx_tuple__65);
+ __pyx_codeobj__66 = (PyObject*)__Pyx_PyCode_New(1, 0, 5, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__65, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_erfc, 98, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__66)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":128
+ *
+ *
+ * def sum_gauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(height, centroid, fwhm)*,
+ * where:
+ */
+ __pyx_tuple__67 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__67)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__67);
+ __Pyx_GIVEREF(__pyx_tuple__67);
+ __pyx_codeobj__68 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__67, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_gauss, 128, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__68)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":176
+ *
+ *
+ * def sum_agauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ * where:
+ */
+ __pyx_tuple__69 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__69)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__69);
+ __Pyx_GIVEREF(__pyx_tuple__69);
+ __pyx_codeobj__70 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__69, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_agauss, 176, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__70)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":222
+ *
+ *
+ * def sum_fastagauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ * where:
+ */
+ __pyx_tuple__71 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__71)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__71);
+ __Pyx_GIVEREF(__pyx_tuple__71);
+ __pyx_codeobj__72 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__71, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_fastagauss, 222, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__72)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":272
+ *
+ *
+ * def sum_splitgauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm1, fwhm2)*,
+ * where:
+ */
+ __pyx_tuple__73 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__73)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__73);
+ __Pyx_GIVEREF(__pyx_tuple__73);
+ __pyx_codeobj__74 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__73, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_splitgauss, 272, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__74)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":321
+ *
+ *
+ * def sum_apvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of pseudo-Voigt functions, defined by *(area, centroid, fwhm,
+ * eta)*.
+ */
+ __pyx_tuple__75 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__75)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__75);
+ __Pyx_GIVEREF(__pyx_tuple__75);
+ __pyx_codeobj__76 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__75, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_apvoigt, 321, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__76)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":371
+ *
+ *
+ * def sum_pvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of pseudo-Voigt functions, defined by *(height, centroid,
+ * fwhm, eta)*.
+ */
+ __pyx_tuple__77 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__77)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__77);
+ __Pyx_GIVEREF(__pyx_tuple__77);
+ __pyx_codeobj__78 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__77, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_pvoigt, 371, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__78)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":422
+ *
+ *
+ * def sum_splitpvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of split pseudo-Voigt functions, defined by *(height,
+ * centroid, fwhm1, fwhm2, eta)*.
+ */
+ __pyx_tuple__79 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__79)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__79);
+ __Pyx_GIVEREF(__pyx_tuple__79);
+ __pyx_codeobj__80 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__79, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_splitpvoigt, 422, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__80)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":477
+ *
+ *
+ * def sum_lorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ * defined by *(height, centroid, fwhm)*.
+ */
+ __pyx_tuple__81 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__81)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__81);
+ __Pyx_GIVEREF(__pyx_tuple__81);
+ __pyx_codeobj__82 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__81, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_lorentz, 477, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__82)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":524
+ *
+ *
+ * def sum_alorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ * defined by *(area, centroid, fwhm)*.
+ */
+ __pyx_tuple__83 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__83)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__83);
+ __Pyx_GIVEREF(__pyx_tuple__83);
+ __pyx_codeobj__84 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__83, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_alorentz, 524, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__84)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":571
+ *
+ *
+ * def sum_splitlorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of split Lorentz distributions,
+ * defined by *(height, centroid, fwhm1, fwhm2)*.
+ */
+ __pyx_tuple__85 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__85)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__85);
+ __Pyx_GIVEREF(__pyx_tuple__85);
+ __pyx_codeobj__86 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__85, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_splitlorentz, 571, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__86)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":619
+ *
+ *
+ * def sum_stepdown(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of stepdown functions.
+ * defined by *(height, centroid, fwhm)*.
+ */
+ __pyx_tuple__87 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__87)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__87);
+ __Pyx_GIVEREF(__pyx_tuple__87);
+ __pyx_codeobj__88 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__87, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_stepdown, 619, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__88)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":667
+ *
+ *
+ * def sum_stepup(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of stepup functions.
+ * defined by *(height, centroid, fwhm)*.
+ */
+ __pyx_tuple__89 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__89)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__89);
+ __Pyx_GIVEREF(__pyx_tuple__89);
+ __pyx_codeobj__90 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__89, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_stepup, 667, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__90)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":716
+ *
+ *
+ * def sum_slit(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of slit functions.
+ * defined by *(height, position, fwhm, beamfwhm)*.
+ */
+ __pyx_tuple__91 = PyTuple_Pack(6, __pyx_n_s_x, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_status); if (unlikely(!__pyx_tuple__91)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__91);
+ __Pyx_GIVEREF(__pyx_tuple__91);
+ __pyx_codeobj__92 = (PyObject*)__Pyx_PyCode_New(1, 0, 6, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__91, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_slit, 716, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__92)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":767
+ *
+ *
+ * def sum_ahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True, lt_term=True, step_term=True):
+ * """Return a sum of ahypermet functions.
+ */
+ __pyx_tuple__93 = PyTuple_Pack(11, __pyx_n_s_x, __pyx_n_s_gaussian_term, __pyx_n_s_st_term, __pyx_n_s_lt_term, __pyx_n_s_step_term, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_tail_flags, __pyx_n_s_status); if (unlikely(!__pyx_tuple__93)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__93);
+ __Pyx_GIVEREF(__pyx_tuple__93);
+ __pyx_codeobj__94 = (PyObject*)__Pyx_PyCode_New(1, 4, 11, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__93, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_ahypermet, 767, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__94)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":849
+ *
+ *
+ * def sum_fastahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True,
+ * lt_term=True, step_term=True):
+ */
+ __pyx_tuple__95 = PyTuple_Pack(11, __pyx_n_s_x, __pyx_n_s_gaussian_term, __pyx_n_s_st_term, __pyx_n_s_lt_term, __pyx_n_s_step_term, __pyx_n_s_params, __pyx_n_s_x_c, __pyx_n_s_params_c, __pyx_n_s_y_c, __pyx_n_s_tail_flags, __pyx_n_s_status); if (unlikely(!__pyx_tuple__95)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__95);
+ __Pyx_GIVEREF(__pyx_tuple__95);
+ __pyx_codeobj__96 = (PyObject*)__Pyx_PyCode_New(1, 4, 11, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__95, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_sum_fastahypermet, 849, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__96)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":942
+ *
+ *
+ * def atan_stepup(x, a, b, c): # <<<<<<<<<<<<<<
+ * """
+ * Step up function using an inverse tangent.
+ */
+ __pyx_tuple__97 = PyTuple_Pack(4, __pyx_n_s_x, __pyx_n_s_a, __pyx_n_s_b, __pyx_n_s_c); if (unlikely(!__pyx_tuple__97)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__97);
+ __Pyx_GIVEREF(__pyx_tuple__97);
+ __pyx_codeobj__98 = (PyObject*)__Pyx_PyCode_New(4, 0, 4, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__97, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_atan_stepup, 942, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__98)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":960
+ *
+ *
+ * def periodic_gauss(x, *pars): # <<<<<<<<<<<<<<
+ * """
+ * Return a sum of gaussian functions defined by
+ */
+ __pyx_tuple__99 = PyTuple_Pack(4, __pyx_n_s_x, __pyx_n_s_pars, __pyx_n_s_newpars, __pyx_n_s_i); if (unlikely(!__pyx_tuple__99)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__99);
+ __Pyx_GIVEREF(__pyx_tuple__99);
+ __pyx_codeobj__100 = (PyObject*)__Pyx_PyCode_New(1, 0, 4, 0, CO_VARARGS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__99, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_periodic_gauss, 960, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__100)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__101 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__101)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__101);
+ __Pyx_GIVEREF(__pyx_tuple__101);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__102 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__102)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__102);
+ __Pyx_GIVEREF(__pyx_tuple__102);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__103 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__103)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__103);
+ __Pyx_GIVEREF(__pyx_tuple__103);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__104 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__104)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__104);
+ __Pyx_GIVEREF(__pyx_tuple__104);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__105 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__105)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__105);
+ __Pyx_GIVEREF(__pyx_tuple__105);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_float_0_5 = PyFloat_FromDouble(0.5); if (unlikely(!__pyx_float_0_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_float_1_0 = PyFloat_FromDouble(1.0); if (unlikely(!__pyx_float_1_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_8 = PyInt_FromLong(8); if (unlikely(!__pyx_int_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initfunctions(void); /*proto*/
+PyMODINIT_FUNC initfunctions(void)
+#else
+PyMODINIT_FUNC PyInit_functions(void); /*proto*/
+PyMODINIT_FUNC PyInit_functions(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_functions(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("functions", __pyx_methods, __pyx_k_This_module_provides_fit_functio, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_functions) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "functions")) {
+ if (unlikely(PyDict_SetItemString(modules, "functions", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "functions.pyx":54
+ * """
+ *
+ * __authors__ = ["P. Knobel"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "17/06/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_P_Knobel);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_P_Knobel);
+ __Pyx_GIVEREF(__pyx_kp_s_P_Knobel);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":55
+ *
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "17/06/2016"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":56
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT"
+ * __date__ = "17/06/2016" # <<<<<<<<<<<<<<
+ *
+ * import logging
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_17_06_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "functions.pyx":58
+ * __date__ = "17/06/2016"
+ *
+ * import logging # <<<<<<<<<<<<<<
+ * import numpy
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":59
+ *
+ * import logging
+ * import numpy # <<<<<<<<<<<<<<
+ *
+ * logging.basicConfig()
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":61
+ * import numpy
+ *
+ * logging.basicConfig() # <<<<<<<<<<<<<<
+ * _logger = logging.getLogger(__name__)
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_basicConfig); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":62
+ *
+ * logging.basicConfig()
+ * _logger = logging.getLogger(__name__) # <<<<<<<<<<<<<<
+ *
+ * cimport cython
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_getLogger); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_name_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logger, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":68
+ *
+ *
+ * def erf(x): # <<<<<<<<<<<<<<
+ * """Return the gaussian error function
+ *
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_1erf, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_erf, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":98
+ *
+ *
+ * def erfc(x): # <<<<<<<<<<<<<<
+ * """Return the gaussian complementary error function
+ *
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_3erfc, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_erfc, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":128
+ *
+ *
+ * def sum_gauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(height, centroid, fwhm)*,
+ * where:
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_5sum_gauss, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_gauss, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":176
+ *
+ *
+ * def sum_agauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ * where:
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_7sum_agauss, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_agauss, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":222
+ *
+ *
+ * def sum_fastagauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ * where:
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_9sum_fastagauss, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_fastagauss, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":272
+ *
+ *
+ * def sum_splitgauss(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of gaussian functions defined by *(area, centroid, fwhm1, fwhm2)*,
+ * where:
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_11sum_splitgauss, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_splitgauss, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 272; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":321
+ *
+ *
+ * def sum_apvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of pseudo-Voigt functions, defined by *(area, centroid, fwhm,
+ * eta)*.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_13sum_apvoigt, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_apvoigt, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":371
+ *
+ *
+ * def sum_pvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of pseudo-Voigt functions, defined by *(height, centroid,
+ * fwhm, eta)*.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_15sum_pvoigt, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_pvoigt, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 371; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":422
+ *
+ *
+ * def sum_splitpvoigt(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of split pseudo-Voigt functions, defined by *(height,
+ * centroid, fwhm1, fwhm2, eta)*.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_17sum_splitpvoigt, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_splitpvoigt, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":477
+ *
+ *
+ * def sum_lorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ * defined by *(height, centroid, fwhm)*.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_19sum_lorentz, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_lorentz, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":524
+ *
+ *
+ * def sum_alorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ * defined by *(area, centroid, fwhm)*.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_21sum_alorentz, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_alorentz, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":571
+ *
+ *
+ * def sum_splitlorentz(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of split Lorentz distributions,
+ * defined by *(height, centroid, fwhm1, fwhm2)*.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_23sum_splitlorentz, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_splitlorentz, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":619
+ *
+ *
+ * def sum_stepdown(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of stepdown functions.
+ * defined by *(height, centroid, fwhm)*.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_25sum_stepdown, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_stepdown, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":667
+ *
+ *
+ * def sum_stepup(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of stepup functions.
+ * defined by *(height, centroid, fwhm)*.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_27sum_stepup, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_stepup, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 667; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":716
+ *
+ *
+ * def sum_slit(x, *params): # <<<<<<<<<<<<<<
+ * """Return a sum of slit functions.
+ * defined by *(height, position, fwhm, beamfwhm)*.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_29sum_slit, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_slit, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":767
+ *
+ *
+ * def sum_ahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True, lt_term=True, step_term=True):
+ * """Return a sum of ahypermet functions.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_31sum_ahypermet, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_ahypermet, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":849
+ *
+ *
+ * def sum_fastahypermet(x, *params, # <<<<<<<<<<<<<<
+ * gaussian_term=True, st_term=True,
+ * lt_term=True, step_term=True):
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_33sum_fastahypermet, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_sum_fastahypermet, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":942
+ *
+ *
+ * def atan_stepup(x, a, b, c): # <<<<<<<<<<<<<<
+ * """
+ * Step up function using an inverse tangent.
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_35atan_stepup, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_atan_stepup, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":960
+ *
+ *
+ * def periodic_gauss(x, *pars): # <<<<<<<<<<<<<<
+ * """
+ * Return a sum of gaussian functions defined by
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_9functions_37periodic_gauss, NULL, __pyx_n_s_functions); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_periodic_gauss, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 960; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "functions.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * #/[inserted by cython to avoid comment start]*##########################################################################
+ * # Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__101, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__102, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__103, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__104, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__105, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init functions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init functions");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static void __Pyx_RaiseBufferIndexError(int axis) {
+ PyErr_Format(PyExc_IndexError,
+ "Out of bounds on buffer access (axis %d)", axis);
+}
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+static PyObject *__pyx_memview_get_double(const char *itemp) {
+ return (PyObject *) PyFloat_FromDouble(*(double *) itemp);
+}
+static int __pyx_memview_set_double(const char *itemp, PyObject *obj) {
+ double value = __pyx_PyFloat_AsDouble(obj);
+ if ((value == (double)-1) && PyErr_Occurred())
+ return 0;
+ *(double *) itemp = value;
+ return 1;
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_double(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_double, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/math/fit/functions/functions.pyx b/silx/math/fit/functions/functions.pyx
new file mode 100644
index 0000000..196b682
--- /dev/null
+++ b/silx/math/fit/functions/functions.pyx
@@ -0,0 +1,986 @@
+# coding: utf-8
+#/*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+#############################################################################*/
+"""This module provides fit functions.
+
+List of fit functions:
+-----------------------
+
+ - :func:`sum_gauss`
+ - :func:`sum_agauss`
+ - :func:`sum_splitgauss`
+ - :func:`sum_fastagauss`
+
+ - :func:`sum_apvoigt`
+ - :func:`sum_pvoigt`
+ - :func:`sum_splitpvoigt`
+
+ - :func:`sum_lorentz`
+ - :func:`sum_alorentz`
+ - :func:`sum_splitlorentz`
+
+ - :func:`sum_stepdown`
+ - :func:`sum_stepup`
+ - :func:`sum_slit`
+
+ - :func:`sum_ahypermet`
+ - :func:`sum_fastahypermet`
+
+Full documentation:
+-------------------
+
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "17/06/2016"
+
+import logging
+import numpy
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+cimport cython
+cimport functions_wrapper
+
+
+def erf(x):
+ """Return the gaussian error function
+
+ :param x: Independant variable where the gaussian error function is
+ calculated
+ :type x: numpy.ndarray or scalar
+ :return: Gaussian error function ``y=erf(x)``
+ :raise: IndexError if ``x`` is an empty array
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] y_c
+
+
+ # force list into numpy array
+ if not hasattr(x, "shape"):
+ x = numpy.asarray(x)
+
+ for len_dim in x.shape:
+ if len_dim == 0:
+ raise IndexError("Cannot compute erf for an empty array")
+
+ x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64)
+
+ status = functions_wrapper.erf_array(&x_c[0], x_c.size, &y_c[0])
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def erfc(x):
+ """Return the gaussian complementary error function
+
+ :param x: Independant variable where the gaussian complementary error
+ function is calculated
+ :type x: numpy.ndarray or scalar
+ :return: Gaussian complementary error function ``y=erfc(x)``
+ :type rtype: numpy.ndarray
+ :raise: IndexError if ``x`` is an empty array
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] y_c
+
+ # force list into numpy array
+ if not hasattr(x, "shape"):
+ x = numpy.asarray(x)
+
+ for len_dim in x.shape:
+ if len_dim == 0:
+ raise IndexError("Cannot compute erfc for an empty array")
+
+ x_c = numpy.array(x, copy=False, dtype=numpy.float64, order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x_c.size,), dtype=numpy.float64)
+
+ status = functions_wrapper.erfc_array(&x_c[0], x_c.size, &y_c[0])
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_gauss(x, *params):
+ """Return a sum of gaussian functions defined by *(height, centroid, fwhm)*,
+ where:
+
+ - *height* is the peak amplitude
+ - *centroid* is the peak x-coordinate
+ - *fwhm* is the full-width at half maximum
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of gaussian parameters (length must be a multiple
+ of 3):
+ *(height1, centroid1, fwhm1, height2, centroid2, fwhm2,...)*
+ :return: Array of sum of gaussian functions at each ``x`` coordinate.
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No gaussian parameters specified. " +
+ "At least 3 parameters are required.")
+
+ # ensure float64 (double) type and 1D contiguous data layout in memory
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_gauss(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ # reshape y_c to match original, possibly unusual, data shape
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_agauss(x, *params):
+ """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ where:
+
+ - *area* is the area underneath the peak
+ - *centroid* is the peak x-coordinate
+ - *fwhm* is the full-width at half maximum
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of gaussian parameters (length must be a multiple
+ of 3):
+ *(area1, centroid1, fwhm1, area2, centroid2, fwhm2,...)*
+ :return: Array of sum of gaussian functions at each ``x`` coordinate.
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No gaussian parameters specified. " +
+ "At least 3 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_agauss(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_fastagauss(x, *params):
+ """Return a sum of gaussian functions defined by *(area, centroid, fwhm)*,
+ where:
+
+ - *area* is the area underneath the peak
+ - *centroid* is the peak x-coordinate
+ - *fwhm* is the full-width at half maximum
+
+ This implementation differs from :func:`sum_agauss` by the usage of a
+ lookup table with precalculated exponential values. This might speed up
+ the computation for large numbers of individual gaussian functions.
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of gaussian parameters (length must be a multiple
+ of 3):
+ *(area1, centroid1, fwhm1, area2, centroid2, fwhm2,...)*
+ :return: Array of sum of gaussian functions at each ``x`` coordinate.
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No gaussian parameters specified. " +
+ "At least 3 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_fastagauss(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_splitgauss(x, *params):
+ """Return a sum of gaussian functions defined by *(area, centroid, fwhm1, fwhm2)*,
+ where:
+
+ - *height* is the peak amplitude
+ - *centroid* is the peak x-coordinate
+ - *fwhm1* is the full-width at half maximum for the distribution
+ when ``x < centroid``
+ - *fwhm2* is the full-width at half maximum for the distribution
+ when ``x > centroid``
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of gaussian parameters (length must be a multiple
+ of 4):
+ *(height1, centroid1, fwhm11, fwhm21, height2, centroid2, fwhm12, fwhm22,...)*
+ :return: Array of sum of split gaussian functions at each ``x`` coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No gaussian parameters specified. " +
+ "At least 4 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_splitgauss(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_apvoigt(x, *params):
+ """Return a sum of pseudo-Voigt functions, defined by *(area, centroid, fwhm,
+ eta)*.
+
+ The pseudo-Voigt profile ``PV(x)`` is an approximation of the Voigt
+ profile using a linear combination of a Gaussian curve ``G(x)`` and a
+ Lorentzian curve ``L(x)`` instead of their convolution.
+
+ - *area* is the area underneath both G(x) and L(x)
+ - *centroid* is the peak x-coordinate for both functions
+ - *fwhm* is the full-width at half maximum of both functions
+ - *eta* is the Lorentz factor: PV(x) = eta * L(x) + (1 - eta) * G(x)
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of pseudo-Voigt parameters (length must be a multiple
+ of 4):
+ *(area1, centroid1, fwhm1, eta1, area2, centroid2, fwhm2, eta2,...)*
+ :return: Array of sum of pseudo-Voigt functions at each ``x`` coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 4 parameters are required.")
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_apvoigt(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_pvoigt(x, *params):
+ """Return a sum of pseudo-Voigt functions, defined by *(height, centroid,
+ fwhm, eta)*.
+
+ The pseudo-Voigt profile ``PV(x)`` is an approximation of the Voigt
+ profile using a linear combination of a Gaussian curve ``G(x)`` and a
+ Lorentzian curve ``L(x)`` instead of their convolution.
+
+ - *height* is the peak amplitude of G(x) and L(x)
+ - *centroid* is the peak x-coordinate for both functions
+ - *fwhm* is the full-width at half maximum of both functions
+ - *eta* is the Lorentz factor: PV(x) = eta * L(x) + (1 - eta) * G(x)
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of pseudo-Voigt parameters (length must be a multiple
+ of 4):
+ *(height1, centroid1, fwhm1, eta1, height2, centroid2, fwhm2, eta2,...)*
+ :return: Array of sum of pseudo-Voigt functions at each ``x`` coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 4 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_pvoigt(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_splitpvoigt(x, *params):
+ """Return a sum of split pseudo-Voigt functions, defined by *(height,
+ centroid, fwhm1, fwhm2, eta)*.
+
+ The pseudo-Voigt profile ``PV(x)`` is an approximation of the Voigt
+ profile using a linear combination of a Gaussian curve ``G(x)`` and a
+ Lorentzian curve ``L(x)`` instead of their convolution.
+
+ - *height* is the peak amplitudefor G(x) and L(x)
+ - *centroid* is the peak x-coordinate for both functions
+ - *fwhm1* is the full-width at half maximum of both functions
+ when ``x < centroid``
+ - *fwhm2* is the full-width at half maximum of both functions
+ when ``x > centroid``
+ - *eta* is the Lorentz factor: PV(x) = eta * L(x) + (1 - eta) * G(x)
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of pseudo-Voigt parameters (length must be a multiple
+ of 5):
+ *(height1, centroid1, fwhm11, fwhm21, eta1,...)*
+ :return: Array of sum of split pseudo-Voigt functions at each ``x``
+ coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 5 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_splitpvoigt(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_lorentz(x, *params):
+ """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ defined by *(height, centroid, fwhm)*.
+
+ - *height* is the peak amplitude
+ - *centroid* is the peak x-coordinate
+ - *fwhm* is the full-width at half maximum
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of Lorentz parameters (length must be a multiple
+ of 3):
+ *(height1, centroid1, fwhm1,...)*
+ :return: Array of sum Lorentz functions at each ``x``
+ coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 3 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_lorentz(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_alorentz(x, *params):
+ """Return a sum of Lorentz distributions, also known as Cauchy distribution,
+ defined by *(area, centroid, fwhm)*.
+
+ - *area* is the area underneath the peak
+ - *centroid* is the peak x-coordinate for both functions
+ - *fwhm* is the full-width at half maximum
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of Lorentz parameters (length must be a multiple
+ of 3):
+ *(area1, centroid1, fwhm1,...)*
+ :return: Array of sum of Lorentz functions at each ``x``
+ coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 3 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_alorentz(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_splitlorentz(x, *params):
+ """Return a sum of split Lorentz distributions,
+ defined by *(height, centroid, fwhm1, fwhm2)*.
+
+ - *height* is the peak amplitude
+ - *centroid* is the peak x-coordinate for both functions
+ - *fwhm1* is the full-width at half maximum for ``x < centroid``
+ - *fwhm2* is the full-width at half maximum for ``x > centroid``
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of Lorentz parameters (length must be a multiple
+ of 4):
+ *(height1, centroid1, fwhm11, fwhm21...)*
+ :return: Array of sum of Lorentz functions at each ``x``
+ coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 4 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_splitlorentz(
+ &x_c[0], x.size,
+ &params_c[0], params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_stepdown(x, *params):
+ """Return a sum of stepdown functions.
+ defined by *(height, centroid, fwhm)*.
+
+ - *height* is the step's amplitude
+ - *centroid* is the step's x-coordinate
+ - *fwhm* is the full-width at half maximum for the derivative,
+ which is a measure of the *sharpness* of the step-down's edge
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of stepdown parameters (length must be a multiple
+ of 3):
+ *(height1, centroid1, fwhm1,...)*
+ :return: Array of sum of stepdown functions at each ``x``
+ coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 3 parameters are required.")
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_stepdown(&x_c[0],
+ x.size,
+ &params_c[0],
+ params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_stepup(x, *params):
+ """Return a sum of stepup functions.
+ defined by *(height, centroid, fwhm)*.
+
+ - *height* is the step's amplitude
+ - *centroid* is the step's x-coordinate
+ - *fwhm* is the full-width at half maximum for the derivative,
+ which is a measure of the *sharpness* of the step-up's edge
+
+ :param x: Independant variable where the gaussians are calculated
+ :type x: numpy.ndarray
+ :param params: Array of stepup parameters (length must be a multiple
+ of 3):
+ *(height1, centroid1, fwhm1,...)*
+ :return: Array of sum of stepup functions at each ``x``
+ coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 3 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_stepup(&x_c[0],
+ x.size,
+ &params_c[0],
+ params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_slit(x, *params):
+ """Return a sum of slit functions.
+ defined by *(height, position, fwhm, beamfwhm)*.
+
+ - *height* is the slit's amplitude
+ - *position* is the center of the slit's x-coordinate
+ - *fwhm* is the full-width at half maximum of the slit
+ - *beamfwhm* is the full-width at half maximum of the
+ derivative, which is a measure of the *sharpness*
+ of the edges of the slit
+
+ :param x: Independant variable where the slits are calculated
+ :type x: numpy.ndarray
+ :param params: Array of slit parameters (length must be a multiple
+ of 4):
+ *(height1, centroid1, fwhm1, beamfwhm1,...)*
+ :return: Array of sum of slit functions at each ``x``
+ coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 4 parameters are required.")
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_slit(&x_c[0],
+ x.size,
+ &params_c[0],
+ params_c.size,
+ &y_c[0])
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_ahypermet(x, *params,
+ gaussian_term=True, st_term=True, lt_term=True, step_term=True):
+ """Return a sum of ahypermet functions.
+ defined by *(area, position, fwhm, st_area_r, st_slope_r, lt_area_r,
+ lt_slope_r, step_height_r)*.
+
+ - *area* is the area underneath the gaussian peak
+ - *position* is the center of the various peaks and the position of
+ the step down
+ - *fwhm* is the full-width at half maximum of the terms
+ - *st_area_r* is factor between the gaussian area and the area of the
+ short tail term
+ - *st_slope_r* is a ratio related to the slope of the short tail
+ in the low ``x`` values (the lower, the steeper)
+ - *lt_area_r* is ratio between the gaussian area and the area of the
+ long tail term
+ - *lt_slope_r* is a ratio related to the slope of the long tail
+ in the low ``x`` values (the lower, the steeper)
+ - *step_height_r* is the ratio between the height of the step down
+ and the gaussian height
+
+ A hypermet function is a sum of four functions (terms):
+
+ - a gaussian term
+ - a long tail term
+ - a short tail term
+ - a step down term
+
+ :param x: Independant variable where the hypermets are calculated
+ :type x: numpy.ndarray
+ :param params: Array of hypermet parameters (length must be a multiple
+ of 8):
+ *(area1, position1, fwhm1, st_area_r1, st_slope_r1, lt_area_r1,
+ lt_slope_r1, step_height_r1...)*
+ :param gaussian_term: If ``True``, enable gaussian term. Default ``True``
+ :param st_term: If ``True``, enable gaussian term. Default ``True``
+ :param lt_term: If ``True``, enable gaussian term. Default ``True``
+ :param step_term: If ``True``, enable gaussian term. Default ``True``
+ :return: Array of sum of hypermet functions at each ``x`` coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 8 parameters are required.")
+
+ # Sum binary flags to activate various terms of the equation
+ tail_flags = 1 if gaussian_term else 0
+ if st_term:
+ tail_flags += 2
+ if lt_term:
+ tail_flags += 4
+ if step_term:
+ tail_flags += 8
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_ahypermet(&x_c[0],
+ x.size,
+ &params_c[0],
+ params_c.size,
+ &y_c[0],
+ tail_flags)
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def sum_fastahypermet(x, *params,
+ gaussian_term=True, st_term=True,
+ lt_term=True, step_term=True):
+ """Return a sum of hypermet functions defined by *(area, position, fwhm,
+ st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r)*.
+
+ - *area* is the area underneath the gaussian peak
+ - *position* is the center of the various peaks and the position of
+ the step down
+ - *fwhm* is the full-width at half maximum of the terms
+ - *st_area_r* is factor between the gaussian area and the area of the
+ short tail term
+ - *st_slope_r* is a parameter related to the slope of the short tail
+ in the low ``x`` values (the lower, the steeper)
+ - *lt_area_r* is factor between the gaussian area and the area of the
+ long tail term
+ - *lt_slope_r* is a parameter related to the slope of the long tail
+ in the low ``x`` values (the lower, the steeper)
+ - *step_height_r* is the factor between the height of the step down
+ and the gaussian height
+
+ A hypermet function is a sum of four functions (terms):
+
+ - a gaussian term
+ - a long tail term
+ - a short tail term
+ - a step down term
+
+ This function differs from :func:`sum_ahypermet` by the use of a lookup
+ table for calculating exponentials. This offers better performance when
+ calculating many functions for large ``x`` arrays.
+
+ :param x: Independant variable where the hypermets are calculated
+ :type x: numpy.ndarray
+ :param params: Array of hypermet parameters (length must be a multiple
+ of 8):
+ *(area1, position1, fwhm1, st_area_r1, st_slope_r1, lt_area_r1,
+ lt_slope_r1, step_height_r1...)*
+ :param gaussian_term: If ``True``, enable gaussian term. Default ``True``
+ :param st_term: If ``True``, enable gaussian term. Default ``True``
+ :param lt_term: If ``True``, enable gaussian term. Default ``True``
+ :param step_term: If ``True``, enable gaussian term. Default ``True``
+ :return: Array of sum of hypermet functions at each ``x`` coordinate
+ """
+ cdef:
+ double[::1] x_c
+ double[::1] params_c
+ double[::1] y_c
+
+ if not len(params):
+ raise IndexError("No parameters specified. " +
+ "At least 8 parameters are required.")
+
+ # Sum binary flags to activate various terms of the equation
+ tail_flags = 1 if gaussian_term else 0
+ if st_term:
+ tail_flags += 2
+ if lt_term:
+ tail_flags += 4
+ if step_term:
+ tail_flags += 8
+
+ # TODO (maybe):
+ # Set flags according to params, to move conditional
+ # branches out of the C code.
+ # E.g., set st_term = False if any of the st_slope_r params
+ # (params[8*i + 4]) is 0, to prevent division by 0. Same thing for
+ # lt_slope_r (params[8*i + 6]) and lt_term.
+
+ x_c = numpy.array(x,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ params_c = numpy.array(params,
+ copy=False,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ y_c = numpy.empty(shape=(x.size,),
+ dtype=numpy.float64)
+
+ status = functions_wrapper.sum_fastahypermet(&x_c[0],
+ x.size,
+ &params_c[0],
+ params_c.size,
+ &y_c[0],
+ tail_flags)
+
+ if status:
+ raise IndexError("Wrong number of parameters for function")
+
+ return numpy.asarray(y_c).reshape(x.shape)
+
+
+def atan_stepup(x, a, b, c):
+ """
+ Step up function using an inverse tangent.
+
+ :param x: Independant variable where the function is calculated
+ :type x: numpy array
+ :param a: Height of the step up
+ :param b: Center of the step up
+ :param c: Parameter related to the slope of the step. A lower ``c``
+ value yields a sharper step.
+ :return: ``a * (0.5 + (arctan((x - b) / c) / pi))``
+ :rtype: numpy array
+ """
+ if not hasattr(x, "shape"):
+ x = numpy.array(x)
+ return a * (0.5 + (numpy.arctan((1.0 * x - b) / c) / numpy.pi))
+
+
+def periodic_gauss(x, *pars):
+ """
+ Return a sum of gaussian functions defined by
+ *(npeaks, delta, height, centroid, fwhm)*,
+ where:
+
+ - *npeaks* is the number of gaussians peaks
+ - *delta* is the constant distance between 2 peaks
+ - *height* is the peak amplitude of all the gaussians
+ - *centroid* is the peak x-coordinate of the first gaussian
+ - *fwhm* is the full-width at half maximum for all the gaussians
+
+ :param x: Independant variable where the function is calculated
+ :param pars: *(npeaks, delta, height, centroid, fwhm)*
+ :return: Sum of ``npeaks`` gaussians
+ """
+
+ if not len(pars):
+ raise IndexError("No parameters specified. " +
+ "At least 5 parameters are required.")
+
+ newpars = numpy.zeros((pars[0], 3), numpy.float)
+ for i in range(int(pars[0])):
+ newpars[i, 0] = pars[2]
+ newpars[i, 1] = pars[3] + i * pars[1]
+ newpars[:, 2] = pars[4]
+ return sum_gauss(x, newpars)
diff --git a/silx/math/fit/functions/functions_wrapper.pxd b/silx/math/fit/functions/functions_wrapper.pxd
new file mode 100644
index 0000000..780116c
--- /dev/null
+++ b/silx/math/fit/functions/functions_wrapper.pxd
@@ -0,0 +1,170 @@
+# 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.
+#
+#############################################################################*/
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "14/06/2016"
+
+cimport cython
+
+cdef extern from "functions.h":
+ int erfc_array(double* x,
+ int len_x,
+ double* y)
+
+ int erf_array(double* x,
+ int len_x,
+ double* y);
+
+ void snip1d(double *data,
+ int size,
+ int width)
+
+ void snip2d(double *data,
+ int nrows,
+ int ncolumns,
+ int width)
+
+ void snip3d(double *data,
+ int nx,
+ int ny,
+ int nz,
+ int width)
+
+ int strip(double* input,
+ long len_input,
+ double c,
+ long niter,
+ int deltai,
+ long* anchors,
+ long len_anchors,
+ double* output)
+
+ int sum_gauss(double* x,
+ int len_x,
+ double* pgauss,
+ int len_pgauss,
+ double* y)
+
+ int sum_agauss(double* x,
+ int len_x,
+ double* pgauss,
+ int len_pgauss,
+ double* y)
+
+ int sum_fastagauss(double* x,
+ int len_x,
+ double* pgauss,
+ int len_pgauss,
+ double* y)
+
+ int sum_splitgauss(double* x,
+ int len_x,
+ double* pgauss,
+ int len_pgauss,
+ double* y)
+
+ int sum_apvoigt(double* x,
+ int len_x,
+ double* pvoigt,
+ int len_pvoigt,
+ double* y)
+
+ int sum_pvoigt(double* x,
+ int len_x,
+ double* pvoigt,
+ int len_pvoigt,
+ double* y)
+
+ int sum_splitpvoigt(double* x,
+ int len_x,
+ double* pvoigt,
+ int len_pvoigt,
+ double* y)
+
+ int sum_lorentz(double* x,
+ int len_x,
+ double* plorentz,
+ int len_plorentz,
+ double* y)
+
+ int sum_alorentz(double* x,
+ int len_x,
+ double* plorentz,
+ int len_plorentz,
+ double* y)
+
+ int sum_splitlorentz(double* x,
+ int len_x,
+ double* plorentz,
+ int len_plorentz,
+ double* y)
+
+ int sum_stepdown(double* x,
+ int len_x,
+ double* pdstep,
+ int len_pdstep,
+ double* y)
+
+ int sum_stepup(double* x,
+ int len_x,
+ double* pustep,
+ int len_pustep,
+ double* y)
+
+ int sum_slit(double* x,
+ int len_x,
+ double* pslit,
+ int len_pslit,
+ double* y)
+
+ int sum_ahypermet(double* x,
+ int len_x,
+ double* phypermet,
+ int len_phypermet,
+ double* y,
+ int tail_flags)
+
+ int sum_fastahypermet(double* x,
+ int len_x,
+ double* phypermet,
+ int len_phypermet,
+ double* y,
+ int tail_flags)
+
+ long seek(long begin_index,
+ long end_index,
+ long nsamples,
+ double fwhm,
+ double sensitivity,
+ double debug_info,
+ long max_npeaks,
+ double * data,
+ double * peaks,
+ double * relevances)
+
+ int SavitskyGolay(double* input,
+ long len_input,
+ int npoints,
+ double* output)
diff --git a/silx/math/fit/functions/include/functions.h b/silx/math/fit/functions/include/functions.h
new file mode 100644
index 0000000..de4209b
--- /dev/null
+++ b/silx/math/fit/functions/include/functions.h
@@ -0,0 +1,68 @@
+/*##########################################################################
+# 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.
+#
+# ############################################################################*/
+
+#ifndef FITFUNCTIONS_H
+#define FITFUNCTIONS_H
+
+/* Helper functions */
+int test_params(int len_params, int len_params_one_function, char* fun_name, char* param_names);
+double myerfc(double x);
+double myerf(double x);
+int erfc_array(double* x, int len_x, double* y);
+int erf_array(double* x, int len_x, double* y);
+
+/* Background functions */
+void snip1d(double *data, int size, int width);
+//void snip1d_multiple(double *data, int n_channels, int snip_width, int n_spectra);
+void snip2d(double *data, int nrows, int ncolumns, int width);
+void snip3d(double *data, int nx, int ny, int nz, int width);
+
+int strip(double* input, long len_input, double c, long niter, int deltai,
+ long* anchors, long len_anchors, double* output);
+
+/* Smoothing functions */
+
+int SavitskyGolay(double* input, long len_input, int npoints, double* output);
+
+/* Fit functions */
+int sum_gauss(double* x, int len_x, double* pgauss, int len_pgauss, double* y);
+int sum_agauss(double* x, int len_x, double* pgauss, int len_pgauss, double* y);
+int sum_fastagauss(double* x, int len_x, double* pgauss, int len_pgauss, double* y);
+int sum_splitgauss(double* x, int len_x, double* pgauss, int len_pgauss, double* y);
+
+int sum_apvoigt(double* x, int len_x, double* pvoigt, int len_pvoigt, double* y);
+int sum_pvoigt(double* x, int len_x, double* pvoigt, int len_pvoigt, double* y);
+int sum_splitpvoigt(double* x, int len_x, double* pvoigt, int len_pvoigt, double* y);
+
+int sum_lorentz(double* x, int len_x, double* plorentz, int len_plorentz, double* y);
+int sum_alorentz(double* x, int len_x, double* plorentz, int len_plorentz, double* y);
+int sum_splitlorentz(double* x, int len_x, double* plorentz, int len_plorentz, double* y);
+
+int sum_stepdown(double* x, int len_x, double* pdstep, int len_pdstep, double* y);
+int sum_stepup(double* x, int len_x, double* pustep, int len_pustep, double* y);
+int sum_slit(double* x, int len_x, double* pslit, int len_pslit, double* y);
+
+int sum_ahypermet(double* x, int len_x, double* phypermet, int len_phypermet, double* y, int tail_flags);
+int sum_fastahypermet(double* x, int len_x, double* phypermet, int len_phypermet, double* y, int tail_flags);
+
+#endif /* #define FITFUNCTIONS_H */
diff --git a/silx/math/fit/functions/src/funs.c b/silx/math/fit/functions/src/funs.c
new file mode 100644
index 0000000..aae173f
--- /dev/null
+++ b/silx/math/fit/functions/src/funs.c
@@ -0,0 +1,1265 @@
+#/*##########################################################################
+# Copyright (c) 2004-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.
+#
+#############################################################################*/
+/*
+ This file provides fit functions.
+
+ It is adapted from PyMca source file "SpecFitFuns.c". The main difference
+ with the original code is that this code does not handle the python
+ wrapping, which is done elsewhere using cython.
+
+ Authors: V.A. Sole, P. Knobel
+ License: MIT
+ Last modified: 17/06/2016
+*/
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "functions.h"
+
+#ifndef M_PI
+#define M_PI 3.1415926535
+#endif
+
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+#if defined(_WIN32)
+#define erf myerf
+#define erfc myerfc
+#endif
+
+#define LOG2 0.69314718055994529
+
+
+int test_params(int len_params,
+ int len_params_one_function,
+ char* fun_name,
+ char* param_names)
+{
+ if (len_params % len_params_one_function) {
+ printf("[%s]Error: Number of parameters must be a multiple of %d.",
+ fun_name, len_params_one_function);
+ printf("\nParameters expected for %s: %s\n",
+ fun_name, param_names);
+ return(1);
+ }
+ if (len_params == 0) {
+ printf("[%s]Error: No parameters specified.", fun_name);
+ printf("\nParameters expected for %s: %s\n",
+ fun_name, param_names);
+ return(1);
+ }
+ return(0);
+}
+
+/* Complementary error function for a single value*/
+double myerfc(double x)
+{
+ double z;
+ double t;
+ double r;
+
+ z=fabs(x);
+ t=1.0/(1.0+0.5*z);
+ r=t * exp(-z * z - 1.26551223 + t * (1.00002368 + t * (0.3740916 +
+ t * (0.09678418 + t * (-0.18628806 + t * (0.27886807 + t * (-1.13520398 +
+ t * (1.48851587 + t * (-0.82215223+t*0.17087277)))))))));
+ if (x<0)
+ r=2.0-r;
+ return (r);
+}
+
+/* Gauss error function for a single value*/
+double myerf(double x)
+{
+ return (1.0 - myerfc(x));
+}
+
+/* Gauss error function for an array
+ y[i]=erf(x[i])
+ returns status code 0
+*/
+int erf_array(double* x, int len_x, double* y)
+{
+ int j;
+ for (j=0; j<len_x; j++) {
+ y[j] = erf(x[j]);
+ }
+ return(0);
+}
+
+/* Complementary error function for an array
+ y[i]=erfc(x[i])
+ returns status code 0*/
+int erfc_array(double* x, int len_x, double* y)
+{
+ int j;
+ for (j=0; j<len_x; j++) {
+ y[j] = erfc(x[j]);
+ }
+ return(0);
+}
+
+/* Use lookup table for fast exp computation */
+double fastexp(double x)
+{
+ int expindex;
+ static double EXP[5000] = {0.0};
+ int i;
+
+/*initialize */
+ if (EXP[0] < 1){
+ for (i=0;i<5000;i++){
+ EXP[i] = exp(-0.01 * i);
+ }
+ }
+/*calculate*/
+ if (x < 0){
+ x = -x;
+ if (x < 50){
+ expindex = (int) (x * 100);
+ return EXP[expindex]*(1.0 - (x - 0.01 * expindex)) ;
+ }else if (x < 100) {
+ expindex = (int) (x * 10);
+ return pow(EXP[expindex]*(1.0 - (x - 0.1 * expindex)),10) ;
+ }else if (x < 1000){
+ expindex = (int) x;
+ return pow(EXP[expindex]*(1.0 - (x - expindex)),20) ;
+ }else if (x < 10000){
+ expindex = (int) (x * 0.1);
+ return pow(EXP[expindex]*(1.0 - (x - 10.0 * expindex)),30) ;
+ }else{
+ return 0;
+ }
+ }else{
+ if (x < 50){
+ expindex = (int) (x * 100);
+ return 1.0/EXP[expindex]*(1.0 - (x - 0.01 * expindex)) ;
+ }else if (x < 100) {
+ expindex = (int) (x * 10);
+ return pow(EXP[expindex]*(1.0 - (x - 0.1 * expindex)),-10) ;
+ }else{
+ return exp(x);
+ }
+ }
+}
+
+
+/* sum_gauss
+ Sum of gaussian functions, defined by (height, centroid, fwhm)
+
+ *height* is the peak amplitude
+ *centroid* is the peak x-coordinate
+ *fwhm* is the full-width at half maximum
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the gaussians are calculated.
+ - len_x: Number of elements in the x array.
+ - pvoigt: Array of gaussian parameters:
+ (height1, centroid1, fwhm1, height2, centroid2, fwhm2,...)
+ - len_pgauss: Number of elements in the pgauss array. Must be
+ a multiple of 3.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_gauss(double* x, int len_x, double* pgauss, int len_pgauss, double* y)
+{
+ int i, j;
+ double dhelp, inv_two_sqrt_two_log2, sigma;
+ double fwhm, centroid, height;
+
+ if (test_params(len_pgauss, 3, "sum_gauss", "height, centroid, fwhm")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ inv_two_sqrt_two_log2 = 1.0 / (2.0 * sqrt(2.0 * LOG2));
+
+ for (i=0; i<len_pgauss/3; i++) {
+ height = pgauss[3*i];
+ centroid = pgauss[3*i+1];
+ fwhm = pgauss[3*i+2];
+
+ sigma = fwhm * inv_two_sqrt_two_log2;
+
+ for (j=0; j<len_x; j++) {
+ dhelp = (x[j] - centroid) / sigma;
+ if (dhelp <= 20) {
+ y[j] += height * exp (-0.5 * dhelp * dhelp);
+ }
+ }
+ }
+ return(0);
+}
+
+/* sum_agauss
+ Sum of gaussian functions defined by (area, centroid, fwhm)
+
+ *area* is the area underneath the peak
+ *centroid* is the peak x-coordinate
+ *fwhm* is the full-width at half maximum
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the gaussians are calculated.
+ - len_x: Number of elements in the x array.
+ - pgauss: Array of gaussian parameters:
+ (area1, centroid1, fwhm1, area2, centroid2, fwhm2,...)
+ - len_pgauss: Number of elements in the pgauss array. Must be
+ a multiple of 3.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_agauss(double* x, int len_x, double* pgauss, int len_pgauss, double* y)
+{
+ int i, j;
+ double dhelp, height, sqrt2PI, sigma, inv_two_sqrt_two_log2;
+ double fwhm, centroid, area;
+
+ if (test_params(len_pgauss, 3, "sum_agauss", "area, centroid, fwhm")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ inv_two_sqrt_two_log2 = 1.0 / (2.0 * sqrt(2.0 * LOG2));
+ sqrt2PI = sqrt(2.0*M_PI);
+
+ for (i=0; i<len_pgauss/3; i++) {
+ area = pgauss[3*i];
+ centroid = pgauss[3*i+1];
+ fwhm = pgauss[3*i+2];
+
+ sigma = fwhm * inv_two_sqrt_two_log2;
+ height = area / (sigma * sqrt2PI);
+
+ for (j=0; j<len_x; j++) {
+ dhelp = (x[j] - centroid)/sigma;
+ if (dhelp <= 35) {
+ y[j] += height * exp (-0.5 * dhelp * dhelp);
+ }
+ }
+ }
+ return(0);
+}
+
+
+/* sum_fastagauss
+ Sum of gaussian functions defined by (area, centroid, fwhm).
+ This implementation uses a lookup table of precalculated exp values
+ and a limited development (exp(-x) = 1 - x for small values of x)
+
+ *area* is the area underneath the peak
+ *centroid* is the peak x-coordinate
+ *fwhm* is the full-width at half maximum
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the gaussians are calculated.
+ - len_x: Number of elements in the x array.
+ - pgauss: Array of gaussian parameters:
+ (area1, centroid1, fwhm1, area2, centroid2, fwhm2,...)
+ - len_pgauss: Number of elements in the pgauss array. Must be
+ a multiple of 3.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+
+int sum_fastagauss(double* x, int len_x, double* pgauss, int len_pgauss, double* y)
+{
+ int i, j, expindex;
+ double dhelp, height, sqrt2PI, sigma, inv_two_sqrt_two_log2;
+ double fwhm, centroid, area;
+ static double EXP[5000];
+
+ if (test_params(len_pgauss, 3, "sum_fastagauss", "area, centroid, fwhm")) {
+ return(1);
+ }
+
+ if (EXP[0] < 1){
+ for (i=0; i<5000; i++){
+ EXP[i] = exp(-0.01 * i);
+ }
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ inv_two_sqrt_two_log2 = 1.0 / (2.0 * sqrt(2.0 * LOG2));
+ sqrt2PI = sqrt(2.0*M_PI);
+
+ for (i=0; i<len_pgauss/3; i++) {
+ area = pgauss[3*i];
+ centroid = pgauss[3*i+1];
+ fwhm = pgauss[3*i+2];
+
+ sigma = fwhm * inv_two_sqrt_two_log2;
+ height = area / (sigma * sqrt2PI);
+
+ for (j=0; j<len_x; j++) {
+ dhelp = (x[j] - centroid)/sigma;
+ if (dhelp <= 15){
+ dhelp = 0.5 * dhelp * dhelp;
+ if (dhelp < 50){
+ expindex = (int) (dhelp * 100);
+ y[j] += height * EXP[expindex] * (1.0 - (dhelp - 0.01 * expindex));
+ }
+ else if (dhelp < 100) {
+ expindex = (int) (dhelp * 10);
+ y[j] += height * pow(EXP[expindex] * (1.0 - (dhelp - 0.1 * expindex)), 10);
+ }
+ else if (dhelp < 1000){
+ expindex = (int) (dhelp);
+ y[j] += height * pow(EXP[expindex] * (1.0 - (dhelp - expindex)), 20);
+ }
+ }
+ }
+ }
+ return(0);
+}
+
+/* sum_splitgauss
+ Sum of split gaussian functions, defined by (height, centroid, fwhm1, fwhm2)
+
+ *height* is the peak amplitude
+ *centroid* is the peak x-coordinate
+ *fwhm1* is the full-width at half maximum of the left half of the curve (x < centroid)
+ *fwhm1* is the full-width at half maximum of the right half of the curve (x > centroid)
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the gaussians are calculated.
+ - len_x: Number of elements in the x array.
+ - pgauss: Array of gaussian parameters:
+ (height1, centroid1, fwhm11, fwhm21, height2, centroid2, fwhm12, fwhm22,...)
+ - len_pgauss: Number of elements in the pgauss array. Must be
+ a multiple of 4.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_splitgauss(double* x, int len_x, double* pgauss, int len_pgauss, double* y)
+{
+ int i, j;
+ double dhelp, inv_two_sqrt_two_log2, sigma1, sigma2;
+ double fwhm1, fwhm2, centroid, height;
+
+ if (test_params(len_pgauss, 4, "sum_splitgauss", "height, centroid, fwhm1, fwhm2")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ inv_two_sqrt_two_log2 = 1.0 / (2.0 * sqrt(2.0 * LOG2));
+
+ for (i=0; i<len_pgauss/4; i++) {
+ height = pgauss[4*i];
+ centroid = pgauss[4*i+1];
+ fwhm1 = pgauss[4*i+2];
+ fwhm2 = pgauss[4*i+3];
+
+ sigma1 = fwhm1 * inv_two_sqrt_two_log2;
+ sigma2 = fwhm2 * inv_two_sqrt_two_log2;
+
+ for (j=0; j<len_x; j++) {
+ dhelp = (x[j] - centroid);
+ if (dhelp > 0) {
+ /* Use fwhm2 when x > centroid */
+ dhelp = dhelp / sigma2;
+ }
+ else {
+ /* Use fwhm1 when x < centroid */
+ dhelp = dhelp / sigma1;
+ }
+
+ if (dhelp <= 20) {
+ y[j] += height * exp (-0.5 * dhelp * dhelp);
+ }
+ }
+ }
+ return(0);
+}
+
+/* sum_apvoigt
+ Sum of pseudo-Voigt functions, defined by (area, centroid, fwhm, eta).
+
+ The pseudo-Voigt profile PV(x) is an approximation of the Voigt profile
+ using a linear combination of a Gaussian curve G(x) and a Lorentzian curve
+ L(x) instead of their convolution.
+
+ *area* is the area underneath both G(x) and L(x)
+ *centroid* is the peak x-coordinate for both functions
+ *fwhm* is the full-width at half maximum of both functions
+ *eta* is the Lorentz factor: PV(x) = eta * L(x) + (1 - eta) * G(x)
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the gaussians are calculated.
+ - len_x: Number of elements in the x array.
+ - pvoigt: Array of Voigt function parameters:
+ (area1, centroid1, fwhm1, eta1, area2, centroid2, fwhm2, eta2,...)
+ - len_voigt: Number of elements in the pvoigt array. Must be
+ a multiple of 4.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_apvoigt(double* x, int len_x, double* pvoigt, int len_pvoigt, double* y)
+{
+ int i, j;
+ double dhelp, inv_two_sqrt_two_log2, sqrt2PI, sigma, height;
+ double area, centroid, fwhm, eta;
+
+ if (test_params(len_pvoigt, 4, "sum_apvoigt", "area, centroid, fwhm, eta")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ inv_two_sqrt_two_log2 = 1.0 / (2.0 * sqrt(2.0 * LOG2));
+ sqrt2PI = sqrt(2.0*M_PI);
+
+
+ for (i=0; i<len_pvoigt/4; i++) {
+ area = pvoigt[4*i];
+ centroid = pvoigt[4*i+1];
+ fwhm = pvoigt[4*i+2];
+ eta = pvoigt[4*i+3];
+
+ sigma = fwhm * inv_two_sqrt_two_log2;
+ height = area / (sigma * sqrt2PI);
+
+ for (j=0; j<len_x; j++) {
+ /* Lorentzian term */
+ dhelp = (x[j] - centroid) / (0.5 * fwhm);
+ dhelp = 1.0 + (dhelp * dhelp);
+ y[j] += eta * (area / (0.5 * M_PI * fwhm * dhelp));
+
+ /* Gaussian term */
+ dhelp = (x[j] - centroid) / sigma;
+ if (dhelp <= 35) {
+ y[j] += (1.0 - eta) * height * exp (-0.5 * dhelp * dhelp);
+ }
+ }
+ }
+ return(0);
+}
+
+/* sum_pvoigt
+ Sum of pseudo-Voigt functions, defined by (height, centroid, fwhm, eta).
+
+ The pseudo-Voigt profile PV(x) is an approximation of the Voigt profile
+ using a linear combination of a Gaussian curve G(x) and a Lorentzian curve
+ L(x) instead of their convolution.
+
+ *height* is the peak amplitude of G(x) and L(x)
+ *centroid* is the peak x-coordinate for both functions
+ *fwhm* is the full-width at half maximum of both functions
+ *eta* is the Lorentz factor: PV(x) = eta * L(x) + (1 - eta) * G(x)
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the gaussians are calculated.
+ - len_x: Number of elements in the x array.
+ - pvoigt: Array of Voigt function parameters:
+ (height1, centroid1, fwhm1, eta1, height2, centroid2, fwhm2, eta2,...)
+ - len_voigt: Number of elements in the pvoigt array. Must be
+ a multiple of 4.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_pvoigt(double* x, int len_x, double* pvoigt, int len_pvoigt, double* y)
+{
+ int i, j;
+ double dhelp, inv_two_sqrt_two_log2, sigma;
+ double height, centroid, fwhm, eta;
+
+ if (test_params(len_pvoigt, 4, "sum_pvoigt", "height, centroid, fwhm, eta")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ inv_two_sqrt_two_log2 = 1.0 / (2.0 * sqrt(2.0 * LOG2));
+
+ for (i=0; i<len_pvoigt/4; i++) {
+ height = pvoigt[4*i];
+ centroid = pvoigt[4*i+1];
+ fwhm = pvoigt[4*i+2];
+ eta = pvoigt[4*i+3];
+
+ sigma = fwhm * inv_two_sqrt_two_log2;
+
+ for (j=0; j<len_x; j++) {
+ /* Lorentzian term */
+ dhelp = (x[j] - centroid) / (0.5 * fwhm);
+ dhelp = 1.0 + (dhelp * dhelp);
+ y[j] += eta * height / dhelp;
+
+ /* Gaussian term */
+ dhelp = (x[j] - centroid) / sigma;
+ if (dhelp <= 35) {
+ y[j] += (1.0 - eta) * height * exp (-0.5 * dhelp * dhelp);
+ }
+ }
+ }
+ return(0);
+}
+
+/* sum_splitpvoigt
+ Sum of split pseudo-Voigt functions, defined by
+ (height, centroid, fwhm1, fwhm2, eta).
+
+ The pseudo-Voigt profile PV(x) is an approximation of the Voigt profile
+ using a linear combination of a Gaussian curve G(x) and a Lorentzian curve
+ L(x) instead of their convolution.
+
+ *height* is the peak amplitude of G(x) and L(x)
+ *centroid* is the peak x-coordinate for both functions
+ *fwhm1* is the full-width at half maximum of both functions for x < centroid
+ *fwhm2* is the full-width at half maximum of both functions for x > centroid
+ *eta* is the Lorentz factor: PV(x) = eta * L(x) + (1 - eta) * G(x)
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the gaussians are calculated.
+ - len_x: Number of elements in the x array.
+ - pvoigt: Array of Voigt function parameters:
+ (height1, centroid1, fwhm11, fwhm21, eta1, ...)
+ - len_voigt: Number of elements in the pvoigt array. Must be
+ a multiple of 5.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_splitpvoigt(double* x, int len_x, double* pvoigt, int len_pvoigt, double* y)
+{
+ int i, j;
+ double dhelp, inv_two_sqrt_two_log2, x_minus_centroid, sigma1, sigma2;
+ double height, centroid, fwhm1, fwhm2, eta;
+
+ if (test_params(len_pvoigt, 5, "sum_splitpvoigt", "height, centroid, fwhm1, fwhm2, eta")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ inv_two_sqrt_two_log2 = 1.0 / (2.0 * sqrt(2.0 * LOG2));
+
+ for (i=0; i<len_pvoigt/5; i++) {
+ height = pvoigt[5*i];
+ centroid = pvoigt[5*i+1];
+ fwhm1 = pvoigt[5*i+2];
+ fwhm2 = pvoigt[5*i+3];
+ eta = pvoigt[5*i+4];
+
+ sigma1 = fwhm1 * inv_two_sqrt_two_log2;
+ sigma2 = fwhm2 * inv_two_sqrt_two_log2;
+
+ for (j=0; j<len_x; j++) {
+ x_minus_centroid = (x[j] - centroid);
+
+ /* Use fwhm2 when x > centroid */
+ if (x_minus_centroid > 0) {
+ /* Lorentzian term */
+ dhelp = x_minus_centroid / (0.5 * fwhm2);
+ dhelp = 1.0 + (dhelp * dhelp);
+ y[j] += eta * height / dhelp;
+
+ /* Gaussian term */
+ dhelp = x_minus_centroid / sigma2;
+ if (dhelp <= 35) {
+ y[j] += (1.0 - eta) * height * exp (-0.5 * dhelp * dhelp);
+ }
+ }
+ /* Use fwhm1 when x < centroid */
+ else {
+ /* Lorentzian term */
+ dhelp = x_minus_centroid / (0.5 * fwhm1);
+ dhelp = 1.0 + (dhelp * dhelp);
+ y[j] += eta * height / dhelp;
+
+ /* Gaussian term */
+ dhelp = x_minus_centroid / sigma1;
+ if (dhelp <= 35) {
+ y[j] += (1.0 - eta) * height * exp (-0.5 * dhelp * dhelp);
+ }
+ }
+ }
+ }
+ return(0);
+}
+
+/* sum_lorentz
+ Sum of Lorentz functions, defined by (height, centroid, fwhm).
+
+ *height* is the peak amplitude
+ *centroid* is the peak's x-coordinate
+ *fwhm* is the full-width at half maximum
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the Lorentzians are calculated.
+ - len_x: Number of elements in the x array.
+ - plorentz: Array of lorentz function parameters:
+ (height1, centroid1, fwhm1, ...)
+ - len_lorentz: Number of elements in the plorentz array. Must be
+ a multiple of 3.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_lorentz(double* x, int len_x, double* plorentz, int len_plorentz, double* y)
+{
+ int i, j;
+ double dhelp;
+ double height, centroid, fwhm;
+
+ if (test_params(len_plorentz, 3, "sum_lorentz", "height, centroid, fwhm")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ for (i=0; i<len_plorentz/3; i++) {
+ height = plorentz[3*i];
+ centroid = plorentz[3*i+1];
+ fwhm = plorentz[3*i+2];
+
+ for (j=0; j<len_x; j++) {
+ dhelp = (x[j] - centroid) / (0.5 * fwhm);
+ dhelp = 1.0 + (dhelp * dhelp);
+ y[j] += height / dhelp;
+ }
+ }
+ return(0);
+}
+
+
+/* sum_alorentz
+ Sum of Lorentz functions, defined by (area, centroid, fwhm).
+
+ *area* is the area underneath the peak
+ *centroid* is the peak's x-coordinate
+ *fwhm* is the full-width at half maximum
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the Lorentzians are calculated.
+ - len_x: Number of elements in the x array.
+ - plorentz: Array of lorentz function parameters:
+ (area1, centroid1, fwhm1, ...)
+ - len_lorentz: Number of elements in the plorentz array. Must be
+ a multiple of 3.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_alorentz(double* x, int len_x, double* plorentz, int len_plorentz, double* y)
+{
+ int i, j;
+ double dhelp;
+ double area, centroid, fwhm;
+
+ if (test_params(len_plorentz, 3, "sum_alorentz", "area, centroid, fwhm")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ for (i=0; i<len_plorentz/3; i++) {
+ area = plorentz[3*i];
+ centroid = plorentz[3*i+1];
+ fwhm = plorentz[3*i+2];
+
+ for (j=0; j<len_x; j++) {
+ dhelp = (x[j] - centroid) / (0.5 * fwhm);
+ dhelp = 1.0 + (dhelp * dhelp);
+ y[j] += area / (0.5 * M_PI * fwhm * dhelp);
+ }
+ }
+ return(0);
+}
+
+
+/* sum_splitlorentz
+ Sum of Lorentz functions, defined by (height, centroid, fwhm1, fwhm2).
+
+ *height* is the peak amplitude
+ *centroid* is the peak's x-coordinate
+ *fwhm1* is the full-width at half maximum for x < centroid
+ *fwhm2* is the full-width at half maximum for x > centroid
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the Lorentzians are calculated.
+ - len_x: Number of elements in the x array.
+ - plorentz: Array of lorentz function parameters:
+ (height1, centroid1, fwhm11, fwhm21 ...)
+ - len_lorentz: Number of elements in the plorentz array. Must be
+ a multiple of 4.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_splitlorentz(double* x, int len_x, double* plorentz, int len_plorentz, double* y)
+{
+ int i, j;
+ double dhelp;
+ double height, centroid, fwhm1, fwhm2;
+
+ if (test_params(len_plorentz, 4, "sum_splitlorentz", "height, centroid, fwhm1, fwhm2")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ for (i=0; i<len_plorentz/4; i++) {
+ height = plorentz[4*i];
+ centroid = plorentz[4*i+1];
+ fwhm1 = plorentz[4*i+2];
+ fwhm2 = plorentz[4*i+3];
+
+ for (j=0; j<len_x; j++) {
+ dhelp = (x[j] - centroid);
+ if (dhelp>0) {
+ dhelp = dhelp / (0.5 * fwhm2);
+ }
+ else {
+ dhelp = dhelp / (0.5 * fwhm1);
+ }
+ dhelp = 1.0 + (dhelp * dhelp);
+ y[j] += height / dhelp;
+ }
+ }
+ return(0);
+}
+
+/* sum_stepdown
+ Sum of stepdown functions, defined by (height, centroid, fwhm).
+
+ *height* is the step amplitude
+ *centroid* is the step's x-coordinate
+ *fwhm* is the full-width at half maximum of the derivative
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the stepdown functions are calculated.
+ - len_x: Number of elements in the x array.
+ - pdstep: Array of downstpe function parameters:
+ (height1, centroid1, fwhm1, ...)
+ - len_pdstep: Number of elements in the pdstep array. Must be
+ a multiple of 3.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_stepdown(double* x, int len_x, double* pdstep, int len_pdstep, double* y)
+{
+ int i, j;
+ double dhelp, sqrt2_inv_2_sqrt_two_log2 ;
+ double height, centroid, fwhm;
+
+ if (test_params(len_pdstep, 3, "sum_stepdown", "height, centroid, fwhm")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ sqrt2_inv_2_sqrt_two_log2 = sqrt(2.0) / (2.0 * sqrt(2.0 * LOG2));
+
+ for (i=0; i<len_pdstep/3; i++) {
+ height = pdstep[3*i];
+ centroid = pdstep[3*i+1];
+ fwhm = pdstep[3*i+2];
+
+ for (j=0; j<len_x; j++) {
+ dhelp = fwhm * sqrt2_inv_2_sqrt_two_log2;
+ dhelp = (x[j] - centroid) / dhelp;
+ y[j] += height * 0.5 * erfc(dhelp);
+ }
+ }
+ return(0);
+}
+
+/* sum_stepup
+ Sum of stepup functions, defined by (height, centroid, fwhm).
+
+ *height* is the step amplitude
+ *centroid* is the step's x-coordinate
+ *fwhm* is the full-width at half maximum of the derivative
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the stepup functions are calculated.
+ - len_x: Number of elements in the x array.
+ - pustep: Array of stepdown function parameters:
+ (height1, centroid1, fwhm1, ...)
+ - len_pustep: Number of elements in the pustep array. Must be
+ a multiple of 3.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_stepup(double* x, int len_x, double* pustep, int len_pustep, double* y)
+{
+ int i, j;
+ double dhelp, sqrt2_inv_2_sqrt_two_log2 ;
+ double height, centroid, fwhm;
+
+ if (test_params(len_pustep, 3, "sum_stepup", "height, centroid, fwhm")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ sqrt2_inv_2_sqrt_two_log2 = sqrt(2.0) / (2.0 * sqrt(2.0 * LOG2));
+
+ for (i=0; i<len_pustep/3; i++) {
+ height = pustep[3*i];
+ centroid = pustep[3*i+1];
+ fwhm = pustep[3*i+2];
+
+ for (j=0; j<len_x; j++) {
+ dhelp = fwhm * sqrt2_inv_2_sqrt_two_log2;
+ dhelp = (x[j] - centroid) / dhelp;
+ y[j] += height * 0.5 * (1.0 + erf(dhelp));
+ }
+ }
+ return(0);
+}
+
+
+/* sum_slit
+ Sum of slit functions, defined by (height, position, fwhm, beamfwhm).
+
+ *height* is the slit height
+ *position* is the slit's center x-coordinate
+ *fwhm* is the full-width at half maximum of the slit
+ *beamfwhm* is the full-width at half maximum of derivative's peaks
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the slit functions are calculated.
+ - len_x: Number of elements in the x array.
+ - pslit: Array of slit function parameters:
+ (height1, centroid1, fwhm1, beamfwhm1 ...)
+ - len_pslit: Number of elements in the pslit array. Must be
+ a multiple of 3.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_slit(double* x, int len_x, double* pslit, int len_pslit, double* y)
+{
+ int i, j;
+ double dhelp, dhelp1, dhelp2, sqrt2_inv_2_sqrt_two_log2, centroid1, centroid2;
+ double height, position, fwhm, beamfwhm;
+
+ if (test_params(len_pslit, 4, "sum_slit", "height, centroid, fwhm, beamfwhm")) {
+ return(1);
+ }
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ sqrt2_inv_2_sqrt_two_log2 = sqrt(2.0) / (2.0 * sqrt(2.0 * LOG2));
+
+ for (i=0; i<len_pslit/4; i++) {
+ height = pslit[4*i];
+ position = pslit[4*i+1];
+ fwhm = pslit[4*i+2];
+ beamfwhm = pslit[4*i+3];
+
+ centroid1 = position - 0.5 * fwhm;
+ centroid2 = position + 0.5 * fwhm;
+
+ for (j=0; j<len_x; j++) {
+ dhelp = beamfwhm * sqrt2_inv_2_sqrt_two_log2;
+ dhelp1 = (x[j] - centroid1) / dhelp;
+ dhelp2 = (x[j] - centroid2) / dhelp;
+ y[j] += height * 0.25 * (1.0 + erf(dhelp1)) * erfc(dhelp2);
+ }
+ }
+ return(0);
+}
+
+
+/* sum_ahypermet
+ Sum of hypermet functions, defined by
+ (area, position, fwhm, st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r).
+
+ - *area* is the area underneath the gaussian peak
+ - *position* is the center of the various peaks and the position of
+ the step down
+ - *fwhm* is the full-width at half maximum of the terms
+ - *st_area_r* is factor between the gaussian area and the area of the
+ short tail term
+ - *st_slope_r* is a parameter related to the slope of the short tail
+ in the low ``x`` values (the lower, the steeper)
+ - *lt_area_r* is factor between the gaussian area and the area of the
+ long tail term
+ - *lt_slope_r* is a parameter related to the slope of the long tail
+ in the low ``x`` values (the lower, the steeper)
+ - *step_height_r* is the factor between the height of the step down
+ and the gaussian height
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the functions are calculated.
+ - len_x: Number of elements in the x array.
+ - phypermet: Array of hypermet function parameters:
+ *(area1, position1, fwhm1, st_area_r1, st_slope_r1, lt_area_r1,
+ lt_slope_r1, step_height_r1, ...)*
+ - len_phypermet: Number of elements in the phypermet array. Must be
+ a multiple of 8.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+ - tail_flags: sum of binary flags to activate the various terms of the
+ function:
+
+ - 1 (b0001): Gaussian term
+ - 2 (b0010): st term
+ - 4 (b0100): lt term
+ - 8 (b1000): step term
+
+ E.g., to activate all termsof the hypermet, use ``tail_flags = 1 + 2 + 4 + 8 = 15``
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_ahypermet(double* x, int len_x, double* phypermet, int len_phypermet, double* y, int tail_flags)
+{
+ int i, j;
+ int g_term_flag, st_term_flag, lt_term_flag, step_term_flag;
+ double c1, c2, sigma, height, sigma_sqrt2, sqrt2PI, inv_2_sqrt_2_log2, x_minus_position, epsilon;
+ double area, position, fwhm, st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r;
+
+ if (test_params(len_phypermet, 8, "sum_hypermet",
+ "height, centroid, fwhm, st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r")) {
+ return(1);
+ }
+
+ g_term_flag = tail_flags & 1;
+ st_term_flag = (tail_flags>>1) & 1;
+ lt_term_flag = (tail_flags>>2) & 1;
+ step_term_flag = (tail_flags>>3) & 1;
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ /* define epsilon to compare floating point values with 0. */
+ epsilon = 0.00000000001;
+
+ sqrt2PI= sqrt(2.0 * M_PI);
+ inv_2_sqrt_2_log2 = 1.0 / (2.0 * sqrt(2.0 * LOG2));
+
+ for (i=0; i<len_phypermet/8; i++) {
+ area = phypermet[8*i];
+ position = phypermet[8*i+1];
+ fwhm = phypermet[8*i+2];
+ st_area_r = phypermet[8*i+3];
+ st_slope_r = phypermet[8*i+4];
+ lt_area_r = phypermet[8*i+5];
+ lt_slope_r = phypermet[8*i+6];
+ step_height_r = phypermet[8*i+7];
+
+ sigma = fwhm * inv_2_sqrt_2_log2;
+ height = area / (sigma * sqrt2PI);
+
+ /* Prevent division by 0 */
+ if (sigma == 0) {
+ printf("fwhm must not be equal to 0");
+ return(1);
+ }
+ sigma_sqrt2 = sigma * 1.4142135623730950488;
+
+ for (j=0; j<len_x; j++) {
+ x_minus_position = x[j] - position;
+ c2 = (0.5 * x_minus_position * x_minus_position) / (sigma * sigma);
+ /* gaussian term */
+ if (g_term_flag) {
+ y[j] += exp(-c2) * height;
+ }
+
+ /* st term */
+ if (st_term_flag) {
+ if (fabs(st_slope_r) > epsilon) {
+ c1 = st_area_r * 0.5 * \
+ erfc((x_minus_position/sigma_sqrt2) + 0.5 * sigma_sqrt2 / st_slope_r);
+ y[j] += ((area * c1) / st_slope_r) * \
+ exp(0.5 * (sigma / st_slope_r) * (sigma / st_slope_r) + \
+ (x_minus_position / st_slope_r));
+ }
+ }
+
+ /* lt term */
+ if (lt_term_flag) {
+ if (fabs(lt_slope_r) > epsilon) {
+ c1 = lt_area_r * \
+ 0.5 * erfc((x_minus_position/sigma_sqrt2) + 0.5 * sigma_sqrt2 / lt_slope_r);
+ y[j] += ((area * c1) / lt_slope_r) * \
+ exp(0.5 * (sigma / lt_slope_r) * (sigma / lt_slope_r) + \
+ (x_minus_position / lt_slope_r));
+ }
+ }
+
+ /* step term flag */
+ if (step_term_flag) {
+ y[j] += step_height_r * (area / (sigma * sqrt2PI)) * \
+ 0.5 * erfc(x_minus_position / sigma_sqrt2);
+ }
+ }
+ }
+ return(0);
+}
+
+/* sum_fastahypermet
+
+ Sum of hypermet functions, defined by
+ (area, position, fwhm, st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r).
+
+ - *area* is the area underneath the gaussian peak
+ - *position* is the center of the various peaks and the position of
+ the step down
+ - *fwhm* is the full-width at half maximum of the terms
+ - *st_area_r* is factor between the gaussian area and the area of the
+ short tail term
+ - *st_slope_r* is a parameter related to the slope of the short tail
+ in the low ``x`` values (the lower, the steeper)
+ - *lt_area_r* is factor between the gaussian area and the area of the
+ long tail term
+ - *lt_slope_r* is a parameter related to the slope of the long tail
+ in the low ``x`` values (the lower, the steeper)
+ - *step_height_r* is the factor between the height of the step down
+ and the gaussian height
+
+ Parameters:
+ -----------
+
+ - x: Independant variable where the functions are calculated.
+ - len_x: Number of elements in the x array.
+ - phypermet: Array of hypermet function parameters:
+ *(area1, position1, fwhm1, st_area_r1, st_slope_r1, lt_area_r1,
+ lt_slope_r1, step_height_r1, ...)*
+ - len_phypermet: Number of elements in the phypermet array. Must be
+ a multiple of 8.
+ - y: Output array. Must have memory allocated for the same number
+ of elements as x (len_x).
+ - tail_flags: sum of binary flags to activate the various terms of the
+ function:
+
+ - 1 (b0001): Gaussian term
+ - 2 (b0010): st term
+ - 4 (b0100): lt term
+ - 8 (b1000): step term
+
+ E.g., to activate all termsof the hypermet, use ``tail_flags = 1 + 2 + 4 + 8 = 15``
+
+ Adapted from PyMca module SpecFitFuns
+*/
+int sum_fastahypermet(double* x, int len_x, double* phypermet, int len_phypermet, double* y, int tail_flags)
+{
+ int i, j;
+ int g_term_flag, st_term_flag, lt_term_flag, step_term_flag;
+ double c1, c2, sigma, height, sigma_sqrt2, sqrt2PI, inv_2_sqrt_2_log2, x_minus_position, epsilon;
+ double area, position, fwhm, st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r;
+
+ if (test_params(len_phypermet, 8, "sum_hypermet",
+ "height, centroid, fwhm, st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r")) {
+ return(1);
+ }
+
+ g_term_flag = tail_flags & 1;
+ st_term_flag = (tail_flags>>1) & 1;
+ lt_term_flag = (tail_flags>>2) & 1;
+ step_term_flag = (tail_flags>>3) & 1;
+
+ /* Initialize output array */
+ for (j=0; j<len_x; j++) {
+ y[j] = 0.;
+ }
+
+ /* define epsilon to compare floating point values with 0. */
+ epsilon = 0.00000000001;
+
+ sqrt2PI= sqrt(2.0 * M_PI);
+ inv_2_sqrt_2_log2 = 1.0 / (2.0 * sqrt(2.0 * LOG2));
+
+ for (i=0; i<len_phypermet/8; i++) {
+ area = phypermet[8*i];
+ position = phypermet[8*i+1];
+ fwhm = phypermet[8*i+2];
+ st_area_r = phypermet[8*i+3];
+ st_slope_r = phypermet[8*i+4];
+ lt_area_r = phypermet[8*i+5];
+ lt_slope_r = phypermet[8*i+6];
+ step_height_r = phypermet[8*i+7];
+
+ sigma = fwhm * inv_2_sqrt_2_log2;
+ height = area / (sigma * sqrt2PI);
+
+ /* Prevent division by 0 */
+ if (sigma == 0) {
+ printf("fwhm must not be equal to 0");
+ return(1);
+ }
+ sigma_sqrt2 = sigma * 1.4142135623730950488;
+
+ for (j=0; j<len_x; j++) {
+ x_minus_position = x[j] - position;
+ c2 = (0.5 * x_minus_position * x_minus_position) / (sigma * sigma);
+ /* gaussian term */
+ if (g_term_flag && c2 < 100) {
+ y[j] += fastexp(-c2) * height;
+ }
+
+ /* st term */
+ if (st_term_flag && (fabs(st_slope_r) > epsilon) && (x_minus_position / st_slope_r) <= 612) {
+ c1 = st_area_r * 0.5 * \
+ erfc((x_minus_position/sigma_sqrt2) + 0.5 * sigma_sqrt2 / st_slope_r);
+ y[j] += ((area * c1) / st_slope_r) * \
+ fastexp(0.5 * (sigma / st_slope_r) * (sigma / st_slope_r) +\
+ (x_minus_position / st_slope_r));
+ }
+
+ /* lt term */
+ if (lt_term_flag && (fabs(lt_slope_r) > epsilon) && (x_minus_position / lt_slope_r) <= 612) {
+ c1 = lt_area_r * \
+ 0.5 * erfc((x_minus_position/sigma_sqrt2) + 0.5 * sigma_sqrt2 / lt_slope_r);
+ y[j] += ((area * c1) / lt_slope_r) * \
+ fastexp(0.5 * (sigma / lt_slope_r) * (sigma / lt_slope_r) +\
+ (x_minus_position / lt_slope_r));
+
+ }
+
+ /* step term flag */
+ if (step_term_flag) {
+ y[j] += step_height_r * (area / (sigma * sqrt2PI)) *\
+ 0.5 * erfc(x_minus_position / sigma_sqrt2);
+ }
+ }
+ }
+ return(0);
+}
+
+void pileup(double* x, long len_x, double* ret, int input2, double zero, double gain)
+{
+ //int input2=0;
+ //double zero=0.0;
+ //double gain=1.0;
+
+ int i, j, k;
+ double *px, *pret, *pall;
+
+ /* the pointer to the starting position of par data */
+ px = x;
+ pret = ret;
+
+ *pret = 0;
+ k = (int )(zero/gain);
+ for (i=input2; i<len_x; i++){
+ pall = x;
+ if ((i+k) >= 0)
+ {
+ pret = (double *) ret+(i+k);
+ for (j=0; j<len_x-i-k ;j++){
+ *pret += *px * (*pall);
+ pall++;
+ pret++;
+ }
+ }
+ px++;
+ }
+}
diff --git a/silx/math/fit/leastsq.py b/silx/math/fit/leastsq.py
new file mode 100644
index 0000000..874c23a
--- /dev/null
+++ b/silx/math/fit/leastsq.py
@@ -0,0 +1,902 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 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.
+#
+# ############################################################################*/
+"""
+This module implements a Levenberg-Marquardt algorithm with constraints on the
+fitted parameters without introducing any other dependendency than numpy.
+
+If scipy dependency is not an issue, and no constraints are applied to the fitting
+parameters, there is no real gain compared to the use of scipy.optimize.curve_fit
+other than a more conservative calculation of uncertainties on fitted parameters.
+
+This module is a refactored version of PyMca Gefit.py module.
+"""
+__authors__ = ["V.A. Sole"]
+__license__ = "MIT"
+__date__ = "24/01/2017"
+__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
+
+import numpy
+from numpy.linalg import inv
+from numpy.linalg.linalg import LinAlgError
+import time
+import logging
+import copy
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+# codes understood by the routine
+CFREE = 0
+CPOSITIVE = 1
+CQUOTED = 2
+CFIXED = 3
+CFACTOR = 4
+CDELTA = 5
+CSUM = 6
+CIGNORED = 7
+
+def leastsq(model, xdata, ydata, p0, sigma=None,
+ constraints=None, model_deriv=None, epsfcn=None,
+ deltachi=None, full_output=None,
+ check_finite=True,
+ left_derivative=False,
+ max_iter=100):
+ """
+ Use non-linear least squares Levenberg-Marquardt algorithm to fit a function, f, to
+ data with optional constraints on the fitted parameters.
+
+ Assumes ``ydata = f(xdata, *params) + eps``
+
+ :param model: callable
+ The model function, f(x, ...). It must take the independent
+ variable as the first argument and the parameters to fit as
+ separate remaining arguments.
+ The returned value is a one dimensional array of floats.
+
+ :param xdata: An M-length sequence.
+ The independent variable where the data is measured.
+
+ :param ydata: An M-length sequence
+ The dependent data --- nominally f(xdata, ...)
+
+ :param p0: N-length sequence
+ Initial guess for the parameters.
+
+ :param sigma: None or M-length sequence, optional
+ If not None, the uncertainties in the ydata array. These are used as
+ weights in the least-squares problem
+ i.e. minimising ``np.sum( ((f(xdata, *popt) - ydata) / sigma)**2 )``
+ If None, the uncertainties are assumed to be 1
+
+ :param constraints:
+ If provided, it is a 2D sequence of dimension (n_parameters, 3) where,
+ for each parameter denoted by the index i, the meaning is
+
+ - constraints[i][0]
+
+ - 0 - Free (CFREE)
+ - 1 - Positive (CPOSITIVE)
+ - 2 - Quoted (CQUOTED)
+ - 3 - Fixed (CFIXED)
+ - 4 - Factor (CFACTOR)
+ - 5 - Delta (CDELTA)
+ - 6 - Sum (CSUM)
+
+
+ - constraints[i][1]
+
+ - Ignored if constraints[i][0] is 0, 1, 3
+ - Min value of the parameter if constraints[i][0] is CQUOTED
+ - Index of fitted parameter to which it is related
+
+ - constraints[i][2]
+
+ - Ignored if constraints[i][0] is 0, 1, 3
+ - Max value of the parameter if constraints[i][0] is CQUOTED
+ - Factor to apply to related parameter with index constraints[i][1]
+ - Difference with parameter with index constraints[i][1]
+ - Sum obtained when adding parameter with index constraints[i][1]
+ :type constraints: *optional*, None or 2D sequence
+
+ :param model_deriv:
+ None (default) or function providing the derivatives of the fitting function respect to the fitted parameters.
+ It will be called as model_deriv(xdata, parameters, index) where parameters is a sequence with the current
+ values of the fitting parameters, index is the fitting parameter index for which the the derivative has
+ to be provided in the supplied array of xdata points.
+ :type model_deriv: *optional*, None or callable
+
+
+ :param epsfcn: float
+ A variable used in determining a suitable parameter variation when
+ calculating the numerical derivatives (for model_deriv=None).
+ Normally the actual step length will be sqrt(epsfcn)*x
+ Original Gefit module was using epsfcn 1.0e-5 while default value
+ is now numpy.finfo(numpy.float).eps as in scipy
+ :type epsfcn: *optional*, float
+
+ :param deltachi: float
+ A variable used to control the minimum change in chisq to consider the
+ fitting process not worth to be continued. Default is 0.1 %.
+ :type deltachi: *optional*, float
+
+ :param full_output: bool, optional
+ non-zero to return all optional outputs. The default is None what will give a warning in case
+ of a constrained fit without having set this kweyword.
+
+ :param check_finite: bool, optional
+ If True, check that the input arrays do not contain nans of infs,
+ and raise a ValueError if they do. Setting this parameter to
+ False will ignore input arrays values containing nans.
+ Default is True.
+
+ :param left_derivative:
+ This parameter only has an influence if no derivative function
+ is provided. When True the left and right derivatives of the
+ model will be calculated for each fitted parameters thus leading to
+ the double number of function evaluations. Default is False.
+ Original Gefit module was always using left_derivative as True.
+ :type left_derivative: *optional*, bool
+
+ :param max_iter: Maximum number of iterations (default is 100)
+
+ :return: Returns a tuple of length 2 (or 3 if full_ouput is True) with the content:
+
+ ``popt``: array
+ Optimal values for the parameters so that the sum of the squared error
+ of ``f(xdata, *popt) - ydata`` is minimized
+ ``pcov``: 2d array
+ If no constraints are applied, this array contains the estimated covariance
+ of popt. The diagonal provides the variance of the parameter estimate.
+ To compute one standard deviation errors use ``perr = np.sqrt(np.diag(pcov))``.
+ If constraints are applied, this array does not contain the estimated covariance of
+ the parameters actually used during the fitting process but the uncertainties after
+ recalculating the covariance if all the parameters were free.
+ To get the actual uncertainties following error propagation of the actually fitted
+ parameters one should set full_output to True and access the uncertainties key.
+ ``infodict``: dict
+ a dictionary of optional outputs with the keys:
+
+ ``uncertainties``
+ The actual uncertainty on the optimized parameters.
+ ``nfev``
+ The number of function calls
+ ``fvec``
+ The function evaluated at the output
+ ``niter``
+ The number of iterations performed
+ ``chisq``
+ The chi square ``np.sum( ((f(xdata, *popt) - ydata) / sigma)**2 )``
+ ``reduced_chisq``
+ The chi square ``np.sum( ((f(xdata, *popt) - ydata) / sigma)**2 )`` divided
+ by the number of degrees of freedom ``(M - number_of_free_parameters)``
+ """
+ function_call_counter = 0
+ if numpy.isscalar(p0):
+ p0 = [p0]
+ parameters = numpy.array(p0, dtype=numpy.float64, copy=False)
+ if deltachi is None:
+ deltachi = 0.001
+
+ # NaNs can not be handled
+ if check_finite:
+ xdata = numpy.asarray_chkfinite(xdata)
+ ydata = numpy.asarray_chkfinite(ydata)
+ if sigma is not None:
+ sigma = numpy.asarray_chkfinite(sigma)
+ else:
+ sigma = numpy.ones((ydata.shape), dtype=numpy.float)
+ ydata.shape = -1
+ sigma.shape = -1
+ else:
+ ydata = numpy.asarray(ydata)
+ xdata = numpy.asarray(xdata)
+ ydata.shape = -1
+ if sigma is not None:
+ sigma = numpy.asarray(sigma)
+ else:
+ sigma = numpy.ones((ydata.shape), dtype=numpy.float)
+ sigma.shape = -1
+ # get rid of NaN in input data
+ idx = numpy.isfinite(ydata)
+ if False in idx:
+ # xdata must have a shape able to be understood by the user function
+ # in principle, one should not need to change it, however, if there are
+ # points to be excluded, one has to be able to exclude them.
+ # We can only hope that the sequence is properly arranged
+ if xdata.size == ydata.size:
+ if len(xdata.shape) != 1:
+ msg = "Need to reshape input xdata."
+ _logger.warning(msg)
+ xdata.shape = -1
+ else:
+ raise ValueError("Cannot reshape xdata to deal with NaN in ydata")
+ ydata = ydata[idx]
+ xdata = xdata[idx]
+ sigma = sigma[idx]
+ idx = numpy.isfinite(sigma)
+ if False in idx:
+ # xdata must have a shape able to be understood by the user function
+ # in principle, one should not need to change it, however, if there are
+ # points to be excluded, one has to be able to exclude them.
+ # We can only hope that the sequence is properly arranged
+ ydata = ydata[idx]
+ xdata = xdata[idx]
+ sigma = sigma[idx]
+ idx = numpy.isfinite(xdata)
+ filter_xdata = False
+ if False in idx:
+ # What to do?
+ try:
+ # Let's see if the function is able to deal with non-finite data
+ msg = "Checking if function can deal with non-finite data"
+ _logger.debug(msg)
+ evaluation = model(xdata, *parameters)
+ function_call_counter += 1
+ if evaluation.shape != ydata.shape:
+ if evaluation.size == ydata.size:
+ msg = "Supplied function does not return a proper array of floats."
+ msg += "\nFunction should be rewritten to return a 1D array of floats."
+ msg += "\nTrying to reshape output."
+ _logger.warning(msg)
+ evaluation.shape = ydata.shape
+ if False in numpy.isfinite(evaluation):
+ msg = "Supplied function unable to handle non-finite x data"
+ msg += "\nAttempting to filter out those x data values."
+ _logger.warning(msg)
+ filter_xdata = True
+ else:
+ filter_xdata = False
+ evaluation = None
+ except:
+ # function cannot handle input data
+ filter_xdata = True
+ if filter_xdata:
+ if xdata.size != ydata.size:
+ raise ValueError("xdata contains non-finite data that cannot be filtered")
+ else:
+ # we leave the xdata as they where
+ old_shape = xdata.shape
+ xdata.shape = ydata.shape
+ idx0 = numpy.isfinite(xdata)
+ xdata.shape = old_shape
+ ydata = ydata[idx0]
+ xdata = xdata[idx]
+ sigma = sigma[idx0]
+ weight = 1.0 / (sigma + numpy.equal(sigma, 0))
+ weight0 = weight * weight
+
+ nparameters = len(parameters)
+
+ if epsfcn is None:
+ epsfcn = numpy.finfo(numpy.float).eps
+ else:
+ epsfcn = max(epsfcn, numpy.finfo(numpy.float).eps)
+
+ # check if constraints have been passed as text
+ constrained_fit = False
+ if constraints is not None:
+ # make sure we work with a list of lists
+ input_constraints = constraints
+ tmp_constraints = [None] * len(input_constraints)
+ for i in range(nparameters):
+ tmp_constraints[i] = list(input_constraints[i])
+ constraints = tmp_constraints
+ for i in range(nparameters):
+ if hasattr(constraints[i][0], "upper"):
+ txt = constraints[i][0].upper()
+ if txt == "FREE":
+ constraints[i][0] = CFREE
+ elif txt == "POSITIVE":
+ constraints[i][0] = CPOSITIVE
+ elif txt == "QUOTED":
+ constraints[i][0] = CQUOTED
+ elif txt == "FIXED":
+ constraints[i][0] = CFIXED
+ elif txt == "FACTOR":
+ constraints[i][0] = CFACTOR
+ constraints[i][1] = int(constraints[i][1])
+ elif txt == "DELTA":
+ constraints[i][0] = CDELTA
+ constraints[i][1] = int(constraints[i][1])
+ elif txt == "SUM":
+ constraints[i][0] = CSUM
+ constraints[i][1] = int(constraints[i][1])
+ elif txt in ["IGNORED", "IGNORE"]:
+ constraints[i][0] = CIGNORED
+ else:
+ #I should raise an exception
+ raise ValueError("Unknown constraint %s" % constraints[i][0])
+ if constraints[i][0] > 0:
+ constrained_fit = True
+ if constrained_fit:
+ if full_output is None:
+ _logger.info("Recommended to set full_output to True when using constraints")
+
+ # Levenberg-Marquardt algorithm
+ fittedpar = parameters.__copy__()
+ flambda = 0.001
+ iiter = max_iter
+ #niter = 0
+ last_evaluation=None
+ x = xdata
+ y = ydata
+ chisq0 = -1
+ iteration_counter = 0
+ while (iiter > 0):
+ weight = weight0
+ """
+ I cannot evaluate the initial chisq here because I do not know
+ if some parameters are to be ignored, otherways I could do it as follows:
+ if last_evaluation is None:
+ yfit = model(x, *fittedpar)
+ last_evaluation = yfit
+ chisq0 = (weight * pow(y-yfit, 2)).sum()
+ and chisq would not need to be recalculated.
+ Passing the last_evaluation assumes that there are no parameters being
+ ignored or not between calls.
+ """
+ iteration_counter += 1
+ chisq0, alpha0, beta, internal_output = chisq_alpha_beta(
+ model, fittedpar,
+ x, y, weight, constraints=constraints,
+ model_deriv=model_deriv,
+ epsfcn=epsfcn,
+ left_derivative=left_derivative,
+ last_evaluation=last_evaluation,
+ full_output=True)
+ n_free = internal_output["n_free"]
+ free_index = internal_output["free_index"]
+ noigno = internal_output["noigno"]
+ fitparam = internal_output["fitparam"]
+ function_calls = internal_output["function_calls"]
+ function_call_counter += function_calls
+ #print("chisq0 = ", chisq0, n_free, fittedpar)
+ #raise
+ nr, nc = alpha0.shape
+ flag = 0
+ #lastdeltachi = chisq0
+ while flag == 0:
+ alpha = alpha0 * (1.0 + flambda * numpy.identity(nr))
+ deltapar = numpy.dot(beta, inv(alpha))
+ if constraints is None:
+ newpar = fitparam + deltapar [0]
+ else:
+ newpar = parameters.__copy__()
+ pwork = numpy.zeros(deltapar.shape, numpy.float)
+ for i in range(n_free):
+ if constraints is None:
+ pwork [0] [i] = fitparam [i] + deltapar [0] [i]
+ elif constraints [free_index[i]][0] == CFREE:
+ pwork [0] [i] = fitparam [i] + deltapar [0] [i]
+ elif constraints [free_index[i]][0] == CPOSITIVE:
+ #abs method
+ pwork [0] [i] = fitparam [i] + deltapar [0] [i]
+ #square method
+ #pwork [0] [i] = (numpy.sqrt(fitparam [i]) + deltapar [0] [i]) * \
+ # (numpy.sqrt(fitparam [i]) + deltapar [0] [i])
+ elif constraints[free_index[i]][0] == CQUOTED:
+ pmax = max(constraints[free_index[i]][1],
+ constraints[free_index[i]][2])
+ pmin = min(constraints[free_index[i]][1],
+ constraints[free_index[i]][2])
+ A = 0.5 * (pmax + pmin)
+ B = 0.5 * (pmax - pmin)
+ if B != 0:
+ pwork [0] [i] = A + \
+ B * numpy.sin(numpy.arcsin((fitparam[i] - A)/B)+ \
+ deltapar [0] [i])
+ else:
+ txt = "Error processing constrained fit\n"
+ txt += "Parameter limits are %g and %g\n" % (pmin, pmax)
+ txt += "A = %g B = %g" % (A, B)
+ raise ValueError("Invalid parameter limits")
+ newpar[free_index[i]] = pwork [0] [i]
+ newpar = numpy.array(_get_parameters(newpar, constraints))
+ workpar = numpy.take(newpar, noigno)
+ yfit = model(x, *workpar)
+ if last_evaluation is None:
+ if len(yfit.shape) > 1:
+ msg = "Supplied function does not return a 1D array of floats."
+ msg += "\nFunction should be rewritten."
+ msg += "\nTrying to reshape output."
+ _logger.warning(msg)
+ yfit.shape = -1
+ function_call_counter += 1
+ chisq = (weight * pow(y-yfit, 2)).sum()
+ absdeltachi = chisq0 - chisq
+ if absdeltachi < 0:
+ flambda *= 10.0
+ if flambda > 1000:
+ flag = 1
+ iiter = 0
+ else:
+ flag = 1
+ fittedpar = newpar.__copy__()
+ lastdeltachi = 100 * (absdeltachi / (chisq + (chisq == 0)))
+ if iteration_counter < 2:
+ # ignore any limit, the fit *has* to be improved
+ pass
+ elif (lastdeltachi) < deltachi:
+ iiter = 0
+ elif absdeltachi < numpy.sqrt(epsfcn):
+ iiter = 0
+ _logger.info("Iteration finished due to too small absolute chi decrement")
+ chisq0 = chisq
+ flambda = flambda / 10.0
+ last_evaluation = yfit
+ iiter = iiter - 1
+ # this is the covariance matrix of the actually fitted parameters
+ cov0 = inv(alpha0)
+ if constraints is None:
+ cov = cov0
+ else:
+ # yet another call needed with all the parameters being free except those
+ # that are FIXED and that will be assigned a 100 % uncertainty.
+ new_constraints = copy.deepcopy(constraints)
+ flag_special = [0] * len(fittedpar)
+ for idx, constraint in enumerate(constraints):
+ if constraints[idx][0] in [CFIXED, CIGNORED]:
+ flag_special[idx] = constraints[idx][0]
+ else:
+ new_constraints[idx][0] = CFREE
+ new_constraints[idx][1] = 0
+ new_constraints[idx][2] = 0
+ chisq, alpha, beta, internal_output = chisq_alpha_beta(
+ model, fittedpar,
+ x, y, weight, constraints=new_constraints,
+ model_deriv=model_deriv,
+ epsfcn=epsfcn,
+ left_derivative=left_derivative,
+ last_evaluation=last_evaluation,
+ full_output=True)
+ # obtained chisq should be identical to chisq0
+ try:
+ cov = inv(alpha)
+ except LinAlgError:
+ _logger.critical("Error calculating covariance matrix after successful fit")
+ cov = None
+ if cov is not None:
+ for idx, value in enumerate(flag_special):
+ if value in [CFIXED, CIGNORED]:
+ cov = numpy.insert(numpy.insert(cov, idx, 0, axis=1), idx, 0, axis=0)
+ cov[idx, idx] = fittedpar[idx] * fittedpar[idx]
+
+ if not full_output:
+ return fittedpar, cov
+ else:
+ sigma0 = numpy.sqrt(abs(numpy.diag(cov0)))
+ sigmapar = _get_sigma_parameters(fittedpar, sigma0, constraints)
+ ddict = {}
+ ddict["chisq"] = chisq0
+ ddict["reduced_chisq"] = chisq0 / (len(yfit)-n_free)
+ ddict["covariance"] = cov0
+ ddict["uncertainties"] = sigmapar
+ ddict["fvec"] = last_evaluation
+ ddict["nfev"] = function_call_counter
+ ddict["niter"] = iteration_counter
+ return fittedpar, cov, ddict #, chisq/(len(yfit)-len(sigma0)), sigmapar,niter,lastdeltachi
+
+def chisq_alpha_beta(model, parameters, x, y, weight, constraints=None,
+ model_deriv=None, epsfcn=None, left_derivative=False,
+ last_evaluation=None, full_output=False):
+
+ """
+ Get chi square, the curvature matrix alpha and the matrix beta according to the input parameters.
+ If all the parameters are unconstrained, the covariance matrix is the inverse of the alpha matrix.
+
+ :param model: callable
+ The model function, f(x, ...). It must take the independent
+ variable as the first argument and the parameters to fit as
+ separate remaining arguments.
+ The returned value is a one dimensional array of floats.
+
+ :param parameters: N-length sequence
+ Values of parameters at which function and derivatives are to be calculated.
+
+ :param x: An M-length sequence.
+ The independent variable where the data is measured.
+
+ :param y: An M-length sequence
+ The dependent data --- nominally f(xdata, ...)
+
+ :param weight: M-length sequence
+ Weights to be applied in the calculation of chi square
+ As a reminder ``chisq = np.sum(weigth * (model(x, *parameters) - y)**2)``
+
+ :param constraints:
+ If provided, it is a 2D sequence of dimension (n_parameters, 3) where,
+ for each parameter denoted by the index i, the meaning is
+
+ - constraints[i][0]
+
+ - 0 - Free (CFREE)
+ - 1 - Positive (CPOSITIVE)
+ - 2 - Quoted (CQUOTED)
+ - 3 - Fixed (CFIXED)
+ - 4 - Factor (CFACTOR)
+ - 5 - Delta (CDELTA)
+ - 6 - Sum (CSUM)
+
+
+ - constraints[i][1]
+
+ - Ignored if constraints[i][0] is 0, 1, 3
+ - Min value of the parameter if constraints[i][0] is CQUOTED
+ - Index of fitted parameter to which it is related
+
+ - constraints[i][2]
+
+ - Ignored if constraints[i][0] is 0, 1, 3
+ - Max value of the parameter if constraints[i][0] is CQUOTED
+ - Factor to apply to related parameter with index constraints[i][1]
+ - Difference with parameter with index constraints[i][1]
+ - Sum obtained when adding parameter with index constraints[i][1]
+ :type constraints: *optional*, None or 2D sequence
+
+ :param model_deriv:
+ None (default) or function providing the derivatives of the fitting function respect to the fitted parameters.
+ It will be called as model_deriv(xdata, parameters, index) where parameters is a sequence with the current
+ values of the fitting parameters, index is the fitting parameter index for which the the derivative has
+ to be provided in the supplied array of xdata points.
+ :type model_deriv: *optional*, None or callable
+
+
+ :param epsfcn: float
+ A variable used in determining a suitable parameter variation when
+ calculating the numerical derivatives (for model_deriv=None).
+ Normally the actual step length will be sqrt(epsfcn)*x
+ Original Gefit module was using epsfcn 1.0e-10 while default value
+ is now numpy.finfo(numpy.float).eps as in scipy
+ :type epsfcn: *optional*, float
+
+ :param left_derivative:
+ This parameter only has an influence if no derivative function
+ is provided. When True the left and right derivatives of the
+ model will be calculated for each fitted parameters thus leading to
+ the double number of function evaluations. Default is False.
+ Original Gefit module was always using left_derivative as True.
+ :type left_derivative: *optional*, bool
+
+ :param last_evaluation: An M-length array
+ Used for optimization purposes. If supplied, this array will be taken as the result of
+ evaluating the function, that is as the result of ``model(x, *parameters)`` thus avoiding
+ the evaluation call.
+
+ :param full_output: bool, optional
+ Additional output used for internal purposes with the keys:
+ ``function_calls``
+ The number of model function calls performed.
+ ``fitparam``
+ A sequence with the actual free parameters
+ ``free_index``
+ Sequence with the indices of the free parameters in input parameters sequence.
+ ``noigno``
+ Sequence with the indices of the original parameters considered in the calculations.
+ """
+ if epsfcn is None:
+ epsfcn = numpy.finfo(numpy.float).eps
+ else:
+ epsfcn = max(epsfcn, numpy.finfo(numpy.float).eps)
+ #nr0, nc = data.shape
+ n_param = len(parameters)
+ if constraints is None:
+ derivfactor = numpy.ones((n_param, ))
+ n_free = n_param
+ noigno = numpy.arange(n_param)
+ free_index = noigno * 1
+ fitparam = parameters * 1
+ else:
+ n_free = 0
+ fitparam = []
+ free_index = []
+ noigno = []
+ derivfactor = []
+ for i in range(n_param):
+ if constraints[i][0] != CIGNORED:
+ noigno.append(i)
+ if constraints[i][0] == CFREE:
+ fitparam.append(parameters [i])
+ derivfactor.append(1.0)
+ free_index.append(i)
+ n_free += 1
+ elif constraints[i][0] == CPOSITIVE:
+ fitparam.append(abs(parameters[i]))
+ derivfactor.append(1.0)
+ #fitparam.append(numpy.sqrt(abs(parameters[i])))
+ #derivfactor.append(2.0*numpy.sqrt(abs(parameters[i])))
+ free_index.append(i)
+ n_free += 1
+ elif constraints[i][0] == CQUOTED:
+ pmax = max(constraints[i][1], constraints[i][2])
+ pmin =min(constraints[i][1], constraints[i][2])
+ if ((pmax-pmin) > 0) & \
+ (parameters[i] <= pmax) & \
+ (parameters[i] >= pmin):
+ A = 0.5 * (pmax + pmin)
+ B = 0.5 * (pmax - pmin)
+ fitparam.append(parameters[i])
+ derivfactor.append(B*numpy.cos(numpy.arcsin((parameters[i] - A)/B)))
+ free_index.append(i)
+ n_free += 1
+ elif (pmax-pmin) > 0:
+ print("WARNING: Quoted parameter outside boundaries")
+ print("Initial value = %f" % parameters[i])
+ print("Limits are %f and %f" % (pmin, pmax))
+ print("Parameter will be kept at its starting value")
+ fitparam = numpy.array(fitparam, numpy.float)
+ alpha = numpy.zeros((n_free, n_free), numpy.float)
+ beta = numpy.zeros((1, n_free), numpy.float)
+ #delta = (fitparam + numpy.equal(fitparam, 0.0)) * 0.00001
+ delta = (fitparam + numpy.equal(fitparam, 0.0)) * numpy.sqrt(epsfcn)
+ nr = y.size
+ ##############
+ # Prior to each call to the function one has to re-calculate the
+ # parameters
+ pwork = parameters.__copy__()
+ for i in range(n_free):
+ pwork [free_index[i]] = fitparam [i]
+ if n_free == 0:
+ raise ValueError("No free parameters to fit")
+ function_calls = 0
+ if not left_derivative:
+ if last_evaluation is not None:
+ f2 = last_evaluation
+ else:
+ f2 = model(x, *parameters)
+ f2.shape = -1
+ function_calls += 1
+ for i in range(n_free):
+ if model_deriv is None:
+ #pwork = parameters.__copy__()
+ pwork[free_index[i]] = fitparam [i] + delta [i]
+ newpar = _get_parameters(pwork.tolist(), constraints)
+ newpar = numpy.take(newpar, noigno)
+ f1 = model(x, *newpar)
+ f1.shape = -1
+ function_calls += 1
+ if left_derivative:
+ pwork[free_index[i]] = fitparam [i] - delta [i]
+ newpar = _get_parameters(pwork.tolist(), constraints)
+ newpar=numpy.take(newpar, noigno)
+ f2 = model(x, *newpar)
+ function_calls += 1
+ help0 = (f1 - f2) / (2.0 * delta[i])
+ else:
+ help0 = (f1 - f2) / (delta[i])
+ help0 = help0 * derivfactor[i]
+ pwork[free_index[i]] = fitparam [i]
+ #removed I resize outside the loop:
+ #help0 = numpy.resize(help0, (1, nr))
+ else:
+ help0 = model_deriv(x, pwork, free_index[i])
+ help0 = help0 * derivfactor[i]
+
+ if i == 0:
+ deriv = help0
+ else:
+ deriv = numpy.concatenate((deriv, help0), 0)
+
+ #line added to resize outside the loop
+ deriv = numpy.resize(deriv, (n_free, nr))
+ if last_evaluation is None:
+ if constraints is None:
+ yfit = model(x, *fitparam)
+ yfit.shape = -1
+ else:
+ newpar = _get_parameters(pwork.tolist(), constraints)
+ newpar = numpy.take(newpar, noigno)
+ yfit = model(x, *newpar)
+ yfit.shape = -1
+ function_calls += 1
+ else:
+ yfit = last_evaluation
+ deltay = y - yfit
+ help0 = weight * deltay
+ for i in range(n_free):
+ derivi = numpy.resize(deriv[i, :], (1, nr))
+ help1 = numpy.resize(numpy.sum((help0 * derivi), 1), (1, 1))
+ if i == 0:
+ beta = help1
+ else:
+ beta = numpy.concatenate((beta, help1), 1)
+ help1 = numpy.inner(deriv, weight*derivi)
+ if i == 0:
+ alpha = help1
+ else:
+ alpha = numpy.concatenate((alpha, help1), 1)
+ chisq = (help0 * deltay).sum()
+ if full_output:
+ ddict = {}
+ ddict["n_free"] = n_free
+ ddict["free_index"] = free_index
+ ddict["noigno"] = noigno
+ ddict["fitparam"] = fitparam
+ ddict["derivfactor"] = derivfactor
+ ddict["function_calls"] = function_calls
+ return chisq, alpha, beta, ddict
+ else:
+ return chisq, alpha, beta
+
+
+def _get_parameters(parameters, constraints):
+ """
+ Apply constraints to input parameters.
+
+ Parameters not depending on other parameters, they are returned as the input.
+
+ Parameters depending on other parameters, return the value after applying the
+ relation to the parameter wo which they are related.
+ """
+ # 0 = Free 1 = Positive 2 = Quoted
+ # 3 = Fixed 4 = Factor 5 = Delta
+ if constraints is None:
+ return parameters * 1
+ newparam = []
+ #first I make the free parameters
+ #because the quoted ones put troubles
+ for i in range(len(constraints)):
+ if constraints[i][0] == CFREE:
+ newparam.append(parameters[i])
+ elif constraints[i][0] == CPOSITIVE:
+ #newparam.append(parameters[i] * parameters[i])
+ newparam.append(abs(parameters[i]))
+ elif constraints[i][0] == CQUOTED:
+ newparam.append(parameters[i])
+ elif abs(constraints[i][0]) == CFIXED:
+ newparam.append(parameters[i])
+ else:
+ newparam.append(parameters[i])
+ for i in range(len(constraints)):
+ if constraints[i][0] == CFACTOR:
+ newparam[i] = constraints[i][2] * newparam[int(constraints[i][1])]
+ elif constraints[i][0] == CDELTA:
+ newparam[i] = constraints[i][2] + newparam[int(constraints[i][1])]
+ elif constraints[i][0] == CIGNORED:
+ # The whole ignored stuff should not be documented because setting
+ # a parameter to 0 is not the same as being ignored.
+ # Being ignored should imply the parameter is simply not accounted for
+ # and should be stripped out of the list of parameters by the program
+ # using this module
+ newparam[i] = 0
+ elif constraints[i][0] == CSUM:
+ newparam[i] = constraints[i][2]-newparam[int(constraints[i][1])]
+ return newparam
+
+
+def _get_sigma_parameters(parameters, sigma0, constraints):
+ """
+ Internal function propagating the uncertainty on the actually fitted parameters and related parameters to the
+ final parameters considering the applied constraints.
+
+ Parameters
+ ----------
+ parameters : 1D sequence of length equal to the number of free parameters N
+ The parameters actually used in the fitting process.
+ sigma0 : 1D sequence of length N
+ Uncertainties calculated as the square-root of the diagonal of
+ the covariance matrix
+ constraints : The set of constraints applied in the fitting process
+ """
+ # 0 = Free 1 = Positive 2 = Quoted
+ # 3 = Fixed 4 = Factor 5 = Delta
+ if constraints is None:
+ return sigma0
+ n_free = 0
+ sigma_par = numpy.zeros(parameters.shape, numpy.float)
+ for i in range(len(constraints)):
+ if constraints[i][0] == CFREE:
+ sigma_par [i] = sigma0[n_free]
+ n_free += 1
+ elif constraints[i][0] == CPOSITIVE:
+ #sigma_par [i] = 2.0 * sigma0[n_free]
+ sigma_par [i] = sigma0[n_free]
+ n_free += 1
+ elif constraints[i][0] == CQUOTED:
+ pmax = max(constraints [i][1], constraints [i][2])
+ pmin = min(constraints [i][1], constraints [i][2])
+ # A = 0.5 * (pmax + pmin)
+ B = 0.5 * (pmax - pmin)
+ if (B > 0) & (parameters [i] < pmax) & (parameters [i] > pmin):
+ sigma_par [i] = abs(B * numpy.cos(parameters[i]) * sigma0[n_free])
+ n_free += 1
+ else:
+ sigma_par [i] = parameters[i]
+ elif abs(constraints[i][0]) == CFIXED:
+ sigma_par[i] = parameters[i]
+ for i in range(len(constraints)):
+ if constraints[i][0] == CFACTOR:
+ sigma_par [i] = constraints[i][2]*sigma_par[int(constraints[i][1])]
+ elif constraints[i][0] == CDELTA:
+ sigma_par [i] = sigma_par[int(constraints[i][1])]
+ elif constraints[i][0] == CSUM:
+ sigma_par [i] = sigma_par[int(constraints[i][1])]
+ return sigma_par
+
+
+def main(argv=None):
+ if argv is None:
+ npoints = 10000
+ elif hasattr(argv, "__len__"):
+ if len(argv) > 1:
+ npoints = int(argv[1])
+ else:
+ print("Usage:")
+ print("fit [npoints]")
+ else:
+ # expected a number
+ npoints = argv
+
+ def gauss(t0, *param0):
+ param = numpy.array(param0)
+ t = numpy.array(t0)
+ dummy = 2.3548200450309493 * (t - param[3]) / param[4]
+ return param[0] + param[1] * t + param[2] * myexp(-0.5 * dummy * dummy)
+
+
+ def myexp(x):
+ # put a (bad) filter to avoid over/underflows
+ # with no python looping
+ return numpy.exp(x * numpy.less(abs(x), 250)) -\
+ 1.0 * numpy.greater_equal(abs(x), 250)
+
+ xx = numpy.arange(npoints, dtype=numpy.float)
+ yy = gauss(xx, *[10.5, 2, 1000.0, 20., 15])
+ sy = numpy.sqrt(abs(yy))
+ parameters = [0.0, 1.0, 900.0, 25., 10]
+ stime = time.time()
+
+ fittedpar, cov, ddict = leastsq(gauss, xx, yy, parameters,
+ sigma=sy,
+ left_derivative=False,
+ full_output=True,
+ check_finite=True)
+ etime = time.time()
+ sigmapars = numpy.sqrt(numpy.diag(cov))
+ print("Took ", etime - stime, "seconds")
+ print("Function calls = ", ddict["nfev"])
+ print("chi square = ", ddict["chisq"])
+ print("Fitted pars = ", fittedpar)
+ print("Sigma pars = ", sigmapars)
+ try:
+ from scipy.optimize import curve_fit as cfit
+ SCIPY = True
+ except ImportError:
+ SCIPY = False
+ if SCIPY:
+ counter = 0
+ stime = time.time()
+ scipy_fittedpar, scipy_cov = cfit(gauss,
+ xx,
+ yy,
+ parameters,
+ sigma=sy)
+ etime = time.time()
+ print("Scipy Took ", etime - stime, "seconds")
+ print("Counter = ", counter)
+ print("scipy = ", scipy_fittedpar)
+ print("Sigma = ", numpy.sqrt(numpy.diag(scipy_cov)))
+
+if __name__ == "__main__":
+ main()
diff --git a/silx/math/fit/peaks/include/peaks.h b/silx/math/fit/peaks/include/peaks.h
new file mode 100644
index 0000000..bd25d96
--- /dev/null
+++ b/silx/math/fit/peaks/include/peaks.h
@@ -0,0 +1,32 @@
+/*##########################################################################
+# 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.
+#
+# ############################################################################*/
+
+#ifndef PEAKS_H
+#define PEAKS_H
+
+/* Smoothing functions */
+
+long seek(long begin_index, long end_index, long nsamples, double fwhm, double sensitivity,
+ double debug_info, double *data, double **peaks, double **relevances);
+
+#endif /* #define PEAKS_H */
diff --git a/silx/math/fit/peaks/peaks.c b/silx/math/fit/peaks/peaks.c
new file mode 100644
index 0000000..e7d9ddc
--- /dev/null
+++ b/silx/math/fit/peaks/peaks.c
@@ -0,0 +1,17746 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__peaks
+#define __PYX_HAVE_API__peaks
+#include "string.h"
+#include "stdlib.h"
+#include "peaks.h"
+#include "pythread.h"
+#include "stdio.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+
+static const char *__pyx_f[] = {
+ "peaks.pyx",
+ "stringsource",
+};
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+static void __Pyx_RaiseBufferIndexError(int axis);
+
+static CYTHON_INLINE unsigned long __Pyx_abs_long(long x) {
+ if (unlikely(x == -LONG_MAX-1))
+ return ((unsigned long)LONG_MAX) + 1U;
+ return (unsigned long) labs(x);
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \
+ __Pyx_SetItemInt_Generic(o, to_py_func(i), v)))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v);
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static PyObject *__pyx_memview_get_double(const char *itemp);
+static int __pyx_memview_set_double(const char *itemp, PyObject *obj);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_long(unsigned long value);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_double(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'peaks_wrapper' */
+
+/* Module declarations from 'peaks' */
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 };
+#define __Pyx_MODULE_NAME "peaks"
+int __pyx_module_is_main_peaks = 0;
+
+/* Implementation of 'peaks' */
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_zip;
+static PyObject *__pyx_builtin_max;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_pf_5peaks_peak_search(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_y, PyObject *__pyx_v_fwhm, PyObject *__pyx_v_sensitivity, PyObject *__pyx_v_begin_index, PyObject *__pyx_v_end_index, PyObject *__pyx_v_debug, PyObject *__pyx_v_relevance_info); /* proto */
+static PyObject *__pyx_pf_5peaks_2guess_fwhm(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_y); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_C[] = "C";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_c[] = "c";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_w[] = "w";
+static char __pyx_k_y[] = "y";
+static char __pyx_k__2[] = "";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k_idx[] = "idx";
+static char __pyx_k_max[] = "max";
+static char __pyx_k_msg[] = "msg";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_y_c[] = "y_c";
+static char __pyx_k_zip[] = "zip";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_copy[] = "copy";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_fwhm[] = "fwhm";
+static char __pyx_k_imax[] = "imax";
+static char __pyx_k_imin[] = "imin";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_yfit[] = "yfit";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_debug[] = "debug";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_empty[] = "empty";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_order[] = "order";
+static char __pyx_k_peaks[] = "peaks";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_strip[] = "strip";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_height[] = "height";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_logger[] = "_logger";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_filters[] = "filters";
+static char __pyx_k_float64[] = "float64";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_logging[] = "logging";
+static char __pyx_k_maximum[] = "maximum";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_n_peaks[] = "n_peaks";
+static char __pyx_k_nonzero[] = "nonzero";
+static char __pyx_k_peaks_c[] = "peaks_c";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_P_Knobel[] = "P. Knobel";
+static char __pyx_k_fwhm_min[] = "fwhm_min";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_posindex[] = "posindex";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_end_index[] = "end_index";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_getLogger[] = "getLogger";
+static char __pyx_k_17_06_2016[] = "17/06/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_background[] = "background";
+static char __pyx_k_guess_fwhm[] = "guess_fwhm";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_relevances[] = "relevances";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_basicConfig[] = "basicConfig";
+static char __pyx_k_begin_index[] = "begin_index";
+static char __pyx_k_niterations[] = "niterations";
+static char __pyx_k_peak_search[] = "peak_search";
+static char __pyx_k_relevance_f[] = "relevance %f\n";
+static char __pyx_k_sensitivity[] = "sensitivity";
+static char __pyx_k_peak_index_f[] = "peak index %f, ";
+static char __pyx_k_relevances_c[] = "relevances_c";
+static char __pyx_k_output_arrays[] = "output arrays";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_relevance_info[] = "relevance_info";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_we_found_d_peaks[] = "we found %d peaks.\n";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_Failed_to_reallocate_memory_for[] = "Failed to reallocate memory for output arrays";
+static char __pyx_k_mntdirect__scisoft_users_tvince[] = "/mntdirect/_scisoft/users/tvincent/src/silx/silx/math/fit/peaks/peaks.pyx";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_Before_memory_allocation_error_h[] = "Before memory allocation error happened, ";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Failed_to_allocate_initial_memor[] = "Failed to allocate initial memory for ";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_This_module_provides_a_peak_sear[] = "This module provides a peak search function and tools related to peak\nanalysis.\n";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static PyObject *__pyx_kp_s_17_06_2016;
+static PyObject *__pyx_kp_s_Before_memory_allocation_error_h;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_n_s_C;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_kp_s_Failed_to_allocate_initial_memor;
+static PyObject *__pyx_kp_s_Failed_to_reallocate_memory_for;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_kp_s_P_Knobel;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_kp_s__2;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_background;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_basicConfig;
+static PyObject *__pyx_n_s_begin_index;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_copy;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_debug;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_empty;
+static PyObject *__pyx_n_s_end_index;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_filters;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float64;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_n_s_fwhm;
+static PyObject *__pyx_n_s_fwhm_min;
+static PyObject *__pyx_n_s_getLogger;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_guess_fwhm;
+static PyObject *__pyx_n_s_height;
+static PyObject *__pyx_n_s_i;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_idx;
+static PyObject *__pyx_n_s_imax;
+static PyObject *__pyx_n_s_imin;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_logger;
+static PyObject *__pyx_n_s_logging;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_max;
+static PyObject *__pyx_n_s_maximum;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_kp_s_mntdirect__scisoft_users_tvince;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_msg;
+static PyObject *__pyx_n_s_n_peaks;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_niterations;
+static PyObject *__pyx_n_s_nonzero;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_n_s_order;
+static PyObject *__pyx_kp_s_output_arrays;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_kp_s_peak_index_f;
+static PyObject *__pyx_n_s_peak_search;
+static PyObject *__pyx_n_s_peaks;
+static PyObject *__pyx_n_s_peaks_c;
+static PyObject *__pyx_n_s_posindex;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_kp_s_relevance_f;
+static PyObject *__pyx_n_s_relevance_info;
+static PyObject *__pyx_n_s_relevances;
+static PyObject *__pyx_n_s_relevances_c;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_sensitivity;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_strip;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_n_s_w;
+static PyObject *__pyx_kp_s_we_found_d_peaks;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_n_s_y;
+static PyObject *__pyx_n_s_y_c;
+static PyObject *__pyx_n_s_yfit;
+static PyObject *__pyx_n_s_zip;
+static PyObject *__pyx_float_0_5;
+static PyObject *__pyx_float_3_5;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_1000;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__11;
+static PyObject *__pyx_slice__12;
+static PyObject *__pyx_slice__13;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_codeobj__16;
+static PyObject *__pyx_codeobj__18;
+
+/* "peaks.pyx":46
+ *
+ *
+ * def peak_search(y, fwhm, sensitivity=3.5, # <<<<<<<<<<<<<<
+ * begin_index=None, end_index=None,
+ * debug=False, relevance_info=False):
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5peaks_1peak_search(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_5peaks_peak_search[] = "peak_search(y, fwhm, sensitivity=3.5, begin_index=None, end_index=None, debug=False, relevance_info=False)\nFind peaks in a curve.\n\n :param y: Data array\n :type y: numpy.ndarray\n :param fwhm: Estimated full width at half maximum of the typical peaks we\n are interested in (expressed in number of samples)\n :param sensitivity: Threshold factor used for peak detection. Only peaks\n with amplitudes higher than ``\317\203 * sensitivity`` - where ``\317\203`` is the\n standard deviation of the noise - qualify as peaks.\n :param begin_index: Index of the first sample of the region of interest\n in the ``y`` array. If ``None``, start from the first sample.\n :param end_index: Index of the last sample of the region of interest in\n the ``y`` array. If ``None``, process until the last sample.\n :param debug: If ``True``, print debug messages. Default: ``False``\n :param relevance_info: If ``True``, add a second dimension with relevance\n information to the output array. Default: ``False``\n :return: 1D sequence with indices of peaks in the data\n if ``relevance_info`` is ``False``.\n Else, sequence of ``(peak_index, peak_relevance)`` tuples (one tuple\n per peak).\n :raise: ``IndexError`` if the number of peaks is too large to fit in the\n output array.\n ";
+static PyMethodDef __pyx_mdef_5peaks_1peak_search = {"peak_search", (PyCFunction)__pyx_pw_5peaks_1peak_search, METH_VARARGS|METH_KEYWORDS, __pyx_doc_5peaks_peak_search};
+static PyObject *__pyx_pw_5peaks_1peak_search(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_y = 0;
+ PyObject *__pyx_v_fwhm = 0;
+ PyObject *__pyx_v_sensitivity = 0;
+ PyObject *__pyx_v_begin_index = 0;
+ PyObject *__pyx_v_end_index = 0;
+ PyObject *__pyx_v_debug = 0;
+ PyObject *__pyx_v_relevance_info = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("peak_search (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_y,&__pyx_n_s_fwhm,&__pyx_n_s_sensitivity,&__pyx_n_s_begin_index,&__pyx_n_s_end_index,&__pyx_n_s_debug,&__pyx_n_s_relevance_info,0};
+ PyObject* values[7] = {0,0,0,0,0,0,0};
+ values[2] = ((PyObject *)__pyx_float_3_5);
+
+ /* "peaks.pyx":47
+ *
+ * def peak_search(y, fwhm, sensitivity=3.5,
+ * begin_index=None, end_index=None, # <<<<<<<<<<<<<<
+ * debug=False, relevance_info=False):
+ * """Find peaks in a curve.
+ */
+ values[3] = ((PyObject *)Py_None);
+ values[4] = ((PyObject *)Py_None);
+
+ /* "peaks.pyx":48
+ * def peak_search(y, fwhm, sensitivity=3.5,
+ * begin_index=None, end_index=None,
+ * debug=False, relevance_info=False): # <<<<<<<<<<<<<<
+ * """Find peaks in a curve.
+ *
+ */
+ values[5] = ((PyObject *)Py_False);
+ values[6] = ((PyObject *)Py_False);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_y)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_fwhm)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("peak_search", 0, 2, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_sensitivity);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_begin_index);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_end_index);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ case 5:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_debug);
+ if (value) { values[5] = value; kw_args--; }
+ }
+ case 6:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_relevance_info);
+ if (value) { values[6] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "peak_search") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_y = values[0];
+ __pyx_v_fwhm = values[1];
+ __pyx_v_sensitivity = values[2];
+ __pyx_v_begin_index = values[3];
+ __pyx_v_end_index = values[4];
+ __pyx_v_debug = values[5];
+ __pyx_v_relevance_info = values[6];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("peak_search", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("peaks.peak_search", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_5peaks_peak_search(__pyx_self, __pyx_v_y, __pyx_v_fwhm, __pyx_v_sensitivity, __pyx_v_begin_index, __pyx_v_end_index, __pyx_v_debug, __pyx_v_relevance_info);
+
+ /* "peaks.pyx":46
+ *
+ *
+ * def peak_search(y, fwhm, sensitivity=3.5, # <<<<<<<<<<<<<<
+ * begin_index=None, end_index=None,
+ * debug=False, relevance_info=False):
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5peaks_peak_search(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_y, PyObject *__pyx_v_fwhm, PyObject *__pyx_v_sensitivity, PyObject *__pyx_v_begin_index, PyObject *__pyx_v_end_index, PyObject *__pyx_v_debug, PyObject *__pyx_v_relevance_info) {
+ int __pyx_v_i;
+ __Pyx_memviewslice __pyx_v_y_c = { 0, 0, { 0 }, { 0 }, { 0 } };
+ double *__pyx_v_peaks_c;
+ double *__pyx_v_relevances_c;
+ long __pyx_v_n_peaks;
+ PyObject *__pyx_v_msg = NULL;
+ PyObject *__pyx_v_peaks = NULL;
+ PyObject *__pyx_v_relevances = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ __Pyx_memviewslice __pyx_t_6 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_7;
+ int __pyx_t_8;
+ long __pyx_t_9;
+ long __pyx_t_10;
+ long __pyx_t_11;
+ double __pyx_t_12;
+ double __pyx_t_13;
+ double __pyx_t_14;
+ Py_ssize_t __pyx_t_15;
+ int __pyx_t_16;
+ unsigned long __pyx_t_17;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("peak_search", 0);
+ __Pyx_INCREF(__pyx_v_begin_index);
+ __Pyx_INCREF(__pyx_v_end_index);
+ __Pyx_INCREF(__pyx_v_debug);
+
+ /* "peaks.pyx":78
+ * double* relevances_c
+ *
+ * y_c = numpy.array(y, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_y);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_y);
+ __Pyx_GIVEREF(__pyx_v_y);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "peaks.pyx":79
+ *
+ * y_c = numpy.array(y,
+ * copy=True, # <<<<<<<<<<<<<<
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_copy, Py_True) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "peaks.pyx":80
+ * y_c = numpy.array(y,
+ * copy=True,
+ * dtype=numpy.float64, # <<<<<<<<<<<<<<
+ * order='C').reshape(-1)
+ * if debug:
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_order, __pyx_n_s_C) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "peaks.pyx":78
+ * double* relevances_c
+ *
+ * y_c = numpy.array(y, # <<<<<<<<<<<<<<
+ * copy=True,
+ * dtype=numpy.float64,
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "peaks.pyx":81
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * if debug:
+ * debug = 1
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_dc_double(__pyx_t_5);
+ if (unlikely(!__pyx_t_6.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_y_c = __pyx_t_6;
+ __pyx_t_6.memview = NULL;
+ __pyx_t_6.data = NULL;
+
+ /* "peaks.pyx":82
+ * dtype=numpy.float64,
+ * order='C').reshape(-1)
+ * if debug: # <<<<<<<<<<<<<<
+ * debug = 1
+ * else:
+ */
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_v_debug); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_7) {
+
+ /* "peaks.pyx":83
+ * order='C').reshape(-1)
+ * if debug:
+ * debug = 1 # <<<<<<<<<<<<<<
+ * else:
+ * debug = 0
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __Pyx_DECREF_SET(__pyx_v_debug, __pyx_int_1);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "peaks.pyx":85
+ * debug = 1
+ * else:
+ * debug = 0 # <<<<<<<<<<<<<<
+ *
+ * if begin_index is None:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __Pyx_DECREF_SET(__pyx_v_debug, __pyx_int_0);
+ }
+ __pyx_L3:;
+
+ /* "peaks.pyx":87
+ * debug = 0
+ *
+ * if begin_index is None: # <<<<<<<<<<<<<<
+ * begin_index = 0
+ * if end_index is None:
+ */
+ __pyx_t_7 = (__pyx_v_begin_index == Py_None);
+ __pyx_t_8 = (__pyx_t_7 != 0);
+ if (__pyx_t_8) {
+
+ /* "peaks.pyx":88
+ *
+ * if begin_index is None:
+ * begin_index = 0 # <<<<<<<<<<<<<<
+ * if end_index is None:
+ * end_index = y_c.size - 1
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __Pyx_DECREF_SET(__pyx_v_begin_index, __pyx_int_0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "peaks.pyx":89
+ * if begin_index is None:
+ * begin_index = 0
+ * if end_index is None: # <<<<<<<<<<<<<<
+ * end_index = y_c.size - 1
+ *
+ */
+ __pyx_t_8 = (__pyx_v_end_index == Py_None);
+ __pyx_t_7 = (__pyx_t_8 != 0);
+ if (__pyx_t_7) {
+
+ /* "peaks.pyx":90
+ * begin_index = 0
+ * if end_index is None:
+ * end_index = y_c.size - 1 # <<<<<<<<<<<<<<
+ *
+ * n_peaks = peaks_wrapper.seek(begin_index, end_index, y_c.size,
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyNumber_Subtract(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_end_index, __pyx_t_5);
+ __pyx_t_5 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "peaks.pyx":92
+ * end_index = y_c.size - 1
+ *
+ * n_peaks = peaks_wrapper.seek(begin_index, end_index, y_c.size, # <<<<<<<<<<<<<<
+ * fwhm, sensitivity, debug,
+ * &y_c[0], &peaks_c, &relevances_c)
+ */
+ __pyx_t_9 = __Pyx_PyInt_As_long(__pyx_v_begin_index); if (unlikely((__pyx_t_9 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __Pyx_PyInt_As_long(__pyx_v_end_index); if (unlikely((__pyx_t_10 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = __pyx_memoryview_fromslice(__pyx_v_y_c, 1, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_11 = __Pyx_PyInt_As_long(__pyx_t_3); if (unlikely((__pyx_t_11 == (long)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "peaks.pyx":93
+ *
+ * n_peaks = peaks_wrapper.seek(begin_index, end_index, y_c.size,
+ * fwhm, sensitivity, debug, # <<<<<<<<<<<<<<
+ * &y_c[0], &peaks_c, &relevances_c)
+ *
+ */
+ __pyx_t_12 = __pyx_PyFloat_AsDouble(__pyx_v_fwhm); if (unlikely((__pyx_t_12 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_13 = __pyx_PyFloat_AsDouble(__pyx_v_sensitivity); if (unlikely((__pyx_t_13 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_14 = __pyx_PyFloat_AsDouble(__pyx_v_debug); if (unlikely((__pyx_t_14 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "peaks.pyx":94
+ * n_peaks = peaks_wrapper.seek(begin_index, end_index, y_c.size,
+ * fwhm, sensitivity, debug,
+ * &y_c[0], &peaks_c, &relevances_c) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_15 = 0;
+ __pyx_t_16 = -1;
+ if (__pyx_t_15 < 0) {
+ __pyx_t_15 += __pyx_v_y_c.shape[0];
+ if (unlikely(__pyx_t_15 < 0)) __pyx_t_16 = 0;
+ } else if (unlikely(__pyx_t_15 >= __pyx_v_y_c.shape[0])) __pyx_t_16 = 0;
+ if (unlikely(__pyx_t_16 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_16);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 94; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "peaks.pyx":92
+ * end_index = y_c.size - 1
+ *
+ * n_peaks = peaks_wrapper.seek(begin_index, end_index, y_c.size, # <<<<<<<<<<<<<<
+ * fwhm, sensitivity, debug,
+ * &y_c[0], &peaks_c, &relevances_c)
+ */
+ __pyx_v_n_peaks = seek(__pyx_t_9, __pyx_t_10, __pyx_t_11, __pyx_t_12, __pyx_t_13, __pyx_t_14, (&(*((double *) ( /* dim=0 */ ((char *) (((double *) __pyx_v_y_c.data) + __pyx_t_15)) )))), (&__pyx_v_peaks_c), (&__pyx_v_relevances_c));
+
+ /* "peaks.pyx":99
+ * # A negative return value means that peaks were found but not enough
+ * # memory could be allocated for all
+ * if n_peaks < 0 and n_peaks != -123456: # <<<<<<<<<<<<<<
+ * msg = "Before memory allocation error happened, "
+ * msg += "we found %d peaks.\n" % abs(n_peaks)
+ */
+ __pyx_t_8 = ((__pyx_v_n_peaks < 0) != 0);
+ if (__pyx_t_8) {
+ } else {
+ __pyx_t_7 = __pyx_t_8;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_8 = ((__pyx_v_n_peaks != -123456) != 0);
+ __pyx_t_7 = __pyx_t_8;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "peaks.pyx":100
+ * # memory could be allocated for all
+ * if n_peaks < 0 and n_peaks != -123456:
+ * msg = "Before memory allocation error happened, " # <<<<<<<<<<<<<<
+ * msg += "we found %d peaks.\n" % abs(n_peaks)
+ * _logger.debug(msg)
+ */
+ __Pyx_INCREF(__pyx_kp_s_Before_memory_allocation_error_h);
+ __pyx_v_msg = __pyx_kp_s_Before_memory_allocation_error_h;
+
+ /* "peaks.pyx":101
+ * if n_peaks < 0 and n_peaks != -123456:
+ * msg = "Before memory allocation error happened, "
+ * msg += "we found %d peaks.\n" % abs(n_peaks) # <<<<<<<<<<<<<<
+ * _logger.debug(msg)
+ * msg = ""
+ */
+ __pyx_t_17 = __Pyx_abs_long(__pyx_v_n_peaks);
+ __pyx_t_3 = __Pyx_PyInt_From_unsigned_long(__pyx_t_17); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyString_Format(__pyx_kp_s_we_found_d_peaks, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_msg, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "peaks.pyx":102
+ * msg = "Before memory allocation error happened, "
+ * msg += "we found %d peaks.\n" % abs(n_peaks)
+ * _logger.debug(msg) # <<<<<<<<<<<<<<
+ * msg = ""
+ * for i in range(abs(n_peaks)):
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_debug); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_msg); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ __Pyx_INCREF(__pyx_v_msg);
+ PyTuple_SET_ITEM(__pyx_t_2, 0+1, __pyx_v_msg);
+ __Pyx_GIVEREF(__pyx_v_msg);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "peaks.pyx":103
+ * msg += "we found %d peaks.\n" % abs(n_peaks)
+ * _logger.debug(msg)
+ * msg = "" # <<<<<<<<<<<<<<
+ * for i in range(abs(n_peaks)):
+ * msg += "peak index %f, " % peaks_c[i]
+ */
+ __Pyx_INCREF(__pyx_kp_s__2);
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_kp_s__2);
+
+ /* "peaks.pyx":104
+ * _logger.debug(msg)
+ * msg = ""
+ * for i in range(abs(n_peaks)): # <<<<<<<<<<<<<<
+ * msg += "peak index %f, " % peaks_c[i]
+ * msg += "relevance %f\n" % relevances_c[i]
+ */
+ __pyx_t_17 = __Pyx_abs_long(__pyx_v_n_peaks);
+ for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_17; __pyx_t_16+=1) {
+ __pyx_v_i = __pyx_t_16;
+
+ /* "peaks.pyx":105
+ * msg = ""
+ * for i in range(abs(n_peaks)):
+ * msg += "peak index %f, " % peaks_c[i] # <<<<<<<<<<<<<<
+ * msg += "relevance %f\n" % relevances_c[i]
+ * _logger.debug(msg)
+ */
+ __pyx_t_3 = PyFloat_FromDouble((__pyx_v_peaks_c[__pyx_v_i])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_peak_index_f, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_msg, __pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "peaks.pyx":106
+ * for i in range(abs(n_peaks)):
+ * msg += "peak index %f, " % peaks_c[i]
+ * msg += "relevance %f\n" % relevances_c[i] # <<<<<<<<<<<<<<
+ * _logger.debug(msg)
+ * free(peaks_c)
+ */
+ __pyx_t_3 = PyFloat_FromDouble((__pyx_v_relevances_c[__pyx_v_i])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_relevance_f, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_msg, __pyx_t_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF_SET(__pyx_v_msg, __pyx_t_3);
+ __pyx_t_3 = 0;
+ }
+
+ /* "peaks.pyx":107
+ * msg += "peak index %f, " % peaks_c[i]
+ * msg += "relevance %f\n" % relevances_c[i]
+ * _logger.debug(msg) # <<<<<<<<<<<<<<
+ * free(peaks_c)
+ * free(relevances_c)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_logger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_debug); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_msg); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ __Pyx_INCREF(__pyx_v_msg);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_msg);
+ __Pyx_GIVEREF(__pyx_v_msg);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "peaks.pyx":108
+ * msg += "relevance %f\n" % relevances_c[i]
+ * _logger.debug(msg)
+ * free(peaks_c) # <<<<<<<<<<<<<<
+ * free(relevances_c)
+ * raise MemoryError("Failed to reallocate memory for output arrays")
+ */
+ free(__pyx_v_peaks_c);
+
+ /* "peaks.pyx":109
+ * _logger.debug(msg)
+ * free(peaks_c)
+ * free(relevances_c) # <<<<<<<<<<<<<<
+ * raise MemoryError("Failed to reallocate memory for output arrays")
+ * # Special value -123456 is returned if the initial memory allocation
+ */
+ free(__pyx_v_relevances_c);
+
+ /* "peaks.pyx":110
+ * free(peaks_c)
+ * free(relevances_c)
+ * raise MemoryError("Failed to reallocate memory for output arrays") # <<<<<<<<<<<<<<
+ * # Special value -123456 is returned if the initial memory allocation
+ * #fails, before any search could be performed
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "peaks.pyx":113
+ * # Special value -123456 is returned if the initial memory allocation
+ * #fails, before any search could be performed
+ * elif n_peaks == -123456: # <<<<<<<<<<<<<<
+ * raise MemoryError("Failed to allocate initial memory for " +
+ * "output arrays")
+ */
+ __pyx_t_7 = ((__pyx_v_n_peaks == -123456) != 0);
+ if (__pyx_t_7) {
+
+ /* "peaks.pyx":114
+ * #fails, before any search could be performed
+ * elif n_peaks == -123456:
+ * raise MemoryError("Failed to allocate initial memory for " + # <<<<<<<<<<<<<<
+ * "output arrays")
+ *
+ */
+ __pyx_t_3 = PyNumber_Add(__pyx_kp_s_Failed_to_allocate_initial_memor, __pyx_kp_s_output_arrays); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "peaks.pyx":117
+ * "output arrays")
+ *
+ * peaks = numpy.empty(shape=(n_peaks,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ * relevances = numpy.empty(shape=(n_peaks,),
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyInt_From_long(__pyx_v_n_peaks); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_shape, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "peaks.pyx":118
+ *
+ * peaks = numpy.empty(shape=(n_peaks,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ * relevances = numpy.empty(shape=(n_peaks,),
+ * dtype=numpy.float64)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "peaks.pyx":117
+ * "output arrays")
+ *
+ * peaks = numpy.empty(shape=(n_peaks,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ * relevances = numpy.empty(shape=(n_peaks,),
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_peaks = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "peaks.pyx":119
+ * peaks = numpy.empty(shape=(n_peaks,),
+ * dtype=numpy.float64)
+ * relevances = numpy.empty(shape=(n_peaks,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_2 = __Pyx_PyInt_From_long(__pyx_v_n_peaks); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_shape, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "peaks.pyx":120
+ * dtype=numpy.float64)
+ * relevances = numpy.empty(shape=(n_peaks,),
+ * dtype=numpy.float64) # <<<<<<<<<<<<<<
+ *
+ * for i in range(n_peaks):
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_float64); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "peaks.pyx":119
+ * peaks = numpy.empty(shape=(n_peaks,),
+ * dtype=numpy.float64)
+ * relevances = numpy.empty(shape=(n_peaks,), # <<<<<<<<<<<<<<
+ * dtype=numpy.float64)
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_relevances = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "peaks.pyx":122
+ * dtype=numpy.float64)
+ *
+ * for i in range(n_peaks): # <<<<<<<<<<<<<<
+ * peaks[i] = peaks_c[i]
+ * relevances[i] = relevances_c[i]
+ */
+ __pyx_t_11 = __pyx_v_n_peaks;
+ for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_11; __pyx_t_16+=1) {
+ __pyx_v_i = __pyx_t_16;
+
+ /* "peaks.pyx":123
+ *
+ * for i in range(n_peaks):
+ * peaks[i] = peaks_c[i] # <<<<<<<<<<<<<<
+ * relevances[i] = relevances_c[i]
+ *
+ */
+ __pyx_t_2 = PyFloat_FromDouble((__pyx_v_peaks_c[__pyx_v_i])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_peaks, __pyx_v_i, __pyx_t_2, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "peaks.pyx":124
+ * for i in range(n_peaks):
+ * peaks[i] = peaks_c[i]
+ * relevances[i] = relevances_c[i] # <<<<<<<<<<<<<<
+ *
+ * free(peaks_c)
+ */
+ __pyx_t_2 = PyFloat_FromDouble((__pyx_v_relevances_c[__pyx_v_i])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_relevances, __pyx_v_i, __pyx_t_2, int, 1, __Pyx_PyInt_From_int, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+
+ /* "peaks.pyx":126
+ * relevances[i] = relevances_c[i]
+ *
+ * free(peaks_c) # <<<<<<<<<<<<<<
+ * free(relevances_c)
+ *
+ */
+ free(__pyx_v_peaks_c);
+
+ /* "peaks.pyx":127
+ *
+ * free(peaks_c)
+ * free(relevances_c) # <<<<<<<<<<<<<<
+ *
+ * if not relevance_info:
+ */
+ free(__pyx_v_relevances_c);
+
+ /* "peaks.pyx":129
+ * free(relevances_c)
+ *
+ * if not relevance_info: # <<<<<<<<<<<<<<
+ * return peaks
+ * else:
+ */
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_v_relevance_info); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_8 = ((!__pyx_t_7) != 0);
+ if (__pyx_t_8) {
+
+ /* "peaks.pyx":130
+ *
+ * if not relevance_info:
+ * return peaks # <<<<<<<<<<<<<<
+ * else:
+ * return list(zip(peaks, relevances))
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_peaks);
+ __pyx_r = __pyx_v_peaks;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "peaks.pyx":132
+ * return peaks
+ * else:
+ * return list(zip(peaks, relevances)) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_peaks);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_peaks);
+ __Pyx_GIVEREF(__pyx_v_peaks);
+ __Pyx_INCREF(__pyx_v_relevances);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_relevances);
+ __Pyx_GIVEREF(__pyx_v_relevances);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_zip, __pyx_t_2, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_2, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "peaks.pyx":46
+ *
+ *
+ * def peak_search(y, fwhm, sensitivity=3.5, # <<<<<<<<<<<<<<
+ * begin_index=None, end_index=None,
+ * debug=False, relevance_info=False):
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
+ __Pyx_AddTraceback("peaks.peak_search", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_y_c, 1);
+ __Pyx_XDECREF(__pyx_v_msg);
+ __Pyx_XDECREF(__pyx_v_peaks);
+ __Pyx_XDECREF(__pyx_v_relevances);
+ __Pyx_XDECREF(__pyx_v_begin_index);
+ __Pyx_XDECREF(__pyx_v_end_index);
+ __Pyx_XDECREF(__pyx_v_debug);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "peaks.pyx":135
+ *
+ *
+ * def guess_fwhm(y): # <<<<<<<<<<<<<<
+ * """Return the full-width at half maximum for the largest peak in
+ * the data array.
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_5peaks_3guess_fwhm(PyObject *__pyx_self, PyObject *__pyx_v_y); /*proto*/
+static char __pyx_doc_5peaks_2guess_fwhm[] = "guess_fwhm(y)\nReturn the full-width at half maximum for the largest peak in\n the data array.\n\n The algorithm removes the background, then finds a global maximum\n and its corresponding FWHM.\n\n This value can be used as an initial fit parameter, used as input for\n an iterative fit function.\n\n :param y: Data to be used for guessing the fwhm.\n :return: Estimation of full-width at half maximum, based on fwhm of\n the global maximum.\n ";
+static PyMethodDef __pyx_mdef_5peaks_3guess_fwhm = {"guess_fwhm", (PyCFunction)__pyx_pw_5peaks_3guess_fwhm, METH_O, __pyx_doc_5peaks_2guess_fwhm};
+static PyObject *__pyx_pw_5peaks_3guess_fwhm(PyObject *__pyx_self, PyObject *__pyx_v_y) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("guess_fwhm (wrapper)", 0);
+ __pyx_r = __pyx_pf_5peaks_2guess_fwhm(__pyx_self, ((PyObject *)__pyx_v_y));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_5peaks_2guess_fwhm(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_y) {
+ long __pyx_v_fwhm_min;
+ PyObject *__pyx_v_background = NULL;
+ PyObject *__pyx_v_yfit = NULL;
+ PyObject *__pyx_v_maximum = NULL;
+ PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_posindex = NULL;
+ PyObject *__pyx_v_height = NULL;
+ PyObject *__pyx_v_imin = NULL;
+ PyObject *__pyx_v_imax = NULL;
+ PyObject *__pyx_v_fwhm = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ long __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("guess_fwhm", 0);
+
+ /* "peaks.pyx":150
+ * """
+ * # set at a minimum value for the fwhm
+ * fwhm_min = 4 # <<<<<<<<<<<<<<
+ *
+ * # remove data background (computed with a strip filter)
+ */
+ __pyx_v_fwhm_min = 4;
+
+ /* "peaks.pyx":153
+ *
+ * # remove data background (computed with a strip filter)
+ * background = filters.strip(y, w=1, niterations=1000) # <<<<<<<<<<<<<<
+ * yfit = y - background
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_strip); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_y);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_y);
+ __Pyx_GIVEREF(__pyx_v_y);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_w, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_niterations, __pyx_int_1000) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_background = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "peaks.pyx":154
+ * # remove data background (computed with a strip filter)
+ * background = filters.strip(y, w=1, niterations=1000)
+ * yfit = y - background # <<<<<<<<<<<<<<
+ *
+ * # basic peak search: find the global maximum
+ */
+ __pyx_t_4 = PyNumber_Subtract(__pyx_v_y, __pyx_v_background); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_v_yfit = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "peaks.pyx":157
+ *
+ * # basic peak search: find the global maximum
+ * maximum = max(yfit) # <<<<<<<<<<<<<<
+ * # find indices of all values == maximum
+ * idx = numpy.nonzero(yfit == maximum)[0]
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_yfit);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_yfit);
+ __Pyx_GIVEREF(__pyx_v_yfit);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_max, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_maximum = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "peaks.pyx":159
+ * maximum = max(yfit)
+ * # find indices of all values == maximum
+ * idx = numpy.nonzero(yfit == maximum)[0] # <<<<<<<<<<<<<<
+ * # take the last one (if any)
+ * if not len(idx):
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_nonzero); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_yfit, __pyx_v_maximum, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_idx = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "peaks.pyx":161
+ * idx = numpy.nonzero(yfit == maximum)[0]
+ * # take the last one (if any)
+ * if not len(idx): # <<<<<<<<<<<<<<
+ * return 0
+ * posindex = idx[-1]
+ */
+ __pyx_t_6 = PyObject_Length(__pyx_v_idx); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = ((!(__pyx_t_6 != 0)) != 0);
+ if (__pyx_t_7) {
+
+ /* "peaks.pyx":162
+ * # take the last one (if any)
+ * if not len(idx):
+ * return 0 # <<<<<<<<<<<<<<
+ * posindex = idx[-1]
+ * height = yfit[posindex]
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+ }
+
+ /* "peaks.pyx":163
+ * if not len(idx):
+ * return 0
+ * posindex = idx[-1] # <<<<<<<<<<<<<<
+ * height = yfit[posindex]
+ *
+ */
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_idx, -1, long, 1, __Pyx_PyInt_From_long, 0, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_posindex = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "peaks.pyx":164
+ * return 0
+ * posindex = idx[-1]
+ * height = yfit[posindex] # <<<<<<<<<<<<<<
+ *
+ * # now find the width of the peak at half maximum
+ */
+ __pyx_t_1 = PyObject_GetItem(__pyx_v_yfit, __pyx_v_posindex); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_height = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "peaks.pyx":167
+ *
+ * # now find the width of the peak at half maximum
+ * imin = posindex # <<<<<<<<<<<<<<
+ * while yfit[imin] > 0.5 * height and imin > 0:
+ * imin -= 1
+ */
+ __Pyx_INCREF(__pyx_v_posindex);
+ __pyx_v_imin = __pyx_v_posindex;
+
+ /* "peaks.pyx":168
+ * # now find the width of the peak at half maximum
+ * imin = posindex
+ * while yfit[imin] > 0.5 * height and imin > 0: # <<<<<<<<<<<<<<
+ * imin -= 1
+ * imax = posindex
+ */
+ while (1) {
+ __pyx_t_1 = PyObject_GetItem(__pyx_v_yfit, __pyx_v_imin); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_float_0_5, __pyx_v_height); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__pyx_t_8) {
+ } else {
+ __pyx_t_7 = __pyx_t_8;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_5 = PyObject_RichCompare(__pyx_v_imin, __pyx_int_0, Py_GT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __pyx_t_8;
+ __pyx_L6_bool_binop_done:;
+ if (!__pyx_t_7) break;
+
+ /* "peaks.pyx":169
+ * imin = posindex
+ * while yfit[imin] > 0.5 * height and imin > 0:
+ * imin -= 1 # <<<<<<<<<<<<<<
+ * imax = posindex
+ * while yfit[imax] > 0.5 * height and imax < len(yfit) - 1:
+ */
+ __pyx_t_5 = PyNumber_InPlaceSubtract(__pyx_v_imin, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF_SET(__pyx_v_imin, __pyx_t_5);
+ __pyx_t_5 = 0;
+ }
+
+ /* "peaks.pyx":170
+ * while yfit[imin] > 0.5 * height and imin > 0:
+ * imin -= 1
+ * imax = posindex # <<<<<<<<<<<<<<
+ * while yfit[imax] > 0.5 * height and imax < len(yfit) - 1:
+ * imax += 1
+ */
+ __Pyx_INCREF(__pyx_v_posindex);
+ __pyx_v_imax = __pyx_v_posindex;
+
+ /* "peaks.pyx":171
+ * imin -= 1
+ * imax = posindex
+ * while yfit[imax] > 0.5 * height and imax < len(yfit) - 1: # <<<<<<<<<<<<<<
+ * imax += 1
+ *
+ */
+ while (1) {
+ __pyx_t_5 = PyObject_GetItem(__pyx_v_yfit, __pyx_v_imax); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_float_0_5, __pyx_v_height); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_1 = PyObject_RichCompare(__pyx_t_5, __pyx_t_3, Py_GT); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_8) {
+ } else {
+ __pyx_t_7 = __pyx_t_8;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = PyObject_Length(__pyx_v_yfit); if (unlikely(__pyx_t_6 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = PyInt_FromSsize_t((__pyx_t_6 - 1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_imax, __pyx_t_1, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_7 = __pyx_t_8;
+ __pyx_L10_bool_binop_done:;
+ if (!__pyx_t_7) break;
+
+ /* "peaks.pyx":172
+ * imax = posindex
+ * while yfit[imax] > 0.5 * height and imax < len(yfit) - 1:
+ * imax += 1 # <<<<<<<<<<<<<<
+ *
+ * fwhm = max(imax - imin - 1, fwhm_min)
+ */
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_imax, __pyx_int_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_imax, __pyx_t_3);
+ __pyx_t_3 = 0;
+ }
+
+ /* "peaks.pyx":174
+ * imax += 1
+ *
+ * fwhm = max(imax - imin - 1, fwhm_min) # <<<<<<<<<<<<<<
+ *
+ * return fwhm
+ */
+ __pyx_t_9 = __pyx_v_fwhm_min;
+ __pyx_t_3 = PyNumber_Subtract(__pyx_v_imax, __pyx_v_imin); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_1 = PyNumber_Subtract(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_5 = __Pyx_PyInt_From_long(__pyx_t_9); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_t_1, Py_GT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_7) {
+ __pyx_t_4 = __Pyx_PyInt_From_long(__pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ } else {
+ __Pyx_INCREF(__pyx_t_1);
+ __pyx_t_3 = __pyx_t_1;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __pyx_t_3;
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_fwhm = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "peaks.pyx":176
+ * fwhm = max(imax - imin - 1, fwhm_min)
+ *
+ * return fwhm # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_fwhm);
+ __pyx_r = __pyx_v_fwhm;
+ goto __pyx_L0;
+
+ /* "peaks.pyx":135
+ *
+ *
+ * def guess_fwhm(y): # <<<<<<<<<<<<<<
+ * """Return the full-width at half maximum for the largest peak in
+ * the data array.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("peaks.guess_fwhm", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_background);
+ __Pyx_XDECREF(__pyx_v_yfit);
+ __Pyx_XDECREF(__pyx_v_maximum);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_posindex);
+ __Pyx_XDECREF(__pyx_v_height);
+ __Pyx_XDECREF(__pyx_v_imin);
+ __Pyx_XDECREF(__pyx_v_imax);
+ __Pyx_XDECREF(__pyx_v_fwhm);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__11);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__11);
+ __Pyx_GIVEREF(__pyx_slice__11);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__12); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__13);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__13);
+ __Pyx_GIVEREF(__pyx_slice__13);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "peaks.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "peaks.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "peaks.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "peaks._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "peaks",
+ __pyx_k_This_module_provides_a_peak_sear, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_17_06_2016, __pyx_k_17_06_2016, sizeof(__pyx_k_17_06_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_Before_memory_allocation_error_h, __pyx_k_Before_memory_allocation_error_h, sizeof(__pyx_k_Before_memory_allocation_error_h), 0, 0, 1, 0},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_n_s_C, __pyx_k_C, sizeof(__pyx_k_C), 0, 0, 1, 1},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Failed_to_allocate_initial_memor, __pyx_k_Failed_to_allocate_initial_memor, sizeof(__pyx_k_Failed_to_allocate_initial_memor), 0, 0, 1, 0},
+ {&__pyx_kp_s_Failed_to_reallocate_memory_for, __pyx_k_Failed_to_reallocate_memory_for, sizeof(__pyx_k_Failed_to_reallocate_memory_for), 0, 0, 1, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_kp_s_P_Knobel, __pyx_k_P_Knobel, sizeof(__pyx_k_P_Knobel), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_kp_s__2, __pyx_k__2, sizeof(__pyx_k__2), 0, 0, 1, 0},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_background, __pyx_k_background, sizeof(__pyx_k_background), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_basicConfig, __pyx_k_basicConfig, sizeof(__pyx_k_basicConfig), 0, 0, 1, 1},
+ {&__pyx_n_s_begin_index, __pyx_k_begin_index, sizeof(__pyx_k_begin_index), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_copy, __pyx_k_copy, sizeof(__pyx_k_copy), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_debug, __pyx_k_debug, sizeof(__pyx_k_debug), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
+ {&__pyx_n_s_end_index, __pyx_k_end_index, sizeof(__pyx_k_end_index), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_filters, __pyx_k_filters, sizeof(__pyx_k_filters), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 0, 1, 1},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_n_s_fwhm, __pyx_k_fwhm, sizeof(__pyx_k_fwhm), 0, 0, 1, 1},
+ {&__pyx_n_s_fwhm_min, __pyx_k_fwhm_min, sizeof(__pyx_k_fwhm_min), 0, 0, 1, 1},
+ {&__pyx_n_s_getLogger, __pyx_k_getLogger, sizeof(__pyx_k_getLogger), 0, 0, 1, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_guess_fwhm, __pyx_k_guess_fwhm, sizeof(__pyx_k_guess_fwhm), 0, 0, 1, 1},
+ {&__pyx_n_s_height, __pyx_k_height, sizeof(__pyx_k_height), 0, 0, 1, 1},
+ {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_idx, __pyx_k_idx, sizeof(__pyx_k_idx), 0, 0, 1, 1},
+ {&__pyx_n_s_imax, __pyx_k_imax, sizeof(__pyx_k_imax), 0, 0, 1, 1},
+ {&__pyx_n_s_imin, __pyx_k_imin, sizeof(__pyx_k_imin), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_logger, __pyx_k_logger, sizeof(__pyx_k_logger), 0, 0, 1, 1},
+ {&__pyx_n_s_logging, __pyx_k_logging, sizeof(__pyx_k_logging), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_max, __pyx_k_max, sizeof(__pyx_k_max), 0, 0, 1, 1},
+ {&__pyx_n_s_maximum, __pyx_k_maximum, sizeof(__pyx_k_maximum), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_k_mntdirect__scisoft_users_tvince, sizeof(__pyx_k_mntdirect__scisoft_users_tvince), 0, 0, 1, 0},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_msg, __pyx_k_msg, sizeof(__pyx_k_msg), 0, 0, 1, 1},
+ {&__pyx_n_s_n_peaks, __pyx_k_n_peaks, sizeof(__pyx_k_n_peaks), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_niterations, __pyx_k_niterations, sizeof(__pyx_k_niterations), 0, 0, 1, 1},
+ {&__pyx_n_s_nonzero, __pyx_k_nonzero, sizeof(__pyx_k_nonzero), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_n_s_order, __pyx_k_order, sizeof(__pyx_k_order), 0, 0, 1, 1},
+ {&__pyx_kp_s_output_arrays, __pyx_k_output_arrays, sizeof(__pyx_k_output_arrays), 0, 0, 1, 0},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_kp_s_peak_index_f, __pyx_k_peak_index_f, sizeof(__pyx_k_peak_index_f), 0, 0, 1, 0},
+ {&__pyx_n_s_peak_search, __pyx_k_peak_search, sizeof(__pyx_k_peak_search), 0, 0, 1, 1},
+ {&__pyx_n_s_peaks, __pyx_k_peaks, sizeof(__pyx_k_peaks), 0, 0, 1, 1},
+ {&__pyx_n_s_peaks_c, __pyx_k_peaks_c, sizeof(__pyx_k_peaks_c), 0, 0, 1, 1},
+ {&__pyx_n_s_posindex, __pyx_k_posindex, sizeof(__pyx_k_posindex), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_kp_s_relevance_f, __pyx_k_relevance_f, sizeof(__pyx_k_relevance_f), 0, 0, 1, 0},
+ {&__pyx_n_s_relevance_info, __pyx_k_relevance_info, sizeof(__pyx_k_relevance_info), 0, 0, 1, 1},
+ {&__pyx_n_s_relevances, __pyx_k_relevances, sizeof(__pyx_k_relevances), 0, 0, 1, 1},
+ {&__pyx_n_s_relevances_c, __pyx_k_relevances_c, sizeof(__pyx_k_relevances_c), 0, 0, 1, 1},
+ {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+ {&__pyx_n_s_sensitivity, __pyx_k_sensitivity, sizeof(__pyx_k_sensitivity), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_strip, __pyx_k_strip, sizeof(__pyx_k_strip), 0, 0, 1, 1},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_n_s_w, __pyx_k_w, sizeof(__pyx_k_w), 0, 0, 1, 1},
+ {&__pyx_kp_s_we_found_d_peaks, __pyx_k_we_found_d_peaks, sizeof(__pyx_k_we_found_d_peaks), 0, 0, 1, 0},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {&__pyx_n_s_y, __pyx_k_y, sizeof(__pyx_k_y), 0, 0, 1, 1},
+ {&__pyx_n_s_y_c, __pyx_k_y_c, sizeof(__pyx_k_y_c), 0, 0, 1, 1},
+ {&__pyx_n_s_yfit, __pyx_k_yfit, sizeof(__pyx_k_yfit), 0, 0, 1, 1},
+ {&__pyx_n_s_zip, __pyx_k_zip, sizeof(__pyx_k_zip), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_zip = __Pyx_GetBuiltinName(__pyx_n_s_zip); if (!__pyx_builtin_zip) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_max = __Pyx_GetBuiltinName(__pyx_n_s_max); if (!__pyx_builtin_max) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "peaks.pyx":81
+ * copy=True,
+ * dtype=numpy.float64,
+ * order='C').reshape(-1) # <<<<<<<<<<<<<<
+ * if debug:
+ * debug = 1
+ */
+ __pyx_tuple_ = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "peaks.pyx":110
+ * free(peaks_c)
+ * free(relevances_c)
+ * raise MemoryError("Failed to reallocate memory for output arrays") # <<<<<<<<<<<<<<
+ * # Special value -123456 is returned if the initial memory allocation
+ * #fails, before any search could be performed
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_Failed_to_reallocate_memory_for); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__7);
+ __Pyx_GIVEREF(__pyx_tuple__7);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__11 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__11);
+ __Pyx_GIVEREF(__pyx_slice__11);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__12 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__12)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__12);
+ __Pyx_GIVEREF(__pyx_slice__12);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__13 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__13)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__13);
+ __Pyx_GIVEREF(__pyx_slice__13);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__14);
+ __Pyx_GIVEREF(__pyx_tuple__14);
+
+ /* "peaks.pyx":46
+ *
+ *
+ * def peak_search(y, fwhm, sensitivity=3.5, # <<<<<<<<<<<<<<
+ * begin_index=None, end_index=None,
+ * debug=False, relevance_info=False):
+ */
+ __pyx_tuple__15 = PyTuple_Pack(15, __pyx_n_s_y, __pyx_n_s_fwhm, __pyx_n_s_sensitivity, __pyx_n_s_begin_index, __pyx_n_s_end_index, __pyx_n_s_debug, __pyx_n_s_relevance_info, __pyx_n_s_i, __pyx_n_s_y_c, __pyx_n_s_peaks_c, __pyx_n_s_relevances_c, __pyx_n_s_n_peaks, __pyx_n_s_msg, __pyx_n_s_peaks, __pyx_n_s_relevances); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+ __pyx_codeobj__16 = (PyObject*)__Pyx_PyCode_New(7, 0, 15, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__15, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_peak_search, 46, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "peaks.pyx":135
+ *
+ *
+ * def guess_fwhm(y): # <<<<<<<<<<<<<<
+ * """Return the full-width at half maximum for the largest peak in
+ * the data array.
+ */
+ __pyx_tuple__17 = PyTuple_Pack(11, __pyx_n_s_y, __pyx_n_s_fwhm_min, __pyx_n_s_background, __pyx_n_s_yfit, __pyx_n_s_maximum, __pyx_n_s_idx, __pyx_n_s_posindex, __pyx_n_s_height, __pyx_n_s_imin, __pyx_n_s_imax, __pyx_n_s_fwhm); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+ __pyx_codeobj__18 = (PyObject*)__Pyx_PyCode_New(1, 0, 11, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__17, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_guess_fwhm, 135, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__19);
+ __Pyx_GIVEREF(__pyx_tuple__19);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__21)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__21);
+ __Pyx_GIVEREF(__pyx_tuple__21);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__22);
+ __Pyx_GIVEREF(__pyx_tuple__22);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__23)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__23);
+ __Pyx_GIVEREF(__pyx_tuple__23);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_float_0_5 = PyFloat_FromDouble(0.5); if (unlikely(!__pyx_float_0_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_float_3_5 = PyFloat_FromDouble(3.5); if (unlikely(!__pyx_float_3_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1000 = PyInt_FromLong(1000); if (unlikely(!__pyx_int_1000)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initpeaks(void); /*proto*/
+PyMODINIT_FUNC initpeaks(void)
+#else
+PyMODINIT_FUNC PyInit_peaks(void); /*proto*/
+PyMODINIT_FUNC PyInit_peaks(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_peaks(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("peaks", __pyx_methods, __pyx_k_This_module_provides_a_peak_sear, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_peaks) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "peaks")) {
+ if (unlikely(PyDict_SetItemString(modules, "peaks", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "peaks.pyx":28
+ * """
+ *
+ * __authors__ = ["P. Knobel"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "17/06/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_P_Knobel);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_P_Knobel);
+ __Pyx_GIVEREF(__pyx_kp_s_P_Knobel);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "peaks.pyx":29
+ *
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "17/06/2016"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "peaks.pyx":30
+ * __authors__ = ["P. Knobel"]
+ * __license__ = "MIT"
+ * __date__ = "17/06/2016" # <<<<<<<<<<<<<<
+ *
+ * import logging
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_17_06_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "peaks.pyx":32
+ * __date__ = "17/06/2016"
+ *
+ * import logging # <<<<<<<<<<<<<<
+ * import numpy
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_logging, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logging, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "peaks.pyx":33
+ *
+ * import logging
+ * import numpy # <<<<<<<<<<<<<<
+ *
+ * from . import filters
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "peaks.pyx":35
+ * import numpy
+ *
+ * from . import filters # <<<<<<<<<<<<<<
+ *
+ * logging.basicConfig()
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_n_s_filters);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_filters);
+ __Pyx_GIVEREF(__pyx_n_s_filters);
+ __pyx_t_2 = __Pyx_Import(__pyx_kp_s__2, __pyx_t_1, 1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_filters); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_filters, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "peaks.pyx":37
+ * from . import filters
+ *
+ * logging.basicConfig() # <<<<<<<<<<<<<<
+ * _logger = logging.getLogger(__name__)
+ *
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_basicConfig); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_1) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "peaks.pyx":38
+ *
+ * logging.basicConfig()
+ * _logger = logging.getLogger(__name__) # <<<<<<<<<<<<<<
+ *
+ * cimport cython
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_logging); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_getLogger); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_name_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_logger, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "peaks.pyx":46
+ *
+ *
+ * def peak_search(y, fwhm, sensitivity=3.5, # <<<<<<<<<<<<<<
+ * begin_index=None, end_index=None,
+ * debug=False, relevance_info=False):
+ */
+ __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_5peaks_1peak_search, NULL, __pyx_n_s_peaks); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_peak_search, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "peaks.pyx":135
+ *
+ *
+ * def guess_fwhm(y): # <<<<<<<<<<<<<<
+ * """Return the full-width at half maximum for the largest peak in
+ * the data array.
+ */
+ __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_5peaks_3guess_fwhm, NULL, __pyx_n_s_peaks); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_guess_fwhm, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "peaks.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * #/[inserted by cython to avoid comment start]*##########################################################################
+ * # Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+ */
+ __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_2 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init peaks", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init peaks");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+static void __Pyx_RaiseBufferIndexError(int axis) {
+ PyErr_Format(PyExc_IndexError,
+ "Out of bounds on buffer access (axis %d)", axis);
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+ int r;
+ if (!j) return -1;
+ r = PyObject_SetItem(o, j, v);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o));
+ if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+ PyObject* old = PyList_GET_ITEM(o, n);
+ Py_INCREF(v);
+ PyList_SET_ITEM(o, n, v);
+ Py_DECREF(old);
+ return 1;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_ass_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return -1;
+ }
+ }
+ return m->sq_ass_item(o, i, v);
+ }
+ }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+ if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) {
+#else
+ if (is_list || PySequence_Check(o)) {
+#endif
+ return PySequence_SetItem(o, i, v);
+ }
+#endif
+ return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) {
+ PyObject* value = __Pyx_PyObject_GetAttrStr(module, name);
+ if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Format(PyExc_ImportError,
+ #if PY_MAJOR_VERSION < 3
+ "cannot import name %.230s", PyString_AS_STRING(name));
+ #else
+ "cannot import name %S", name);
+ #endif
+ }
+ return value;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+static PyObject *__pyx_memview_get_double(const char *itemp) {
+ return (PyObject *) PyFloat_FromDouble(*(double *) itemp);
+}
+static int __pyx_memview_set_double(const char *itemp, PyObject *obj) {
+ double value = __pyx_PyFloat_AsDouble(obj);
+ if ((value == (double)-1) && PyErr_Occurred())
+ return 0;
+ *(double *) itemp = value;
+ return 1;
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_long(unsigned long value) {
+ const unsigned long neg_one = (unsigned long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(unsigned long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(unsigned long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(unsigned long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(unsigned long),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_double(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_double, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/math/fit/peaks/peaks.pyx b/silx/math/fit/peaks/peaks.pyx
new file mode 100644
index 0000000..02753b0
--- /dev/null
+++ b/silx/math/fit/peaks/peaks.pyx
@@ -0,0 +1,176 @@
+# coding: utf-8
+#/*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+#############################################################################*/
+"""This module provides a peak search function and tools related to peak
+analysis.
+"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "17/06/2016"
+
+import logging
+import numpy
+
+from . import filters
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+
+cimport cython
+from libc.stdlib cimport free
+
+cimport peaks_wrapper
+
+
+def peak_search(y, fwhm, sensitivity=3.5,
+ begin_index=None, end_index=None,
+ debug=False, relevance_info=False):
+ """Find peaks in a curve.
+
+ :param y: Data array
+ :type y: numpy.ndarray
+ :param fwhm: Estimated full width at half maximum of the typical peaks we
+ are interested in (expressed in number of samples)
+ :param sensitivity: Threshold factor used for peak detection. Only peaks
+ with amplitudes higher than ``σ * sensitivity`` - where ``σ`` is the
+ standard deviation of the noise - qualify as peaks.
+ :param begin_index: Index of the first sample of the region of interest
+ in the ``y`` array. If ``None``, start from the first sample.
+ :param end_index: Index of the last sample of the region of interest in
+ the ``y`` array. If ``None``, process until the last sample.
+ :param debug: If ``True``, print debug messages. Default: ``False``
+ :param relevance_info: If ``True``, add a second dimension with relevance
+ information to the output array. Default: ``False``
+ :return: 1D sequence with indices of peaks in the data
+ if ``relevance_info`` is ``False``.
+ Else, sequence of ``(peak_index, peak_relevance)`` tuples (one tuple
+ per peak).
+ :raise: ``IndexError`` if the number of peaks is too large to fit in the
+ output array.
+ """
+ cdef:
+ int i
+ double[::1] y_c
+ double* peaks_c
+ double* relevances_c
+
+ y_c = numpy.array(y,
+ copy=True,
+ dtype=numpy.float64,
+ order='C').reshape(-1)
+ if debug:
+ debug = 1
+ else:
+ debug = 0
+
+ if begin_index is None:
+ begin_index = 0
+ if end_index is None:
+ end_index = y_c.size - 1
+
+ n_peaks = peaks_wrapper.seek(begin_index, end_index, y_c.size,
+ fwhm, sensitivity, debug,
+ &y_c[0], &peaks_c, &relevances_c)
+
+
+ # A negative return value means that peaks were found but not enough
+ # memory could be allocated for all
+ if n_peaks < 0 and n_peaks != -123456:
+ msg = "Before memory allocation error happened, "
+ msg += "we found %d peaks.\n" % abs(n_peaks)
+ _logger.debug(msg)
+ msg = ""
+ for i in range(abs(n_peaks)):
+ msg += "peak index %f, " % peaks_c[i]
+ msg += "relevance %f\n" % relevances_c[i]
+ _logger.debug(msg)
+ free(peaks_c)
+ free(relevances_c)
+ raise MemoryError("Failed to reallocate memory for output arrays")
+ # Special value -123456 is returned if the initial memory allocation
+ # fails, before any search could be performed
+ elif n_peaks == -123456:
+ raise MemoryError("Failed to allocate initial memory for " +
+ "output arrays")
+
+ peaks = numpy.empty(shape=(n_peaks,),
+ dtype=numpy.float64)
+ relevances = numpy.empty(shape=(n_peaks,),
+ dtype=numpy.float64)
+
+ for i in range(n_peaks):
+ peaks[i] = peaks_c[i]
+ relevances[i] = relevances_c[i]
+
+ free(peaks_c)
+ free(relevances_c)
+
+ if not relevance_info:
+ return peaks
+ else:
+ return list(zip(peaks, relevances))
+
+
+def guess_fwhm(y):
+ """Return the full-width at half maximum for the largest peak in
+ the data array.
+
+ The algorithm removes the background, then finds a global maximum
+ and its corresponding FWHM.
+
+ This value can be used as an initial fit parameter, used as input for
+ an iterative fit function.
+
+ :param y: Data to be used for guessing the fwhm.
+ :return: Estimation of full-width at half maximum, based on fwhm of
+ the global maximum.
+ """
+ # set at a minimum value for the fwhm
+ fwhm_min = 4
+
+ # remove data background (computed with a strip filter)
+ background = filters.strip(y, w=1, niterations=1000)
+ yfit = y - background
+
+ # basic peak search: find the global maximum
+ maximum = max(yfit)
+ # find indices of all values == maximum
+ idx = numpy.nonzero(yfit == maximum)[0]
+ # take the last one (if any)
+ if not len(idx):
+ return 0
+ posindex = idx[-1]
+ height = yfit[posindex]
+
+ # now find the width of the peak at half maximum
+ imin = posindex
+ while yfit[imin] > 0.5 * height and imin > 0:
+ imin -= 1
+ imax = posindex
+ while yfit[imax] > 0.5 * height and imax < len(yfit) - 1:
+ imax += 1
+
+ fwhm = max(imax - imin - 1, fwhm_min)
+
+ return fwhm
diff --git a/silx/math/fit/peaks/peaks_wrapper.pxd b/silx/math/fit/peaks/peaks_wrapper.pxd
new file mode 100644
index 0000000..4c77dc6
--- /dev/null
+++ b/silx/math/fit/peaks/peaks_wrapper.pxd
@@ -0,0 +1,41 @@
+# 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.
+#
+#############################################################################*/
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "22/06/2016"
+
+cimport cython
+
+cdef extern from "peaks.h":
+ long seek(long begin_index,
+ long end_index,
+ long nsamples,
+ double fwhm,
+ double sensitivity,
+ double debug_info,
+ double * data,
+ double ** peaks,
+ double ** relevances)
+
diff --git a/silx/math/fit/peaks/src/peaks.c b/silx/math/fit/peaks/src/peaks.c
new file mode 100644
index 0000000..65cb4f6
--- /dev/null
+++ b/silx/math/fit/peaks/src/peaks.c
@@ -0,0 +1,255 @@
+#/*##########################################################################
+# Copyright (c) 2004-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.
+#
+#############################################################################*/
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "peaks.h"
+
+
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+/* Peak search function, adapted from PyMca SpecFitFuns
+
+ This uses a convolution with the second-derivative of a gaussian curve, to
+ smooth the data.
+
+ Arguments:
+
+ - begin_index: First index of the region of interest in the input data
+ array
+ - end_index: Last index of the region of interest in the input data
+ array
+ - nsamples: Number of samples in the input array
+ - fwhm: Full width at half maximum for the gaussian used for smoothing.
+ - sensitivity:
+ - debug_info: If different from 0, print debugging messages
+ - data: input array of 1D data
+ - peaks: pointer to output array of peak indices
+ - relevances: pointer to output array of peak relevances
+*/
+long seek(long begin_index,
+ long end_index,
+ long nsamples,
+ double fwhm,
+ double sensitivity,
+ double debug_info,
+ double *data,
+ double **peaks,
+ double **relevances)
+{
+ /* local variables */
+ double *peaks0, *relevances0;
+ double *realloc_peaks, *realloc_relevances;
+ double sigma, sigma2, sigma4;
+ long max_gfactor = 100;
+ double gfactor[100];
+ long nr_factor;
+ double lowthreshold;
+ double data2[2];
+ double nom;
+ double den2;
+ long channel1;
+ long lld;
+ long cch;
+ long cfac, cfac2, max_cfac;
+ long ihelp1, ihelp2;
+ long i;
+ long max_npeaks = 100;
+ long n_peaks = 0;
+ double peakstarted = 0;
+
+ peaks0 = malloc(100 * sizeof(double));
+ relevances0 = malloc(100 * sizeof(double));
+ if (peaks0 == NULL || relevances0 == NULL) {
+ printf("Error: failed to allocate memory for peaks array.");
+ return(-123456);
+ }
+ /* Make sure the peaks matrix is filled with zeros */
+ for (i=0;i<100;i++){
+ peaks0[i] = 0.0;
+ relevances0[i] = 0.0;
+ }
+ /* Output pointers */
+ *peaks = peaks0;
+ *relevances = relevances0;
+
+ /* prepare the calculation of the Gaussian scaling factors */
+
+ sigma = fwhm / 2.35482;
+ sigma2 = sigma * sigma;
+ sigma4 = sigma2 * sigma2;
+ lowthreshold = 0.01 / sigma2;
+
+ /* calculate the factors until lower threshold reached */
+ nr_factor = 0;
+ max_cfac = MIN(max_gfactor, ((end_index - begin_index - 2) / 2) - 1);
+ for (cfac=0; cfac < max_cfac; cfac++) {
+ nr_factor++;
+ cfac2 = (cfac+1) * (cfac+1);
+ gfactor[cfac] = (sigma2 - cfac2) * exp(-cfac2/(sigma2*2.0)) / sigma4;
+
+ if ((gfactor[cfac] < lowthreshold)
+ && (gfactor[cfac] > (-lowthreshold))){
+ break;
+ }
+ }
+
+ /* What comes now is specific to MCA spectra ... */
+ lld = 0;
+ while (data[lld] == 0) {
+ lld++;
+ }
+ lld = lld + (int) (0.5 * fwhm);
+
+ channel1 = begin_index - nr_factor - 1;
+ channel1 = MAX (channel1, lld);
+ if(debug_info){
+ printf("nrfactor = %ld\n", nr_factor);
+ }
+ /* calculates smoothed value and variance at begincalc */
+ cch = MAX(begin_index, 0);
+ nom = data[cch] / sigma2;
+ den2 = data[cch] / sigma4;
+ for (cfac = 0; cfac < nr_factor; cfac++){
+ ihelp1 = cch-cfac;
+ if (ihelp1 < 0){
+ ihelp1 = 0;
+ }
+ ihelp2 = cch+cfac;
+ if (ihelp2 >= nsamples){
+ ihelp2 = nsamples-1;
+ }
+ nom += gfactor[cfac] * (data[ihelp2] + data[ihelp1]);
+ den2 += gfactor[cfac] * gfactor[cfac] *
+ (data[ihelp2] + data[ihelp1]);
+ }
+
+ /* now normalize the smoothed value to the standard deviation */
+ if (den2 <= 0.0) {
+ data2[1] = 0.0;
+ }else{
+ data2[1] = nom / sqrt(den2);
+ }
+ data[0] = data[1];
+
+ while (cch <= MIN(end_index,nsamples-2)){
+ /* calculate gaussian smoothed values */
+ data2[0] = data2[1];
+ cch++;
+ nom = data[cch]/sigma2;
+ den2 = data[cch] / sigma4;
+ for (cfac = 1; cfac < nr_factor; cfac++){
+ ihelp1 = cch-cfac;
+ if (ihelp1 < 0){
+ ihelp1 = 0;
+ }
+ ihelp2 = cch+cfac;
+ if (ihelp2 >= nsamples){
+ ihelp2 = nsamples-1;
+ }
+ nom += gfactor[cfac-1] * (data[ihelp2] + data[ihelp1]);
+ den2 += gfactor[cfac-1] * gfactor[cfac-1] *
+ (data[ihelp2] + data[ihelp1]);
+ }
+ /* now normalize the smoothed value to the standard deviation */
+ if (den2 <= 0) {
+ data2[1] = 0;
+ }else{
+ data2[1] = nom / sqrt(den2);
+ }
+ /* look if the current point falls in a peak */
+ if (data2[1] > sensitivity) {
+ if(peakstarted == 0){
+ if (data2[1] > data2[0]){
+ /* this second test is to prevent a peak from outside
+ the region from being detected at the beginning of the search */
+ peakstarted=1;
+ }
+ }
+ /* there is a peak */
+ if (debug_info){
+ printf("At cch = %ld y[cch] = %g\n", cch, data[cch]);
+ printf("data2[0] = %g\n", data2[0]);
+ printf("data2[1] = %g\n", data2[1]);
+ printf("sensitivity = %g\n", sensitivity);
+ }
+ if(peakstarted == 1){
+ /* look for the top of the peak */
+ if (data2[1] < data2[0]) {
+ /* we are close to the top of the peak */
+ if (debug_info){
+ printf("we are close to the top of the peak\n");
+ }
+ if (n_peaks == max_npeaks) {
+ max_npeaks = max_npeaks + 100;
+ realloc_peaks = realloc(peaks0, max_npeaks * sizeof(double));
+ realloc_relevances = realloc(relevances0, max_npeaks * sizeof(double));
+ if (realloc_peaks == NULL || realloc_relevances == NULL) {
+ printf("Error: failed to extend memory for peaks array.");
+ *peaks = peaks0;
+ *relevances = relevances0;
+ return(-n_peaks);
+ }
+ else {
+ peaks0 = realloc_peaks;
+ relevances0 = realloc_relevances;
+ }
+ }
+ peaks0[n_peaks] = cch-1;
+ relevances0[n_peaks] = data2[0];
+ n_peaks++;
+ peakstarted=2;
+ }
+ }
+ /* Doublet case */
+ if(peakstarted == 2){
+ if ((cch-peaks0[n_peaks-1]) > 0.6 * fwhm) {
+ if (data2[1] > data2[0]){
+ if(debug_info){
+ printf("We may have a doublet\n");
+ }
+ peakstarted=1;
+ }
+ }
+ }
+ }else{
+ if (peakstarted==1){
+ /* We were on a peak but we did not find the top */
+ if(debug_info){
+ printf("We were on a peak but we did not find the top\n");
+ }
+ }
+ peakstarted=0;
+ }
+ }
+ if(debug_info){
+ for (i=0;i< n_peaks;i++){
+ printf("Peak %ld found at ",i+1);
+ printf("index %g with y = %g\n", peaks0[i],data[(long ) peaks0[i]]);
+ }
+ }
+ *peaks = peaks0;
+ *relevances = relevances0;
+ return (n_peaks);
+}
diff --git a/silx/math/fit/setup.py b/silx/math/fit/setup.py
new file mode 100644
index 0000000..f4e1f42
--- /dev/null
+++ b/silx/math/fit/setup.py
@@ -0,0 +1,89 @@
+# 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.
+#
+# ############################################################################*/
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "22/06/2016"
+
+import os.path
+
+import numpy
+
+from numpy.distutils.misc_util import Configuration
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('fit', parent_package, top_path)
+ config.add_subpackage('test')
+
+ # =====================================
+ # fit functions
+ # =====================================
+ fit_dir = 'functions'
+ fit_src = [os.path.join(fit_dir, "src", srcf)
+ for srcf in ["funs.c"]]
+ fit_src.append(os.path.join(fit_dir, "functions.pyx"))
+ fit_inc = [os.path.join(fit_dir, 'include'), numpy.get_include()]
+
+ config.add_extension('functions',
+ sources=fit_src,
+ include_dirs=fit_inc,
+ language='c')
+
+ # =====================================
+ # fit filters
+ # =====================================
+ fit_dir = 'filters'
+ fit_src = [os.path.join(fit_dir, "src", srcf)
+ for srcf in ["smoothnd.c", "snip1d.c",
+ "snip2d.c", "snip3d.c", "strip.c"]]
+ fit_src.append(os.path.join(fit_dir, "filters.pyx"))
+ fit_inc = [os.path.join(fit_dir, 'include'), numpy.get_include()]
+
+ config.add_extension('filters',
+ sources=fit_src,
+ include_dirs=fit_inc,
+ language='c')
+
+ # =====================================
+ # peaks
+ # =====================================
+ fit_dir = 'peaks'
+ fit_src = [os.path.join(fit_dir, "src", srcf)
+ for srcf in ["peaks.c"]]
+ fit_src.append(os.path.join(fit_dir, "peaks.pyx"))
+ fit_inc = [os.path.join(fit_dir, 'include'), numpy.get_include()]
+
+ config.add_extension('peaks',
+ sources=fit_src,
+ include_dirs=fit_inc,
+ language='c')
+ # =====================================
+ # =====================================
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/math/fit/test/__init__.py b/silx/math/fit/test/__init__.py
new file mode 100644
index 0000000..d3d8ce8
--- /dev/null
+++ b/silx/math/fit/test/__init__.py
@@ -0,0 +1,46 @@
+# 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.
+#
+# ############################################################################*/
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "22/06/2016"
+
+import unittest
+
+from .test_fit import suite as test_curve_fit
+from .test_functions import suite as test_fitfuns
+from .test_filters import suite as test_fitfilters
+from .test_peaks import suite as test_peaks
+from .test_fitmanager import suite as test_fitmanager
+from .test_bgtheories import suite as test_bgtheories
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(test_curve_fit())
+ test_suite.addTest(test_fitfuns())
+ test_suite.addTest(test_fitfilters())
+ test_suite.addTest(test_peaks())
+ test_suite.addTest(test_fitmanager())
+ test_suite.addTest(test_bgtheories())
+ return test_suite
diff --git a/silx/math/fit/test/test_bgtheories.py b/silx/math/fit/test/test_bgtheories.py
new file mode 100644
index 0000000..e9fea37
--- /dev/null
+++ b/silx/math/fit/test/test_bgtheories.py
@@ -0,0 +1,169 @@
+# 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.
+#
+# ############################################################################*/
+import copy
+import unittest
+import numpy
+import random
+
+from silx.math.fit import bgtheories
+from silx.math.fit.functions import sum_gauss
+
+
+class TestBgTheories(unittest.TestCase):
+ """
+ """
+ def setUp(self):
+ self.x = numpy.arange(100)
+ self.y = 10 + 0.05 * self.x + sum_gauss(self.x, 10., 45., 15.)
+ # add a very narrow high amplitude peak to test strip and snip
+ self.y += sum_gauss(self.x, 100., 75., 2.)
+ self.narrow_peak_index = list(self.x).index(75)
+ random.seed()
+
+ def tearDown(self):
+ pass
+
+ def testTheoriesAttrs(self):
+ for theory_name in bgtheories.THEORY:
+ self.assertIsInstance(theory_name, str)
+ self.assertTrue(hasattr(bgtheories.THEORY[theory_name],
+ "function"))
+ self.assertTrue(hasattr(bgtheories.THEORY[theory_name].function,
+ "__call__"))
+ # Ensure legacy functions are not renamed accidentally
+ self.assertTrue(
+ {"No Background", "Constant", "Linear", "Strip", "Snip"}.issubset(
+ set(bgtheories.THEORY)))
+
+ def testNoBg(self):
+ nobgfun = bgtheories.THEORY["No Background"].function
+ self.assertTrue(numpy.array_equal(nobgfun(self.x, self.y),
+ numpy.zeros_like(self.x)))
+ # default estimate
+ self.assertEqual(bgtheories.THEORY["No Background"].estimate(self.x, self.y),
+ ([], []))
+
+ def testConstant(self):
+ consfun = bgtheories.THEORY["Constant"].function
+ c = random.random() * 100
+ self.assertTrue(numpy.array_equal(consfun(self.x, self.y, c),
+ c * numpy.ones_like(self.x)))
+ # default estimate
+ esti_par, cons = bgtheories.THEORY["Constant"].estimate(self.x, self.y)
+ self.assertEqual(cons,
+ [[0, 0, 0]])
+ self.assertAlmostEqual(esti_par,
+ min(self.y))
+
+ def testLinear(self):
+ linfun = bgtheories.THEORY["Linear"].function
+ a = random.random() * 100
+ b = random.random() * 100
+ self.assertTrue(numpy.array_equal(linfun(self.x, self.y, a, b),
+ a + b * self.x))
+ # default estimate
+ esti_par, cons = bgtheories.THEORY["Linear"].estimate(self.x, self.y)
+
+ self.assertEqual(cons,
+ [[0, 0, 0], [0, 0, 0]])
+ self.assertAlmostEqual(esti_par[0], 10, places=3)
+ self.assertAlmostEqual(esti_par[1], 0.05, places=3)
+
+ def testStrip(self):
+ stripfun = bgtheories.THEORY["Strip"].function
+ anchors = sorted(random.sample(list(self.x), 4))
+ anchors_indices = [list(self.x).index(a) for a in anchors]
+
+ # we really want to strip away the narrow peak
+ anchors_indices_copy = copy.deepcopy(anchors_indices)
+ for idx in anchors_indices_copy:
+ if abs(idx - self.narrow_peak_index) < 5:
+ anchors_indices.remove(idx)
+ anchors.remove(self.x[idx])
+
+ width = 2
+ niter = 1000
+ bgtheories.THEORY["Strip"].configure(AnchorsList=anchors, AnchorsFlag=True)
+
+ bg = stripfun(self.x, self.y, width, niter)
+
+ # assert peak amplitude has been decreased
+ self.assertLess(bg[self.narrow_peak_index],
+ self.y[self.narrow_peak_index])
+
+ # default estimate
+ for i in anchors_indices:
+ self.assertEqual(bg[i], self.y[i])
+
+ # estimated parameters are equal to the default ones in the config dict
+ bgtheories.THEORY["Strip"].configure(StripWidth=7, StripIterations=8)
+ esti_par, cons = bgtheories.THEORY["Strip"].estimate(self.x, self.y)
+ self.assertTrue(numpy.array_equal(cons, [[3, 0, 0], [3, 0, 0]]))
+ self.assertEqual(esti_par, [7, 8])
+
+ def testSnip(self):
+ snipfun = bgtheories.THEORY["Snip"].function
+ anchors = sorted(random.sample(list(self.x), 4))
+ anchors_indices = [list(self.x).index(a) for a in anchors]
+
+ # we want to strip away the narrow peak, so remove nearby anchors
+ anchors_indices_copy = copy.deepcopy(anchors_indices)
+ for idx in anchors_indices_copy:
+ if abs(idx - self.narrow_peak_index) < 5:
+ anchors_indices.remove(idx)
+ anchors.remove(self.x[idx])
+
+ width = 16
+ bgtheories.THEORY["Snip"].configure(AnchorsList=anchors, AnchorsFlag=True)
+ bg = snipfun(self.x, self.y, width)
+
+ # assert peak amplitude has been decreased
+ self.assertLess(bg[self.narrow_peak_index],
+ self.y[self.narrow_peak_index],
+ "Snip didn't decrease the peak amplitude.")
+
+ # anchored data must remain fixed
+ for i in anchors_indices:
+ self.assertEqual(bg[i], self.y[i])
+
+ # estimated parameters are equal to the default ones in the config dict
+ bgtheories.THEORY["Snip"].configure(SnipWidth=7)
+ esti_par, cons = bgtheories.THEORY["Snip"].estimate(self.x, self.y)
+ self.assertTrue(numpy.array_equal(cons, [[3, 0, 0]]))
+ self.assertEqual(esti_par, [7])
+
+
+test_cases = (TestBgTheories,)
+
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/fit/test/test_filters.py b/silx/math/fit/test/test_filters.py
new file mode 100644
index 0000000..078b998
--- /dev/null
+++ b/silx/math/fit/test/test_filters.py
@@ -0,0 +1,137 @@
+# 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.
+#
+# ############################################################################*/
+import numpy
+import unittest
+from silx.math.fit import filters
+from silx.math.fit import functions
+from silx.test.utils import add_relative_noise
+
+
+class TestSmooth(unittest.TestCase):
+ """
+ Unit tests of smoothing functions.
+
+ Test that the difference between a synthetic curve with 5% added random
+ noise and the result of smoothing that signal is less than 5%. We compare
+ the sum of all samples in each curve.
+ """
+ def setUp(self):
+ x = numpy.arange(5000)
+ # (height1, center1, fwhm1, beamfwhm...)
+ slit_params = (50, 500, 200, 100,
+ 50, 600, 80, 30,
+ 20, 2000, 150, 150,
+ 50, 2250, 110, 100,
+ 40, 3000, 50, 10,
+ 23, 4980, 250, 20)
+
+ self.y1 = functions.sum_slit(x, *slit_params)
+ # 5% noise
+ self.y1 = add_relative_noise(self.y1, 5.)
+
+ # (height1, center1, fwhm1...)
+ step_params = (50, 500, 200,
+ 50, 600, 80,
+ 20, 2000, 150,
+ 50, 2250, 110,
+ 40, 3000, 50,
+ 23, 4980, 250,)
+
+ self.y2 = functions.sum_stepup(x, *step_params)
+ # 5% noise
+ self.y2 = add_relative_noise(self.y2, 5.)
+
+ self.y3 = functions.sum_stepdown(x, *step_params)
+ # 5% noise
+ self.y3 = add_relative_noise(self.y3, 5.)
+
+ def tearDown(self):
+ pass
+
+ def testSavitskyGolay(self):
+ npts = 25
+ for y in [self.y1, self.y2, self.y3]:
+ smoothed_y = filters.savitsky_golay(y, npoints=npts)
+
+ # we added +-5% of random noise. The difference must be much lower
+ # than 5%.
+ diff = abs(sum(smoothed_y) - sum(y)) / sum(y)
+ self.assertLess(diff, 0.05,
+ "Difference between data with 5%% noise and " +
+ "smoothed data is > 5%% (%f %%)" % (diff * 100))
+
+ # Try various smoothing levels
+ npts += 25
+
+ def testSmooth1d(self):
+ """Test the 1D smoothing against the formula
+ ys[i] = (y[i-1] + 2 * y[i] + y[i+1]) / 4 (for 1 < i < n-1)"""
+ smoothed_y = filters.smooth1d(self.y1)
+
+ for i in range(1, len(self.y1) - 1):
+ self.assertAlmostEqual(4 * smoothed_y[i],
+ self.y1[i-1] + 2 * self.y1[i] + self.y1[i+1])
+
+ def testSmooth2d(self):
+ """Test that a 2D smoothing is the same as two successive and
+ orthogonal 1D smoothings"""
+ x = numpy.arange(10000)
+
+ noise = 2 * numpy.random.random(10000) - 1
+ noise *= 0.05
+ y = x * (1 + noise)
+
+ y.shape = (100, 100)
+
+ smoothed_y = filters.smooth2d(y)
+
+ intermediate_smooth = numpy.zeros_like(y)
+ expected_smooth = numpy.zeros_like(y)
+ # smooth along first dimension
+ for i in range(0, y.shape[0]):
+ intermediate_smooth[i, :] = filters.smooth1d(y[i, :])
+
+ # smooth along second dimension
+ for j in range(0, y.shape[1]):
+ expected_smooth[:, j] = filters.smooth1d(intermediate_smooth[:, j])
+
+ for i in range(0, y.shape[0]):
+ for j in range(0, y.shape[1]):
+ self.assertAlmostEqual(smoothed_y[i, j],
+ expected_smooth[i, j])
+
+
+test_cases = (TestSmooth,)
+
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/fit/test/test_fit.py b/silx/math/fit/test/test_fit.py
new file mode 100644
index 0000000..4d159c0
--- /dev/null
+++ b/silx/math/fit/test/test_fit.py
@@ -0,0 +1,382 @@
+# 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.
+#
+# ############################################################################*/
+"""
+Nominal tests of the leastsq function.
+"""
+
+import unittest
+
+import numpy
+import sys
+
+
+class Test_leastsq(unittest.TestCase):
+ """
+ Unit tests of the leastsq function.
+ """
+
+ ndims = None
+
+ def setUp(self):
+ try:
+ from silx.math.fit import leastsq
+ self.instance = leastsq
+ except ImportError:
+ self.instance = None
+
+ def myexp(x):
+ # put a (bad) filter to avoid over/underflows
+ # with no python looping
+ return numpy.exp(x*numpy.less(abs(x), 250)) - \
+ 1.0 * numpy.greater_equal(abs(x), 250)
+
+ self.my_exp = myexp
+
+ def gauss(x, *params):
+ params = numpy.array(params, copy=False, dtype=numpy.float)
+ result = params[0] + params[1] * x
+ for i in range(2, len(params), 3):
+ p = params[i:(i+3)]
+ dummy = 2.3548200450309493*(x - p[1])/p[2]
+ result += p[0] * self.my_exp(-0.5 * dummy * dummy)
+ return result
+
+ self.gauss = gauss
+
+ def gauss_derivative(x, params, idx):
+ if idx == 0:
+ return numpy.ones(len(x), numpy.float)
+ if idx == 1:
+ return x
+ gaussian_peak = (idx - 2) // 3
+ gaussian_parameter = (idx - 2) % 3
+ actual_idx = 2 + 3 * gaussian_peak
+ p = params[actual_idx:(actual_idx+3)]
+ if gaussian_parameter == 0:
+ return self.gauss(x, *[0, 0, 1.0, p[1], p[2]])
+ if gaussian_parameter == 1:
+ tmp = self.gauss(x, *[0, 0, p[0], p[1], p[2]])
+ tmp *= 2.3548200450309493*(x - p[1])/p[2]
+ return tmp * 2.3548200450309493/p[2]
+ if gaussian_parameter == 2:
+ tmp = self.gauss(x, *[0, 0, p[0], p[1], p[2]])
+ tmp *= 2.3548200450309493*(x - p[1])/p[2]
+ return tmp * 2.3548200450309493*(x - p[1])/(p[2]*p[2])
+
+ self.gauss_derivative = gauss_derivative
+
+ def tearDown(self):
+ self.instance = None
+ self.gauss = None
+ self.gauss_derivative = None
+ self.my_exp = None
+ self.model_function = None
+ self.model_derivative = None
+
+ def testImport(self):
+ self.assertTrue(self.instance is not None,
+ "Cannot import leastsq from silx.math.fit")
+
+ def testUnconstrainedFitNoWeight(self):
+ parameters_actual = [10.5, 2, 1000.0, 20., 15]
+ x = numpy.arange(10000.)
+ y = self.gauss(x, *parameters_actual)
+ parameters_estimate = [0.0, 1.0, 900.0, 25., 10]
+ model_function = self.gauss
+
+ fittedpar, cov = self.instance(model_function, x, y, parameters_estimate)
+ test_condition = numpy.allclose(parameters_actual, fittedpar)
+ if not test_condition:
+ msg = "Unsuccessfull fit\n"
+ for i in range(len(fittedpar)):
+ msg += "Expected %g obtained %g\n" % (parameters_actual[i],
+ fittedpar[i])
+ self.assertTrue(test_condition, msg)
+
+ def testUnconstrainedFitWeight(self):
+ parameters_actual = [10.5,2,1000.0,20.,15]
+ x = numpy.arange(10000.)
+ y = self.gauss(x, *parameters_actual)
+ sigma = numpy.sqrt(y)
+ parameters_estimate = [0.0, 1.0, 900.0, 25., 10]
+ model_function = self.gauss
+
+ fittedpar, cov = self.instance(model_function, x, y,
+ parameters_estimate,
+ sigma=sigma)
+ test_condition = numpy.allclose(parameters_actual, fittedpar)
+ if not test_condition:
+ msg = "Unsuccessfull fit\n"
+ for i in range(len(fittedpar)):
+ msg += "Expected %g obtained %g\n" % (parameters_actual[i],
+ fittedpar[i])
+ self.assertTrue(test_condition, msg)
+
+ def testDerivativeFunction(self):
+ parameters_actual = [10.5, 2, 10000.0, 20., 150, 5000, 900., 300]
+ x = numpy.arange(10000.)
+ y = self.gauss(x, *parameters_actual)
+ delta = numpy.sqrt(numpy.finfo(numpy.float).eps)
+ for i in range(len(parameters_actual)):
+ p = parameters_actual * 1
+ if p[i] == 0:
+ delta_par = delta
+ else:
+ delta_par = p[i] * delta
+ if i > 2:
+ p[0] = 0.0
+ p[1] = 0.0
+ p[i] += delta_par
+ yPlus = self.gauss(x, *p)
+ p[i] = parameters_actual[i] - delta_par
+ yMinus = self.gauss(x, *p)
+ numerical_derivative = (yPlus - yMinus) / (2 * delta_par)
+ #numerical_derivative = (self.gauss(x, *p) - y) / delta_par
+ p[i] = parameters_actual[i]
+ derivative = self.gauss_derivative(x, p, i)
+ diff = numerical_derivative - derivative
+ test_condition = numpy.allclose(numerical_derivative,
+ derivative, atol=5.0e-6)
+ if not test_condition:
+ msg = "Error calculating derivative of parameter %d." % i
+ msg += "\n diff min = %g diff max = %g" % (diff.min(), diff.max())
+ self.assertTrue(test_condition, msg)
+
+ def testConstrainedFit(self):
+ CFREE = 0
+ CPOSITIVE = 1
+ CQUOTED = 2
+ CFIXED = 3
+ CFACTOR = 4
+ CDELTA = 5
+ CSUM = 6
+ parameters_actual = [10.5, 2, 10000.0, 20., 150, 5000, 900., 300]
+ x = numpy.arange(10000.)
+ y = self.gauss(x, *parameters_actual)
+ parameters_estimate = [0.0, 1.0, 900.0, 25., 10, 400, 850, 200]
+ model_function = self.gauss
+ model_deriv = self.gauss_derivative
+ constraints_all_free = [[0, 0, 0]] * len(parameters_actual)
+ constraints_all_positive = [[1, 0, 0]] * len(parameters_actual)
+ constraints_delta_position = [[0, 0, 0]] * len(parameters_actual)
+ constraints_delta_position[6] = [CDELTA, 3, 880]
+ constraints_sum_position = constraints_all_positive * 1
+ constraints_sum_position[6] = [CSUM, 3, 920]
+ constraints_factor = constraints_delta_position * 1
+ constraints_factor[2] = [CFACTOR, 5, 2]
+ constraints_list = [None,
+ constraints_all_free,
+ constraints_all_positive,
+ constraints_delta_position,
+ constraints_sum_position]
+
+ # for better code coverage, the warning recommending to set full_output
+ # to True when using constraints should be shown at least once
+ full_output = True
+ for index, constraints in enumerate(constraints_list):
+ if index == 2:
+ full_output = None
+ elif index == 3:
+ full_output = 0
+ for model_deriv in [None, self.gauss_derivative]:
+ for sigma in [None, numpy.sqrt(y)]:
+ fittedpar, cov = self.instance(model_function, x, y,
+ parameters_estimate,
+ sigma=sigma,
+ constraints=constraints,
+ model_deriv=model_deriv,
+ full_output=full_output)[:2]
+ full_output = True
+
+ test_condition = numpy.allclose(parameters_actual, fittedpar)
+ if not test_condition:
+ msg = "Unsuccessfull fit\n"
+ for i in range(len(fittedpar)):
+ msg += "Expected %g obtained %g\n" % (parameters_actual[i],
+ fittedpar[i])
+ self.assertTrue(test_condition, msg)
+
+ def testUnconstrainedFitAnalyticalDerivative(self):
+ parameters_actual = [10.5, 2, 1000.0, 20., 15]
+ x = numpy.arange(10000.)
+ y = self.gauss(x, *parameters_actual)
+ sigma = numpy.sqrt(y)
+ parameters_estimate = [0.0, 1.0, 900.0, 25., 10]
+ model_function = self.gauss
+ model_deriv = self.gauss_derivative
+
+ fittedpar, cov = self.instance(model_function, x, y,
+ parameters_estimate,
+ sigma=sigma,
+ model_deriv=model_deriv)
+ test_condition = numpy.allclose(parameters_actual, fittedpar)
+ if not test_condition:
+ msg = "Unsuccessfull fit\n"
+ for i in range(len(fittedpar)):
+ msg += "Expected %g obtained %g\n" % (parameters_actual[i],
+ fittedpar[i])
+ self.assertTrue(test_condition, msg)
+
+ def testBadlyShapedData(self):
+ parameters_actual = [10.5, 2, 1000.0, 20., 15]
+ x = numpy.arange(10000.).reshape(1000, 10)
+ y = self.gauss(x, *parameters_actual)
+ sigma = numpy.sqrt(y)
+ parameters_estimate = [0.0, 1.0, 900.0, 25., 10]
+ model_function = self.gauss
+
+ for check_finite in [True, False]:
+ fittedpar, cov = self.instance(model_function, x, y,
+ parameters_estimate,
+ sigma=sigma,
+ check_finite=check_finite)
+ test_condition = numpy.allclose(parameters_actual, fittedpar)
+ if not test_condition:
+ msg = "Unsuccessfull fit\n"
+ for i in range(len(fittedpar)):
+ msg += "Expected %g obtained %g\n" % (parameters_actual[i],
+ fittedpar[i])
+ self.assertTrue(test_condition, msg)
+
+ def testDataWithNaN(self):
+ parameters_actual = [10.5, 2, 1000.0, 20., 15]
+ x = numpy.arange(10000.).reshape(1000, 10)
+ y = self.gauss(x, *parameters_actual)
+ sigma = numpy.sqrt(y)
+ parameters_estimate = [0.0, 1.0, 900.0, 25., 10]
+ model_function = self.gauss
+ x[500] = numpy.inf
+ # check default behavior
+ try:
+ self.instance(model_function, x, y,
+ parameters_estimate,
+ sigma=sigma)
+ except ValueError:
+ info = "%s" % sys.exc_info()[1]
+ self.assertTrue("array must not contain inf" in info)
+
+ # check requested behavior
+ try:
+ self.instance(model_function, x, y,
+ parameters_estimate,
+ sigma=sigma,
+ check_finite=True)
+ except ValueError:
+ info = "%s" % sys.exc_info()[1]
+ self.assertTrue("array must not contain inf" in info)
+
+ fittedpar, cov = self.instance(model_function, x, y,
+ parameters_estimate,
+ sigma=sigma,
+ check_finite=False)
+ test_condition = numpy.allclose(parameters_actual, fittedpar)
+ if not test_condition:
+ msg = "Unsuccessfull fit\n"
+ for i in range(len(fittedpar)):
+ msg += "Expected %g obtained %g\n" % (parameters_actual[i],
+ fittedpar[i])
+ self.assertTrue(test_condition, msg)
+
+ # testing now with ydata containing NaN
+ x = numpy.arange(10000.).reshape(1000, 10)
+ y[500] = numpy.nan
+ fittedpar, cov = self.instance(model_function, x, y,
+ parameters_estimate,
+ sigma=sigma,
+ check_finite=False)
+
+ test_condition = numpy.allclose(parameters_actual, fittedpar)
+ if not test_condition:
+ msg = "Unsuccessfull fit\n"
+ for i in range(len(fittedpar)):
+ msg += "Expected %g obtained %g\n" % (parameters_actual[i],
+ fittedpar[i])
+ self.assertTrue(test_condition, msg)
+
+ # testing now with sigma containing NaN
+ sigma[300] = numpy.nan
+ fittedpar, cov = self.instance(model_function, x, y,
+ parameters_estimate,
+ sigma=sigma,
+ check_finite=False)
+ test_condition = numpy.allclose(parameters_actual, fittedpar)
+ if not test_condition:
+ msg = "Unsuccessfull fit\n"
+ for i in range(len(fittedpar)):
+ msg += "Expected %g obtained %g\n" % (parameters_actual[i],
+ fittedpar[i])
+ self.assertTrue(test_condition, msg)
+
+ def testUncertainties(self):
+ """Test for validity of uncertainties in returned full-output
+ dictionary. This is a non-regression test for pull request #197"""
+ parameters_actual = [10.5, 2, 1000.0, 20., 15, 2001.0, 30.1, 16]
+ x = numpy.arange(10000.)
+ y = self.gauss(x, *parameters_actual)
+ parameters_estimate = [0.0, 1.0, 900.0, 25., 10., 1500., 20., 2.0]
+
+ # test that uncertainties are not 0.
+ fittedpar, cov, infodict = self.instance(self.gauss, x, y, parameters_estimate,
+ full_output=True)
+ uncertainties = infodict["uncertainties"]
+ self.assertEqual(len(uncertainties), len(parameters_actual))
+ self.assertEqual(len(uncertainties), len(fittedpar))
+ for uncertainty in uncertainties:
+ self.assertNotAlmostEqual(uncertainty, 0.)
+
+ # set constraint FIXED for half the parameters.
+ # This should cause leastsq to return 100% uncertainty.
+ parameters_estimate = [10.6, 2.1, 1000.1, 20.1, 15.1, 2001.1, 30.2, 16.1]
+ CFIXED = 3
+ CFREE = 0
+ constraints = []
+ for i in range(len(parameters_estimate)):
+ if i % 2:
+ constraints.append([CFIXED, 0, 0])
+ else:
+ constraints.append([CFREE, 0, 0])
+ fittedpar, cov, infodict = self.instance(self.gauss, x, y, parameters_estimate,
+ constraints=constraints,
+ full_output=True)
+ uncertainties = infodict["uncertainties"]
+ for i in range(len(parameters_estimate)):
+ if i % 2:
+ # test that all FIXED parameters have 100% uncertainty
+ self.assertAlmostEqual(uncertainties[i],
+ parameters_estimate[i])
+
+
+test_cases = (Test_leastsq,)
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/fit/test/test_fitmanager.py b/silx/math/fit/test/test_fitmanager.py
new file mode 100644
index 0000000..38c4802
--- /dev/null
+++ b/silx/math/fit/test/test_fitmanager.py
@@ -0,0 +1,498 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""
+Tests for fitmanager module
+"""
+
+import unittest
+import numpy
+import os.path
+
+from silx.math.fit import fitmanager
+from silx.math.fit import fittheories
+from silx.math.fit import bgtheories
+from silx.math.fit.fittheory import FitTheory
+from silx.math.fit.functions import sum_gauss, sum_stepdown, sum_stepup
+
+from silx.test.utils import temp_dir
+
+custom_function_definition = """
+import copy
+from silx.math.fit.fittheory import FitTheory
+
+CONFIG = {'d': 1.}
+
+def myfun(x, a, b, c):
+ "Model function"
+ return (a * x**2 + b * x + c) / CONFIG['d']
+
+def myesti(x, y):
+ "Initial parameters for iterative fit (a, b, c) = (1, 1, 1)"
+ return (1., 1., 1.), ((0, 0, 0), (0, 0, 0), (0, 0, 0))
+
+def myconfig(d=1., **kw):
+ "This function can modify CONFIG"
+ CONFIG["d"] = d
+ return CONFIG
+
+def myderiv(x, parameters, index):
+ "Custom derivative (does not work, causes singular matrix)"
+ pars_plus = copy.copy(parameters)
+ pars_plus[index] *= 1.0001
+
+ pars_minus = parameters
+ pars_minus[index] *= copy.copy(0.9999)
+
+ delta_fun = myfun(x, *pars_plus) - myfun(x, *pars_minus)
+ delta_par = parameters[index] * 0.0001 * 2
+
+ return delta_fun / delta_par
+
+THEORY = {
+ 'my fit theory':
+ FitTheory(function=myfun,
+ parameters=('A', 'B', 'C'),
+ estimate=myesti,
+ configure=myconfig,
+ derivative=myderiv)
+}
+
+"""
+
+old_custom_function_definition = """
+CONFIG = {'d': 1.0}
+
+def myfun(x, a, b, c):
+ "Model function"
+ return (a * x**2 + b * x + c) / CONFIG['d']
+
+def myesti(x, y, bg, xscalinq, yscaling):
+ "Initial parameters for iterative fit (a, b, c) = (1, 1, 1)"
+ return (1., 1., 1.), ((0, 0, 0), (0, 0, 0), (0, 0, 0))
+
+def myconfig(**kw):
+ "Update or complete CONFIG dictionary"
+ for key in kw:
+ CONFIG[key] = kw[key]
+ return CONFIG
+
+THEORY = ['my fit theory']
+PARAMETERS = [('A', 'B', 'C')]
+FUNCTION = [myfun]
+ESTIMATE = [myesti]
+CONFIGURE = [myconfig]
+
+"""
+
+
+def _order_of_magnitude(x):
+ return numpy.log10(x).round()
+
+
+class TestFitmanager(unittest.TestCase):
+ """
+ Unit tests of multi-peak functions.
+ """
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def testFitManager(self):
+ """Test fit manager on synthetic data using a gaussian function
+ and a linear background"""
+ # Create synthetic data with a sum of gaussian functions
+ x = numpy.arange(1000).astype(numpy.float)
+
+ p = [1000, 100., 250,
+ 255, 650., 45,
+ 1500, 800.5, 95]
+ linear_bg = 2.65 * x + 13
+ y = linear_bg + sum_gauss(x, *p)
+
+ # Fitting
+ fit = fitmanager.FitManager()
+ fit.setdata(x=x, y=y)
+ fit.loadtheories(fittheories)
+ # Use one of the default fit functions
+ fit.settheory('Gaussians')
+ fit.setbackground('Linear')
+ fit.estimate()
+ fit.runfit()
+
+ # fit.fit_results[]
+
+ # first 2 parameters are related to the linear background
+ self.assertEqual(fit.fit_results[0]["name"], "Constant")
+ self.assertAlmostEqual(fit.fit_results[0]["fitresult"], 13)
+ self.assertEqual(fit.fit_results[1]["name"], "Slope")
+ self.assertAlmostEqual(fit.fit_results[1]["fitresult"], 2.65)
+
+ for i, param in enumerate(fit.fit_results[2:]):
+ param_number = i // 3 + 1
+ if i % 3 == 0:
+ self.assertEqual(param["name"],
+ "Height%d" % param_number)
+ elif i % 3 == 1:
+ self.assertEqual(param["name"],
+ "Position%d" % param_number)
+ elif i % 3 == 2:
+ self.assertEqual(param["name"],
+ "FWHM%d" % param_number)
+
+ self.assertAlmostEqual(param["fitresult"],
+ p[i])
+ self.assertAlmostEqual(_order_of_magnitude(param["estimation"]),
+ _order_of_magnitude(p[i]))
+
+ def testLoadCustomFitFunction(self):
+ """Test FitManager using a custom fit function defined in an external
+ file and imported with FitManager.loadtheories"""
+ # Create synthetic data with a sum of gaussian functions
+ x = numpy.arange(100).astype(numpy.float)
+
+ # a, b, c are the fit parameters
+ # d is a known scaling parameter that is set using configure()
+ a, b, c, d = 1.5, 2.5, 3.5, 4.5
+ y = (a * x**2 + b * x + c) / d
+
+ # Fitting
+ fit = fitmanager.FitManager()
+ fit.setdata(x=x, y=y)
+
+ # Create a temporary function definition file, and import it
+ with temp_dir() as tmpDir:
+ tmpfile = os.path.join(tmpDir, 'customfun.py')
+ # custom_function_definition
+ fd = open(tmpfile, "w")
+ fd.write(custom_function_definition)
+ fd.close()
+ fit.loadtheories(tmpfile)
+ tmpfile_pyc = os.path.join(tmpDir, 'customfun.pyc')
+ if os.path.exists(tmpfile_pyc):
+ os.unlink(tmpfile_pyc)
+ os.unlink(tmpfile)
+
+ fit.settheory('my fit theory')
+ # Test configure
+ fit.configure(d=4.5)
+ fit.estimate()
+ fit.runfit()
+
+ self.assertEqual(fit.fit_results[0]["name"],
+ "A1")
+ self.assertAlmostEqual(fit.fit_results[0]["fitresult"],
+ 1.5)
+ self.assertEqual(fit.fit_results[1]["name"],
+ "B1")
+ self.assertAlmostEqual(fit.fit_results[1]["fitresult"],
+ 2.5)
+ self.assertEqual(fit.fit_results[2]["name"],
+ "C1")
+ self.assertAlmostEqual(fit.fit_results[2]["fitresult"],
+ 3.5)
+
+ def testLoadOldCustomFitFunction(self):
+ """Test FitManager using a custom fit function defined in an external
+ file and imported with FitManager.loadtheories (legacy PyMca format)"""
+ # Create synthetic data with a sum of gaussian functions
+ x = numpy.arange(100).astype(numpy.float)
+
+ # a, b, c are the fit parameters
+ # d is a known scaling parameter that is set using configure()
+ a, b, c, d = 1.5, 2.5, 3.5, 4.5
+ y = (a * x**2 + b * x + c) / d
+
+ # Fitting
+ fit = fitmanager.FitManager()
+ fit.setdata(x=x, y=y)
+
+ # Create a temporary function definition file, and import it
+ with temp_dir() as tmpDir:
+ tmpfile = os.path.join(tmpDir, 'oldcustomfun.py')
+ # custom_function_definition
+ fd = open(tmpfile, "w")
+ fd.write(old_custom_function_definition)
+ fd.close()
+ fit.loadtheories(tmpfile)
+ tmpfile_pyc = os.path.join(tmpDir, 'oldcustomfun.pyc')
+ if os.path.exists(tmpfile_pyc):
+ os.unlink(tmpfile_pyc)
+ os.unlink(tmpfile)
+
+ fit.settheory('my fit theory')
+ fit.configure(d=4.5)
+ fit.estimate()
+ fit.runfit()
+
+ self.assertEqual(fit.fit_results[0]["name"],
+ "A1")
+ self.assertAlmostEqual(fit.fit_results[0]["fitresult"],
+ 1.5)
+ self.assertEqual(fit.fit_results[1]["name"],
+ "B1")
+ self.assertAlmostEqual(fit.fit_results[1]["fitresult"],
+ 2.5)
+ self.assertEqual(fit.fit_results[2]["name"],
+ "C1")
+ self.assertAlmostEqual(fit.fit_results[2]["fitresult"],
+ 3.5)
+
+ def testAddTheory(self, estimate=True):
+ """Test FitManager using a custom fit function imported with
+ FitManager.addtheory"""
+ # Create synthetic data with a sum of gaussian functions
+ x = numpy.arange(100).astype(numpy.float)
+
+ # a, b, c are the fit parameters
+ # d is a known scaling parameter that is set using configure()
+ a, b, c, d = -3.14, 1234.5, 10000, 4.5
+ y = (a * x**2 + b * x + c) / d
+
+ # Fitting
+ fit = fitmanager.FitManager()
+ fit.setdata(x=x, y=y)
+
+ # Define and add the fit theory
+ CONFIG = {'d': 1.}
+
+ def myfun(x_, a_, b_, c_):
+ """"Model function"""
+ return (a_ * x_**2 + b_ * x_ + c_) / CONFIG['d']
+
+ def myesti(x_, y_):
+ """"Initial parameters for iterative fit:
+ (a, b, c) = (1, 1, 1)
+ Constraints all set to 0 (FREE)"""
+ return (1., 1., 1.), ((0, 0, 0), (0, 0, 0), (0, 0, 0))
+
+ def myconfig(d_=1., **kw):
+ """This function can modify CONFIG"""
+ CONFIG["d"] = d_
+ return CONFIG
+
+ def myderiv(x_, parameters, index):
+ """Custom derivative"""
+ pars_plus = numpy.array(parameters, copy=True)
+ pars_plus[index] *= 1.001
+
+ pars_minus = numpy.array(parameters, copy=True)
+ pars_minus[index] *= 0.999
+
+ delta_fun = myfun(x_, *pars_plus) - myfun(x_, *pars_minus)
+ delta_par = parameters[index] * 0.001 * 2
+
+ return delta_fun / delta_par
+
+ fit.addtheory("polynomial",
+ FitTheory(function=myfun,
+ parameters=["A", "B", "C"],
+ estimate=myesti if estimate else None,
+ configure=myconfig,
+ derivative=myderiv))
+
+ fit.settheory('polynomial')
+ fit.configure(d_=4.5)
+ fit.estimate()
+ params1, sigmas, infodict = fit.runfit()
+
+ self.assertEqual(fit.fit_results[0]["name"],
+ "A1")
+ self.assertAlmostEqual(fit.fit_results[0]["fitresult"],
+ -3.14)
+ self.assertEqual(fit.fit_results[1]["name"],
+ "B1")
+ # params1[1] is the same as fit.fit_results[1]["fitresult"]
+ self.assertAlmostEqual(params1[1],
+ 1234.5)
+ self.assertEqual(fit.fit_results[2]["name"],
+ "C1")
+ self.assertAlmostEqual(params1[2],
+ 10000)
+
+ # change configuration scaling factor and check that the fit returns
+ # different values
+ fit.configure(d_=5.)
+ fit.estimate()
+ params2, sigmas, infodict = fit.runfit()
+ for p1, p2 in zip(params1, params2):
+ self.assertFalse(numpy.array_equal(p1, p2),
+ "Fit parameters are equal even though the " +
+ "configuration has been changed")
+
+ def testNoEstimate(self):
+ """Ensure that the in the absence of the estimation function,
+ the default estimation function :meth:`FitTheory.default_estimate`
+ is used."""
+ self.testAddTheory(estimate=False)
+
+ def testStep(self):
+ """Test fit manager on a step function with a more complex estimate
+ function than the gaussian (convolution filter)"""
+ for theory_name, theory_fun in (('Step Down', sum_stepdown),
+ ('Step Up', sum_stepup)):
+ # Create synthetic data with a sum of gaussian functions
+ x = numpy.arange(1000).astype(numpy.float)
+
+ # ('Height', 'Position', 'FWHM')
+ p = [1000, 439, 250]
+
+ constantbg = 13
+ y = theory_fun(x, *p) + constantbg
+
+ # Fitting
+ fit = fitmanager.FitManager()
+ fit.setdata(x=x, y=y)
+ fit.loadtheories(fittheories)
+ fit.settheory(theory_name)
+ fit.setbackground('Constant')
+
+ fit.estimate()
+
+ params, sigmas, infodict = fit.runfit()
+
+ # first parameter is the constant background
+ self.assertAlmostEqual(params[0], 13, places=5)
+ for i, param in enumerate(params[1:]):
+ self.assertAlmostEqual(param, p[i], places=5)
+ self.assertAlmostEqual(_order_of_magnitude(fit.fit_results[i+1]["estimation"]),
+ _order_of_magnitude(p[i]))
+
+
+def quadratic(x, a, b, c):
+ return a * x**2 + b * x + c
+
+
+def cubic(x, a, b, c, d):
+ return a * x**3 + b * x**2 + c * x + d
+
+
+class TestPolynomials(unittest.TestCase):
+ """Test polynomial fit theories and fit background"""
+ def setUp(self):
+ self.x = numpy.arange(100).astype(numpy.float)
+
+ def testQuadraticBg(self):
+ gaussian_params = [100, 45, 8]
+ poly_params = [0.05, -2, 3]
+ p = numpy.poly1d(poly_params)
+
+ y = p(self.x) + sum_gauss(self.x, *gaussian_params)
+
+ fm = fitmanager.FitManager(self.x, y)
+ fm.loadbgtheories(bgtheories)
+ fm.loadtheories(fittheories)
+ fm.settheory("Gaussians")
+ fm.setbackground("Degree 2 Polynomial")
+ esti_params = fm.estimate()
+ fit_params = fm.runfit()[0]
+
+ for p, pfit in zip(poly_params + gaussian_params, fit_params):
+ self.assertAlmostEqual(p,
+ pfit)
+
+ def testCubicBg(self):
+ gaussian_params = [1000, 45, 8]
+ poly_params = [0.0005, -0.05, 3, -4]
+ p = numpy.poly1d(poly_params)
+
+ y = p(self.x) + sum_gauss(self.x, *gaussian_params)
+
+ fm = fitmanager.FitManager(self.x, y)
+ fm.loadtheories(fittheories)
+ fm.settheory("Gaussians")
+ fm.setbackground("Degree 3 Polynomial")
+ esti_params = fm.estimate()
+ fit_params = fm.runfit()[0]
+
+ for p, pfit in zip(poly_params + gaussian_params, fit_params):
+ self.assertAlmostEqual(p,
+ pfit)
+
+ def testQuarticcBg(self):
+ gaussian_params = [10000, 69, 25]
+ poly_params = [5e-10, 0.0005, 0.005, 2, 4]
+ p = numpy.poly1d(poly_params)
+
+ y = p(self.x) + sum_gauss(self.x, *gaussian_params)
+
+ fm = fitmanager.FitManager(self.x, y)
+ fm.loadtheories(fittheories)
+ fm.settheory("Gaussians")
+ fm.setbackground("Degree 4 Polynomial")
+ esti_params = fm.estimate()
+ fit_params = fm.runfit()[0]
+
+ for p, pfit in zip(poly_params + gaussian_params, fit_params):
+ self.assertAlmostEqual(p,
+ pfit,
+ places=5)
+
+ def _testPoly(self, poly_params, theory, places=5):
+ p = numpy.poly1d(poly_params)
+
+ y = p(self.x)
+
+ fm = fitmanager.FitManager(self.x, y)
+ fm.loadbgtheories(bgtheories)
+ fm.loadtheories(fittheories)
+ fm.settheory(theory)
+ esti_params = fm.estimate()
+ fit_params = fm.runfit()[0]
+
+ for p, pfit in zip(poly_params, fit_params):
+ self.assertAlmostEqual(p, pfit, places=places)
+
+ def testQuadratic(self):
+ self._testPoly([0.05, -2, 3],
+ "Degree 2 Polynomial")
+
+ def testCubic(self):
+ self._testPoly([0.0005, -0.05, 3, -4],
+ "Degree 3 Polynomial")
+
+ def testQuartic(self):
+ self._testPoly([1, -2, 3, -4, -5],
+ "Degree 4 Polynomial")
+
+ def testQuintic(self):
+ self._testPoly([1, -2, 3, -4, -5, 6],
+ "Degree 5 Polynomial",
+ places=4)
+
+
+test_cases = (TestFitmanager, TestPolynomials)
+
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/fit/test/test_functions.py b/silx/math/fit/test/test_functions.py
new file mode 100644
index 0000000..ce7dbd6
--- /dev/null
+++ b/silx/math/fit/test/test_functions.py
@@ -0,0 +1,272 @@
+# 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.
+#
+# ############################################################################*/
+"""
+Tests for functions module
+"""
+
+import unittest
+import numpy
+import math
+
+from silx.math.fit import functions
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "21/07/2016"
+
+class Test_functions(unittest.TestCase):
+ """
+ Unit tests of multi-peak functions.
+ """
+ def setUp(self):
+ self.x = numpy.arange(11)
+
+ # height, center, sigma1, sigma2
+ (h, c, s1, s2) = (7., 5., 3., 2.1)
+ self.g_params = {
+ "height": h,
+ "center": c,
+ #"sigma": s,
+ "fwhm1": 2 * math.sqrt(2 * math.log(2)) * s1,
+ "fwhm2": 2 * math.sqrt(2 * math.log(2)) * s2,
+ "area1": h * s1 * math.sqrt(2 * math.pi)
+ }
+ # result of `7 * scipy.signal.gaussian(11, 3)`
+ self.scipy_gaussian = numpy.array(
+ [1.74546546, 2.87778603, 4.24571462, 5.60516182, 6.62171628,
+ 7., 6.62171628, 5.60516182, 4.24571462, 2.87778603,
+ 1.74546546]
+ )
+
+ # result of:
+ # numpy.concatenate((7 * scipy.signal.gaussian(11, 3)[0:5],
+ # 7 * scipy.signal.gaussian(11, 2.1)[5:11]))
+ self.scipy_asym_gaussian = numpy.array(
+ [1.74546546, 2.87778603, 4.24571462, 5.60516182, 6.62171628,
+ 7., 6.24968751, 4.44773692, 2.52313452, 1.14093853, 0.41124877]
+ )
+
+ def tearDown(self):
+ pass
+
+ def testGauss(self):
+ """Compare sum_gauss with scipy.signals.gaussian"""
+ y = functions.sum_gauss(self.x,
+ self.g_params["height"],
+ self.g_params["center"],
+ self.g_params["fwhm1"])
+
+ for i in range(11):
+ self.assertAlmostEqual(y[i], self.scipy_gaussian[i])
+
+ def testAGauss(self):
+ """Compare sum_agauss with scipy.signals.gaussian"""
+ y = functions.sum_agauss(self.x,
+ self.g_params["area1"],
+ self.g_params["center"],
+ self.g_params["fwhm1"])
+ for i in range(11):
+ self.assertAlmostEqual(y[i], self.scipy_gaussian[i])
+
+ def testFastAGauss(self):
+ """Compare sum_fastagauss with scipy.signals.gaussian
+ Limit precision to 3 decimal places."""
+ y = functions.sum_fastagauss(self.x,
+ self.g_params["area1"],
+ self.g_params["center"],
+ self.g_params["fwhm1"])
+ for i in range(11):
+ self.assertAlmostEqual(y[i], self.scipy_gaussian[i], 3)
+
+
+ def testSplitGauss(self):
+ """Compare sum_splitgauss with scipy.signals.gaussian"""
+ y = functions.sum_splitgauss(self.x,
+ self.g_params["height"],
+ self.g_params["center"],
+ self.g_params["fwhm1"],
+ self.g_params["fwhm2"])
+ for i in range(11):
+ self.assertAlmostEqual(y[i], self.scipy_asym_gaussian[i])
+
+ def testErf(self):
+ """Compare erf with math.erf"""
+ # scalars
+ self.assertAlmostEqual(functions.erf(0.14), math.erf(0.14), places=5)
+ self.assertAlmostEqual(functions.erf(0), math.erf(0), places=5)
+ self.assertAlmostEqual(functions.erf(-0.74), math.erf(-0.74), places=5)
+
+ # lists
+ x = [-5, -2, -1.5, -0.6, 0, 0.1, 2, 3]
+ erfx = functions.erf(x)
+ for i in range(len(x)):
+ self.assertAlmostEqual(erfx[i],
+ math.erf(x[i]),
+ places=5)
+
+ # ndarray
+ x = numpy.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]])
+ erfx = functions.erf(x)
+ for i in range(x.shape[0]):
+ for j in range(x.shape[1]):
+ self.assertAlmostEqual(erfx[i, j],
+ math.erf(x[i, j]),
+ places=5)
+
+ def testErfc(self):
+ """Compare erf with math.erf"""
+ # scalars
+ self.assertAlmostEqual(functions.erfc(0.14), math.erfc(0.14), places=5)
+ self.assertAlmostEqual(functions.erfc(0), math.erfc(0), places=5)
+ self.assertAlmostEqual(functions.erfc(-0.74), math.erfc(-0.74), places=5)
+
+ # lists
+ x = [-5, -2, -1.5, -0.6, 0, 0.1, 2, 3]
+ erfcx = functions.erfc(x)
+ for i in range(len(x)):
+ self.assertAlmostEqual(erfcx[i], math.erfc(x[i]), places=5)
+
+ # ndarray
+ x = numpy.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]])
+ erfcx = functions.erfc(x)
+ for i in range(x.shape[0]):
+ for j in range(x.shape[1]):
+ self.assertAlmostEqual(erfcx[i, j], math.erfc(x[i, j]), places=5)
+
+ def testAtanStepUp(self):
+ """Compare atan_stepup with math.atan
+
+ atan_stepup(x, a, b, c) = a * (0.5 + (arctan((x - b) / c) / pi))"""
+ x0 = numpy.arange(100) / 6.33
+ y0 = functions.atan_stepup(x0, 11.1, 22.2, 3.33)
+
+ for x, y in zip(x0, y0):
+ self.assertAlmostEqual(
+ 11.1 * (0.5 + math.atan((x - 22.2) / 3.33) / math.pi),
+ y
+ )
+
+ def testStepUp(self):
+ """sanity check for step up:
+
+ - derivative must be largest around the step center
+ - max value must be close to height parameter
+
+ """
+ x0 = numpy.arange(1000)
+ center = 444
+ height = 1234
+ fwhm = 210
+ y0 = functions.sum_stepup(x0, height, center, fwhm)
+
+ self.assertLess(max(y0), height)
+ self.assertAlmostEqual(max(y0), height, places=1)
+ self.assertAlmostEqual(min(y0), 0, places=1)
+
+ deriv0 = _numerical_derivative(functions.sum_stepup, x0, [height, center, fwhm])
+
+ # Test center position within +- 1 sample of max derivative
+ index_max_deriv = numpy.argmax(deriv0)
+ self.assertLess(abs(index_max_deriv - center),
+ 1)
+
+ def testStepDown(self):
+ """sanity check for step down:
+
+ - absolute value of derivative must be largest around the step center
+ - max value must be close to height parameter
+
+ """
+ x0 = numpy.arange(1000)
+ center = 444
+ height = 1234
+ fwhm = 210
+ y0 = functions.sum_stepdown(x0, height, center, fwhm)
+
+ self.assertLess(max(y0), height)
+ self.assertAlmostEqual(max(y0), height, places=1)
+ self.assertAlmostEqual(min(y0), 0, places=1)
+
+ deriv0 = _numerical_derivative(functions.sum_stepdown, x0, [height, center, fwhm])
+
+ # Test center position within +- 1 sample of max derivative
+ index_min_deriv = numpy.argmax(-deriv0)
+ self.assertLess(abs(index_min_deriv - center),
+ 1)
+
+ def testSlit(self):
+ """sanity check for slit:
+
+ - absolute value of derivative must be largest around the step center
+ - max value must be close to height parameter
+
+ """
+ x0 = numpy.arange(1000)
+ center = 444
+ height = 1234
+ fwhm = 210
+ beamfwhm = 30
+ y0 = functions.sum_slit(x0, height, center, fwhm, beamfwhm)
+
+ self.assertAlmostEqual(max(y0), height, places=1)
+ self.assertAlmostEqual(min(y0), 0, places=1)
+
+ deriv0 = _numerical_derivative(functions.sum_slit, x0, [height, center, fwhm, beamfwhm])
+
+ # Test step up center position (center - fwhm/2) within +- 1 sample of max derivative
+ index_max_deriv = numpy.argmax(deriv0)
+ self.assertLess(abs(index_max_deriv - (center - fwhm/2)),
+ 1)
+ # Test step down center position (center + fwhm/2) within +- 1 sample of min derivative
+ index_min_deriv = numpy.argmin(deriv0)
+ self.assertLess(abs(index_min_deriv - (center + fwhm/2)),
+ 1)
+
+
+def _numerical_derivative(f, x, params=[], delta_factor=0.0001):
+ """Compute the numerical derivative of ``f`` for all values of ``x``.
+
+ :param f: function
+ :param x: Array of evenly spaced abscissa values
+ :param params: list of additional parameters
+ :return: Array of derivative values
+ """
+ deltax = (x[1] - x[0]) * delta_factor
+ y_plus = f(x + deltax, *params)
+ y_minus = f(x - deltax, *params)
+
+ return (y_plus - y_minus) / (2 * deltax)
+
+test_cases = (Test_functions,)
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/fit/test/test_peaks.py b/silx/math/fit/test/test_peaks.py
new file mode 100644
index 0000000..17eb75d
--- /dev/null
+++ b/silx/math/fit/test/test_peaks.py
@@ -0,0 +1,146 @@
+# 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.
+#
+# ############################################################################*/
+"""
+Tests for peaks module
+"""
+
+import unittest
+import numpy
+import math
+
+from silx.math.fit import functions
+from silx.math.fit import peaks
+
+class Test_peak_search(unittest.TestCase):
+ """
+ Unit tests of peak_search on various types of multi-peak functions.
+ """
+ def setUp(self):
+ self.x = numpy.arange(5000)
+ # (height1, center1, fwhm1, ...)
+ self.h_c_fwhm = (50, 500, 100,
+ 50, 600, 80,
+ 20, 2000, 100,
+ 50, 2250, 110,
+ 40, 3000, 99,
+ 23, 4980, 80)
+ # (height1, center1, fwhm1, eta1 ...)
+ self.h_c_fwhm_eta = (50, 500, 100, 0.4,
+ 50, 600, 80, 0.5,
+ 20, 2000, 100, 0.6,
+ 50, 2250, 110, 0.7,
+ 40, 3000, 99, 0.8,
+ 23, 4980, 80, 0.3,)
+ # (height1, center1, fwhm11, fwhm21, ...)
+ self.h_c_fwhm_fwhm = (50, 500, 100, 85,
+ 50, 600, 80, 110,
+ 20, 2000, 100, 100,
+ 50, 2250, 110, 99,
+ 40, 3000, 99, 110,
+ 23, 4980, 80, 80,)
+ # (height1, center1, fwhm11, fwhm21, eta1 ...)
+ self.h_c_fwhm_fwhm_eta = (50, 500, 100, 85, 0.4,
+ 50, 600, 80, 110, 0.5,
+ 20, 2000, 100, 100, 0.6,
+ 50, 2250, 110, 99, 0.7,
+ 40, 3000, 99, 110, 0.8,
+ 23, 4980, 80, 80, 0.3,)
+ # (area1, center1, fwhm1, ...)
+ self.a_c_fwhm = (2550, 500, 100,
+ 2000, 600, 80,
+ 500, 2000, 100,
+ 4000, 2250, 110,
+ 2300, 3000, 99,
+ 3333, 4980, 80)
+ # (area1, center1, fwhm1, eta1 ...)
+ self.a_c_fwhm_eta = (500, 500, 100, 0.4,
+ 500, 600, 80, 0.5,
+ 200, 2000, 100, 0.6,
+ 500, 2250, 110, 0.7,
+ 400, 3000, 99, 0.8,
+ 230, 4980, 80, 0.3,)
+ # (area, position, fwhm, st_area_r, st_slope_r, lt_area_r, lt_slope_r, step_height_r)
+ self.hypermet_params = (1000, 500, 200, 0.2, 100, 0.3, 100, 0.05,
+ 1000, 1000, 200, 0.2, 100, 0.3, 100, 0.05,
+ 1000, 2000, 200, 0.2, 100, 0.3, 100, 0.05,
+ 1000, 2350, 200, 0.2, 100, 0.3, 100, 0.05,
+ 1000, 3000, 200, 0.2, 100, 0.3, 100, 0.05,
+ 1000, 4900, 200, 0.2, 100, 0.3, 100, 0.05,)
+
+
+ def tearDown(self):
+ pass
+
+ def get_peaks(self, function, params):
+ """
+
+ :param function: Multi-peak function
+ :param params: Parameter for this function
+ :return: list of (peak, relevance) tuples
+ """
+ y = function(self.x, *params)
+ return peaks.peak_search(y=y, fwhm=100, relevance_info=True)
+
+ def testPeakSearch_various_functions(self):
+ """Run peak search on a variety of synthetic functions, and
+ check that result falls within +-25 samples of the actual peak
+ (reasonable delta considering a fwhm of ~100 samples) and effects
+ of overlapping peaks)."""
+ f_p = ((functions.sum_gauss, self.h_c_fwhm ),
+ (functions.sum_lorentz, self.h_c_fwhm),
+ (functions.sum_pvoigt, self.h_c_fwhm_eta),
+ (functions.sum_splitgauss, self.h_c_fwhm_fwhm),
+ (functions.sum_splitlorentz, self.h_c_fwhm_fwhm),
+ (functions.sum_splitpvoigt, self.h_c_fwhm_fwhm_eta),
+ (functions.sum_agauss, self.a_c_fwhm),
+ (functions.sum_fastagauss, self.a_c_fwhm),
+ (functions.sum_alorentz, self.a_c_fwhm),
+ (functions.sum_apvoigt, self.a_c_fwhm_eta),
+ (functions.sum_ahypermet, self.hypermet_params),
+ (functions.sum_fastahypermet, self.hypermet_params),)
+
+ for function, params in f_p:
+ peaks = self.get_peaks(function, params)
+
+ self.assertEqual(len(peaks), 6,
+ "Wrong number of peaks detected")
+
+ for i in range(6):
+ theoretical_peak_index = params[i*(len(params)//6) + 1]
+ found_peak_index = peaks[i][0]
+ self.assertLess(abs(found_peak_index - theoretical_peak_index), 25)
+
+
+test_cases = (Test_peak_search,)
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/histogram.py b/silx/math/histogram.py
new file mode 100644
index 0000000..3ee0482
--- /dev/null
+++ b/silx/math/histogram.py
@@ -0,0 +1,593 @@
+# 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.
+#
+# ############################################################################*/
+
+
+"""
+This module provides a function and a class to compute multidimensional
+histograms.
+
+
+Classes
+=======
+
+- :class:`Histogramnd` : multi dimensional histogram.
+- :class:`HistogramndLut` : optimized to compute several histograms from data sharing the same coordinates.
+
+Examples
+========
+
+Single histogram
+----------------
+
+Given some 3D data:
+
+>>> import numpy as np
+>>> shape = (10**7, 3)
+>>> sample = np.random.random(shape) * 500
+>>> weights = np.random.random((shape[0],))
+
+Computing the histogram with Histogramnd :
+
+>>> from silx.math import Histogramnd
+>>> n_bins = 35
+>>> ranges = [[40., 150.], [-130., 250.], [0., 505]]
+>>> histo, w_histo, edges = Histogramnd(sample, n_bins=n_bins, histo_range=ranges, weights=weights)
+
+Histogramnd can accumulate sets of data that don't have the same
+coordinates :
+
+>>> from silx.math import Histogramnd
+>>> histo_obj = Histogramnd(sample, n_bins=n_bins, histo_range=ranges, weights=weights)
+>>> sample_2 = np.random.random(shape) * 200
+>>> weights_2 = np.random.random((shape[0],))
+>>> histo_obj.accumulate(sample_2, weights=weights_2)
+
+And then access the results:
+
+>>> histo = histo_obj.histo
+>>> weighted_histo = histo_obj.weighted_histo
+
+or even:
+
+>>> histo, w_histo, edges = histo_obj
+
+Accumulating histograms (LUT)
+-----------------------------
+In some situations we need to compute the weighted histogram of several
+sets of data (weights) that have the same coordinates (sample).
+
+Again, some data (2 sets of weights) :
+
+>>> import numpy as np
+>>> shape = (10**7, 3)
+>>> sample = np.random.random(shape) * 500
+>>> weights_1 = np.random.random((shape[0],))
+>>> weights_2 = np.random.random((shape[0],))
+
+And getting the result with HistogramLut :
+
+>>> from silx.math import HistogramndLut
+
+>>> n_bins = 35
+>>> ranges = [[40., 150.], [-130., 250.], [0., 505]]
+
+>>> histo_lut = HistogramndLut(sample, ranges, n_bins)
+
+First call, with weight_1 :
+
+>>> histo_lut.accumulate(weights_1)
+
+Second call, with weight_2 :
+
+>>> histo_lut.accumulate(weights_2)
+
+Retrieving the results (this is a copy of what's actually stored in
+this instance) :
+
+>>> histo = histo_lut.histo
+>>> w_histo = histo_lut.weighted_histo
+
+Note that the following code gives the same result, but the
+HistogramndLut instance does not store the accumulated weighted histogram.
+
+First call with weights_1
+
+>>> histo, w_histo = histo_lut.apply_lut(weights_1)
+
+Second call with weights_2
+
+>>> histo, w_histo = histo_lut.apply_lut(weights_2, histo=histo, weighted_histo=w_histo)
+
+Bin edges
+---------
+When computing an histogram the caller is asked to provide the histogram
+range along each coordinates (parameter *histo_range*). This parameter must
+be given a [N, 2] array where N is the number of dimensions of the histogram.
+
+In other words, the caller must provide, for each dimension,
+the left edge of the first (*leftmost*) bin, and the right edge of the
+last (*rightmost*) bin.
+
+E.g. : for a 1D sample, for a histo_range equal to [0, 10] and n_bins=4, the
+bins ranges will be :
+
+* [0, 2.5[, [2.5, 5[, [5, 7.5[, [7.5, 10 **[** if last_bin_closed = **False**
+* [0, 2.5[, [2.5, 5[, [5, 7.5[, [7.5, 10 **]** if last_bin_closed = **True**
+
+....
+""" # noqa
+
+__authors__ = ["D. Naudet"]
+__license__ = "MIT"
+__date__ = "15/09/2016"
+
+import numpy as np
+from .chistogramnd import chistogramnd as _chistogramnd # noqa
+from .chistogramnd_lut import histogramnd_get_lut as _histo_get_lut
+from .chistogramnd_lut import histogramnd_from_lut as _histo_from_lut
+
+
+class Histogramnd(object):
+ """
+ Computes the multidimensional histogram of some data.
+ """ # noqa
+
+ def __init__(self,
+ sample,
+ histo_range,
+ n_bins,
+ weights=None,
+ weight_min=None,
+ weight_max=None,
+ last_bin_closed=False,
+ wh_dtype=None):
+ """
+ :param sample:
+ The data to be histogrammed.
+ Its shape must be either
+ (N,) if it contains one dimensional coordinates,
+ or an (N,D) array where the rows are the
+ coordinates of points in a D dimensional space.
+ The following dtypes are supported : :class:`numpy.float64`,
+ :class:`numpy.float32`, :class:`numpy.int32`.
+
+ .. warning:: if sample is not a C_CONTIGUOUS ndarray (e.g : a non
+ contiguous slice) then histogramnd will have to do make an internal
+ copy.
+ :type sample: :class:`numpy.array`
+
+ :param histo_range:
+ A (N, 2) array containing the histogram range along each dimension,
+ where N is the sample's number of dimensions.
+ :type histo_range: array_like
+
+ :param n_bins:
+ The number of bins :
+ * a scalar (same number of bins for all dimensions)
+ * a D elements array (number of bins for each dimensions)
+ :type n_bins: scalar or array_like
+
+ :param weights:
+ A N elements numpy array of values associated with
+ each sample.
+ The values of the *weighted_histo* array
+ returned by the function are equal to the sum of
+ the weights associated with the samples falling
+ into each bin.
+ The following dtypes are supported : :class:`numpy.float64`,
+ :class:`numpy.float32`, :class:`numpy.int32`.
+
+ .. note:: If None, the weighted histogram returned will be None.
+ :type weights: *optional*, :class:`numpy.array`
+
+ :param weight_min:
+ Use this parameter to filter out all samples whose
+ weights are lower than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+ :type weight_min: *optional*, scalar
+
+ :param weight_max:
+ Use this parameter to filter out all samples whose
+ weights are higher than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+
+ :type weight_max: *optional*, scalar
+
+ :param last_bin_closed:
+ By default the last bin is half
+ open (i.e.: [x,y) ; x included, y
+ excluded), like all the other bins.
+ Set this parameter to true if you want
+ the LAST bin to be closed.
+ :type last_bin_closed: *optional*, :class:`python.boolean`
+
+ :param wh_dtype: type of the weighted histogram array.
+ If not provided, the weighted histogram array will contain values
+ of type numpy.double. Allowed values are : `numpy.double` and
+ `numpy.float32`
+ :type wh_dtype: *optional*, numpy data type
+ """
+
+ self.__histo_range = histo_range
+ self.__n_bins = n_bins
+ self.__last_bin_closed = last_bin_closed
+ self.__wh_dtype = wh_dtype
+
+ if sample is None:
+ self.__data = [None, None, None]
+ else:
+ self.__data = _chistogramnd(sample,
+ self.__histo_range,
+ self.__n_bins,
+ weights=weights,
+ weight_min=weight_min,
+ weight_max=weight_max,
+ last_bin_closed=self.__last_bin_closed,
+ wh_dtype=self.__wh_dtype)
+
+ def __getitem__(self, key):
+ """
+ If necessary, results can be unpacked from an instance of Histogramnd :
+ *histogram*, *weighted histogram*, *bins edge*.
+
+ Example :
+
+ .. code-block:: python
+
+ histo, w_histo, edges = Histogramnd(sample, histo_range, n_bins, weights)
+
+ """
+ return self.__data[key]
+
+ def accumulate(self,
+ sample,
+ weights=None,
+ weight_min=None,
+ weight_max=None):
+ """
+ Computes the multidimensional histogram of some data and accumulates it
+ into the histogram held by this instance of Histogramnd.
+
+ :param sample:
+ The data to be histogrammed.
+ Its shape must be either
+ (N,) if it contains one dimensional coordinates,
+ or an (N,D) array where the rows are the
+ coordinates of points in a D dimensional space.
+ The following dtypes are supported : :class:`numpy.float64`,
+ :class:`numpy.float32`, :class:`numpy.int32`.
+
+ .. warning:: if sample is not a C_CONTIGUOUS ndarray (e.g : a non
+ contiguous slice) then histogramnd will have to do make an internal
+ copy.
+ :type sample: :class:`numpy.array`
+
+ :param weights:
+ A N elements numpy array of values associated with
+ each sample.
+ The values of the *weighted_histo* array
+ returned by the function are equal to the sum of
+ the weights associated with the samples falling
+ into each bin.
+ The following dtypes are supported : :class:`numpy.float64`,
+ :class:`numpy.float32`, :class:`numpy.int32`.
+
+ .. note:: If None, the weighted histogram returned will be None.
+ :type weights: *optional*, :class:`numpy.array`
+
+ :param weight_min:
+ Use this parameter to filter out all samples whose
+ weights are lower than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+ :type weight_min: *optional*, scalar
+
+ :param weight_max:
+ Use this parameter to filter out all samples whose
+ weights are higher than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+ :type weight_max: *optional*, scalar
+ """
+ result = _chistogramnd(sample,
+ self.__histo_range,
+ self.__n_bins,
+ weights=weights,
+ weight_min=weight_min,
+ weight_max=weight_max,
+ last_bin_closed=self.__last_bin_closed,
+ histo=self.__data[0],
+ weighted_histo=self.__data[1],
+ wh_dtype=self.__wh_dtype)
+ if self.__data[0] is None:
+ self.__data = result
+ elif self.__data[1] is None and result[1] is not None:
+ self.__data = result
+
+ histo = property(lambda self: self[0])
+ """ Histogram array, or None if this instance was initialized without
+ <sample> and accumulate has not been called yet.
+
+ .. note:: this is a **reference** to the array store in this
+ Histogramnd instance, use with caution.
+ """
+ weighted_histo = property(lambda self: self[1])
+ """ Weighted Histogram, or None if this instance was initialized without
+ <sample>, or no weights have been passed to __init__ nor accumulate.
+
+ .. note:: this is a **reference** to the array store in this
+ Histogramnd instance, use with caution.
+ """
+ edges = property(lambda self: self[2])
+ """ Bins edges, or None if this instance was initialized without
+ <sample> and accumulate has not been called yet.
+ """
+
+
+class HistogramndLut(object):
+ """
+ The HistogramndLut class allows you to bin data onto a regular grid.
+ The use of HistogramndLut is interesting when several sets of data that
+ share the same coordinates (*sample*) have to be mapped onto the same grid.
+ """
+
+ def __init__(self,
+ sample,
+ histo_range,
+ n_bins,
+ last_bin_closed=False,
+ dtype=None):
+ """
+ :param sample:
+ The coordinates of the data to be histogrammed.
+ Its shape must be either (N,) if it contains one dimensional
+ coordinates, or an (N, D) array where the rows are the
+ coordinates of points in a D dimensional space.
+ The following dtypes are supported : :class:`numpy.float64`,
+ :class:`numpy.float32`, :class:`numpy.int32`.
+ :type sample: :class:`numpy.array`
+
+ :param histo_range:
+ A (N, 2) array containing the histogram range along each dimension,
+ where N is the sample's number of dimensions.
+ :type histo_range: array_like
+
+ :param n_bins:
+ The number of bins :
+ * a scalar (same number of bins for all dimensions)
+ * a D elements array (number of bins for each dimensions)
+ :type n_bins: scalar or array_like
+
+ :param dtype: data type of the weighted histogram. If None, the data type
+ will be the same as the first weights array provided (on first call of
+ the instance).
+ :type dtype: `numpy.dtype`
+
+ :param last_bin_closed:
+ By default the last bin is half
+ open (i.e.: [x,y) ; x included, y
+ excluded), like all the other bins.
+ Set this parameter to true if you want
+ the LAST bin to be closed.
+ :type last_bin_closed: *optional*, :class:`python.boolean`
+ """
+ lut, histo, edges = _histo_get_lut(sample,
+ histo_range,
+ n_bins,
+ last_bin_closed=last_bin_closed)
+
+ self.__n_bins = np.array(histo.shape)
+ self.__histo_range = histo_range
+ self.__lut = lut
+ self.__histo = None
+ self.__weighted_histo = None
+ self.__edges = edges
+ self.__dtype = dtype
+ self.__shape = histo.shape
+ self.__last_bin_closed = last_bin_closed
+ self.clear()
+
+ def clear(self):
+ """
+ Resets the instance (zeroes the histograms).
+ """
+ self.__weighted_histo = None
+ self.__histo = None
+
+ @property
+ def lut(self):
+ """
+ Copy of the Lut
+ """
+ return self.__lut.copy()
+
+ def histo(self, copy=True):
+ """
+ Histogram (a copy of it), or None if `~accumulate` has not been called yet
+ (or clear was just called).
+ If *copy* is set to False then the actual reference to the array is
+ returned *(use with caution)*.
+ """
+ if copy and self.__histo is not None:
+ return self.__histo.copy()
+ return self.__histo
+
+ def weighted_histo(self, copy=True):
+ """
+ Weighted histogram (a copy of it), or None if `~accumulate` has not been called yet
+ (or clear was just called). If *copy* is set to False then the actual
+ reference to the array is returned *(use with caution)*.
+ """
+ if copy and self.__weighted_histo is not None:
+ return self.__weighted_histo.copy()
+ return self.__weighted_histo
+
+ @property
+ def histo_range(self):
+ """
+ Bins ranges.
+ """
+ return self.__histo_range.copy()
+
+ @property
+ def n_bins(self):
+ """
+ Number of bins in each direction.
+ """
+ return self.__n_bins.copy()
+
+ @property
+ def bins_edges(self):
+ """
+ Bins edges of the histograms, one array for each dimensions.
+ """
+ return tuple([edges[:] for edges in self.__edges])
+
+ @property
+ def last_bin_closed(self):
+ """
+ Returns True if the rightmost bin in each dimension is close (i.e :
+ values equal to the rightmost bin edge is included in the bin).
+ """
+ return self.__last_bin_closed
+
+ def accumulate(self,
+ weights,
+ weight_min=None,
+ weight_max=None):
+ """
+ Computes the multidimensional histogram of some data and adds it to
+ the current histogram stored by this instance. The results can be
+ retrieved with the :attr:`~.histo` and :attr:`~.weighted_histo`
+ properties.
+
+ :param weights:
+ A numpy array of values associated with each sample. The number of
+ elements in the array must be the same as the number of samples
+ provided at instantiation time.
+ :type histo_range: array_like
+
+ :param weight_min:
+ Use this parameter to filter out all samples whose
+ weights are lower than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+ :type weight_min: *optional*, scalar
+
+ :param weight_max:
+ Use this parameter to filter out all samples whose
+ weights are higher than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+
+ :type weight_max: *optional*, scalar
+ """
+ if self.__dtype is None:
+ self.__dtype = weights.dtype
+
+ histo, w_histo = _histo_from_lut(weights,
+ self.__lut,
+ histo=self.__histo,
+ weighted_histo=self.__weighted_histo,
+ shape=self.__shape,
+ dtype=self.__dtype,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ if self.__histo is None:
+ self.__histo = histo
+
+ if self.__weighted_histo is None:
+ self.__weighted_histo = w_histo
+
+ def apply_lut(self,
+ weights,
+ histo=None,
+ weighted_histo=None,
+ weight_min=None,
+ weight_max=None):
+ """
+ Computes the multidimensional histogram of some data and returns the
+ result (it is NOT added to the current histogram stored by this
+ instance).
+
+ :param weights:
+ A numpy array of values associated with each sample. The number of
+ elements in the array must be the same as the number of samples
+ provided at instantiation time.
+ :type histo_range: array_like
+
+ :param histo:
+ Use this parameter if you want to pass your
+ own histogram array instead of the one
+ created by this function. New values
+ will be added to this array. The returned array
+ will then be this one.
+ :type histo: *optional*, :class:`numpy.array`
+
+ :param weighted_histo:
+ Use this parameter if you want to pass your
+ own weighted histogram array instead of
+ the created by this function. New
+ values will be added to this array. The returned array
+ will then be this one (same reference).
+ :type weighted_histo: *optional*, :class:`numpy.array`
+
+ :param weight_min:
+ Use this parameter to filter out all samples whose
+ weights are lower than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+ :type weight_min: *optional*, scalar
+
+ :param weight_max:
+ Use this parameter to filter out all samples whose
+ weights are higher than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+ :type weight_max: *optional*, scalar
+ """
+ histo, w_histo = _histo_from_lut(weights,
+ self.__lut,
+ histo=histo,
+ weighted_histo=weighted_histo,
+ shape=self.__shape,
+ dtype=self.__dtype,
+ weight_min=weight_min,
+ weight_max=weight_max)
+ self.__dtype = w_histo.dtype
+ return histo, w_histo
+
+if __name__ == '__main__':
+ pass
diff --git a/silx/math/histogramnd/chistogramnd.c b/silx/math/histogramnd/chistogramnd.c
new file mode 100644
index 0000000..83ce0cf
--- /dev/null
+++ b/silx/math/histogramnd/chistogramnd.c
@@ -0,0 +1,28300 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__chistogramnd
+#define __PYX_HAVE_API__chistogramnd
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#include "include/histogramnd_c.h"
+#include "pythread.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+ #if defined(__cplusplus)
+ #define CYTHON_CCOMPLEX 1
+ #elif defined(_Complex_I)
+ #define CYTHON_CCOMPLEX 1
+ #else
+ #define CYTHON_CCOMPLEX 0
+ #endif
+#endif
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #include <complex>
+ #else
+ #include <complex.h>
+ #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+ #undef _Complex_I
+ #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+ "chistogramnd.pyx",
+ "__init__.pxd",
+ "stringsource",
+ "type.pxd",
+};
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":723
+ * # in Cython to enable them only on the right systems.
+ *
+ * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":724
+ *
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":725
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int64 int64_t
+ * #ctypedef npy_int96 int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96 int96_t
+ * #ctypedef npy_int128 int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":730
+ * #ctypedef npy_int128 int128_t
+ *
+ * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":731
+ *
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":732
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64 uint64_t
+ * #ctypedef npy_uint96 uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96 uint96_t
+ * #ctypedef npy_uint128 uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":737
+ * #ctypedef npy_uint128 uint128_t
+ *
+ * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_float64 float64_t
+ * #ctypedef npy_float80 float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":738
+ *
+ * ctypedef npy_float32 float32_t
+ * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80 float80_t
+ * #ctypedef npy_float128 float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong longlong_t
+ *
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":749
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_ulong uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
+ * ctypedef npy_longlong longlong_t
+ *
+ * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":752
+ *
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":753
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_intp intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ * ctypedef npy_intp intp_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp uintp_t
+ *
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":756
+ *
+ * ctypedef npy_intp intp_t
+ * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_double float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_uintp uintp_t
+ *
+ * ctypedef npy_double float_t # <<<<<<<<<<<<<<
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":759
+ *
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ *
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":760
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cfloat cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< float > __pyx_t_float_complex;
+ #else
+ typedef float _Complex __pyx_t_float_complex;
+ #endif
+#else
+ typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< double > __pyx_t_double_complex;
+ #else
+ typedef double _Complex __pyx_t_double_complex;
+ #endif
+#else
+ typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd;
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ *
+ * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":763
+ *
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":764
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cdouble complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "chistogramnd.pyx":36
+ *
+ *
+ * def chistogramnd(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd {
+ PyObject_HEAD
+ PyObject *__pyx_v_sample_type;
+ PyObject *__pyx_v_weights_type;
+};
+
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __Pyx_PyObject_DelAttrStr(o,n) __Pyx_PyObject_SetAttrStr(o,n,NULL)
+static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr_name, PyObject* value) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_setattro))
+ return tp->tp_setattro(obj, attr_name, value);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_setattr))
+ return tp->tp_setattr(obj, PyString_AS_STRING(attr_name), value);
+#endif
+ return PyObject_SetAttr(obj, attr_name, value);
+}
+#else
+#define __Pyx_PyObject_DelAttrStr(o,n) PyObject_DelAttr(o,n)
+#define __Pyx_PyObject_SetAttrStr(o,n,v) PyObject_SetAttr(o,n,v)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
+
+#define __Pyx_CyFunction_USED 1
+#include <structmember.h>
+#define __Pyx_CYFUNCTION_STATICMETHOD 0x01
+#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02
+#define __Pyx_CYFUNCTION_CCLASS 0x04
+#define __Pyx_CyFunction_GetClosure(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_closure)
+#define __Pyx_CyFunction_GetClassObj(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_classobj)
+#define __Pyx_CyFunction_Defaults(type, f) \
+ ((type *)(((__pyx_CyFunctionObject *) (f))->defaults))
+#define __Pyx_CyFunction_SetDefaultsGetter(f, g) \
+ ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g)
+typedef struct {
+ PyCFunctionObject func;
+#if PY_VERSION_HEX < 0x030500A0
+ PyObject *func_weakreflist;
+#endif
+ PyObject *func_dict;
+ PyObject *func_name;
+ PyObject *func_qualname;
+ PyObject *func_doc;
+ PyObject *func_globals;
+ PyObject *func_code;
+ PyObject *func_closure;
+ PyObject *func_classobj;
+ void *defaults;
+ int defaults_pyobjects;
+ int flags;
+ PyObject *defaults_tuple;
+ PyObject *defaults_kwdict;
+ PyObject *(*defaults_getter)(PyObject *);
+ PyObject *func_annotations;
+} __pyx_CyFunctionObject;
+static PyTypeObject *__pyx_CyFunctionType = 0;
+#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \
+ __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code)
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
+ int flags, PyObject* qualname,
+ PyObject *self,
+ PyObject *module, PyObject *globals,
+ PyObject* code);
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m,
+ size_t size,
+ int pyobjects);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m,
+ PyObject *tuple);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m,
+ PyObject *dict);
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
+ PyObject *dict);
+static int __Pyx_CyFunction_init(void);
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+ PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+ PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
+ int has_cstart, int has_cstop, int wraparound);
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE npy_int32 __Pyx_PyInt_As_npy_int32(PyObject *);
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #define __Pyx_CREAL(z) ((z).real())
+ #define __Pyx_CIMAG(z) ((z).imag())
+ #else
+ #define __Pyx_CREAL(z) (__real__(z))
+ #define __Pyx_CIMAG(z) (__imag__(z))
+ #endif
+#else
+ #define __Pyx_CREAL(z) ((z).real)
+ #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+ #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+ #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+ #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+ #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eqf(a, b) ((a)==(b))
+ #define __Pyx_c_sumf(a, b) ((a)+(b))
+ #define __Pyx_c_difff(a, b) ((a)-(b))
+ #define __Pyx_c_prodf(a, b) ((a)*(b))
+ #define __Pyx_c_quotf(a, b) ((a)/(b))
+ #define __Pyx_c_negf(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+ #define __Pyx_c_conjf(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_absf(z) (::std::abs(z))
+ #define __Pyx_c_powf(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zerof(z) ((z)==0)
+ #define __Pyx_c_conjf(z) (conjf(z))
+ #if 1
+ #define __Pyx_c_absf(z) (cabsf(z))
+ #define __Pyx_c_powf(a, b) (cpowf(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eq(a, b) ((a)==(b))
+ #define __Pyx_c_sum(a, b) ((a)+(b))
+ #define __Pyx_c_diff(a, b) ((a)-(b))
+ #define __Pyx_c_prod(a, b) ((a)*(b))
+ #define __Pyx_c_quot(a, b) ((a)/(b))
+ #define __Pyx_c_neg(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zero(z) ((z)==(double)0)
+ #define __Pyx_c_conj(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (::std::abs(z))
+ #define __Pyx_c_pow(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zero(z) ((z)==0)
+ #define __Pyx_c_conj(z) (conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (cabs(z))
+ #define __Pyx_c_pow(a, b) (cpow(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_double(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_int(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_float(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+ #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'histogramnd_c' */
+
+/* Module declarations from 'chistogramnd' */
+static PyTypeObject *__pyx_ptype_12chistogramnd___pyx_scope_struct__chistogramnd = 0;
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static int __pyx_f_12chistogramnd__histogramnd_double_double_double(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, double, double); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_double_float_double(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, float, float); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_double_int32_t_double(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, __pyx_t_5numpy_int32_t, __pyx_t_5numpy_int32_t); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_float_double_double(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, double, double); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_float_float_double(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, float, float); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_float_int32_t_double(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, __pyx_t_5numpy_int32_t, __pyx_t_5numpy_int32_t); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_double_double(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, double, double); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_float_double(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, float, float); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_int32_t_double(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, __pyx_t_5numpy_int32_t, __pyx_t_5numpy_int32_t); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_double_double_float(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, double, double); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_double_float_float(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, float, float); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_double_int32_t_float(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, __pyx_t_5numpy_int32_t, __pyx_t_5numpy_int32_t); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_float_double_float(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, double, double); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_float_float_float(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, float, float); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_float_int32_t_float(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, __pyx_t_5numpy_int32_t, __pyx_t_5numpy_int32_t); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_double_float(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, double, double); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_float_float(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, float, float); /*proto*/
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_int32_t_float(__Pyx_memviewslice, __Pyx_memviewslice, int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, int, __pyx_t_5numpy_int32_t, __pyx_t_5numpy_int32_t); /*proto*/
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_int = { "int", NULL, sizeof(int), { 0 }, 0, IS_UNSIGNED(int) ? 'U' : 'I', IS_UNSIGNED(int), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t = { "uint32_t", NULL, sizeof(__pyx_t_5numpy_uint32_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint32_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint32_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_float = { "float", NULL, sizeof(float), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t = { "int32_t", NULL, sizeof(__pyx_t_5numpy_int32_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int32_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int32_t), 0 };
+#define __Pyx_MODULE_NAME "chistogramnd"
+int __pyx_module_is_main_chistogramnd = 0;
+
+/* Implementation of 'chistogramnd' */
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_Exception;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_12chistogramnd_chistogramnd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sample, PyObject *__pyx_v_histo_range, PyObject *__pyx_v_n_bins, PyObject *__pyx_v_weights, PyObject *__pyx_v_weight_min, PyObject *__pyx_v_weight_max, PyObject *__pyx_v_last_bin_closed, PyObject *__pyx_v_histo, PyObject *__pyx_v_weighted_histo, PyObject *__pyx_v_wh_dtype); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_12chistogramnd___pyx_scope_struct__chistogramnd(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_B[] = "B";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_c[] = "c";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_np[] = "np";
+static char __pyx_k_rc[] = "rc";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k_any[] = "any";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_sum[] = "sum";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_tile[] = "tile";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_edges[] = "edges";
+static char __pyx_k_equal[] = "equal";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_histo[] = "histo";
+static char __pyx_k_i_dim[] = "i_dim";
+static char __pyx_k_int32[] = "int32";
+static char __pyx_k_ndmin[] = "ndmin";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_zeros[] = "zeros";
+static char __pyx_k_double[] = "double";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_n_bins[] = "n_bins";
+static char __pyx_k_n_dims[] = "n_dims";
+static char __pyx_k_n_elem[] = "n_elem";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_offset[] = "offset";
+static char __pyx_k_sample[] = "sample";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_uint32[] = "uint32";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_cumul_c[] = "cumul_c";
+static char __pyx_k_float32[] = "float32";
+static char __pyx_k_float64[] = "float64";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_histo_c[] = "histo_c";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_s_shape[] = "s_shape";
+static char __pyx_k_w_shape[] = "w_shape";
+static char __pyx_k_weights[] = "weights";
+static char __pyx_k_D_Naudet[] = "D. Naudet";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_n_bins_c[] = "n_bins_c";
+static char __pyx_k_sample_c[] = "sample_c";
+static char __pyx_k_wh_dtype[] = "wh_dtype";
+static char __pyx_k_Exception[] = "Exception";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_bin_edges[] = "bin_edges";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_weights_c[] = "weights_c";
+static char __pyx_k_01_02_2016[] = "01/02/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_weight_max[] = "weight_max";
+static char __pyx_k_weight_min[] = "weight_min";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_bin_edges_c[] = "bin_edges_c";
+static char __pyx_k_histo_range[] = "histo_range";
+static char __pyx_k_sample_type[] = "sample_type";
+static char __pyx_k_C_CONTIGUOUS[] = "C_CONTIGUOUS";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_chistogramnd[] = "chistogramnd";
+static char __pyx_k_option_flags[] = "option_flags";
+static char __pyx_k_output_shape[] = "output_shape";
+static char __pyx_k_weights_type[] = "weights_type";
+static char __pyx_k_histo_range_c[] = "histo_range_c";
+static char __pyx_k_i_histo_range[] = "i_histo_range";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_weighted_histo[] = "weighted_histo";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_err_histo_range[] = "err_histo_range";
+static char __pyx_k_last_bin_closed[] = "last_bin_closed";
+static char __pyx_k_ascontiguousarray[] = "ascontiguousarray";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_raise_unsupported_type[] = "raise_unsupported_type";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_wh_dtype_type_not_supported_0[] = "<wh_dtype> type not supported : {0}.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_users_payno_Documents_dev_esrf[] = "/users/payno/Documents/dev/esrf/silx/paynoSilx/silx/silx/math/histogramnd/chistogramnd.pyx";
+static char __pyx_k_weights_must_be_an_array_whose[] = "<weights> must be an array whose length is equal to the number of samples.";
+static char __pyx_k_Case_not_supported_sample_0_and[] = "Case not supported - sample:{0} and weights:{1}.";
+static char __pyx_k_histo_must_be_a_C_CONTIGUOUS_nu[] = "<histo> must be a C_CONTIGUOUS numpy array.";
+static char __pyx_k_histo_range_error_expected_n_di[] = "<histo_range> error : expected {n_dims} sets of lower and upper bin edges, got the following instead : {histo_range}. (provided <sample> contains {n_dims}D values)";
+static char __pyx_k_histogramnd_returned_an_error_0[] = "histogramnd returned an error : {0}";
+static char __pyx_k_mntdirect__scisoft_users_tvince[] = "/mntdirect/_scisoft/users/tvincent/src/silx/silx/math/histogramnd/chistogramnd.pyx";
+static char __pyx_k_n_bins_only_positive_values_all[] = "<n_bins> : only positive values allowed.";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_weighted_histo_must_be_a_C_CONT[] = "<weighted_histo> must be a C_CONTIGUOUS numpy array.";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_Provided_histo_array_doesn_t_hav[] = "Provided <histo> array doesn't have a shape compatible with <n_bins> : should be {0} instead of {1}.";
+static char __pyx_k_Provided_weighted_histo_array_do[] = "Provided <weighted_histo> array doesn't have a shape compatible with <n_bins> : should be {0} instead of {1}.";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_chistogramnd_locals_raise_unsupp[] = "chistogramnd.<locals>.raise_unsupported_type";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_histogramnd_failed_to_allocate_m[] = "histogramnd failed to allocate memory.";
+static char __pyx_k_n_bins_must_be_either_a_scalar_s[] = "n_bins must be either a scalar (same number of bins for all dimensions) or an array (number of bins for each dimension).";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static char __pyx_k_Provided_histo_array_doesn_t_hav_2[] = "Provided <histo> array doesn't have the expected type : should be {0} instead of {1}.";
+static char __pyx_k_Provided_weighted_histo_array_do_2[] = "Provided <weighted_histo> array doesn't have the expected type : should be {0} or {1} instead of {2}.";
+static PyObject *__pyx_kp_s_01_02_2016;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_n_s_C_CONTIGUOUS;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_kp_s_Case_not_supported_sample_0_and;
+static PyObject *__pyx_kp_s_D_Naudet;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_n_s_Exception;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_kp_s_Provided_histo_array_doesn_t_hav;
+static PyObject *__pyx_kp_s_Provided_histo_array_doesn_t_hav_2;
+static PyObject *__pyx_kp_s_Provided_weighted_histo_array_do;
+static PyObject *__pyx_kp_s_Provided_weighted_histo_array_do_2;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_any;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_ascontiguousarray;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_bin_edges;
+static PyObject *__pyx_n_s_bin_edges_c;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_chistogramnd;
+static PyObject *__pyx_n_s_chistogramnd_locals_raise_unsupp;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_cumul_c;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_double;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_edges;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_equal;
+static PyObject *__pyx_n_s_err_histo_range;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float32;
+static PyObject *__pyx_n_s_float64;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_histo;
+static PyObject *__pyx_n_s_histo_c;
+static PyObject *__pyx_kp_s_histo_must_be_a_C_CONTIGUOUS_nu;
+static PyObject *__pyx_n_s_histo_range;
+static PyObject *__pyx_n_s_histo_range_c;
+static PyObject *__pyx_kp_s_histo_range_error_expected_n_di;
+static PyObject *__pyx_kp_s_histogramnd_failed_to_allocate_m;
+static PyObject *__pyx_kp_s_histogramnd_returned_an_error_0;
+static PyObject *__pyx_n_s_i_dim;
+static PyObject *__pyx_n_s_i_histo_range;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_int32;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_last_bin_closed;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_kp_s_mntdirect__scisoft_users_tvince;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_n_bins;
+static PyObject *__pyx_n_s_n_bins_c;
+static PyObject *__pyx_kp_s_n_bins_must_be_either_a_scalar_s;
+static PyObject *__pyx_kp_s_n_bins_only_positive_values_all;
+static PyObject *__pyx_n_s_n_dims;
+static PyObject *__pyx_n_s_n_elem;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_ndmin;
+static PyObject *__pyx_n_s_np;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_n_s_offset;
+static PyObject *__pyx_n_s_option_flags;
+static PyObject *__pyx_n_s_output_shape;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_raise_unsupported_type;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_rc;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_s_shape;
+static PyObject *__pyx_n_s_sample;
+static PyObject *__pyx_n_s_sample_c;
+static PyObject *__pyx_n_s_sample_type;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_sum;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_n_s_tile;
+static PyObject *__pyx_n_s_uint32;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_n_s_w_shape;
+static PyObject *__pyx_n_s_weight_max;
+static PyObject *__pyx_n_s_weight_min;
+static PyObject *__pyx_n_s_weighted_histo;
+static PyObject *__pyx_kp_s_weighted_histo_must_be_a_C_CONT;
+static PyObject *__pyx_n_s_weights;
+static PyObject *__pyx_n_s_weights_c;
+static PyObject *__pyx_kp_s_weights_must_be_an_array_whose;
+static PyObject *__pyx_n_s_weights_type;
+static PyObject *__pyx_n_s_wh_dtype;
+static PyObject *__pyx_kp_s_wh_dtype_type_not_supported_0;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_n_s_zeros;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__23;
+static PyObject *__pyx_slice__24;
+static PyObject *__pyx_slice__25;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__26;
+static PyObject *__pyx_tuple__27;
+static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__30;
+static PyObject *__pyx_tuple__31;
+static PyObject *__pyx_tuple__32;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_codeobj__8;
+static PyObject *__pyx_codeobj__28;
+
+/* "chistogramnd.pyx":36
+ *
+ *
+ * def chistogramnd(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_12chistogramnd_1chistogramnd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_12chistogramnd_chistogramnd[] = "chistogramnd(sample, histo_range, n_bins, weights=None, weight_min=None, weight_max=None, last_bin_closed=False, histo=None, weighted_histo=None, wh_dtype=None)\nComputes the multidimensional histogram of some data.\n\n :param sample:\n The data to be histogrammed.\n Its shape must be either\n (N,) if it contains one dimensional coordinates,\n or an (N,D) array where the rows are the\n coordinates of points in a D dimensional space.\n The following dtypes are supported : :class:`numpy.float64`,\n :class:`numpy.float32`, :class:`numpy.int32`.\n\n .. warning:: if sample is not a C_CONTIGUOUS ndarray (e.g : a non\n contiguous slice) then histogramnd will have to do make an internal\n copy.\n :type sample: :class:`numpy.array`\n\n :param histo_range:\n A (N, 2) array containing the histogram range along each dimension,\n where N is the sample's number of dimensions.\n :type histo_range: array_like\n\n :param n_bins:\n The number of bins :\n * a scalar (same number of bins for all dimensions)\n * a D elements array (number of bins for each dimensions)\n :type n_bins: scalar or array_like\n\n :param weights:\n A N elements numpy array of values associated with\n each sample.\n The values of the *weighted_histo* array\n returned by the function are equal to the sum of\n the weights associated with the samples falling\n into each bin.\n The following dtypes are supported : :class:`numpy.float64`,\n :class:`numpy.float32`, :class:`numpy.int32`.\n\n .. note:: If None, the weighted histogram returned will be None.\n :type weights: *optional*, :class:`numpy.array`\n\n :param weight_min:\n Use this parameter to filter out all samples whose\n weights are lower than this value.\n\n .. note:: This value will be cast to the same type\n as *weig""hts*.\n :type weight_min: *optional*, scalar\n\n :param weight_max:\n Use this parameter to filter out all samples whose\n weights are higher than this value.\n\n .. note:: This value will be cast to the same type\n as *weights*.\n\n :type weight_max: *optional*, scalar\n\n :param last_bin_closed:\n By default the last bin is half\n open (i.e.: [x,y) ; x included, y\n excluded), like all the other bins.\n Set this parameter to true if you want\n the LAST bin to be closed.\n :type last_bin_closed: *optional*, :class:`python.boolean`\n\n :param histo:\n Use this parameter if you want to pass your\n own histogram array instead of the one\n created by this function. New values\n will be added to this array. The returned array\n will then be this one (same reference).\n\n .. warning:: If the histo array was created by a previous\n call to histogramnd then the user is\n responsible for providing the same parameters\n (*n_bins*, *histo_range*, ...).\n :type histo: *optional*, :class:`numpy.array`\n\n :param weighted_histo:\n Use this parameter if you want to pass your\n own weighted histogram array instead of\n the created by this function. New\n values will be added to this array. The returned array\n will then be this one (same reference).\n\n .. warning:: If the weighted_histo array was created by a previous\n call to histogramnd then the user is\n responsible for providing the same parameters\n (*n_bins*, *histo_range*, ...).\n\n .. warning:: if weighted_histo is not a C_CONTIGUOUS ndarray (e.g : a\n non contiguous slice) then histogramnd will have to do make an\n internal copy.\n :type weighted_histo: *optional*, :class:`numpy.array`\n \n :param wh_dtype: type of the weighted histogram array. T""his parameter is\n ignored if *weighted_histo* is provided. If not provided, the\n weighted histogram array will contain values of the same type as\n *weights*. Allowed values are : `numpu.double` and `numpy.float32`.\n :type wh_dtype: *optional*, numpy data type\n\n :return: Histogram (bin counts, always returned), weighted histogram of\n the sample (or *None* if weights is *None*) and bin edges for each\n dimension.\n :rtype: *tuple* (:class:`numpy.array`, :class:`numpy.array`, `tuple`) or\n (:class:`numpy.array`, None, `tuple`)\n ";
+static PyMethodDef __pyx_mdef_12chistogramnd_1chistogramnd = {"chistogramnd", (PyCFunction)__pyx_pw_12chistogramnd_1chistogramnd, METH_VARARGS|METH_KEYWORDS, __pyx_doc_12chistogramnd_chistogramnd};
+static PyObject *__pyx_pw_12chistogramnd_1chistogramnd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_sample = 0;
+ PyObject *__pyx_v_histo_range = 0;
+ PyObject *__pyx_v_n_bins = 0;
+ PyObject *__pyx_v_weights = 0;
+ PyObject *__pyx_v_weight_min = 0;
+ PyObject *__pyx_v_weight_max = 0;
+ PyObject *__pyx_v_last_bin_closed = 0;
+ PyObject *__pyx_v_histo = 0;
+ PyObject *__pyx_v_weighted_histo = 0;
+ PyObject *__pyx_v_wh_dtype = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("chistogramnd (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_sample,&__pyx_n_s_histo_range,&__pyx_n_s_n_bins,&__pyx_n_s_weights,&__pyx_n_s_weight_min,&__pyx_n_s_weight_max,&__pyx_n_s_last_bin_closed,&__pyx_n_s_histo,&__pyx_n_s_weighted_histo,&__pyx_n_s_wh_dtype,0};
+ PyObject* values[10] = {0,0,0,0,0,0,0,0,0,0};
+
+ /* "chistogramnd.pyx":39
+ * histo_range,
+ * n_bins,
+ * weights=None, # <<<<<<<<<<<<<<
+ * weight_min=None,
+ * weight_max=None,
+ */
+ values[3] = ((PyObject *)Py_None);
+
+ /* "chistogramnd.pyx":40
+ * n_bins,
+ * weights=None,
+ * weight_min=None, # <<<<<<<<<<<<<<
+ * weight_max=None,
+ * last_bin_closed=False,
+ */
+ values[4] = ((PyObject *)Py_None);
+
+ /* "chistogramnd.pyx":41
+ * weights=None,
+ * weight_min=None,
+ * weight_max=None, # <<<<<<<<<<<<<<
+ * last_bin_closed=False,
+ * histo=None,
+ */
+ values[5] = ((PyObject *)Py_None);
+
+ /* "chistogramnd.pyx":42
+ * weight_min=None,
+ * weight_max=None,
+ * last_bin_closed=False, # <<<<<<<<<<<<<<
+ * histo=None,
+ * weighted_histo=None,
+ */
+ values[6] = ((PyObject *)Py_False);
+
+ /* "chistogramnd.pyx":43
+ * weight_max=None,
+ * last_bin_closed=False,
+ * histo=None, # <<<<<<<<<<<<<<
+ * weighted_histo=None,
+ * wh_dtype=None):
+ */
+ values[7] = ((PyObject *)Py_None);
+
+ /* "chistogramnd.pyx":44
+ * last_bin_closed=False,
+ * histo=None,
+ * weighted_histo=None, # <<<<<<<<<<<<<<
+ * wh_dtype=None):
+ * """Computes the multidimensional histogram of some data.
+ */
+ values[8] = ((PyObject *)Py_None);
+
+ /* "chistogramnd.pyx":45
+ * histo=None,
+ * weighted_histo=None,
+ * wh_dtype=None): # <<<<<<<<<<<<<<
+ * """Computes the multidimensional histogram of some data.
+ *
+ */
+ values[9] = ((PyObject *)Py_None);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9);
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("chistogramnd", 0, 3, 10, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("chistogramnd", 0, 3, 10, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weights);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weight_min);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ case 5:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weight_max);
+ if (value) { values[5] = value; kw_args--; }
+ }
+ case 6:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed);
+ if (value) { values[6] = value; kw_args--; }
+ }
+ case 7:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_histo);
+ if (value) { values[7] = value; kw_args--; }
+ }
+ case 8:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weighted_histo);
+ if (value) { values[8] = value; kw_args--; }
+ }
+ case 9:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_wh_dtype);
+ if (value) { values[9] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "chistogramnd") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9);
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_sample = values[0];
+ __pyx_v_histo_range = values[1];
+ __pyx_v_n_bins = values[2];
+ __pyx_v_weights = values[3];
+ __pyx_v_weight_min = values[4];
+ __pyx_v_weight_max = values[5];
+ __pyx_v_last_bin_closed = values[6];
+ __pyx_v_histo = values[7];
+ __pyx_v_weighted_histo = values[8];
+ __pyx_v_wh_dtype = values[9];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("chistogramnd", 0, 3, 10, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd.chistogramnd", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_12chistogramnd_chistogramnd(__pyx_self, __pyx_v_sample, __pyx_v_histo_range, __pyx_v_n_bins, __pyx_v_weights, __pyx_v_weight_min, __pyx_v_weight_max, __pyx_v_last_bin_closed, __pyx_v_histo, __pyx_v_weighted_histo, __pyx_v_wh_dtype);
+
+ /* "chistogramnd.pyx":36
+ *
+ *
+ * def chistogramnd(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":292
+ * # functions. so I have to explicitly list them all...
+ *
+ * def raise_unsupported_type(): # <<<<<<<<<<<<<<
+ * raise TypeError('Case not supported - sample:{0} '
+ * 'and weights:{1}.'
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_12chistogramnd_12chistogramnd_1raise_unsupported_type(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyMethodDef __pyx_mdef_12chistogramnd_12chistogramnd_1raise_unsupported_type = {"raise_unsupported_type", (PyCFunction)__pyx_pw_12chistogramnd_12chistogramnd_1raise_unsupported_type, METH_NOARGS, 0};
+static PyObject *__pyx_pw_12chistogramnd_12chistogramnd_1raise_unsupported_type(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("raise_unsupported_type (wrapper)", 0);
+ __pyx_r = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_self);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(PyObject *__pyx_self) {
+ struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *__pyx_cur_scope;
+ struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *__pyx_outer_scope;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ Py_ssize_t __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("raise_unsupported_type", 0);
+ __pyx_outer_scope = (struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *) __Pyx_CyFunction_GetClosure(__pyx_self);
+ __pyx_cur_scope = __pyx_outer_scope;
+
+ /* "chistogramnd.pyx":295
+ * raise TypeError('Case not supported - sample:{0} '
+ * 'and weights:{1}.'
+ * ''.format(sample_type, weights_type)) # <<<<<<<<<<<<<<
+ *
+ * sample_c = np.ascontiguousarray(sample.reshape((sample.size,)))
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Case_not_supported_sample_0_and, __pyx_n_s_format); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ if (unlikely(!__pyx_cur_scope->__pyx_v_sample_type)) { __Pyx_RaiseClosureNameError("sample_type"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+ if (unlikely(!__pyx_cur_scope->__pyx_v_weights_type)) { __Pyx_RaiseClosureNameError("weights_type"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+ __pyx_t_3 = NULL;
+ __pyx_t_4 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_4 = 1;
+ }
+ }
+ __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (__pyx_t_3) {
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ }
+ __Pyx_INCREF(__pyx_cur_scope->__pyx_v_sample_type);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_cur_scope->__pyx_v_sample_type);
+ __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_sample_type);
+ __Pyx_INCREF(__pyx_cur_scope->__pyx_v_weights_type);
+ PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_cur_scope->__pyx_v_weights_type);
+ __Pyx_GIVEREF(__pyx_cur_scope->__pyx_v_weights_type);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":293
+ *
+ * def raise_unsupported_type():
+ * raise TypeError('Case not supported - sample:{0} ' # <<<<<<<<<<<<<<
+ * 'and weights:{1}.'
+ * ''.format(sample_type, weights_type))
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":292
+ * # functions. so I have to explicitly list them all...
+ *
+ * def raise_unsupported_type(): # <<<<<<<<<<<<<<
+ * raise TypeError('Case not supported - sample:{0} '
+ * 'and weights:{1}.'
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("chistogramnd.chistogramnd.raise_unsupported_type", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":36
+ *
+ *
+ * def chistogramnd(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+
+static PyObject *__pyx_pf_12chistogramnd_chistogramnd(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sample, PyObject *__pyx_v_histo_range, PyObject *__pyx_v_n_bins, PyObject *__pyx_v_weights, PyObject *__pyx_v_weight_min, PyObject *__pyx_v_weight_max, PyObject *__pyx_v_last_bin_closed, PyObject *__pyx_v_histo, PyObject *__pyx_v_weighted_histo, PyObject *__pyx_v_wh_dtype) {
+ struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *__pyx_cur_scope;
+ PyObject *__pyx_v_s_shape = NULL;
+ PyObject *__pyx_v_n_dims = NULL;
+ PyObject *__pyx_v_w_shape = NULL;
+ PyObject *__pyx_v_i_histo_range = NULL;
+ int __pyx_v_err_histo_range;
+ PyObject *__pyx_v_output_shape = NULL;
+ PyObject *__pyx_v_option_flags = NULL;
+ PyObject *__pyx_v_n_elem = NULL;
+ PyObject *__pyx_v_bin_edges = NULL;
+ PyObject *__pyx_v_raise_unsupported_type = 0;
+ PyObject *__pyx_v_sample_c = NULL;
+ PyObject *__pyx_v_weights_c = NULL;
+ PyObject *__pyx_v_histo_range_c = NULL;
+ PyObject *__pyx_v_n_bins_c = NULL;
+ PyObject *__pyx_v_histo_c = NULL;
+ PyObject *__pyx_v_cumul_c = NULL;
+ PyObject *__pyx_v_bin_edges_c = NULL;
+ long __pyx_v_rc;
+ PyObject *__pyx_v_edges = NULL;
+ PyObject *__pyx_v_offset = NULL;
+ PyObject *__pyx_v_i_dim = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ __Pyx_memviewslice __pyx_t_13 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_14 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_15;
+ int __pyx_t_16;
+ __Pyx_memviewslice __pyx_t_17 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_18 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_19 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_20 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_21 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_22;
+ double __pyx_t_23;
+ double __pyx_t_24;
+ __Pyx_memviewslice __pyx_t_25 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_26 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_27 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_28 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_29 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_30 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_31 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ float __pyx_t_32;
+ float __pyx_t_33;
+ __Pyx_memviewslice __pyx_t_34 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_35 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_36 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_37 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_38 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_39 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_40 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __pyx_t_5numpy_int32_t __pyx_t_41;
+ __pyx_t_5numpy_int32_t __pyx_t_42;
+ __Pyx_memviewslice __pyx_t_43 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_44 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_45 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_46 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_47 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_48 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_49 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_50 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_51 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_52 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_53 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_54 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_55 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_56 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_57 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_58 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_59 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_60 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_61 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_62 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_63 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_64 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_65 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_66 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_67 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_68 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_69 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_70 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_71 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_72 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_73 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_74 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_75 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_76 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_77 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_78 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_79 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_80 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_81 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_82 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_83 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_84 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_85 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_86 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_87 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_88 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_89 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_90 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_91 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_92 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_93 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_94 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_95 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_96 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_97 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_98 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_99 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_100 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_101 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_102 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_103 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_104 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_105 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_106 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_107 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_108 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_109 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_110 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_111 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_112 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_113 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_114 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_115 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_116 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_117 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_118 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_119 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_120 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_121 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_122 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_123 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_124 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_125 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_126 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_127 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_128 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_129 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_130 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_131 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_132 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_133 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_134 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_135 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_136 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_137 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_138 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_139 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_140 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_141 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_142 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_143 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_144 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_145 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_146 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_147 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ PyObject *(*__pyx_t_148)(PyObject *);
+ int __pyx_t_149;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("chistogramnd", 0);
+ __pyx_cur_scope = (struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *)__pyx_tp_new_12chistogramnd___pyx_scope_struct__chistogramnd(__pyx_ptype_12chistogramnd___pyx_scope_struct__chistogramnd, __pyx_empty_tuple, NULL);
+ if (unlikely(!__pyx_cur_scope)) {
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ }
+ __Pyx_GOTREF(__pyx_cur_scope);
+ __Pyx_INCREF(__pyx_v_histo_range);
+ __Pyx_INCREF(__pyx_v_n_bins);
+ __Pyx_INCREF(__pyx_v_weight_min);
+ __Pyx_INCREF(__pyx_v_weight_max);
+ __Pyx_INCREF(__pyx_v_histo);
+ __Pyx_INCREF(__pyx_v_weighted_histo);
+ __Pyx_INCREF(__pyx_v_wh_dtype);
+
+ /* "chistogramnd.pyx":154
+ * """ # noqa
+ *
+ * if wh_dtype is None: # <<<<<<<<<<<<<<
+ * wh_dtype = np.double
+ * elif wh_dtype not in (np.double, np.float32):
+ */
+ __pyx_t_1 = (__pyx_v_wh_dtype == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":155
+ *
+ * if wh_dtype is None:
+ * wh_dtype = np.double # <<<<<<<<<<<<<<
+ * elif wh_dtype not in (np.double, np.float32):
+ * raise ValueError('<wh_dtype> type not supported : {0}.'.format(wh_dtype))
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_wh_dtype, __pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+
+ /* "chistogramnd.pyx":156
+ * if wh_dtype is None:
+ * wh_dtype = np.double
+ * elif wh_dtype not in (np.double, np.float32): # <<<<<<<<<<<<<<
+ * raise ValueError('<wh_dtype> type not supported : {0}.'.format(wh_dtype))
+ *
+ */
+ __Pyx_INCREF(__pyx_v_wh_dtype);
+ __pyx_t_4 = __pyx_v_wh_dtype;
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyObject_RichCompare(__pyx_t_4, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyObject_RichCompare(__pyx_t_4, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L4_bool_binop_done:;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "chistogramnd.pyx":157
+ * wh_dtype = np.double
+ * elif wh_dtype not in (np.double, np.float32):
+ * raise ValueError('<wh_dtype> type not supported : {0}.'.format(wh_dtype)) # <<<<<<<<<<<<<<
+ *
+ * if (weighted_histo is not None and
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_wh_dtype_type_not_supported_0, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_v_wh_dtype); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ __Pyx_INCREF(__pyx_v_wh_dtype);
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_wh_dtype);
+ __Pyx_GIVEREF(__pyx_v_wh_dtype);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L3:;
+
+ /* "chistogramnd.pyx":159
+ * raise ValueError('<wh_dtype> type not supported : {0}.'.format(wh_dtype))
+ *
+ * if (weighted_histo is not None and # <<<<<<<<<<<<<<
+ * weighted_histo.flags['C_CONTIGUOUS'] is False):
+ * raise ValueError('<weighted_histo> must be a C_CONTIGUOUS numpy array.')
+ */
+ __pyx_t_2 = (__pyx_v_weighted_histo != Py_None);
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_1 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+
+ /* "chistogramnd.pyx":160
+ *
+ * if (weighted_histo is not None and
+ * weighted_histo.flags['C_CONTIGUOUS'] is False): # <<<<<<<<<<<<<<
+ * raise ValueError('<weighted_histo> must be a C_CONTIGUOUS numpy array.')
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_flags); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_GetItem(__pyx_t_4, __pyx_n_s_C_CONTIGUOUS); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_7 = (__pyx_t_3 == Py_False);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_2 = (__pyx_t_7 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "chistogramnd.pyx":161
+ * if (weighted_histo is not None and
+ * weighted_histo.flags['C_CONTIGUOUS'] is False):
+ * raise ValueError('<weighted_histo> must be a C_CONTIGUOUS numpy array.') # <<<<<<<<<<<<<<
+ *
+ * if histo is not None and histo.flags['C_CONTIGUOUS'] is False:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd.pyx":163
+ * raise ValueError('<weighted_histo> must be a C_CONTIGUOUS numpy array.')
+ *
+ * if histo is not None and histo.flags['C_CONTIGUOUS'] is False: # <<<<<<<<<<<<<<
+ * raise ValueError('<histo> must be a C_CONTIGUOUS numpy array.')
+ *
+ */
+ __pyx_t_2 = (__pyx_v_histo != Py_None);
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_1 = __pyx_t_7;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_flags); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_GetItem(__pyx_t_3, __pyx_n_s_C_CONTIGUOUS); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_7 = (__pyx_t_4 == Py_False);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_2 = (__pyx_t_7 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "chistogramnd.pyx":164
+ *
+ * if histo is not None and histo.flags['C_CONTIGUOUS'] is False:
+ * raise ValueError('<histo> must be a C_CONTIGUOUS numpy array.') # <<<<<<<<<<<<<<
+ *
+ * s_shape = sample.shape
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd.pyx":166
+ * raise ValueError('<histo> must be a C_CONTIGUOUS numpy array.')
+ *
+ * s_shape = sample.shape # <<<<<<<<<<<<<<
+ *
+ * n_dims = 1 if len(s_shape) == 1 else s_shape[1]
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_v_s_shape = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":168
+ * s_shape = sample.shape
+ *
+ * n_dims = 1 if len(s_shape) == 1 else s_shape[1] # <<<<<<<<<<<<<<
+ *
+ * if weights is not None:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_s_shape); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (((__pyx_t_8 == 1) != 0)) {
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_t_4 = __pyx_int_1;
+ } else {
+ __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_s_shape, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __pyx_t_3;
+ __pyx_t_3 = 0;
+ }
+ __pyx_v_n_dims = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":170
+ * n_dims = 1 if len(s_shape) == 1 else s_shape[1]
+ *
+ * if weights is not None: # <<<<<<<<<<<<<<
+ * w_shape = weights.shape
+ *
+ */
+ __pyx_t_1 = (__pyx_v_weights != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":171
+ *
+ * if weights is not None:
+ * w_shape = weights.shape # <<<<<<<<<<<<<<
+ *
+ * # making sure the sample and weights sizes are coherent
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_v_w_shape = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":175
+ * # making sure the sample and weights sizes are coherent
+ * # 2 different cases : 2D sample (N,M) and 1D (N)
+ * if len(w_shape) != 1 or w_shape[0] != s_shape[0]: # <<<<<<<<<<<<<<
+ * raise ValueError('<weights> must be an array whose length '
+ * 'is equal to the number of samples.')
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_w_shape); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((__pyx_t_8 != 1) != 0);
+ if (!__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_w_shape, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_s_shape, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_4, __pyx_t_3, Py_NE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L14_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":176
+ * # 2 different cases : 2D sample (N,M) and 1D (N)
+ * if len(w_shape) != 1 or w_shape[0] != s_shape[0]:
+ * raise ValueError('<weights> must be an array whose length ' # <<<<<<<<<<<<<<
+ * 'is equal to the number of samples.')
+ *
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd.pyx":179
+ * 'is equal to the number of samples.')
+ *
+ * weights_type = weights.dtype # <<<<<<<<<<<<<<
+ * else:
+ * weights_type = None
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_dtype); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_cur_scope->__pyx_v_weights_type = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L12;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":181
+ * weights_type = weights.dtype
+ * else:
+ * weights_type = None # <<<<<<<<<<<<<<
+ *
+ * # just in case those arent numpy arrays
+ */
+ __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_cur_scope->__pyx_v_weights_type = Py_None;
+ }
+ __pyx_L12:;
+
+ /* "chistogramnd.pyx":186
+ * # (this allows the user to provide native python lists,
+ * # => easier for testing)
+ * i_histo_range = histo_range # <<<<<<<<<<<<<<
+ * histo_range = np.array(histo_range)
+ * err_histo_range = False
+ */
+ __Pyx_INCREF(__pyx_v_histo_range);
+ __pyx_v_i_histo_range = __pyx_v_histo_range;
+
+ /* "chistogramnd.pyx":187
+ * # => easier for testing)
+ * i_histo_range = histo_range
+ * histo_range = np.array(histo_range) # <<<<<<<<<<<<<<
+ * err_histo_range = False
+ *
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_histo_range); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ __Pyx_INCREF(__pyx_v_histo_range);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_histo_range);
+ __Pyx_GIVEREF(__pyx_v_histo_range);
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF_SET(__pyx_v_histo_range, __pyx_t_6);
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":188
+ * i_histo_range = histo_range
+ * histo_range = np.array(histo_range)
+ * err_histo_range = False # <<<<<<<<<<<<<<
+ *
+ * if n_dims == 1:
+ */
+ __pyx_v_err_histo_range = 0;
+
+ /* "chistogramnd.pyx":190
+ * err_histo_range = False
+ *
+ * if n_dims == 1: # <<<<<<<<<<<<<<
+ * if histo_range.shape == (2,):
+ * pass
+ */
+ __pyx_t_6 = PyObject_RichCompare(__pyx_v_n_dims, __pyx_int_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":191
+ *
+ * if n_dims == 1:
+ * if histo_range.shape == (2,): # <<<<<<<<<<<<<<
+ * pass
+ * elif histo_range.shape == (1, 2):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_6, __pyx_tuple__4, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_2) {
+ goto __pyx_L17;
+ }
+
+ /* "chistogramnd.pyx":193
+ * if histo_range.shape == (2,):
+ * pass
+ * elif histo_range.shape == (1, 2): # <<<<<<<<<<<<<<
+ * histo_range.shape = -1
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_4, __pyx_tuple__5, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":194
+ * pass
+ * elif histo_range.shape == (1, 2):
+ * histo_range.shape = -1 # <<<<<<<<<<<<<<
+ * else:
+ * err_histo_range = True
+ */
+ if (__Pyx_PyObject_SetAttrStr(__pyx_v_histo_range, __pyx_n_s_shape, __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":196
+ * histo_range.shape = -1
+ * else:
+ * err_histo_range = True # <<<<<<<<<<<<<<
+ * elif n_dims != 1 and histo_range.shape != (n_dims, 2):
+ * err_histo_range = True
+ */
+ __pyx_v_err_histo_range = 1;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+
+ /* "chistogramnd.pyx":197
+ * else:
+ * err_histo_range = True
+ * elif n_dims != 1 and histo_range.shape != (n_dims, 2): # <<<<<<<<<<<<<<
+ * err_histo_range = True
+ *
+ */
+ __pyx_t_6 = PyObject_RichCompare(__pyx_v_n_dims, __pyx_int_1, Py_NE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L18_bool_binop_done;
+ }
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_n_dims);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_n_dims);
+ __Pyx_GIVEREF(__pyx_v_n_dims);
+ __Pyx_INCREF(__pyx_int_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_int_2);
+ __Pyx_GIVEREF(__pyx_int_2);
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_6, __pyx_t_4, Py_NE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L18_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":198
+ * err_histo_range = True
+ * elif n_dims != 1 and histo_range.shape != (n_dims, 2):
+ * err_histo_range = True # <<<<<<<<<<<<<<
+ *
+ * if err_histo_range:
+ */
+ __pyx_v_err_histo_range = 1;
+ goto __pyx_L16;
+ }
+ __pyx_L16:;
+
+ /* "chistogramnd.pyx":200
+ * err_histo_range = True
+ *
+ * if err_histo_range: # <<<<<<<<<<<<<<
+ * raise ValueError('<histo_range> error : expected {n_dims} sets of '
+ * 'lower and upper bin edges, '
+ */
+ __pyx_t_2 = (__pyx_v_err_histo_range != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":206
+ * '(provided <sample> contains '
+ * '{n_dims}D values)'
+ * ''.format(histo_range=i_histo_range, # <<<<<<<<<<<<<<
+ * n_dims=n_dims))
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_histo_range_error_expected_n_di, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_histo_range, __pyx_v_i_histo_range) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":207
+ * '{n_dims}D values)'
+ * ''.format(histo_range=i_histo_range,
+ * n_dims=n_dims)) # <<<<<<<<<<<<<<
+ *
+ * # checking n_bins size
+ */
+ if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_n_dims, __pyx_v_n_dims) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":206
+ * '(provided <sample> contains '
+ * '{n_dims}D values)'
+ * ''.format(histo_range=i_histo_range, # <<<<<<<<<<<<<<
+ * n_dims=n_dims))
+ *
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":201
+ *
+ * if err_histo_range:
+ * raise ValueError('<histo_range> error : expected {n_dims} sets of ' # <<<<<<<<<<<<<<
+ * 'lower and upper bin edges, '
+ * 'got the following instead : {histo_range}. '
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd.pyx":210
+ *
+ * # checking n_bins size
+ * n_bins = np.array(n_bins, ndmin=1) # <<<<<<<<<<<<<<
+ * if len(n_bins) == 1:
+ * n_bins = np.tile(n_bins, n_dims)
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_n_bins);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_n_bins);
+ __Pyx_GIVEREF(__pyx_v_n_bins);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_ndmin, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF_SET(__pyx_v_n_bins, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":211
+ * # checking n_bins size
+ * n_bins = np.array(n_bins, ndmin=1)
+ * if len(n_bins) == 1: # <<<<<<<<<<<<<<
+ * n_bins = np.tile(n_bins, n_dims)
+ * elif n_bins.shape != (n_dims,):
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_n_bins); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((__pyx_t_8 == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":212
+ * n_bins = np.array(n_bins, ndmin=1)
+ * if len(n_bins) == 1:
+ * n_bins = np.tile(n_bins, n_dims) # <<<<<<<<<<<<<<
+ * elif n_bins.shape != (n_dims,):
+ * raise ValueError('n_bins must be either a scalar (same number '
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_tile); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_4 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_n_bins);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+__pyx_t_8, __pyx_v_n_bins);
+ __Pyx_GIVEREF(__pyx_v_n_bins);
+ __Pyx_INCREF(__pyx_v_n_dims);
+ PyTuple_SET_ITEM(__pyx_t_4, 1+__pyx_t_8, __pyx_v_n_dims);
+ __Pyx_GIVEREF(__pyx_v_n_dims);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF_SET(__pyx_v_n_bins, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L21;
+ }
+
+ /* "chistogramnd.pyx":213
+ * if len(n_bins) == 1:
+ * n_bins = np.tile(n_bins, n_dims)
+ * elif n_bins.shape != (n_dims,): # <<<<<<<<<<<<<<
+ * raise ValueError('n_bins must be either a scalar (same number '
+ * 'of bins for all dimensions) or '
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_n_dims);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_n_dims);
+ __Pyx_GIVEREF(__pyx_v_n_dims);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_t_6, Py_NE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":214
+ * n_bins = np.tile(n_bins, n_dims)
+ * elif n_bins.shape != (n_dims,):
+ * raise ValueError('n_bins must be either a scalar (same number ' # <<<<<<<<<<<<<<
+ * 'of bins for all dimensions) or '
+ * 'an array (number of bins for each '
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L21:;
+
+ /* "chistogramnd.pyx":222
+ * # exception is thrown when calling np.zeros
+ * # also testing for negative/null values
+ * if np.any(np.equal(n_bins, None)) or np.any(n_bins <= 0): # <<<<<<<<<<<<<<
+ * raise ValueError('<n_bins> : only positive values allowed.')
+ *
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_any); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_equal); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_10 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_n_bins);
+ PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_8, __pyx_v_n_bins);
+ __Pyx_GIVEREF(__pyx_v_n_bins);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_8, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_10, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_9) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_6); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9); __Pyx_GIVEREF(__pyx_t_9); __pyx_t_9 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_10, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (!__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_any); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_n_bins, __pyx_int_0, Py_LE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":223
+ * # also testing for negative/null values
+ * if np.any(np.equal(n_bins, None)) or np.any(n_bins <= 0):
+ * raise ValueError('<n_bins> : only positive values allowed.') # <<<<<<<<<<<<<<
+ *
+ * output_shape = tuple(n_bins)
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd.pyx":225
+ * raise ValueError('<n_bins> : only positive values allowed.')
+ *
+ * output_shape = tuple(n_bins) # <<<<<<<<<<<<<<
+ *
+ * # checking the histo array, if provided
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_n_bins);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_n_bins);
+ __Pyx_GIVEREF(__pyx_v_n_bins);
+ __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), __pyx_t_4, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_output_shape = ((PyObject*)__pyx_t_10);
+ __pyx_t_10 = 0;
+
+ /* "chistogramnd.pyx":228
+ *
+ * # checking the histo array, if provided
+ * if histo is None: # <<<<<<<<<<<<<<
+ * histo = np.zeros(output_shape, dtype=np.uint32)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_histo == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "chistogramnd.pyx":229
+ * # checking the histo array, if provided
+ * if histo is None:
+ * histo = np.zeros(output_shape, dtype=np.uint32) # <<<<<<<<<<<<<<
+ * else:
+ * if histo.shape != output_shape:
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_zeros); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_INCREF(__pyx_v_output_shape);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_output_shape);
+ __Pyx_GIVEREF(__pyx_v_output_shape);
+ __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_uint32); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_10, __pyx_t_9); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF_SET(__pyx_v_histo, __pyx_t_6);
+ __pyx_t_6 = 0;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":231
+ * histo = np.zeros(output_shape, dtype=np.uint32)
+ * else:
+ * if histo.shape != output_shape: # <<<<<<<<<<<<<<
+ * raise ValueError('Provided <histo> array doesn\'t have '
+ * 'a shape compatible with <n_bins> '
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_9 = PyObject_RichCompare(__pyx_t_6, __pyx_v_output_shape, Py_NE); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_1) {
+
+ /* "chistogramnd.pyx":235
+ * 'a shape compatible with <n_bins> '
+ * ': should be {0} instead of {1}.'
+ * ''.format(output_shape, histo.shape)) # <<<<<<<<<<<<<<
+ * if histo.dtype != np.uint32:
+ * raise ValueError('Provided <histo> array doesn\'t have '
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Provided_histo_array_doesn_t_hav, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_4 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_3 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_output_shape);
+ PyTuple_SET_ITEM(__pyx_t_3, 0+__pyx_t_8, __pyx_v_output_shape);
+ __Pyx_GIVEREF(__pyx_v_output_shape);
+ PyTuple_SET_ITEM(__pyx_t_3, 1+__pyx_t_8, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_3, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":232
+ * else:
+ * if histo.shape != output_shape:
+ * raise ValueError('Provided <histo> array doesn\'t have ' # <<<<<<<<<<<<<<
+ * 'a shape compatible with <n_bins> '
+ * ': should be {0} instead of {1}.'
+ */
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_6, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd.pyx":236
+ * ': should be {0} instead of {1}.'
+ * ''.format(output_shape, histo.shape))
+ * if histo.dtype != np.uint32: # <<<<<<<<<<<<<<
+ * raise ValueError('Provided <histo> array doesn\'t have '
+ * 'the expected type '
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_uint32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_9, __pyx_t_3, Py_NE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (__pyx_t_1) {
+
+ /* "chistogramnd.pyx":240
+ * 'the expected type '
+ * ': should be {0} instead of {1}.'
+ * ''.format(np.uint32, histo.dtype)) # <<<<<<<<<<<<<<
+ *
+ * # checking the weighted_histo array, if provided
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Provided_histo_array_doesn_t_hav_2, __pyx_n_s_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_uint32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_4 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_5 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_8, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_8, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_10 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":237
+ * ''.format(output_shape, histo.shape))
+ * if histo.dtype != np.uint32:
+ * raise ValueError('Provided <histo> array doesn\'t have ' # <<<<<<<<<<<<<<
+ * 'the expected type '
+ * ': should be {0} instead of {1}.'
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ __pyx_L25:;
+
+ /* "chistogramnd.pyx":243
+ *
+ * # checking the weighted_histo array, if provided
+ * if weights_type is None: # <<<<<<<<<<<<<<
+ * # no weights provided, not creating the weighted_histo array
+ * weighted_histo = None
+ */
+ __pyx_t_1 = (__pyx_cur_scope->__pyx_v_weights_type == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":245
+ * if weights_type is None:
+ * # no weights provided, not creating the weighted_histo array
+ * weighted_histo = None # <<<<<<<<<<<<<<
+ * elif weighted_histo is None:
+ * # weights provided, but no weighted_histo, creating it
+ */
+ __Pyx_INCREF(Py_None);
+ __Pyx_DECREF_SET(__pyx_v_weighted_histo, Py_None);
+ goto __pyx_L28;
+ }
+
+ /* "chistogramnd.pyx":246
+ * # no weights provided, not creating the weighted_histo array
+ * weighted_histo = None
+ * elif weighted_histo is None: # <<<<<<<<<<<<<<
+ * # weights provided, but no weighted_histo, creating it
+ * if wh_dtype is None:
+ */
+ __pyx_t_2 = (__pyx_v_weighted_histo == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "chistogramnd.pyx":248
+ * elif weighted_histo is None:
+ * # weights provided, but no weighted_histo, creating it
+ * if wh_dtype is None: # <<<<<<<<<<<<<<
+ * wh_dtype = weights_type
+ * weighted_histo = np.zeros(output_shape, dtype=wh_dtype)
+ */
+ __pyx_t_1 = (__pyx_v_wh_dtype == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":249
+ * # weights provided, but no weighted_histo, creating it
+ * if wh_dtype is None:
+ * wh_dtype = weights_type # <<<<<<<<<<<<<<
+ * weighted_histo = np.zeros(output_shape, dtype=wh_dtype)
+ * else:
+ */
+ __Pyx_INCREF(__pyx_cur_scope->__pyx_v_weights_type);
+ __Pyx_DECREF_SET(__pyx_v_wh_dtype, __pyx_cur_scope->__pyx_v_weights_type);
+ goto __pyx_L29;
+ }
+ __pyx_L29:;
+
+ /* "chistogramnd.pyx":250
+ * if wh_dtype is None:
+ * wh_dtype = weights_type
+ * weighted_histo = np.zeros(output_shape, dtype=wh_dtype) # <<<<<<<<<<<<<<
+ * else:
+ * # weighted_histo provided, checking shape/dtype
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_zeros); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_output_shape);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_output_shape);
+ __Pyx_GIVEREF(__pyx_v_output_shape);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_v_wh_dtype) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, __pyx_t_5); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF_SET(__pyx_v_weighted_histo, __pyx_t_9);
+ __pyx_t_9 = 0;
+ goto __pyx_L28;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":253
+ * else:
+ * # weighted_histo provided, checking shape/dtype
+ * if weighted_histo.shape != output_shape: # <<<<<<<<<<<<<<
+ * raise ValueError('Provided <weighted_histo> array doesn\'t have '
+ * 'a shape compatible with <n_bins> '
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_9, __pyx_v_output_shape, Py_NE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":257
+ * 'a shape compatible with <n_bins> '
+ * ': should be {0} instead of {1}.'
+ * ''.format(output_shape, weighted_histo.shape)) # <<<<<<<<<<<<<<
+ * if (weighted_histo.dtype != np.float64 and
+ * weighted_histo.dtype != np.float32):
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Provided_weighted_histo_array_do, __pyx_n_s_format); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_3 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_10 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ if (__pyx_t_3) {
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_output_shape);
+ PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_8, __pyx_v_output_shape);
+ __Pyx_GIVEREF(__pyx_v_output_shape);
+ PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_10, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "chistogramnd.pyx":254
+ * # weighted_histo provided, checking shape/dtype
+ * if weighted_histo.shape != output_shape:
+ * raise ValueError('Provided <weighted_histo> array doesn\'t have ' # <<<<<<<<<<<<<<
+ * 'a shape compatible with <n_bins> '
+ * ': should be {0} instead of {1}.'
+ */
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd.pyx":258
+ * ': should be {0} instead of {1}.'
+ * ''.format(output_shape, weighted_histo.shape))
+ * if (weighted_histo.dtype != np.float64 and # <<<<<<<<<<<<<<
+ * weighted_histo.dtype != np.float32):
+ * raise ValueError('Provided <weighted_histo> array doesn\'t have '
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float64); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_t_5, __pyx_t_10, Py_NE); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L32_bool_binop_done;
+ }
+
+ /* "chistogramnd.pyx":259
+ * ''.format(output_shape, weighted_histo.shape))
+ * if (weighted_histo.dtype != np.float64 and
+ * weighted_histo.dtype != np.float32): # <<<<<<<<<<<<<<
+ * raise ValueError('Provided <weighted_histo> array doesn\'t have '
+ * 'the expected type '
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_t_9, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L32_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":263
+ * 'the expected type '
+ * ': should be {0} or {1} instead of {2}.'
+ * ''.format(np.double, # <<<<<<<<<<<<<<
+ * np.float32,
+ * weighted_histo.dtype))
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Provided_weighted_histo_array_do_2, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_double); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "chistogramnd.pyx":264
+ * ': should be {0} or {1} instead of {2}.'
+ * ''.format(np.double,
+ * np.float32, # <<<<<<<<<<<<<<
+ * weighted_histo.dtype))
+ *
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float32); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "chistogramnd.pyx":265
+ * ''.format(np.double,
+ * np.float32,
+ * weighted_histo.dtype)) # <<<<<<<<<<<<<<
+ *
+ * option_flags = 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_4 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_11 = PyTuple_New(3+__pyx_t_8); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_11, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_11, 1+__pyx_t_8, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_11, 2+__pyx_t_8, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_6 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_11, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":260
+ * if (weighted_histo.dtype != np.float64 and
+ * weighted_histo.dtype != np.float32):
+ * raise ValueError('Provided <weighted_histo> array doesn\'t have ' # <<<<<<<<<<<<<<
+ * 'the expected type '
+ * ': should be {0} or {1} instead of {2}.'
+ */
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_5, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ __pyx_L28:;
+
+ /* "chistogramnd.pyx":267
+ * weighted_histo.dtype))
+ *
+ * option_flags = 0 # <<<<<<<<<<<<<<
+ *
+ * if weight_min is not None:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_v_option_flags = __pyx_int_0;
+
+ /* "chistogramnd.pyx":269
+ * option_flags = 0
+ *
+ * if weight_min is not None: # <<<<<<<<<<<<<<
+ * option_flags |= histogramnd_c.HISTO_WEIGHT_MIN
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_weight_min != Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "chistogramnd.pyx":270
+ *
+ * if weight_min is not None:
+ * option_flags |= histogramnd_c.HISTO_WEIGHT_MIN # <<<<<<<<<<<<<<
+ * else:
+ * weight_min = 0
+ */
+ __pyx_t_10 = PyInt_FromLong(HISTO_WEIGHT_MIN); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = PyNumber_InPlaceOr(__pyx_v_option_flags, __pyx_t_10); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF_SET(__pyx_v_option_flags, __pyx_t_5);
+ __pyx_t_5 = 0;
+ goto __pyx_L34;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":272
+ * option_flags |= histogramnd_c.HISTO_WEIGHT_MIN
+ * else:
+ * weight_min = 0 # <<<<<<<<<<<<<<
+ *
+ * if weight_max is not None:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __Pyx_DECREF_SET(__pyx_v_weight_min, __pyx_int_0);
+ }
+ __pyx_L34:;
+
+ /* "chistogramnd.pyx":274
+ * weight_min = 0
+ *
+ * if weight_max is not None: # <<<<<<<<<<<<<<
+ * option_flags |= histogramnd_c.HISTO_WEIGHT_MAX
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_weight_max != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":275
+ *
+ * if weight_max is not None:
+ * option_flags |= histogramnd_c.HISTO_WEIGHT_MAX # <<<<<<<<<<<<<<
+ * else:
+ * weight_max = 0
+ */
+ __pyx_t_5 = PyInt_FromLong(HISTO_WEIGHT_MAX); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_10 = PyNumber_InPlaceOr(__pyx_v_option_flags, __pyx_t_5); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF_SET(__pyx_v_option_flags, __pyx_t_10);
+ __pyx_t_10 = 0;
+ goto __pyx_L35;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":277
+ * option_flags |= histogramnd_c.HISTO_WEIGHT_MAX
+ * else:
+ * weight_max = 0 # <<<<<<<<<<<<<<
+ *
+ * if last_bin_closed is not None and last_bin_closed:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __Pyx_DECREF_SET(__pyx_v_weight_max, __pyx_int_0);
+ }
+ __pyx_L35:;
+
+ /* "chistogramnd.pyx":279
+ * weight_max = 0
+ *
+ * if last_bin_closed is not None and last_bin_closed: # <<<<<<<<<<<<<<
+ * option_flags |= histogramnd_c.HISTO_LAST_BIN_CLOSED
+ *
+ */
+ __pyx_t_1 = (__pyx_v_last_bin_closed != Py_None);
+ __pyx_t_7 = (__pyx_t_1 != 0);
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_2 = __pyx_t_7;
+ goto __pyx_L37_bool_binop_done;
+ }
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_v_last_bin_closed); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __pyx_t_7;
+ __pyx_L37_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd.pyx":280
+ *
+ * if last_bin_closed is not None and last_bin_closed:
+ * option_flags |= histogramnd_c.HISTO_LAST_BIN_CLOSED # <<<<<<<<<<<<<<
+ *
+ * sample_type = sample.dtype
+ */
+ __pyx_t_10 = PyInt_FromLong(HISTO_LAST_BIN_CLOSED); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = PyNumber_InPlaceOr(__pyx_v_option_flags, __pyx_t_10); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF_SET(__pyx_v_option_flags, __pyx_t_5);
+ __pyx_t_5 = 0;
+ goto __pyx_L36;
+ }
+ __pyx_L36:;
+
+ /* "chistogramnd.pyx":282
+ * option_flags |= histogramnd_c.HISTO_LAST_BIN_CLOSED
+ *
+ * sample_type = sample.dtype # <<<<<<<<<<<<<<
+ *
+ * n_elem = sample.size // n_dims
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_dtype); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_cur_scope->__pyx_v_sample_type = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":284
+ * sample_type = sample.dtype
+ *
+ * n_elem = sample.size // n_dims # <<<<<<<<<<<<<<
+ *
+ * bin_edges = np.zeros(n_bins.sum() + n_bins.size, dtype=np.double)
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_10 = PyNumber_FloorDivide(__pyx_t_5, __pyx_v_n_dims); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_n_elem = __pyx_t_10;
+ __pyx_t_10 = 0;
+
+ /* "chistogramnd.pyx":286
+ * n_elem = sample.size // n_dims
+ *
+ * bin_edges = np.zeros(n_bins.sum() + n_bins.size, dtype=np.double) # <<<<<<<<<<<<<<
+ *
+ * # wanted to store the functions in a dict (with the supported types
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_sum); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_11))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_11);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_11, function);
+ }
+ }
+ if (__pyx_t_9) {
+ __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_t_11, __pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_10 = __Pyx_PyObject_CallNoArg(__pyx_t_11); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_9 = PyNumber_Add(__pyx_t_10, __pyx_t_11); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_double); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_dtype, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_11, __pyx_t_9); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 286; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_bin_edges = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":292
+ * # functions. so I have to explicitly list them all...
+ *
+ * def raise_unsupported_type(): # <<<<<<<<<<<<<<
+ * raise TypeError('Case not supported - sample:{0} '
+ * 'and weights:{1}.'
+ */
+ __pyx_t_3 = __Pyx_CyFunction_NewEx(&__pyx_mdef_12chistogramnd_12chistogramnd_1raise_unsupported_type, 0, __pyx_n_s_chistogramnd_locals_raise_unsupp, ((PyObject*)__pyx_cur_scope), __pyx_n_s_chistogramnd, __pyx_d, ((PyObject *)__pyx_codeobj__8)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_raise_unsupported_type = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":297
+ * ''.format(sample_type, weights_type))
+ *
+ * sample_c = np.ascontiguousarray(sample.reshape((sample.size,))) # <<<<<<<<<<<<<<
+ *
+ * weights_c = (np.ascontiguousarray(weights.reshape((weights.size,)))
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_size); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_10) {
+ __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_9);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_11))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_11);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_11, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_11, __pyx_t_9); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_v_sample_c = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":300
+ *
+ * weights_c = (np.ascontiguousarray(weights.reshape((weights.size,)))
+ * if weights is not None else None) # <<<<<<<<<<<<<<
+ *
+ * histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)),
+ */
+ __pyx_t_2 = (__pyx_v_weights != Py_None);
+ if ((__pyx_t_2 != 0)) {
+
+ /* "chistogramnd.pyx":299
+ * sample_c = np.ascontiguousarray(sample.reshape((sample.size,)))
+ *
+ * weights_c = (np.ascontiguousarray(weights.reshape((weights.size,))) # <<<<<<<<<<<<<<
+ * if weights is not None else None)
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_10); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_12, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_11);
+ } else {
+ __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_12, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_3 = __pyx_t_11;
+ __pyx_t_11 = 0;
+ } else {
+
+ /* "chistogramnd.pyx":300
+ *
+ * weights_c = (np.ascontiguousarray(weights.reshape((weights.size,)))
+ * if weights is not None else None) # <<<<<<<<<<<<<<
+ *
+ * histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)),
+ */
+ __Pyx_INCREF(Py_None);
+ __pyx_t_3 = Py_None;
+ }
+ __pyx_v_weights_c = __pyx_t_3;
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":302
+ * if weights is not None else None)
+ *
+ * histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)), # <<<<<<<<<<<<<<
+ * dtype=np.double)
+ *
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_reshape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_size); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ __pyx_t_12 = 0;
+ __pyx_t_12 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_12)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_12);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ }
+ }
+ if (!__pyx_t_12) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_12); __Pyx_GIVEREF(__pyx_t_12); __pyx_t_12 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "chistogramnd.pyx":303
+ *
+ * histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)),
+ * dtype=np.double) # <<<<<<<<<<<<<<
+ *
+ * n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)),
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_double); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":302
+ * if weights is not None else None)
+ *
+ * histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)), # <<<<<<<<<<<<<<
+ * dtype=np.double)
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_9, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_histo_range_c = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":305
+ * dtype=np.double)
+ *
+ * n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)), # <<<<<<<<<<<<<<
+ * dtype=np.int32)
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_reshape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_size); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ __pyx_t_11 = 0;
+ __pyx_t_11 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_11)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_11);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ }
+ }
+ if (!__pyx_t_11) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_11); __Pyx_GIVEREF(__pyx_t_11); __pyx_t_11 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_12, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+
+ /* "chistogramnd.pyx":306
+ *
+ * n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)),
+ * dtype=np.int32) # <<<<<<<<<<<<<<
+ *
+ * histo_c = histo.reshape((histo.size,))
+ */
+ __pyx_t_12 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_12, __pyx_n_s_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+ if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":305
+ * dtype=np.double)
+ *
+ * n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)), # <<<<<<<<<<<<<<
+ * dtype=np.int32)
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_n_bins_c = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":308
+ * dtype=np.int32)
+ *
+ * histo_c = histo.reshape((histo.size,)) # <<<<<<<<<<<<<<
+ *
+ * if weighted_histo is not None:
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_reshape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_size); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_9) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_12 = PyTuple_New(1+1); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ PyTuple_SET_ITEM(__pyx_t_12, 0, __pyx_t_9); __Pyx_GIVEREF(__pyx_t_9); __pyx_t_9 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_12, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_12, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_histo_c = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":310
+ * histo_c = histo.reshape((histo.size,))
+ *
+ * if weighted_histo is not None: # <<<<<<<<<<<<<<
+ * cumul_c = weighted_histo.reshape((weighted_histo.size,))
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_weighted_histo != Py_None);
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":311
+ *
+ * if weighted_histo is not None:
+ * cumul_c = weighted_histo.reshape((weighted_histo.size,)) # <<<<<<<<<<<<<<
+ * else:
+ * cumul_c = None
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_reshape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_size); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ __pyx_t_12 = 0;
+ __pyx_t_12 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_12)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_12);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_12) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_12); __Pyx_GIVEREF(__pyx_t_12); __pyx_t_12 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_9, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_cumul_c = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L39;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":313
+ * cumul_c = weighted_histo.reshape((weighted_histo.size,))
+ * else:
+ * cumul_c = None # <<<<<<<<<<<<<<
+ *
+ * bin_edges_c = np.ascontiguousarray(bin_edges.reshape((bin_edges.size,)))
+ */
+ __Pyx_INCREF(Py_None);
+ __pyx_v_cumul_c = Py_None;
+ }
+ __pyx_L39:;
+
+ /* "chistogramnd.pyx":315
+ * cumul_c = None
+ *
+ * bin_edges_c = np.ascontiguousarray(bin_edges.reshape((bin_edges.size,))) # <<<<<<<<<<<<<<
+ *
+ * rc = 0
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_bin_edges, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_12 = __Pyx_PyObject_GetAttrStr(__pyx_v_bin_edges, __pyx_n_s_size); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_12);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_12);
+ __Pyx_GIVEREF(__pyx_t_12);
+ __pyx_t_12 = 0;
+ __pyx_t_12 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_12 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_12)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_12);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_12) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_12); __Pyx_GIVEREF(__pyx_t_12); __pyx_t_12 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ __pyx_t_11 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_10, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_10, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_bin_edges_c = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":317
+ * bin_edges_c = np.ascontiguousarray(bin_edges.reshape((bin_edges.size,)))
+ *
+ * rc = 0 # <<<<<<<<<<<<<<
+ *
+ * if weighted_histo is None or weighted_histo.dtype == np.double:
+ */
+ __pyx_v_rc = 0;
+
+ /* "chistogramnd.pyx":319
+ * rc = 0
+ *
+ * if weighted_histo is None or weighted_histo.dtype == np.double: # <<<<<<<<<<<<<<
+ *
+ * if sample_type == np.float64:
+ */
+ __pyx_t_2 = (__pyx_v_weighted_histo == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (!__pyx_t_1) {
+ } else {
+ __pyx_t_7 = __pyx_t_1;
+ goto __pyx_L41_bool_binop_done;
+ }
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_double); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_t_5, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_7 = __pyx_t_1;
+ __pyx_L41_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":321
+ * if weighted_histo is None or weighted_histo.dtype == np.double:
+ *
+ * if sample_type == np.float64: # <<<<<<<<<<<<<<
+ *
+ * if weights_type == np.float64 or weights_type is None:
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float64); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_sample_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":323
+ * if sample_type == np.float64:
+ *
+ * if weights_type == np.float64 or weights_type is None: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_double_double_double(sample_c,
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float64); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (!__pyx_t_1) {
+ } else {
+ __pyx_t_7 = __pyx_t_1;
+ goto __pyx_L45_bool_binop_done;
+ }
+ __pyx_t_1 = (__pyx_cur_scope->__pyx_v_weights_type == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ __pyx_t_7 = __pyx_t_2;
+ __pyx_L45_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":325
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_double_double_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_13 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_13.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":326
+ *
+ * rc = _histogramnd_double_double_double(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_14 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_14.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":327
+ * rc = _histogramnd_double_double_double(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":328
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":329
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_17 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_17.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":330
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_18 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_18.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":331
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_19 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_19.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":332
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_20 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_20.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":333
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_21 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_21.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":334
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":335
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_23 = __pyx_PyFloat_AsDouble(__pyx_v_weight_min); if (unlikely((__pyx_t_23 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":336
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.float32:
+ */
+ __pyx_t_24 = __pyx_PyFloat_AsDouble(__pyx_v_weight_max); if (unlikely((__pyx_t_24 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":325
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_double_double_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_double_double_double(__pyx_t_13, __pyx_t_14, __pyx_t_15, __pyx_t_16, __pyx_t_17, __pyx_t_18, __pyx_t_19, __pyx_t_20, __pyx_t_21, __pyx_t_22, __pyx_t_23, __pyx_t_24);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_13, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_14, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_17, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_18, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_19, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_20, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_21, 1);
+ goto __pyx_L44;
+ }
+
+ /* "chistogramnd.pyx":338
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.float32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_double_float_double(sample_c,
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":340
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_double_float_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_25 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_25.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":341
+ *
+ * rc = _histogramnd_double_float_double(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_26 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_26.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":342
+ * rc = _histogramnd_double_float_double(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":343
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 343; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":344
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_27 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_27.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 344; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":345
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_28 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_28.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 345; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":346
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_29 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_29.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":347
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_30 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_30.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":348
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_31 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_31.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 348; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":349
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":350
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_32 = __pyx_PyFloat_AsFloat(__pyx_v_weight_min); if (unlikely((__pyx_t_32 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":351
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.int32:
+ */
+ __pyx_t_33 = __pyx_PyFloat_AsFloat(__pyx_v_weight_max); if (unlikely((__pyx_t_33 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":340
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_double_float_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_double_float_double(__pyx_t_25, __pyx_t_26, __pyx_t_22, __pyx_t_16, __pyx_t_27, __pyx_t_28, __pyx_t_29, __pyx_t_30, __pyx_t_31, __pyx_t_15, __pyx_t_32, __pyx_t_33);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_25, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_26, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_27, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_28, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_29, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_30, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_31, 1);
+ goto __pyx_L44;
+ }
+
+ /* "chistogramnd.pyx":353
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.int32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_double_int32_t_double(sample_c,
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_int32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":355
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_double_int32_t_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_34 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_34.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":356
+ *
+ * rc = _histogramnd_double_int32_t_double(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_35 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_35.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":357
+ * rc = _histogramnd_double_int32_t_double(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":358
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":359
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_36 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_36.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":360
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_37 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_37.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":361
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_38 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_38.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":362
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_39 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_39.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":363
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_40 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_40.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":364
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":365
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_41 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_min); if (unlikely((__pyx_t_41 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":366
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_t_42 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_max); if (unlikely((__pyx_t_42 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":355
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_double_int32_t_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_double_int32_t_double(__pyx_t_34, __pyx_t_35, __pyx_t_15, __pyx_t_16, __pyx_t_36, __pyx_t_37, __pyx_t_38, __pyx_t_39, __pyx_t_40, __pyx_t_22, __pyx_t_41, __pyx_t_42);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_34, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_35, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_36, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_37, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_38, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_39, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_40, 1);
+ goto __pyx_L44;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":369
+ *
+ * else:
+ * raise_unsupported_type() # <<<<<<<<<<<<<<
+ *
+ * # endif sample_type == np.float64
+ */
+ __pyx_t_9 = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_v_raise_unsupported_type); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __pyx_L44:;
+ goto __pyx_L43;
+ }
+
+ /* "chistogramnd.pyx":372
+ *
+ * # endif sample_type == np.float64
+ * elif sample_type == np.float32: # <<<<<<<<<<<<<<
+ *
+ * if weights_type == np.float64 or weights_type is None:
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_sample_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":374
+ * elif sample_type == np.float32:
+ *
+ * if weights_type == np.float64 or weights_type is None: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_float_double_double(sample_c,
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float64); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_7 = __pyx_t_2;
+ goto __pyx_L48_bool_binop_done;
+ }
+ __pyx_t_2 = (__pyx_cur_scope->__pyx_v_weights_type == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ __pyx_t_7 = __pyx_t_1;
+ __pyx_L48_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":376
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_float_double_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_43 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_43.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 376; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":377
+ *
+ * rc = _histogramnd_float_double_double(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_44 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_44.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":378
+ * rc = _histogramnd_float_double_double(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":379
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":380
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_45 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_45.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":381
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_46 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_46.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":382
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_47 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_47.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 382; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":383
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_48 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_48.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":384
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_49 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_49.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":385
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":386
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_24 = __pyx_PyFloat_AsDouble(__pyx_v_weight_min); if (unlikely((__pyx_t_24 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":387
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.float32:
+ */
+ __pyx_t_23 = __pyx_PyFloat_AsDouble(__pyx_v_weight_max); if (unlikely((__pyx_t_23 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 387; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":376
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_float_double_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_float_double_double(__pyx_t_43, __pyx_t_44, __pyx_t_22, __pyx_t_16, __pyx_t_45, __pyx_t_46, __pyx_t_47, __pyx_t_48, __pyx_t_49, __pyx_t_15, __pyx_t_24, __pyx_t_23);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_43, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_44, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_45, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_46, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_47, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_48, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_49, 1);
+ goto __pyx_L47;
+ }
+
+ /* "chistogramnd.pyx":389
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.float32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_float_float_double(sample_c,
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 389; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":391
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_float_float_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_50 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_50.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 391; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":392
+ *
+ * rc = _histogramnd_float_float_double(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_51 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_51.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 392; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":393
+ * rc = _histogramnd_float_float_double(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 393; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":394
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 394; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":395
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_52 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_52.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":396
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_53 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_53.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":397
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_54 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_54.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":398
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_55 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_55.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":399
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_56 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_56.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 399; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":400
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 400; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":401
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_33 = __pyx_PyFloat_AsFloat(__pyx_v_weight_min); if (unlikely((__pyx_t_33 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 401; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":402
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.int32:
+ */
+ __pyx_t_32 = __pyx_PyFloat_AsFloat(__pyx_v_weight_max); if (unlikely((__pyx_t_32 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 402; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":391
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_float_float_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_float_float_double(__pyx_t_50, __pyx_t_51, __pyx_t_15, __pyx_t_16, __pyx_t_52, __pyx_t_53, __pyx_t_54, __pyx_t_55, __pyx_t_56, __pyx_t_22, __pyx_t_33, __pyx_t_32);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_50, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_51, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_52, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_53, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_54, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_55, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_56, 1);
+ goto __pyx_L47;
+ }
+
+ /* "chistogramnd.pyx":404
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.int32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_float_int32_t_double(sample_c,
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_int32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 404; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":406
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_float_int32_t_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_57 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_57.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 406; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":407
+ *
+ * rc = _histogramnd_float_int32_t_double(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_58 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_58.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":408
+ * rc = _histogramnd_float_int32_t_double(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":409
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":410
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_59 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_59.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 410; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":411
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_60 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_60.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":412
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_61 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_61.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":413
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_62 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_62.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":414
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_63 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_63.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 414; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":415
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 415; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":416
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_42 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_min); if (unlikely((__pyx_t_42 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 416; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":417
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_t_41 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_max); if (unlikely((__pyx_t_41 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":406
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_float_int32_t_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_float_int32_t_double(__pyx_t_57, __pyx_t_58, __pyx_t_22, __pyx_t_16, __pyx_t_59, __pyx_t_60, __pyx_t_61, __pyx_t_62, __pyx_t_63, __pyx_t_15, __pyx_t_42, __pyx_t_41);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_57, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_58, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_59, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_60, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_61, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_62, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_63, 1);
+ goto __pyx_L47;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":420
+ *
+ * else:
+ * raise_unsupported_type() # <<<<<<<<<<<<<<
+ *
+ * # endif sample_type == np.float32
+ */
+ __pyx_t_9 = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_v_raise_unsupported_type); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __pyx_L47:;
+ goto __pyx_L43;
+ }
+
+ /* "chistogramnd.pyx":423
+ *
+ * # endif sample_type == np.float32
+ * elif sample_type == np.int32: # <<<<<<<<<<<<<<
+ *
+ * if weights_type == np.float64 or weights_type is None:
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_int32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_sample_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":425
+ * elif sample_type == np.int32:
+ *
+ * if weights_type == np.float64 or weights_type is None: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_int32_t_double_double(sample_c,
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float64); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (!__pyx_t_1) {
+ } else {
+ __pyx_t_7 = __pyx_t_1;
+ goto __pyx_L51_bool_binop_done;
+ }
+ __pyx_t_1 = (__pyx_cur_scope->__pyx_v_weights_type == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ __pyx_t_7 = __pyx_t_2;
+ __pyx_L51_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":427
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_int32_t_double_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_64 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_64.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":428
+ *
+ * rc = _histogramnd_int32_t_double_double(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_65 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_65.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":429
+ * rc = _histogramnd_int32_t_double_double(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":430
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":431
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_66 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_66.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 431; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":432
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_67 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_67.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":433
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_68 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_68.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":434
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_69 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_69.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":435
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_70 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_70.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":436
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":437
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_23 = __pyx_PyFloat_AsDouble(__pyx_v_weight_min); if (unlikely((__pyx_t_23 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":438
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.float32:
+ */
+ __pyx_t_24 = __pyx_PyFloat_AsDouble(__pyx_v_weight_max); if (unlikely((__pyx_t_24 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":427
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_int32_t_double_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_int32_t_double_double(__pyx_t_64, __pyx_t_65, __pyx_t_15, __pyx_t_16, __pyx_t_66, __pyx_t_67, __pyx_t_68, __pyx_t_69, __pyx_t_70, __pyx_t_22, __pyx_t_23, __pyx_t_24);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_64, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_65, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_66, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_67, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_68, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_69, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_70, 1);
+ goto __pyx_L50;
+ }
+
+ /* "chistogramnd.pyx":440
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.float32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_int32_t_float_double(sample_c,
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_float32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":442
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_int32_t_float_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_71 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_71.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":443
+ *
+ * rc = _histogramnd_int32_t_float_double(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_72 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_72.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":444
+ * rc = _histogramnd_int32_t_float_double(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":445
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":446
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_73 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_73.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":447
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_74 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_74.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":448
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_75 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_75.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":449
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_76 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_76.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":450
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_77 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_77.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":451
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":452
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_32 = __pyx_PyFloat_AsFloat(__pyx_v_weight_min); if (unlikely((__pyx_t_32 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":453
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.int32:
+ */
+ __pyx_t_33 = __pyx_PyFloat_AsFloat(__pyx_v_weight_max); if (unlikely((__pyx_t_33 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":442
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_int32_t_float_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_int32_t_float_double(__pyx_t_71, __pyx_t_72, __pyx_t_22, __pyx_t_16, __pyx_t_73, __pyx_t_74, __pyx_t_75, __pyx_t_76, __pyx_t_77, __pyx_t_15, __pyx_t_32, __pyx_t_33);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_71, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_72, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_73, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_74, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_75, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_76, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_77, 1);
+ goto __pyx_L50;
+ }
+
+ /* "chistogramnd.pyx":455
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.int32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_int32_t_int32_t_double(sample_c,
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_int32); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_10, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":457
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_int32_t_int32_t_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_78 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_78.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":458
+ *
+ * rc = _histogramnd_int32_t_int32_t_double(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_79 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_79.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":459
+ * rc = _histogramnd_int32_t_int32_t_double(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":460
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":461
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_80 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_80.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":462
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_81 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_81.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":463
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_82 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_82.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":464
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_83 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_83.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":465
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_84 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_84.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":466
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":467
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_41 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_min); if (unlikely((__pyx_t_41 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":468
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_t_42 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_max); if (unlikely((__pyx_t_42 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":457
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_int32_t_int32_t_double(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_int32_t_int32_t_double(__pyx_t_78, __pyx_t_79, __pyx_t_15, __pyx_t_16, __pyx_t_80, __pyx_t_81, __pyx_t_82, __pyx_t_83, __pyx_t_84, __pyx_t_22, __pyx_t_41, __pyx_t_42);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_78, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_79, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_80, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_81, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_82, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_83, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_84, 1);
+ goto __pyx_L50;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":471
+ *
+ * else:
+ * raise_unsupported_type() # <<<<<<<<<<<<<<
+ *
+ * # endif sample_type == np.int32:
+ */
+ __pyx_t_9 = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_v_raise_unsupported_type); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __pyx_L50:;
+ goto __pyx_L43;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":475
+ * # endif sample_type == np.int32:
+ * else:
+ * raise_unsupported_type() # <<<<<<<<<<<<<<
+ *
+ * # endif weighted_histo is None or weighted_histo.dtype == np.double:
+ */
+ __pyx_t_9 = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_v_raise_unsupported_type); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __pyx_L43:;
+ goto __pyx_L40;
+ }
+
+ /* "chistogramnd.pyx":478
+ *
+ * # endif weighted_histo is None or weighted_histo.dtype == np.double:
+ * elif weighted_histo.dtype == np.float32: # <<<<<<<<<<<<<<
+ *
+ * if sample_type == np.float64:
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_t_9, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":480
+ * elif weighted_histo.dtype == np.float32:
+ *
+ * if sample_type == np.float64: # <<<<<<<<<<<<<<
+ *
+ * if weights_type == np.float64 or weights_type is None:
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_sample_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":482
+ * if sample_type == np.float64:
+ *
+ * if weights_type == np.float64 or weights_type is None: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_double_double_float(sample_c,
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_7 = __pyx_t_2;
+ goto __pyx_L55_bool_binop_done;
+ }
+ __pyx_t_2 = (__pyx_cur_scope->__pyx_v_weights_type == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ __pyx_t_7 = __pyx_t_1;
+ __pyx_L55_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":484
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_double_double_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_85 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_85.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":485
+ *
+ * rc = _histogramnd_double_double_float(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_86 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_86.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 485; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":486
+ * rc = _histogramnd_double_double_float(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":487
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":488
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_87 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_87.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":489
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_88 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_88.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":490
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_89 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_89.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":491
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_90 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_90.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":492
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_91 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_91.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":493
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":494
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_24 = __pyx_PyFloat_AsDouble(__pyx_v_weight_min); if (unlikely((__pyx_t_24 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":495
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.float32:
+ */
+ __pyx_t_23 = __pyx_PyFloat_AsDouble(__pyx_v_weight_max); if (unlikely((__pyx_t_23 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":484
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_double_double_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_double_double_float(__pyx_t_85, __pyx_t_86, __pyx_t_22, __pyx_t_16, __pyx_t_87, __pyx_t_88, __pyx_t_89, __pyx_t_90, __pyx_t_91, __pyx_t_15, __pyx_t_24, __pyx_t_23);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_85, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_86, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_87, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_88, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_89, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_90, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_91, 1);
+ goto __pyx_L54;
+ }
+
+ /* "chistogramnd.pyx":497
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.float32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_double_float_float(sample_c,
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 497; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":499
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_double_float_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_92 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_92.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":500
+ *
+ * rc = _histogramnd_double_float_float(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_93 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_93.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 500; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":501
+ * rc = _histogramnd_double_float_float(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":502
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":503
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_94 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_94.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":504
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_95 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_95.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":505
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_96 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_96.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 505; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":506
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_97 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_97.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":507
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_98 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_98.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":508
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 508; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":509
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_33 = __pyx_PyFloat_AsFloat(__pyx_v_weight_min); if (unlikely((__pyx_t_33 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 509; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":510
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.int32:
+ */
+ __pyx_t_32 = __pyx_PyFloat_AsFloat(__pyx_v_weight_max); if (unlikely((__pyx_t_32 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":499
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_double_float_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_double_float_float(__pyx_t_92, __pyx_t_93, __pyx_t_15, __pyx_t_16, __pyx_t_94, __pyx_t_95, __pyx_t_96, __pyx_t_97, __pyx_t_98, __pyx_t_22, __pyx_t_33, __pyx_t_32);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_92, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_93, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_94, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_95, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_96, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_97, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_98, 1);
+ goto __pyx_L54;
+ }
+
+ /* "chistogramnd.pyx":512
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.int32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_double_int32_t_float(sample_c,
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 512; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":514
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_double_int32_t_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_99 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_99.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":515
+ *
+ * rc = _histogramnd_double_int32_t_float(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_100 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_100.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":516
+ * rc = _histogramnd_double_int32_t_float(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 516; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":517
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 517; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":518
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_101 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_101.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 518; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":519
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_102 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_102.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":520
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_103 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_103.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":521
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_104 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_104.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":522
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_105 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_105.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 522; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":523
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":524
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_42 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_min); if (unlikely((__pyx_t_42 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":525
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_t_41 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_max); if (unlikely((__pyx_t_41 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":514
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_double_int32_t_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_double_int32_t_float(__pyx_t_99, __pyx_t_100, __pyx_t_22, __pyx_t_16, __pyx_t_101, __pyx_t_102, __pyx_t_103, __pyx_t_104, __pyx_t_105, __pyx_t_15, __pyx_t_42, __pyx_t_41);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_99, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_100, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_101, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_102, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_103, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_104, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_105, 1);
+ goto __pyx_L54;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":528
+ *
+ * else:
+ * raise_unsupported_type() # <<<<<<<<<<<<<<
+ *
+ * # endif sample_type == np.float64
+ */
+ __pyx_t_10 = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_v_raise_unsupported_type); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __pyx_L54:;
+ goto __pyx_L53;
+ }
+
+ /* "chistogramnd.pyx":531
+ *
+ * # endif sample_type == np.float64
+ * elif sample_type == np.float32: # <<<<<<<<<<<<<<
+ *
+ * if weights_type == np.float64 or weights_type is None:
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_sample_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":533
+ * elif sample_type == np.float32:
+ *
+ * if weights_type == np.float64 or weights_type is None: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_float_double_float(sample_c,
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (!__pyx_t_1) {
+ } else {
+ __pyx_t_7 = __pyx_t_1;
+ goto __pyx_L58_bool_binop_done;
+ }
+ __pyx_t_1 = (__pyx_cur_scope->__pyx_v_weights_type == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ __pyx_t_7 = __pyx_t_2;
+ __pyx_L58_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":535
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_float_double_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_106 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_106.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 535; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":536
+ *
+ * rc = _histogramnd_float_double_float(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_107 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_107.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":537
+ * rc = _histogramnd_float_double_float(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 537; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":538
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":539
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_108 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_108.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 539; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":540
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_109 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_109.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":541
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_110 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_110.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":542
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_111 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_111.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 542; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":543
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_112 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_112.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 543; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":544
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":545
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_23 = __pyx_PyFloat_AsDouble(__pyx_v_weight_min); if (unlikely((__pyx_t_23 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 545; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":546
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.float32:
+ */
+ __pyx_t_24 = __pyx_PyFloat_AsDouble(__pyx_v_weight_max); if (unlikely((__pyx_t_24 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":535
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_float_double_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_float_double_float(__pyx_t_106, __pyx_t_107, __pyx_t_15, __pyx_t_16, __pyx_t_108, __pyx_t_109, __pyx_t_110, __pyx_t_111, __pyx_t_112, __pyx_t_22, __pyx_t_23, __pyx_t_24);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_106, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_107, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_108, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_109, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_110, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_111, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_112, 1);
+ goto __pyx_L57;
+ }
+
+ /* "chistogramnd.pyx":548
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.float32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_float_float_float(sample_c,
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":550
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_float_float_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_113 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_113.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 550; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":551
+ *
+ * rc = _histogramnd_float_float_float(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_114 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_114.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 551; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":552
+ * rc = _histogramnd_float_float_float(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 552; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":553
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 553; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":554
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_115 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_115.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":555
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_116 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_116.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":556
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_117 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_117.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 556; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":557
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_118 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_118.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 557; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":558
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_119 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_119.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 558; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":559
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 559; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":560
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_32 = __pyx_PyFloat_AsFloat(__pyx_v_weight_min); if (unlikely((__pyx_t_32 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 560; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":561
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.int32:
+ */
+ __pyx_t_33 = __pyx_PyFloat_AsFloat(__pyx_v_weight_max); if (unlikely((__pyx_t_33 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":550
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_float_float_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_float_float_float(__pyx_t_113, __pyx_t_114, __pyx_t_22, __pyx_t_16, __pyx_t_115, __pyx_t_116, __pyx_t_117, __pyx_t_118, __pyx_t_119, __pyx_t_15, __pyx_t_32, __pyx_t_33);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_113, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_114, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_115, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_116, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_117, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_118, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_119, 1);
+ goto __pyx_L57;
+ }
+
+ /* "chistogramnd.pyx":563
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.int32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_float_int32_t_float(sample_c,
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":565
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_float_int32_t_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_120 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_120.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 565; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":566
+ *
+ * rc = _histogramnd_float_int32_t_float(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_121 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_121.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 566; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":567
+ * rc = _histogramnd_float_int32_t_float(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 567; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":568
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":569
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_122 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_122.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":570
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_123 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_123.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 570; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":571
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_124 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_124.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 571; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":572
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_125 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_125.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":573
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_126 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_126.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 573; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":574
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 574; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":575
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_41 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_min); if (unlikely((__pyx_t_41 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 575; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":576
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_t_42 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_max); if (unlikely((__pyx_t_42 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 576; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":565
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_float_int32_t_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_float_int32_t_float(__pyx_t_120, __pyx_t_121, __pyx_t_15, __pyx_t_16, __pyx_t_122, __pyx_t_123, __pyx_t_124, __pyx_t_125, __pyx_t_126, __pyx_t_22, __pyx_t_41, __pyx_t_42);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_120, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_121, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_122, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_123, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_124, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_125, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_126, 1);
+ goto __pyx_L57;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":579
+ *
+ * else:
+ * raise_unsupported_type() # <<<<<<<<<<<<<<
+ *
+ * # endif sample_type == np.float32
+ */
+ __pyx_t_10 = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_v_raise_unsupported_type); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __pyx_L57:;
+ goto __pyx_L53;
+ }
+
+ /* "chistogramnd.pyx":582
+ *
+ * # endif sample_type == np.float32
+ * elif sample_type == np.int32: # <<<<<<<<<<<<<<
+ *
+ * if weights_type == np.float64 or weights_type is None:
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 582; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 582; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_sample_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 582; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 582; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":584
+ * elif sample_type == np.int32:
+ *
+ * if weights_type == np.float64 or weights_type is None: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_int32_t_double_float(sample_c,
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 584; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 584; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 584; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 584; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_7 = __pyx_t_2;
+ goto __pyx_L61_bool_binop_done;
+ }
+ __pyx_t_2 = (__pyx_cur_scope->__pyx_v_weights_type == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ __pyx_t_7 = __pyx_t_1;
+ __pyx_L61_bool_binop_done:;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":586
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_int32_t_double_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_127 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_127.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 586; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":587
+ *
+ * rc = _histogramnd_int32_t_double_float(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_128 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_128.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 587; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":588
+ * rc = _histogramnd_int32_t_double_float(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 588; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":589
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 589; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":590
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_129 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_129.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 590; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":591
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_130 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_130.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 591; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":592
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_131 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_131.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":593
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_132 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_132.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 593; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":594
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_133 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_133.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 594; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":595
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 595; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":596
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_24 = __pyx_PyFloat_AsDouble(__pyx_v_weight_min); if (unlikely((__pyx_t_24 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 596; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":597
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.float32:
+ */
+ __pyx_t_23 = __pyx_PyFloat_AsDouble(__pyx_v_weight_max); if (unlikely((__pyx_t_23 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":586
+ * if weights_type == np.float64 or weights_type is None:
+ *
+ * rc = _histogramnd_int32_t_double_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_int32_t_double_float(__pyx_t_127, __pyx_t_128, __pyx_t_22, __pyx_t_16, __pyx_t_129, __pyx_t_130, __pyx_t_131, __pyx_t_132, __pyx_t_133, __pyx_t_15, __pyx_t_24, __pyx_t_23);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_127, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_128, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_129, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_130, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_131, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_132, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_133, 1);
+ goto __pyx_L60;
+ }
+
+ /* "chistogramnd.pyx":599
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.float32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_int32_t_float_float(sample_c,
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 599; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":601
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_int32_t_float_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_134 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_134.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 601; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":602
+ *
+ * rc = _histogramnd_int32_t_float_float(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_135 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_135.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":603
+ * rc = _histogramnd_int32_t_float_float(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":604
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":605
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_136 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_136.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 605; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":606
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_137 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_137.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 606; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":607
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_138 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_138.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 607; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":608
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_139 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_139.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 608; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":609
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_140 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_140.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":610
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 610; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":611
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_33 = __pyx_PyFloat_AsFloat(__pyx_v_weight_min); if (unlikely((__pyx_t_33 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 611; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":612
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * elif weights_type == np.int32:
+ */
+ __pyx_t_32 = __pyx_PyFloat_AsFloat(__pyx_v_weight_max); if (unlikely((__pyx_t_32 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 612; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":601
+ * elif weights_type == np.float32:
+ *
+ * rc = _histogramnd_int32_t_float_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_int32_t_float_float(__pyx_t_134, __pyx_t_135, __pyx_t_15, __pyx_t_16, __pyx_t_136, __pyx_t_137, __pyx_t_138, __pyx_t_139, __pyx_t_140, __pyx_t_22, __pyx_t_33, __pyx_t_32);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_134, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_135, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_136, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_137, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_138, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_139, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_140, 1);
+ goto __pyx_L60;
+ }
+
+ /* "chistogramnd.pyx":614
+ * weight_max=weight_max)
+ *
+ * elif weights_type == np.int32: # <<<<<<<<<<<<<<
+ *
+ * rc = _histogramnd_int32_t_int32_t_float(sample_c,
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyObject_RichCompare(__pyx_cur_scope->__pyx_v_weights_type, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":616
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_int32_t_int32_t_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_t_141 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_sample_c);
+ if (unlikely(!__pyx_t_141.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 616; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":617
+ *
+ * rc = _histogramnd_int32_t_int32_t_float(sample_c,
+ * weights_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_142 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_weights_c);
+ if (unlikely(!__pyx_t_142.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 617; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":618
+ * rc = _histogramnd_int32_t_int32_t_float(sample_c,
+ * weights_c,
+ * n_dims, # <<<<<<<<<<<<<<
+ * n_elem,
+ * histo_range_c,
+ */
+ __pyx_t_22 = __Pyx_PyInt_As_int(__pyx_v_n_dims); if (unlikely((__pyx_t_22 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 618; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":619
+ * weights_c,
+ * n_dims,
+ * n_elem, # <<<<<<<<<<<<<<
+ * histo_range_c,
+ * n_bins_c,
+ */
+ __pyx_t_16 = __Pyx_PyInt_As_int(__pyx_v_n_elem); if (unlikely((__pyx_t_16 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":620
+ * n_dims,
+ * n_elem,
+ * histo_range_c, # <<<<<<<<<<<<<<
+ * n_bins_c,
+ * histo_c,
+ */
+ __pyx_t_143 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_histo_range_c);
+ if (unlikely(!__pyx_t_143.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":621
+ * n_elem,
+ * histo_range_c,
+ * n_bins_c, # <<<<<<<<<<<<<<
+ * histo_c,
+ * cumul_c,
+ */
+ __pyx_t_144 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(__pyx_v_n_bins_c);
+ if (unlikely(!__pyx_t_144.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":622
+ * histo_range_c,
+ * n_bins_c,
+ * histo_c, # <<<<<<<<<<<<<<
+ * cumul_c,
+ * bin_edges_c,
+ */
+ __pyx_t_145 = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(__pyx_v_histo_c);
+ if (unlikely(!__pyx_t_145.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 622; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":623
+ * n_bins_c,
+ * histo_c,
+ * cumul_c, # <<<<<<<<<<<<<<
+ * bin_edges_c,
+ * option_flags,
+ */
+ __pyx_t_146 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_v_cumul_c);
+ if (unlikely(!__pyx_t_146.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 623; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":624
+ * histo_c,
+ * cumul_c,
+ * bin_edges_c, # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min=weight_min,
+ */
+ __pyx_t_147 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_v_bin_edges_c);
+ if (unlikely(!__pyx_t_147.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":625
+ * cumul_c,
+ * bin_edges_c,
+ * option_flags, # <<<<<<<<<<<<<<
+ * weight_min=weight_min,
+ * weight_max=weight_max)
+ */
+ __pyx_t_15 = __Pyx_PyInt_As_int(__pyx_v_option_flags); if (unlikely((__pyx_t_15 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":626
+ * bin_edges_c,
+ * option_flags,
+ * weight_min=weight_min, # <<<<<<<<<<<<<<
+ * weight_max=weight_max)
+ *
+ */
+ __pyx_t_42 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_min); if (unlikely((__pyx_t_42 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 626; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":627
+ * option_flags,
+ * weight_min=weight_min,
+ * weight_max=weight_max) # <<<<<<<<<<<<<<
+ *
+ * else:
+ */
+ __pyx_t_41 = __Pyx_PyInt_As_npy_int32(__pyx_v_weight_max); if (unlikely((__pyx_t_41 == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 627; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":616
+ * elif weights_type == np.int32:
+ *
+ * rc = _histogramnd_int32_t_int32_t_float(sample_c, # <<<<<<<<<<<<<<
+ * weights_c,
+ * n_dims,
+ */
+ __pyx_v_rc = __pyx_f_12chistogramnd__histogramnd_int32_t_int32_t_float(__pyx_t_141, __pyx_t_142, __pyx_t_22, __pyx_t_16, __pyx_t_143, __pyx_t_144, __pyx_t_145, __pyx_t_146, __pyx_t_147, __pyx_t_15, __pyx_t_42, __pyx_t_41);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_141, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_142, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_143, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_144, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_145, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_146, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_147, 1);
+ goto __pyx_L60;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":630
+ *
+ * else:
+ * raise_unsupported_type() # <<<<<<<<<<<<<<
+ *
+ * # endif sample_type == np.int32:
+ */
+ __pyx_t_10 = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_v_raise_unsupported_type); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 630; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __pyx_L60:;
+ goto __pyx_L53;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":634
+ * # endif sample_type == np.int32:
+ * else:
+ * raise_unsupported_type() # <<<<<<<<<<<<<<
+ *
+ * # end elseif weighted_histo.dtype == np.float32:
+ */
+ __pyx_t_10 = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_v_raise_unsupported_type); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 634; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __pyx_L53:;
+ goto __pyx_L40;
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":639
+ * else:
+ * # this isnt supposed to happen since weighted_histo type was checked earlier
+ * raise_unsupported_type() # <<<<<<<<<<<<<<
+ *
+ * if rc != histogramnd_c.HISTO_OK:
+ */
+ __pyx_t_10 = __pyx_pf_12chistogramnd_12chistogramnd_raise_unsupported_type(__pyx_v_raise_unsupported_type); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 639; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __pyx_L40:;
+
+ /* "chistogramnd.pyx":641
+ * raise_unsupported_type()
+ *
+ * if rc != histogramnd_c.HISTO_OK: # <<<<<<<<<<<<<<
+ * if rc == histogramnd_c.HISTO_ERR_ALLOC:
+ * raise MemoryError('histogramnd failed to allocate memory.')
+ */
+ __pyx_t_7 = ((__pyx_v_rc != HISTO_OK) != 0);
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":642
+ *
+ * if rc != histogramnd_c.HISTO_OK:
+ * if rc == histogramnd_c.HISTO_ERR_ALLOC: # <<<<<<<<<<<<<<
+ * raise MemoryError('histogramnd failed to allocate memory.')
+ * else:
+ */
+ __pyx_t_7 = ((__pyx_v_rc == HISTO_ERR_ALLOC) != 0);
+ if (__pyx_t_7) {
+
+ /* "chistogramnd.pyx":643
+ * if rc != histogramnd_c.HISTO_OK:
+ * if rc == histogramnd_c.HISTO_ERR_ALLOC:
+ * raise MemoryError('histogramnd failed to allocate memory.') # <<<<<<<<<<<<<<
+ * else:
+ * raise Exception('histogramnd returned an error : {0}'
+ */
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "chistogramnd.pyx":646
+ * else:
+ * raise Exception('histogramnd returned an error : {0}'
+ * ''.format(rc)) # <<<<<<<<<<<<<<
+ *
+ * edges = []
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_histogramnd_returned_an_error_0, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = __Pyx_PyInt_From_long(__pyx_v_rc); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_GOTREF(__pyx_t_10);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 646; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":645
+ * raise MemoryError('histogramnd failed to allocate memory.')
+ * else:
+ * raise Exception('histogramnd returned an error : {0}' # <<<<<<<<<<<<<<
+ * ''.format(rc))
+ *
+ */
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_Exception, __pyx_t_5, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "chistogramnd.pyx":648
+ * ''.format(rc))
+ *
+ * edges = [] # <<<<<<<<<<<<<<
+ * offset = 0
+ * for i_dim in range(n_dims):
+ */
+ __pyx_t_10 = PyList_New(0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_v_edges = ((PyObject*)__pyx_t_10);
+ __pyx_t_10 = 0;
+
+ /* "chistogramnd.pyx":649
+ *
+ * edges = []
+ * offset = 0 # <<<<<<<<<<<<<<
+ * for i_dim in range(n_dims):
+ * edges.append(bin_edges[offset:offset + n_bins[i_dim] + 1])
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_v_offset = __pyx_int_0;
+
+ /* "chistogramnd.pyx":650
+ * edges = []
+ * offset = 0
+ * for i_dim in range(n_dims): # <<<<<<<<<<<<<<
+ * edges.append(bin_edges[offset:offset + n_bins[i_dim] + 1])
+ * offset += n_bins[i_dim] + 1
+ */
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_INCREF(__pyx_v_n_dims);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_n_dims);
+ __Pyx_GIVEREF(__pyx_v_n_dims);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_10, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (likely(PyList_CheckExact(__pyx_t_5)) || PyTuple_CheckExact(__pyx_t_5)) {
+ __pyx_t_10 = __pyx_t_5; __Pyx_INCREF(__pyx_t_10); __pyx_t_8 = 0;
+ __pyx_t_148 = NULL;
+ } else {
+ __pyx_t_8 = -1; __pyx_t_10 = PyObject_GetIter(__pyx_t_5); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_148 = Py_TYPE(__pyx_t_10)->tp_iternext; if (unlikely(!__pyx_t_148)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_148)) {
+ if (likely(PyList_CheckExact(__pyx_t_10))) {
+ if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_10)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_10, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_10, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_10)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_10, __pyx_t_8); __Pyx_INCREF(__pyx_t_5); __pyx_t_8++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_10, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_148(__pyx_t_10);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_i_dim, __pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":651
+ * offset = 0
+ * for i_dim in range(n_dims):
+ * edges.append(bin_edges[offset:offset + n_bins[i_dim] + 1]) # <<<<<<<<<<<<<<
+ * offset += n_bins[i_dim] + 1
+ *
+ */
+ __pyx_t_5 = PyObject_GetItem(__pyx_v_n_bins, __pyx_v_i_dim); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = PyNumber_Add(__pyx_v_offset, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetSlice(__pyx_v_bin_edges, 0, 0, &__pyx_v_offset, &__pyx_t_5, NULL, 0, 0, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_149 = __Pyx_PyList_Append(__pyx_v_edges, __pyx_t_3); if (unlikely(__pyx_t_149 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 651; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":652
+ * for i_dim in range(n_dims):
+ * edges.append(bin_edges[offset:offset + n_bins[i_dim] + 1])
+ * offset += n_bins[i_dim] + 1 # <<<<<<<<<<<<<<
+ *
+ * return histo, weighted_histo, tuple(edges)
+ */
+ __pyx_t_3 = PyObject_GetItem(__pyx_v_n_bins, __pyx_v_i_dim); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyNumber_InPlaceAdd(__pyx_v_offset, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF_SET(__pyx_v_offset, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":650
+ * edges = []
+ * offset = 0
+ * for i_dim in range(n_dims): # <<<<<<<<<<<<<<
+ * edges.append(bin_edges[offset:offset + n_bins[i_dim] + 1])
+ * offset += n_bins[i_dim] + 1
+ */
+ }
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+
+ /* "chistogramnd.pyx":654
+ * offset += n_bins[i_dim] + 1
+ *
+ * return histo, weighted_histo, tuple(edges) # <<<<<<<<<<<<<<
+ *
+ * # =====================
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_10 = PyList_AsTuple(__pyx_v_edges); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_histo);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_histo);
+ __Pyx_GIVEREF(__pyx_v_histo);
+ __Pyx_INCREF(__pyx_v_weighted_histo);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_weighted_histo);
+ __Pyx_GIVEREF(__pyx_v_weighted_histo);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":36
+ *
+ *
+ * def chistogramnd(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_12);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_13, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_14, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_17, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_18, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_19, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_20, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_21, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_25, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_26, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_27, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_28, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_29, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_30, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_31, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_34, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_35, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_36, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_37, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_38, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_39, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_40, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_43, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_44, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_45, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_46, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_47, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_48, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_49, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_50, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_51, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_52, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_53, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_54, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_55, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_56, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_57, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_58, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_59, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_60, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_61, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_62, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_63, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_64, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_65, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_66, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_67, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_68, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_69, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_70, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_71, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_72, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_73, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_74, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_75, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_76, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_77, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_78, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_79, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_80, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_81, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_82, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_83, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_84, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_85, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_86, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_87, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_88, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_89, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_90, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_91, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_92, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_93, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_94, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_95, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_96, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_97, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_98, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_99, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_100, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_101, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_102, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_103, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_104, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_105, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_106, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_107, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_108, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_109, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_110, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_111, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_112, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_113, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_114, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_115, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_116, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_117, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_118, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_119, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_120, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_121, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_122, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_123, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_124, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_125, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_126, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_127, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_128, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_129, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_130, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_131, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_132, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_133, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_134, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_135, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_136, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_137, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_138, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_139, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_140, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_141, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_142, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_143, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_144, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_145, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_146, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_147, 1);
+ __Pyx_AddTraceback("chistogramnd.chistogramnd", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_s_shape);
+ __Pyx_XDECREF(__pyx_v_n_dims);
+ __Pyx_XDECREF(__pyx_v_w_shape);
+ __Pyx_XDECREF(__pyx_v_i_histo_range);
+ __Pyx_XDECREF(__pyx_v_output_shape);
+ __Pyx_XDECREF(__pyx_v_option_flags);
+ __Pyx_XDECREF(__pyx_v_n_elem);
+ __Pyx_XDECREF(__pyx_v_bin_edges);
+ __Pyx_XDECREF(__pyx_v_raise_unsupported_type);
+ __Pyx_XDECREF(__pyx_v_sample_c);
+ __Pyx_XDECREF(__pyx_v_weights_c);
+ __Pyx_XDECREF(__pyx_v_histo_range_c);
+ __Pyx_XDECREF(__pyx_v_n_bins_c);
+ __Pyx_XDECREF(__pyx_v_histo_c);
+ __Pyx_XDECREF(__pyx_v_cumul_c);
+ __Pyx_XDECREF(__pyx_v_bin_edges_c);
+ __Pyx_XDECREF(__pyx_v_edges);
+ __Pyx_XDECREF(__pyx_v_offset);
+ __Pyx_XDECREF(__pyx_v_i_dim);
+ __Pyx_XDECREF(__pyx_v_histo_range);
+ __Pyx_XDECREF(__pyx_v_n_bins);
+ __Pyx_XDECREF(__pyx_v_weight_min);
+ __Pyx_XDECREF(__pyx_v_weight_max);
+ __Pyx_XDECREF(__pyx_v_histo);
+ __Pyx_XDECREF(__pyx_v_weighted_histo);
+ __Pyx_XDECREF(__pyx_v_wh_dtype);
+ __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":665
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_double_double(double[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_double_double_double(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, double __pyx_v_weight_min, double __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":678
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_double_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":679
+ *
+ * return histogramnd_c.histogramnd_double_double_double(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":682
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":683
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":684
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":685
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":686
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":678
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_double_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_double_double_double((&(*((double *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":665
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_double_double(double[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":696
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_float_double(double[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_double_float_double(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, float __pyx_v_weight_min, float __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":709
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_float_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":710
+ *
+ * return histogramnd_c.histogramnd_double_float_double(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":713
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":714
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":715
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":716
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":717
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":709
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_float_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_double_float_double((&(*((double *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":696
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_float_double(double[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":727
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_int32_t_double(double[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_double_int32_t_double(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, __pyx_t_5numpy_int32_t __pyx_v_weight_min, __pyx_t_5numpy_int32_t __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":740
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_int32_t_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":741
+ *
+ * return histogramnd_c.histogramnd_double_int32_t_double(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":744
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":745
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":746
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":747
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":748
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":740
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_int32_t_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_double_int32_t_double((&(*((double *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":727
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_int32_t_double(double[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":763
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_double_double(float[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_float_double_double(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, double __pyx_v_weight_min, double __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":776
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_double_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":777
+ *
+ * return histogramnd_c.histogramnd_float_double_double(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":780
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":781
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":782
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":783
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":784
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":776
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_double_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_float_double_double((&(*((float *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":763
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_double_double(float[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":794
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_float_double(float[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_float_float_double(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, float __pyx_v_weight_min, float __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":807
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_float_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":808
+ *
+ * return histogramnd_c.histogramnd_float_float_double(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":811
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":812
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":813
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":814
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":815
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":807
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_float_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_float_float_double((&(*((float *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":794
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_float_double(float[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":825
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_int32_t_double(float[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_float_int32_t_double(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, __pyx_t_5numpy_int32_t __pyx_v_weight_min, __pyx_t_5numpy_int32_t __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":838
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_int32_t_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":839
+ *
+ * return histogramnd_c.histogramnd_float_int32_t_double(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":842
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":843
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":844
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":845
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":846
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":838
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_int32_t_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_float_int32_t_double((&(*((float *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":825
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_int32_t_double(float[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":861
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_double_double(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_double_double(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, double __pyx_v_weight_min, double __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":874
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_double_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":875
+ *
+ * return histogramnd_c.histogramnd_int32_t_double_double(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":878
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":879
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":880
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":881
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":882
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":874
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_double_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_int32_t_double_double((&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":861
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_double_double(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":892
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_float_double(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_float_double(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, float __pyx_v_weight_min, float __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":905
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_float_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":906
+ *
+ * return histogramnd_c.histogramnd_int32_t_float_double(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":909
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":910
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":911
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":912
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":913
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":905
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_float_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_int32_t_float_double((&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":892
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_float_double(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":923
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_int32_t_double(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_int32_t_double(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, __pyx_t_5numpy_int32_t __pyx_v_weight_min, __pyx_t_5numpy_int32_t __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":936
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_int32_t_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":937
+ *
+ * return histogramnd_c.histogramnd_int32_t_int32_t_double(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":940
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":941
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":942
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":943
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":944
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":936
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_int32_t_double(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_int32_t_int32_t_double((&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":923
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_int32_t_double(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":959
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_double_float(double[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_double_double_float(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, double __pyx_v_weight_min, double __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":972
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_double_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":973
+ *
+ * return histogramnd_c.histogramnd_double_double_float(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":976
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":977
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":978
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":979
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":980
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":972
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_double_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_double_double_float((&(*((double *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":959
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_double_float(double[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":990
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_float_float(double[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_double_float_float(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, float __pyx_v_weight_min, float __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":1003
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_float_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":1004
+ *
+ * return histogramnd_c.histogramnd_double_float_float(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":1007
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":1008
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":1009
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":1010
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":1011
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":1003
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_float_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_double_float_float((&(*((double *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":990
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_float_float(double[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":1021
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_int32_t_float(double[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_double_int32_t_float(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, __pyx_t_5numpy_int32_t __pyx_v_weight_min, __pyx_t_5numpy_int32_t __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":1034
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_int32_t_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":1035
+ *
+ * return histogramnd_c.histogramnd_double_int32_t_float(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":1038
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":1039
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":1040
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":1041
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":1042
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":1034
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_double_int32_t_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_double_int32_t_float((&(*((double *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":1021
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_double_int32_t_float(double[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":1057
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_double_float(float[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_float_double_float(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, double __pyx_v_weight_min, double __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":1070
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_double_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":1071
+ *
+ * return histogramnd_c.histogramnd_float_double_float(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":1074
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":1075
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":1076
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":1077
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":1078
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":1070
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_double_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_float_double_float((&(*((float *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":1057
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_double_float(float[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":1088
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_float_float(float[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_float_float_float(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, float __pyx_v_weight_min, float __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":1101
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_float_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":1102
+ *
+ * return histogramnd_c.histogramnd_float_float_float(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":1105
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":1106
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":1107
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":1108
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":1109
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":1101
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_float_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_float_float_float((&(*((float *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":1088
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_float_float(float[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":1119
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_int32_t_float(float[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_float_int32_t_float(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, __pyx_t_5numpy_int32_t __pyx_v_weight_min, __pyx_t_5numpy_int32_t __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":1132
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_int32_t_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":1133
+ *
+ * return histogramnd_c.histogramnd_float_int32_t_float(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":1136
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":1137
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":1138
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":1139
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":1140
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":1132
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_float_int32_t_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_float_int32_t_float((&(*((float *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":1119
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_float_int32_t_float(float[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":1155
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_double_float(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_double_float(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, double __pyx_v_weight_min, double __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":1168
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_double_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":1169
+ *
+ * return histogramnd_c.histogramnd_int32_t_double_float(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":1172
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":1173
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":1174
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":1175
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":1176
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":1168
+ * double weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_double_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_int32_t_double_float((&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":1155
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_double_float(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * double[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":1186
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_float_float(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_float_float(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, float __pyx_v_weight_min, float __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":1199
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_float_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":1200
+ *
+ * return histogramnd_c.histogramnd_int32_t_float_float(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":1203
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":1204
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":1205
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":1206
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":1207
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":1199
+ * float weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_float_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_int32_t_float_float((&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":1186
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_float_float(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * float[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "chistogramnd.pyx":1217
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_int32_t_float(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+static int __pyx_f_12chistogramnd__histogramnd_int32_t_int32_t_float(__Pyx_memviewslice __pyx_v_sample, __Pyx_memviewslice __pyx_v_weights, int __pyx_v_n_dims, int __pyx_v_n_elem, __Pyx_memviewslice __pyx_v_histo_range, __Pyx_memviewslice __pyx_v_n_bins, __Pyx_memviewslice __pyx_v_histo, __Pyx_memviewslice __pyx_v_cumul, __Pyx_memviewslice __pyx_v_bin_edges, int __pyx_v_option_flags, __pyx_t_5numpy_int32_t __pyx_v_weight_min, __pyx_t_5numpy_int32_t __pyx_v_weight_max) {
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+
+ /* "chistogramnd.pyx":1230
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_int32_t_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":1231
+ *
+ * return histogramnd_c.histogramnd_int32_t_int32_t_float(&sample[0],
+ * &weights[0], # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_2 = 0;
+
+ /* "chistogramnd.pyx":1234
+ * n_dims,
+ * n_elem,
+ * &histo_range[0], # <<<<<<<<<<<<<<
+ * &n_bins[0],
+ * &histo[0],
+ */
+ __pyx_t_3 = 0;
+
+ /* "chistogramnd.pyx":1235
+ * n_elem,
+ * &histo_range[0],
+ * &n_bins[0], # <<<<<<<<<<<<<<
+ * &histo[0],
+ * &cumul[0],
+ */
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd.pyx":1236
+ * &histo_range[0],
+ * &n_bins[0],
+ * &histo[0], # <<<<<<<<<<<<<<
+ * &cumul[0],
+ * &bin_edges[0],
+ */
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd.pyx":1237
+ * &n_bins[0],
+ * &histo[0],
+ * &cumul[0], # <<<<<<<<<<<<<<
+ * &bin_edges[0],
+ * option_flags,
+ */
+ __pyx_t_6 = 0;
+
+ /* "chistogramnd.pyx":1238
+ * &histo[0],
+ * &cumul[0],
+ * &bin_edges[0], # <<<<<<<<<<<<<<
+ * option_flags,
+ * weight_min,
+ */
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd.pyx":1230
+ * numpy.int32_t weight_max) nogil:
+ *
+ * return histogramnd_c.histogramnd_int32_t_int32_t_float(&sample[0], # <<<<<<<<<<<<<<
+ * &weights[0],
+ * n_dims,
+ */
+ __pyx_r = histogramnd_int32_t_int32_t_float((&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_sample.data + __pyx_t_1 * __pyx_v_sample.strides[0]) )))), (&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_weights.data + __pyx_t_2 * __pyx_v_weights.strides[0]) )))), __pyx_v_n_dims, __pyx_v_n_elem, (&(*((double *) ( /* dim=0 */ (__pyx_v_histo_range.data + __pyx_t_3 * __pyx_v_histo_range.strides[0]) )))), (&(*((int *) ( /* dim=0 */ (__pyx_v_n_bins.data + __pyx_t_4 * __pyx_v_n_bins.strides[0]) )))), (&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_histo.data + __pyx_t_5 * __pyx_v_histo.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_cumul.data + __pyx_t_6 * __pyx_v_cumul.strides[0]) )))), (&(*((double *) ( /* dim=0 */ (__pyx_v_bin_edges.data + __pyx_t_7 * __pyx_v_bin_edges.strides[0]) )))), __pyx_v_option_flags, __pyx_v_weight_min, __pyx_v_weight_max);
+ goto __pyx_L0;
+
+ /* "chistogramnd.pyx":1217
+ * @cython.initializedcheck(False)
+ * @cython.nonecheck(False)
+ * cdef int _histogramnd_int32_t_int32_t_float(numpy.int32_t[:] sample, # <<<<<<<<<<<<<<
+ * numpy.int32_t[:] weights,
+ * int n_dims,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_copy_shape;
+ int __pyx_v_i;
+ int __pyx_v_ndim;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ int __pyx_v_t;
+ char *__pyx_v_f;
+ PyArray_Descr *__pyx_v_descr = 0;
+ int __pyx_v_offset;
+ int __pyx_v_hasfields;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":200
+ * # of flags
+ *
+ * if info == NULL: return # <<<<<<<<<<<<<<
+ *
+ * cdef int copy_shape, i, ndim
+ */
+ __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+ if (__pyx_t_1) {
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":204
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ *
+ * ndim = PyArray_NDIM(self)
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<<
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":208
+ * ndim = PyArray_NDIM(self)
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * copy_shape = 1
+ * else:
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * copy_shape = 1 # <<<<<<<<<<<<<<
+ * else:
+ * copy_shape = 0
+ */
+ __pyx_v_copy_shape = 1;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ * copy_shape = 1
+ * else:
+ * copy_shape = 0 # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+ __pyx_v_copy_shape = 0;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":213
+ * copy_shape = 0
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L6_bool_binop_done;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L9_bool_binop_done;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<<
+ * info.ndim = ndim
+ * if copy_shape:
+ */
+ __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim # <<<<<<<<<<<<<<
+ * if copy_shape:
+ * # Allocate new buffer for strides and shape info.
+ */
+ __pyx_v_info->ndim = __pyx_v_ndim;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":223
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim
+ * if copy_shape: # <<<<<<<<<<<<<<
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ */
+ __pyx_t_1 = (__pyx_v_copy_shape != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2) # <<<<<<<<<<<<<<
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":227
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+ __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":228
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ */
+ __pyx_t_4 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<<
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ */
+ (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+ (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+ }
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self) # <<<<<<<<<<<<<<
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self) # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ */
+ __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+ }
+ __pyx_L11:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":234
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<<
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ *
+ */
+ __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<<
+ *
+ * cdef int t
+ */
+ __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *
+ * cdef int t
+ * cdef char* f = NULL # <<<<<<<<<<<<<<
+ * cdef dtype descr = self.descr
+ * cdef list stack
+ */
+ __pyx_v_f = NULL;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":240
+ * cdef int t
+ * cdef char* f = NULL
+ * cdef dtype descr = self.descr # <<<<<<<<<<<<<<
+ * cdef list stack
+ * cdef int offset
+ */
+ __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":244
+ * cdef int offset
+ *
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<<
+ *
+ * if not hasfields and not copy_shape:
+ */
+ __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":246
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ *
+ * if not hasfields and not copy_shape: # <<<<<<<<<<<<<<
+ * # do not call releasebuffer
+ * info.obj = None
+ */
+ __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":248
+ * if not hasfields and not copy_shape:
+ * # do not call releasebuffer
+ * info.obj = None # <<<<<<<<<<<<<<
+ * else:
+ * # need to call releasebuffer
+ */
+ __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = Py_None;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":251
+ * else:
+ * # need to call releasebuffer
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * if not hasfields:
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+ }
+ __pyx_L14:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":253
+ * info.obj = self
+ *
+ * if not hasfields: # <<<<<<<<<<<<<<
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":254
+ *
+ * if not hasfields:
+ * t = descr.type_num # <<<<<<<<<<<<<<
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ */
+ __pyx_t_4 = __pyx_v_descr->type_num;
+ __pyx_v_t = __pyx_t_4;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":255
+ * if not hasfields:
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+ if (!__pyx_t_2) {
+ goto __pyx_L20_next_or;
+ } else {
+ }
+ __pyx_t_2 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_L20_next_or:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L19_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ switch (__pyx_v_t) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ */
+ case NPY_BYTE:
+ __pyx_v_f = __pyx_k_b;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ */
+ case NPY_UBYTE:
+ __pyx_v_f = __pyx_k_B;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ */
+ case NPY_SHORT:
+ __pyx_v_f = __pyx_k_h;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ */
+ case NPY_USHORT:
+ __pyx_v_f = __pyx_k_H;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ */
+ case NPY_INT:
+ __pyx_v_f = __pyx_k_i;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ */
+ case NPY_UINT:
+ __pyx_v_f = __pyx_k_I;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ */
+ case NPY_LONG:
+ __pyx_v_f = __pyx_k_l;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ */
+ case NPY_ULONG:
+ __pyx_v_f = __pyx_k_L;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ */
+ case NPY_LONGLONG:
+ __pyx_v_f = __pyx_k_q;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ */
+ case NPY_ULONGLONG:
+ __pyx_v_f = __pyx_k_Q;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ */
+ case NPY_FLOAT:
+ __pyx_v_f = __pyx_k_f;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ */
+ case NPY_DOUBLE:
+ __pyx_v_f = __pyx_k_d;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ */
+ case NPY_LONGDOUBLE:
+ __pyx_v_f = __pyx_k_g;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+ case NPY_CFLOAT:
+ __pyx_v_f = __pyx_k_Zf;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O"
+ */
+ case NPY_CDOUBLE:
+ __pyx_v_f = __pyx_k_Zd;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ */
+ case NPY_CLONGDOUBLE:
+ __pyx_v_f = __pyx_k_Zg;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ case NPY_OBJECT:
+ __pyx_v_f = __pyx_k_O;
+ break;
+ default:
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * info.format = f
+ * return
+ */
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ break;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f # <<<<<<<<<<<<<<
+ * return
+ * else:
+ */
+ __pyx_v_info->format = __pyx_v_f;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":278
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f
+ * return # <<<<<<<<<<<<<<
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ * return
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<<
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ */
+ __pyx_v_info->format = ((char *)malloc(255));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":281
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<<
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1,
+ */
+ (__pyx_v_info->format[0]) = '^';
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":282
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0 # <<<<<<<<<<<<<<
+ * f = _util_dtypestring(descr, info.format + 1,
+ * info.format + _buffer_format_string_len,
+ */
+ __pyx_v_offset = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<<
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ */
+ __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_7;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":286
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<<
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+ (__pyx_v_f[0]) = '\x00';
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+ __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":289
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<<
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":290
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format) # <<<<<<<<<<<<<<
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides)
+ */
+ free(__pyx_v_info->format);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * stdlib.free(info.strides)
+ * # info.shape was stored after info.strides in the same block
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides) # <<<<<<<<<<<<<<
+ * # info.shape was stored after info.strides in the same block
+ *
+ */
+ free(__pyx_v_info->strides);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":769
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ * return PyArray_MultiIterNew(1, <void*>a) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":772
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":775
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":778
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":781
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e) # <<<<<<<<<<<<<<
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+ PyArray_Descr *__pyx_v_child = 0;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ PyObject *__pyx_v_fields = 0;
+ PyObject *__pyx_v_childname = NULL;
+ PyObject *__pyx_v_new_offset = NULL;
+ PyObject *__pyx_v_t = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":790
+ * cdef int delta_offset
+ * cdef tuple i
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * cdef tuple fields
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":791
+ * cdef tuple i
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ * cdef tuple fields
+ *
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ if (unlikely(__pyx_v_descr->names == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+ for (;;) {
+ if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":795
+ *
+ * for childname in descr.names:
+ * fields = descr.fields[childname] # <<<<<<<<<<<<<<
+ * child, new_offset = fields
+ *
+ */
+ __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":796
+ * for childname in descr.names:
+ * fields = descr.fields[childname]
+ * child, new_offset = fields # <<<<<<<<<<<<<<
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+ if (likely(__pyx_v_fields != Py_None)) {
+ PyObject* sequence = __pyx_v_fields;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ #else
+ __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ #endif
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+ __pyx_t_3 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ * child, new_offset = fields
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+ if (!__pyx_t_7) {
+ goto __pyx_L8_next_or;
+ } else {
+ }
+ __pyx_t_7 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_L8_next_or:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * # One could encode it in the format string and have Cython
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":813
+ *
+ * # Output padding bytes
+ * while offset[0] < new_offset: # <<<<<<<<<<<<<<
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ */
+ while (1) {
+ __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (!__pyx_t_6) break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":814
+ * # Output padding bytes
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<<
+ * f += 1
+ * offset[0] += 1
+ */
+ (__pyx_v_f[0]) = 120;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":815
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte
+ * f += 1 # <<<<<<<<<<<<<<
+ * offset[0] += 1
+ *
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ * offset[0] += 1 # <<<<<<<<<<<<<<
+ *
+ * offset[0] += child.itemsize
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ * offset[0] += 1
+ *
+ * offset[0] += child.itemsize # <<<<<<<<<<<<<<
+ *
+ * if not PyDataType_HASFIELDS(child):
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":820
+ * offset[0] += child.itemsize
+ *
+ * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<<
+ * t = child.type_num
+ * if end - f < 5:
+ */
+ __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ *
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num # <<<<<<<<<<<<<<
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.")
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":822
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num
+ * if end - f < 5: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short.")
+ *
+ */
+ __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 98;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":827
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 66;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":828
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 104;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 72;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 105;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 73;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 108;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 76;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 113;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 81;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 102;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 100;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 103;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 102;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 100;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 103;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 79;
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * f += 1
+ * else:
+ */
+ __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L15:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * f += 1 # <<<<<<<<<<<<<<
+ * else:
+ * # Cython ignores struct boundary information ("T{...}"),
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":849
+ * # Cython ignores struct boundary information ("T{...}"),
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<<
+ * return f
+ *
+ */
+ __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_9;
+ }
+ __pyx_L13:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":850
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset)
+ * return f # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_f;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_child);
+ __Pyx_XDECREF(__pyx_v_fields);
+ __Pyx_XDECREF(__pyx_v_childname);
+ __Pyx_XDECREF(__pyx_v_new_offset);
+ __Pyx_XDECREF(__pyx_v_t);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+ PyObject *__pyx_v_baseptr;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("set_array_base", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ * cdef PyObject* baseptr
+ * if base is None: # <<<<<<<<<<<<<<
+ * baseptr = NULL
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_base == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * cdef PyObject* baseptr
+ * if base is None:
+ * baseptr = NULL # <<<<<<<<<<<<<<
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ */
+ __pyx_v_baseptr = NULL;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ * baseptr = NULL
+ * else:
+ * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<<
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ */
+ Py_INCREF(__pyx_v_base);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base # <<<<<<<<<<<<<<
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr
+ */
+ __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":973
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base) # <<<<<<<<<<<<<<
+ * arr.base = baseptr
+ *
+ */
+ Py_XDECREF(__pyx_v_arr->base);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr # <<<<<<<<<<<<<<
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ */
+ __pyx_v_arr->base = __pyx_v_baseptr;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("get_array_base", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL: # <<<<<<<<<<<<<<
+ * return None
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":978
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL:
+ * return None # <<<<<<<<<<<<<<
+ * else:
+ * return <object>arr.base
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ * return None
+ * else:
+ * return <object>arr.base # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+ __pyx_r = ((PyObject *)__pyx_v_arr->base);
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__23);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__23);
+ __Pyx_GIVEREF(__pyx_slice__23);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__24); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__25);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__25);
+ __Pyx_GIVEREF(__pyx_slice__25);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+
+static struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *__pyx_freelist_12chistogramnd___pyx_scope_struct__chistogramnd[8];
+static int __pyx_freecount_12chistogramnd___pyx_scope_struct__chistogramnd = 0;
+
+static PyObject *__pyx_tp_new_12chistogramnd___pyx_scope_struct__chistogramnd(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ PyObject *o;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely((__pyx_freecount_12chistogramnd___pyx_scope_struct__chistogramnd > 0) & (t->tp_basicsize == sizeof(struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd)))) {
+ o = (PyObject*)__pyx_freelist_12chistogramnd___pyx_scope_struct__chistogramnd[--__pyx_freecount_12chistogramnd___pyx_scope_struct__chistogramnd];
+ memset(o, 0, sizeof(struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd));
+ (void) PyObject_INIT(o, t);
+ PyObject_GC_Track(o);
+ } else {
+ o = (*t->tp_alloc)(t, 0);
+ if (unlikely(!o)) return 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_12chistogramnd___pyx_scope_struct__chistogramnd(PyObject *o) {
+ struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *p = (struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *)o;
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->__pyx_v_sample_type);
+ Py_CLEAR(p->__pyx_v_weights_type);
+ if (CYTHON_COMPILING_IN_CPYTHON && ((__pyx_freecount_12chistogramnd___pyx_scope_struct__chistogramnd < 8) & (Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd)))) {
+ __pyx_freelist_12chistogramnd___pyx_scope_struct__chistogramnd[__pyx_freecount_12chistogramnd___pyx_scope_struct__chistogramnd++] = ((struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *)o);
+ } else {
+ (*Py_TYPE(o)->tp_free)(o);
+ }
+}
+
+static int __pyx_tp_traverse_12chistogramnd___pyx_scope_struct__chistogramnd(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *p = (struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *)o;
+ if (p->__pyx_v_sample_type) {
+ e = (*v)(p->__pyx_v_sample_type, a); if (e) return e;
+ }
+ if (p->__pyx_v_weights_type) {
+ e = (*v)(p->__pyx_v_weights_type, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_12chistogramnd___pyx_scope_struct__chistogramnd(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *p = (struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd *)o;
+ tmp = ((PyObject*)p->__pyx_v_sample_type);
+ p->__pyx_v_sample_type = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->__pyx_v_weights_type);
+ p->__pyx_v_weights_type = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyTypeObject __pyx_type_12chistogramnd___pyx_scope_struct__chistogramnd = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "chistogramnd.__pyx_scope_struct__chistogramnd", /*tp_name*/
+ sizeof(struct __pyx_obj_12chistogramnd___pyx_scope_struct__chistogramnd), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_12chistogramnd___pyx_scope_struct__chistogramnd, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_12chistogramnd___pyx_scope_struct__chistogramnd, /*tp_traverse*/
+ __pyx_tp_clear_12chistogramnd___pyx_scope_struct__chistogramnd, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_12chistogramnd___pyx_scope_struct__chistogramnd, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "chistogramnd.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "chistogramnd.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "chistogramnd.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "chistogramnd._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "chistogramnd",
+ 0, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_01_02_2016, __pyx_k_01_02_2016, sizeof(__pyx_k_01_02_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_n_s_C_CONTIGUOUS, __pyx_k_C_CONTIGUOUS, sizeof(__pyx_k_C_CONTIGUOUS), 0, 0, 1, 1},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_kp_s_Case_not_supported_sample_0_and, __pyx_k_Case_not_supported_sample_0_and, sizeof(__pyx_k_Case_not_supported_sample_0_and), 0, 0, 1, 0},
+ {&__pyx_kp_s_D_Naudet, __pyx_k_D_Naudet, sizeof(__pyx_k_D_Naudet), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_n_s_Exception, __pyx_k_Exception, sizeof(__pyx_k_Exception), 0, 0, 1, 1},
+ {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_kp_s_Provided_histo_array_doesn_t_hav, __pyx_k_Provided_histo_array_doesn_t_hav, sizeof(__pyx_k_Provided_histo_array_doesn_t_hav), 0, 0, 1, 0},
+ {&__pyx_kp_s_Provided_histo_array_doesn_t_hav_2, __pyx_k_Provided_histo_array_doesn_t_hav_2, sizeof(__pyx_k_Provided_histo_array_doesn_t_hav_2), 0, 0, 1, 0},
+ {&__pyx_kp_s_Provided_weighted_histo_array_do, __pyx_k_Provided_weighted_histo_array_do, sizeof(__pyx_k_Provided_weighted_histo_array_do), 0, 0, 1, 0},
+ {&__pyx_kp_s_Provided_weighted_histo_array_do_2, __pyx_k_Provided_weighted_histo_array_do_2, sizeof(__pyx_k_Provided_weighted_histo_array_do_2), 0, 0, 1, 0},
+ {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_any, __pyx_k_any, sizeof(__pyx_k_any), 0, 0, 1, 1},
+ {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+ {&__pyx_n_s_ascontiguousarray, __pyx_k_ascontiguousarray, sizeof(__pyx_k_ascontiguousarray), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_bin_edges, __pyx_k_bin_edges, sizeof(__pyx_k_bin_edges), 0, 0, 1, 1},
+ {&__pyx_n_s_bin_edges_c, __pyx_k_bin_edges_c, sizeof(__pyx_k_bin_edges_c), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_chistogramnd, __pyx_k_chistogramnd, sizeof(__pyx_k_chistogramnd), 0, 0, 1, 1},
+ {&__pyx_n_s_chistogramnd_locals_raise_unsupp, __pyx_k_chistogramnd_locals_raise_unsupp, sizeof(__pyx_k_chistogramnd_locals_raise_unsupp), 0, 0, 1, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_cumul_c, __pyx_k_cumul_c, sizeof(__pyx_k_cumul_c), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_double, __pyx_k_double, sizeof(__pyx_k_double), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_edges, __pyx_k_edges, sizeof(__pyx_k_edges), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_equal, __pyx_k_equal, sizeof(__pyx_k_equal), 0, 0, 1, 1},
+ {&__pyx_n_s_err_histo_range, __pyx_k_err_histo_range, sizeof(__pyx_k_err_histo_range), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_float32, __pyx_k_float32, sizeof(__pyx_k_float32), 0, 0, 1, 1},
+ {&__pyx_n_s_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 0, 1, 1},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_histo, __pyx_k_histo, sizeof(__pyx_k_histo), 0, 0, 1, 1},
+ {&__pyx_n_s_histo_c, __pyx_k_histo_c, sizeof(__pyx_k_histo_c), 0, 0, 1, 1},
+ {&__pyx_kp_s_histo_must_be_a_C_CONTIGUOUS_nu, __pyx_k_histo_must_be_a_C_CONTIGUOUS_nu, sizeof(__pyx_k_histo_must_be_a_C_CONTIGUOUS_nu), 0, 0, 1, 0},
+ {&__pyx_n_s_histo_range, __pyx_k_histo_range, sizeof(__pyx_k_histo_range), 0, 0, 1, 1},
+ {&__pyx_n_s_histo_range_c, __pyx_k_histo_range_c, sizeof(__pyx_k_histo_range_c), 0, 0, 1, 1},
+ {&__pyx_kp_s_histo_range_error_expected_n_di, __pyx_k_histo_range_error_expected_n_di, sizeof(__pyx_k_histo_range_error_expected_n_di), 0, 0, 1, 0},
+ {&__pyx_kp_s_histogramnd_failed_to_allocate_m, __pyx_k_histogramnd_failed_to_allocate_m, sizeof(__pyx_k_histogramnd_failed_to_allocate_m), 0, 0, 1, 0},
+ {&__pyx_kp_s_histogramnd_returned_an_error_0, __pyx_k_histogramnd_returned_an_error_0, sizeof(__pyx_k_histogramnd_returned_an_error_0), 0, 0, 1, 0},
+ {&__pyx_n_s_i_dim, __pyx_k_i_dim, sizeof(__pyx_k_i_dim), 0, 0, 1, 1},
+ {&__pyx_n_s_i_histo_range, __pyx_k_i_histo_range, sizeof(__pyx_k_i_histo_range), 0, 0, 1, 1},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_int32, __pyx_k_int32, sizeof(__pyx_k_int32), 0, 0, 1, 1},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_last_bin_closed, __pyx_k_last_bin_closed, sizeof(__pyx_k_last_bin_closed), 0, 0, 1, 1},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_k_mntdirect__scisoft_users_tvince, sizeof(__pyx_k_mntdirect__scisoft_users_tvince), 0, 0, 1, 0},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_n_bins, __pyx_k_n_bins, sizeof(__pyx_k_n_bins), 0, 0, 1, 1},
+ {&__pyx_n_s_n_bins_c, __pyx_k_n_bins_c, sizeof(__pyx_k_n_bins_c), 0, 0, 1, 1},
+ {&__pyx_kp_s_n_bins_must_be_either_a_scalar_s, __pyx_k_n_bins_must_be_either_a_scalar_s, sizeof(__pyx_k_n_bins_must_be_either_a_scalar_s), 0, 0, 1, 0},
+ {&__pyx_kp_s_n_bins_only_positive_values_all, __pyx_k_n_bins_only_positive_values_all, sizeof(__pyx_k_n_bins_only_positive_values_all), 0, 0, 1, 0},
+ {&__pyx_n_s_n_dims, __pyx_k_n_dims, sizeof(__pyx_k_n_dims), 0, 0, 1, 1},
+ {&__pyx_n_s_n_elem, __pyx_k_n_elem, sizeof(__pyx_k_n_elem), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+ {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_ndmin, __pyx_k_ndmin, sizeof(__pyx_k_ndmin), 0, 0, 1, 1},
+ {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_n_s_offset, __pyx_k_offset, sizeof(__pyx_k_offset), 0, 0, 1, 1},
+ {&__pyx_n_s_option_flags, __pyx_k_option_flags, sizeof(__pyx_k_option_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_output_shape, __pyx_k_output_shape, sizeof(__pyx_k_output_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_raise_unsupported_type, __pyx_k_raise_unsupported_type, sizeof(__pyx_k_raise_unsupported_type), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_rc, __pyx_k_rc, sizeof(__pyx_k_rc), 0, 0, 1, 1},
+ {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+ {&__pyx_n_s_s_shape, __pyx_k_s_shape, sizeof(__pyx_k_s_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_sample, __pyx_k_sample, sizeof(__pyx_k_sample), 0, 0, 1, 1},
+ {&__pyx_n_s_sample_c, __pyx_k_sample_c, sizeof(__pyx_k_sample_c), 0, 0, 1, 1},
+ {&__pyx_n_s_sample_type, __pyx_k_sample_type, sizeof(__pyx_k_sample_type), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_sum, __pyx_k_sum, sizeof(__pyx_k_sum), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_n_s_tile, __pyx_k_tile, sizeof(__pyx_k_tile), 0, 0, 1, 1},
+ {&__pyx_n_s_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 0, 1, 1},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_n_s_w_shape, __pyx_k_w_shape, sizeof(__pyx_k_w_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_weight_max, __pyx_k_weight_max, sizeof(__pyx_k_weight_max), 0, 0, 1, 1},
+ {&__pyx_n_s_weight_min, __pyx_k_weight_min, sizeof(__pyx_k_weight_min), 0, 0, 1, 1},
+ {&__pyx_n_s_weighted_histo, __pyx_k_weighted_histo, sizeof(__pyx_k_weighted_histo), 0, 0, 1, 1},
+ {&__pyx_kp_s_weighted_histo_must_be_a_C_CONT, __pyx_k_weighted_histo_must_be_a_C_CONT, sizeof(__pyx_k_weighted_histo_must_be_a_C_CONT), 0, 0, 1, 0},
+ {&__pyx_n_s_weights, __pyx_k_weights, sizeof(__pyx_k_weights), 0, 0, 1, 1},
+ {&__pyx_n_s_weights_c, __pyx_k_weights_c, sizeof(__pyx_k_weights_c), 0, 0, 1, 1},
+ {&__pyx_kp_s_weights_must_be_an_array_whose, __pyx_k_weights_must_be_an_array_whose, sizeof(__pyx_k_weights_must_be_an_array_whose), 0, 0, 1, 0},
+ {&__pyx_n_s_weights_type, __pyx_k_weights_type, sizeof(__pyx_k_weights_type), 0, 0, 1, 1},
+ {&__pyx_n_s_wh_dtype, __pyx_k_wh_dtype, sizeof(__pyx_k_wh_dtype), 0, 0, 1, 1},
+ {&__pyx_kp_s_wh_dtype_type_not_supported_0, __pyx_k_wh_dtype_type_not_supported_0, sizeof(__pyx_k_wh_dtype_type_not_supported_0), 0, 0, 1, 0},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Exception = __Pyx_GetBuiltinName(__pyx_n_s_Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "chistogramnd.pyx":161
+ * if (weighted_histo is not None and
+ * weighted_histo.flags['C_CONTIGUOUS'] is False):
+ * raise ValueError('<weighted_histo> must be a C_CONTIGUOUS numpy array.') # <<<<<<<<<<<<<<
+ *
+ * if histo is not None and histo.flags['C_CONTIGUOUS'] is False:
+ */
+ __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_weighted_histo_must_be_a_C_CONT); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "chistogramnd.pyx":164
+ *
+ * if histo is not None and histo.flags['C_CONTIGUOUS'] is False:
+ * raise ValueError('<histo> must be a C_CONTIGUOUS numpy array.') # <<<<<<<<<<<<<<
+ *
+ * s_shape = sample.shape
+ */
+ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_histo_must_be_a_C_CONTIGUOUS_nu); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "chistogramnd.pyx":176
+ * # 2 different cases : 2D sample (N,M) and 1D (N)
+ * if len(w_shape) != 1 or w_shape[0] != s_shape[0]:
+ * raise ValueError('<weights> must be an array whose length ' # <<<<<<<<<<<<<<
+ * 'is equal to the number of samples.')
+ *
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_weights_must_be_an_array_whose); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "chistogramnd.pyx":191
+ *
+ * if n_dims == 1:
+ * if histo_range.shape == (2,): # <<<<<<<<<<<<<<
+ * pass
+ * elif histo_range.shape == (1, 2):
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_int_2); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "chistogramnd.pyx":193
+ * if histo_range.shape == (2,):
+ * pass
+ * elif histo_range.shape == (1, 2): # <<<<<<<<<<<<<<
+ * histo_range.shape = -1
+ * else:
+ */
+ __pyx_tuple__5 = PyTuple_Pack(2, __pyx_int_1, __pyx_int_2); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "chistogramnd.pyx":214
+ * n_bins = np.tile(n_bins, n_dims)
+ * elif n_bins.shape != (n_dims,):
+ * raise ValueError('n_bins must be either a scalar (same number ' # <<<<<<<<<<<<<<
+ * 'of bins for all dimensions) or '
+ * 'an array (number of bins for each '
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_n_bins_must_be_either_a_scalar_s); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+
+ /* "chistogramnd.pyx":223
+ * # also testing for negative/null values
+ * if np.any(np.equal(n_bins, None)) or np.any(n_bins <= 0):
+ * raise ValueError('<n_bins> : only positive values allowed.') # <<<<<<<<<<<<<<
+ *
+ * output_shape = tuple(n_bins)
+ */
+ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_n_bins_only_positive_values_all); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__7);
+ __Pyx_GIVEREF(__pyx_tuple__7);
+
+ /* "chistogramnd.pyx":292
+ * # functions. so I have to explicitly list them all...
+ *
+ * def raise_unsupported_type(): # <<<<<<<<<<<<<<
+ * raise TypeError('Case not supported - sample:{0} '
+ * 'and weights:{1}.'
+ */
+ __pyx_codeobj__8 = (PyObject*)__Pyx_PyCode_New(0, 0, 0, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_raise_unsupported_type, 292, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":643
+ * if rc != histogramnd_c.HISTO_OK:
+ * if rc == histogramnd_c.HISTO_ERR_ALLOC:
+ * raise MemoryError('histogramnd failed to allocate memory.') # <<<<<<<<<<<<<<
+ * else:
+ * raise Exception('histogramnd returned an error : {0}'
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_histogramnd_failed_to_allocate_m); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 643; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__12);
+ __Pyx_GIVEREF(__pyx_tuple__12);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__13);
+ __Pyx_GIVEREF(__pyx_tuple__13);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__14);
+ __Pyx_GIVEREF(__pyx_tuple__14);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__19);
+ __Pyx_GIVEREF(__pyx_tuple__19);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__21)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__21);
+ __Pyx_GIVEREF(__pyx_tuple__21);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__22);
+ __Pyx_GIVEREF(__pyx_tuple__22);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__23 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__23)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__23);
+ __Pyx_GIVEREF(__pyx_slice__23);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__24 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__24)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__24);
+ __Pyx_GIVEREF(__pyx_slice__24);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__25 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__25)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__25);
+ __Pyx_GIVEREF(__pyx_slice__25);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__26);
+ __Pyx_GIVEREF(__pyx_tuple__26);
+
+ /* "chistogramnd.pyx":36
+ *
+ *
+ * def chistogramnd(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+ __pyx_tuple__27 = PyTuple_Pack(34, __pyx_n_s_sample, __pyx_n_s_histo_range, __pyx_n_s_n_bins, __pyx_n_s_weights, __pyx_n_s_weight_min, __pyx_n_s_weight_max, __pyx_n_s_last_bin_closed, __pyx_n_s_histo, __pyx_n_s_weighted_histo, __pyx_n_s_wh_dtype, __pyx_n_s_s_shape, __pyx_n_s_n_dims, __pyx_n_s_w_shape, __pyx_n_s_weights_type, __pyx_n_s_i_histo_range, __pyx_n_s_err_histo_range, __pyx_n_s_output_shape, __pyx_n_s_option_flags, __pyx_n_s_sample_type, __pyx_n_s_n_elem, __pyx_n_s_bin_edges, __pyx_n_s_raise_unsupported_type, __pyx_n_s_raise_unsupported_type, __pyx_n_s_sample_c, __pyx_n_s_weights_c, __pyx_n_s_histo_range_c, __pyx_n_s_n_bins_c, __pyx_n_s_histo_c, __pyx_n_s_cumul_c, __pyx_n_s_bin_edges_c, __pyx_n_s_rc, __pyx_n_s_edges, __pyx_n_s_offset, __pyx_n_s_i_dim); if (unlikely(!__pyx_tuple__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__27);
+ __Pyx_GIVEREF(__pyx_tuple__27);
+ __pyx_codeobj__28 = (PyObject*)__Pyx_PyCode_New(10, 0, 34, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_chistogramnd, 36, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__29)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__29);
+ __Pyx_GIVEREF(__pyx_tuple__29);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__30)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__30);
+ __Pyx_GIVEREF(__pyx_tuple__30);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__31)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__31);
+ __Pyx_GIVEREF(__pyx_tuple__31);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__32)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__32);
+ __Pyx_GIVEREF(__pyx_tuple__32);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__33 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__33);
+ __Pyx_GIVEREF(__pyx_tuple__33);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initchistogramnd(void); /*proto*/
+PyMODINIT_FUNC initchistogramnd(void)
+#else
+PyMODINIT_FUNC PyInit_chistogramnd(void); /*proto*/
+PyMODINIT_FUNC PyInit_chistogramnd(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_chistogramnd(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("chistogramnd", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_chistogramnd) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "chistogramnd")) {
+ if (unlikely(PyDict_SetItemString(modules, "chistogramnd", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type_12chistogramnd___pyx_scope_struct__chistogramnd) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_12chistogramnd___pyx_scope_struct__chistogramnd.tp_print = 0;
+ __pyx_ptype_12chistogramnd___pyx_scope_struct__chistogramnd = &__pyx_type_12chistogramnd___pyx_scope_struct__chistogramnd;
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type",
+ #if CYTHON_COMPILING_IN_PYPY
+ sizeof(PyTypeObject),
+ #else
+ sizeof(PyHeapTypeObject),
+ #endif
+ 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "chistogramnd.pyx":25
+ * # ############################################################################*[inserted by cython to avoid comment closer]/
+ *
+ * __authors__ = ["D. Naudet"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "01/02/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_D_Naudet);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_D_Naudet);
+ __Pyx_GIVEREF(__pyx_kp_s_D_Naudet);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":26
+ *
+ * __authors__ = ["D. Naudet"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "01/02/2016"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":27
+ * __authors__ = ["D. Naudet"]
+ * __license__ = "MIT"
+ * __date__ = "01/02/2016" # <<<<<<<<<<<<<<
+ *
+ * cimport numpy # noqa
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_01_02_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd.pyx":31
+ * cimport numpy # noqa
+ * cimport cython
+ * import numpy as np # <<<<<<<<<<<<<<
+ *
+ * cimport histogramnd_c
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":36
+ *
+ *
+ * def chistogramnd(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_12chistogramnd_1chistogramnd, NULL, __pyx_n_s_chistogramnd); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_chistogramnd, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd.pyx":1244
+ *
+ *
+ * if __name__=='__main__': # <<<<<<<<<<<<<<
+ * pass
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = (__Pyx_PyString_Equals(__pyx_t_1, __pyx_n_s_main, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_2) {
+ goto __pyx_L2;
+ }
+ __pyx_L2:;
+
+ /* "chistogramnd.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * # /[inserted by cython to avoid comment start]*##########################################################################
+ * # Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init chistogramnd", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init chistogramnd");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) {
+ PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname);
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
+ PyObject* fake_module;
+ PyTypeObject* cached_type = NULL;
+ fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
+ if (!fake_module) return NULL;
+ Py_INCREF(fake_module);
+ cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
+ if (cached_type) {
+ if (!PyType_Check((PyObject*)cached_type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s is not a type object",
+ type->tp_name);
+ goto bad;
+ }
+ if (cached_type->tp_basicsize != type->tp_basicsize) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s has the wrong size, try recompiling",
+ type->tp_name);
+ goto bad;
+ }
+ } else {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+ PyErr_Clear();
+ if (PyType_Ready(type) < 0) goto bad;
+ if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
+ goto bad;
+ Py_INCREF(type);
+ cached_type = type;
+ }
+done:
+ Py_DECREF(fake_module);
+ return cached_type;
+bad:
+ Py_XDECREF(cached_type);
+ cached_type = NULL;
+ goto done;
+}
+
+static PyObject *
+__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure)
+{
+ if (unlikely(op->func_doc == NULL)) {
+ if (op->func.m_ml->ml_doc) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc);
+#else
+ op->func_doc = PyString_FromString(op->func.m_ml->ml_doc);
+#endif
+ if (unlikely(op->func_doc == NULL))
+ return NULL;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+ Py_INCREF(op->func_doc);
+ return op->func_doc;
+}
+static int
+__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp = op->func_doc;
+ if (value == NULL) {
+ value = Py_None;
+ }
+ Py_INCREF(value);
+ op->func_doc = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_name == NULL)) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name);
+#else
+ op->func_name = PyString_InternFromString(op->func.m_ml->ml_name);
+#endif
+ if (unlikely(op->func_name == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_name);
+ return op->func_name;
+}
+static int
+__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__name__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_name;
+ Py_INCREF(value);
+ op->func_name = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_qualname);
+ return op->func_qualname;
+}
+static int
+__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__qualname__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_qualname;
+ Py_INCREF(value);
+ op->func_qualname = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure)
+{
+ PyObject *self;
+ self = m->func_closure;
+ if (self == NULL)
+ self = Py_None;
+ Py_INCREF(self);
+ return self;
+}
+static PyObject *
+__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_dict == NULL)) {
+ op->func_dict = PyDict_New();
+ if (unlikely(op->func_dict == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_dict);
+ return op->func_dict;
+}
+static int
+__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+ if (unlikely(value == NULL)) {
+ PyErr_SetString(PyExc_TypeError,
+ "function's dictionary may not be deleted");
+ return -1;
+ }
+ if (unlikely(!PyDict_Check(value))) {
+ PyErr_SetString(PyExc_TypeError,
+ "setting function's dictionary to a non-dict");
+ return -1;
+ }
+ tmp = op->func_dict;
+ Py_INCREF(value);
+ op->func_dict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_globals);
+ return op->func_globals;
+}
+static PyObject *
+__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op)
+{
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+static PyObject *
+__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op)
+{
+ PyObject* result = (op->func_code) ? op->func_code : Py_None;
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) {
+ PyObject *res = op->defaults_getter((PyObject *) op);
+ if (unlikely(!res))
+ return -1;
+ op->defaults_tuple = PyTuple_GET_ITEM(res, 0);
+ Py_INCREF(op->defaults_tuple);
+ op->defaults_kwdict = PyTuple_GET_ITEM(res, 1);
+ Py_INCREF(op->defaults_kwdict);
+ Py_DECREF(res);
+ return 0;
+}
+static int
+__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyTuple_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__defaults__ must be set to a tuple object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_tuple;
+ op->defaults_tuple = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_tuple;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_tuple;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__kwdefaults__ must be set to a dict object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_kwdict;
+ op->defaults_kwdict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_kwdict;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_kwdict;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value || value == Py_None) {
+ value = NULL;
+ } else if (!PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__annotations__ must be set to a dict object");
+ return -1;
+ }
+ Py_XINCREF(value);
+ tmp = op->func_annotations;
+ op->func_annotations = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->func_annotations;
+ if (unlikely(!result)) {
+ result = PyDict_New();
+ if (unlikely(!result)) return NULL;
+ op->func_annotations = result;
+ }
+ Py_INCREF(result);
+ return result;
+}
+static PyGetSetDef __pyx_CyFunction_getsets[] = {
+ {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0},
+ {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0},
+ {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0},
+ {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+#ifndef PY_WRITE_RESTRICTED
+#define PY_WRITE_RESTRICTED WRITE_RESTRICTED
+#endif
+static PyMemberDef __pyx_CyFunction_members[] = {
+ {(char *) "__module__", T_OBJECT, offsetof(__pyx_CyFunctionObject, func.m_module), PY_WRITE_RESTRICTED, 0},
+ {0, 0, 0, 0, 0}
+};
+static PyObject *
+__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromString(m->func.m_ml->ml_name);
+#else
+ return PyString_FromString(m->func.m_ml->ml_name);
+#endif
+}
+static PyMethodDef __pyx_CyFunction_methods[] = {
+ {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0},
+ {0, 0, 0, 0}
+};
+#if PY_VERSION_HEX < 0x030500A0
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist)
+#else
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
+#endif
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname,
+ PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
+ __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
+ if (op == NULL)
+ return NULL;
+ op->flags = flags;
+ __Pyx_CyFunction_weakreflist(op) = NULL;
+ op->func.m_ml = ml;
+ op->func.m_self = (PyObject *) op;
+ Py_XINCREF(closure);
+ op->func_closure = closure;
+ Py_XINCREF(module);
+ op->func.m_module = module;
+ op->func_dict = NULL;
+ op->func_name = NULL;
+ Py_INCREF(qualname);
+ op->func_qualname = qualname;
+ op->func_doc = NULL;
+ op->func_classobj = NULL;
+ op->func_globals = globals;
+ Py_INCREF(op->func_globals);
+ Py_XINCREF(code);
+ op->func_code = code;
+ op->defaults_pyobjects = 0;
+ op->defaults = NULL;
+ op->defaults_tuple = NULL;
+ op->defaults_kwdict = NULL;
+ op->defaults_getter = NULL;
+ op->func_annotations = NULL;
+ PyObject_GC_Track(op);
+ return (PyObject *) op;
+}
+static int
+__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
+{
+ Py_CLEAR(m->func_closure);
+ Py_CLEAR(m->func.m_module);
+ Py_CLEAR(m->func_dict);
+ Py_CLEAR(m->func_name);
+ Py_CLEAR(m->func_qualname);
+ Py_CLEAR(m->func_doc);
+ Py_CLEAR(m->func_globals);
+ Py_CLEAR(m->func_code);
+ Py_CLEAR(m->func_classobj);
+ Py_CLEAR(m->defaults_tuple);
+ Py_CLEAR(m->defaults_kwdict);
+ Py_CLEAR(m->func_annotations);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_XDECREF(pydefaults[i]);
+ PyMem_Free(m->defaults);
+ m->defaults = NULL;
+ }
+ return 0;
+}
+static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
+{
+ PyObject_GC_UnTrack(m);
+ if (__Pyx_CyFunction_weakreflist(m) != NULL)
+ PyObject_ClearWeakRefs((PyObject *) m);
+ __Pyx_CyFunction_clear(m);
+ PyObject_GC_Del(m);
+}
+static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg)
+{
+ Py_VISIT(m->func_closure);
+ Py_VISIT(m->func.m_module);
+ Py_VISIT(m->func_dict);
+ Py_VISIT(m->func_name);
+ Py_VISIT(m->func_qualname);
+ Py_VISIT(m->func_doc);
+ Py_VISIT(m->func_globals);
+ Py_VISIT(m->func_code);
+ Py_VISIT(m->func_classobj);
+ Py_VISIT(m->defaults_tuple);
+ Py_VISIT(m->defaults_kwdict);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_VISIT(pydefaults[i]);
+ }
+ return 0;
+}
+static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
+ Py_INCREF(func);
+ return func;
+ }
+ if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) {
+ if (type == NULL)
+ type = (PyObject *)(Py_TYPE(obj));
+ return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type)));
+ }
+ if (obj == Py_None)
+ obj = NULL;
+ return __Pyx_PyMethod_New(func, obj, type);
+}
+static PyObject*
+__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromFormat("<cyfunction %U at %p>",
+ op->func_qualname, (void *)op);
+#else
+ return PyString_FromFormat("<cyfunction %s at %p>",
+ PyString_AsString(op->func_qualname), (void *)op);
+#endif
+}
+#if CYTHON_COMPILING_IN_PYPY
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyCFunctionObject* f = (PyCFunctionObject*)func;
+ PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ PyObject *self = PyCFunction_GET_SELF(func);
+ Py_ssize_t size;
+ switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+ case METH_VARARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0)
+ return (*meth)(self, arg);
+ break;
+ case METH_VARARGS | METH_KEYWORDS:
+ return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+ case METH_NOARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 0)
+ return (*meth)(self, NULL);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes no arguments (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ case METH_O:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 1)
+ return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes exactly one argument (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError, "Bad call flags in "
+ "__Pyx_CyFunction_Call. METH_OLDARGS is no "
+ "longer supported!");
+ return NULL;
+ }
+ PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+ f->m_ml->ml_name);
+ return NULL;
+}
+#else
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ return PyCFunction_Call(func, arg, kw);
+}
+#endif
+static PyTypeObject __pyx_CyFunctionType_type = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "cython_function_or_method",
+ sizeof(__pyx_CyFunctionObject),
+ 0,
+ (destructor) __Pyx_CyFunction_dealloc,
+ 0,
+ 0,
+ 0,
+#if PY_MAJOR_VERSION < 3
+ 0,
+#else
+ 0,
+#endif
+ (reprfunc) __Pyx_CyFunction_repr,
+ 0,
+ 0,
+ 0,
+ 0,
+ __Pyx_CyFunction_Call,
+ 0,
+ 0,
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ 0,
+ (traverseproc) __Pyx_CyFunction_traverse,
+ (inquiry) __Pyx_CyFunction_clear,
+ 0,
+#if PY_VERSION_HEX < 0x030500A0
+ offsetof(__pyx_CyFunctionObject, func_weakreflist),
+#else
+ offsetof(PyCFunctionObject, m_weakreflist),
+#endif
+ 0,
+ 0,
+ __pyx_CyFunction_methods,
+ __pyx_CyFunction_members,
+ __pyx_CyFunction_getsets,
+ 0,
+ 0,
+ __Pyx_CyFunction_descr_get,
+ 0,
+ offsetof(__pyx_CyFunctionObject, func_dict),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ 0,
+#endif
+};
+static int __Pyx_CyFunction_init(void) {
+#if !CYTHON_COMPILING_IN_PYPY
+ __pyx_CyFunctionType_type.tp_call = PyCFunction_Call;
+#endif
+ __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
+ if (__pyx_CyFunctionType == NULL) {
+ return -1;
+ }
+ return 0;
+}
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults = PyMem_Malloc(size);
+ if (!m->defaults)
+ return PyErr_NoMemory();
+ memset(m->defaults, 0, size);
+ m->defaults_pyobjects = pyobjects;
+ return m->defaults;
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_tuple = tuple;
+ Py_INCREF(tuple);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_kwdict = dict;
+ Py_INCREF(dict);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->func_annotations = dict;
+ Py_INCREF(dict);
+}
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+ PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+ PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
+ int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyMappingMethods* mp;
+#if PY_MAJOR_VERSION < 3
+ PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
+ if (likely(ms && ms->sq_slice)) {
+ if (!has_cstart) {
+ if (_py_start && (*_py_start != Py_None)) {
+ cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
+ if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+ } else
+ cstart = 0;
+ }
+ if (!has_cstop) {
+ if (_py_stop && (*_py_stop != Py_None)) {
+ cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
+ if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+ } else
+ cstop = PY_SSIZE_T_MAX;
+ }
+ if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
+ Py_ssize_t l = ms->sq_length(obj);
+ if (likely(l >= 0)) {
+ if (cstop < 0) {
+ cstop += l;
+ if (cstop < 0) cstop = 0;
+ }
+ if (cstart < 0) {
+ cstart += l;
+ if (cstart < 0) cstart = 0;
+ }
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ goto bad;
+ }
+ }
+ return ms->sq_slice(obj, cstart, cstop);
+ }
+#endif
+ mp = Py_TYPE(obj)->tp_as_mapping;
+ if (likely(mp && mp->mp_subscript))
+#endif
+ {
+ PyObject* result;
+ PyObject *py_slice, *py_start, *py_stop;
+ if (_py_slice) {
+ py_slice = *_py_slice;
+ } else {
+ PyObject* owned_start = NULL;
+ PyObject* owned_stop = NULL;
+ if (_py_start) {
+ py_start = *_py_start;
+ } else {
+ if (has_cstart) {
+ owned_start = py_start = PyInt_FromSsize_t(cstart);
+ if (unlikely(!py_start)) goto bad;
+ } else
+ py_start = Py_None;
+ }
+ if (_py_stop) {
+ py_stop = *_py_stop;
+ } else {
+ if (has_cstop) {
+ owned_stop = py_stop = PyInt_FromSsize_t(cstop);
+ if (unlikely(!py_stop)) {
+ Py_XDECREF(owned_start);
+ goto bad;
+ }
+ } else
+ py_stop = Py_None;
+ }
+ py_slice = PySlice_New(py_start, py_stop, Py_None);
+ Py_XDECREF(owned_start);
+ Py_XDECREF(owned_stop);
+ if (unlikely(!py_slice)) goto bad;
+ }
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = mp->mp_subscript(obj, py_slice);
+#else
+ result = PyObject_GetItem(obj, py_slice);
+#endif
+ if (!_py_slice) {
+ Py_DECREF(py_slice);
+ }
+ return result;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name);
+bad:
+ return NULL;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static CYTHON_INLINE npy_int32 __Pyx_PyInt_As_npy_int32(PyObject *x) {
+ const npy_int32 neg_one = (npy_int32) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(npy_int32) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (npy_int32) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(npy_int32, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(npy_int32) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(npy_int32) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(npy_int32, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(npy_int32, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(npy_int32) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, long, PyLong_AsLong(x))
+ } else if (sizeof(npy_int32) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ npy_int32 val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (npy_int32) -1;
+ }
+ } else {
+ npy_int32 val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (npy_int32) -1;
+ val = __Pyx_PyInt_As_npy_int32(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to npy_int32");
+ return (npy_int32) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to npy_int32");
+ return (npy_int32) -1;
+}
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return ::std::complex< float >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return x + y*(__pyx_t_float_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ __pyx_t_float_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrtf(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypotf(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ float denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(a, a);
+ case 3:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, a);
+ case 4:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_absf(a);
+ theta = atan2f(a.imag, a.real);
+ }
+ lnr = logf(r);
+ z_r = expf(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cosf(z_theta);
+ z.imag = z_r * sinf(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return ::std::complex< double >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return x + y*(__pyx_t_double_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ __pyx_t_double_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrt(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypot(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ double denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(a, a);
+ case 3:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, a);
+ case 4:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_abs(a);
+ theta = atan2(a.imag, a.real);
+ }
+ lnr = log(r);
+ z_r = exp(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cos(z_theta);
+ z.imag = z_r * sin(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_double(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_double, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_int(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_int, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_float(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_float, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+ PyObject *py_name = 0;
+ PyObject *py_module = 0;
+ py_name = __Pyx_PyIdentifier_FromString(name);
+ if (!py_name)
+ goto bad;
+ py_module = PyImport_Import(py_name);
+ Py_DECREF(py_name);
+ return py_module;
+bad:
+ Py_XDECREF(py_name);
+ return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+ size_t size, int strict)
+{
+ PyObject *py_module = 0;
+ PyObject *result = 0;
+ PyObject *py_name = 0;
+ char warning[200];
+ Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+ PyObject *py_basicsize;
+#endif
+ py_module = __Pyx_ImportModule(module_name);
+ if (!py_module)
+ goto bad;
+ py_name = __Pyx_PyIdentifier_FromString(class_name);
+ if (!py_name)
+ goto bad;
+ result = PyObject_GetAttr(py_module, py_name);
+ Py_DECREF(py_name);
+ py_name = 0;
+ Py_DECREF(py_module);
+ py_module = 0;
+ if (!result)
+ goto bad;
+ if (!PyType_Check(result)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.%.200s is not a type object",
+ module_name, class_name);
+ goto bad;
+ }
+#ifndef Py_LIMITED_API
+ basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+ py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+ if (!py_basicsize)
+ goto bad;
+ basicsize = PyLong_AsSsize_t(py_basicsize);
+ Py_DECREF(py_basicsize);
+ py_basicsize = 0;
+ if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+ goto bad;
+#endif
+ if (!strict && (size_t)basicsize > size) {
+ PyOS_snprintf(warning, sizeof(warning),
+ "%s.%s size changed, may indicate binary incompatibility",
+ module_name, class_name);
+ if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+ }
+ else if ((size_t)basicsize != size) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s.%.200s has the wrong size, try recompiling",
+ module_name, class_name);
+ goto bad;
+ }
+ return (PyTypeObject *)result;
+bad:
+ Py_XDECREF(py_module);
+ Py_XDECREF(result);
+ return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/math/histogramnd/chistogramnd.pyx b/silx/math/histogramnd/chistogramnd.pyx
new file mode 100644
index 0000000..f7b4b78
--- /dev/null
+++ b/silx/math/histogramnd/chistogramnd.pyx
@@ -0,0 +1,1245 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+
+__authors__ = ["D. Naudet"]
+__license__ = "MIT"
+__date__ = "01/02/2016"
+
+cimport numpy # noqa
+cimport cython
+import numpy as np
+
+cimport histogramnd_c
+
+
+def chistogramnd(sample,
+ histo_range,
+ n_bins,
+ weights=None,
+ weight_min=None,
+ weight_max=None,
+ last_bin_closed=False,
+ histo=None,
+ weighted_histo=None,
+ wh_dtype=None):
+ """Computes the multidimensional histogram of some data.
+
+ :param sample:
+ The data to be histogrammed.
+ Its shape must be either
+ (N,) if it contains one dimensional coordinates,
+ or an (N,D) array where the rows are the
+ coordinates of points in a D dimensional space.
+ The following dtypes are supported : :class:`numpy.float64`,
+ :class:`numpy.float32`, :class:`numpy.int32`.
+
+ .. warning:: if sample is not a C_CONTIGUOUS ndarray (e.g : a non
+ contiguous slice) then histogramnd will have to do make an internal
+ copy.
+ :type sample: :class:`numpy.array`
+
+ :param histo_range:
+ A (N, 2) array containing the histogram range along each dimension,
+ where N is the sample's number of dimensions.
+ :type histo_range: array_like
+
+ :param n_bins:
+ The number of bins :
+ * a scalar (same number of bins for all dimensions)
+ * a D elements array (number of bins for each dimensions)
+ :type n_bins: scalar or array_like
+
+ :param weights:
+ A N elements numpy array of values associated with
+ each sample.
+ The values of the *weighted_histo* array
+ returned by the function are equal to the sum of
+ the weights associated with the samples falling
+ into each bin.
+ The following dtypes are supported : :class:`numpy.float64`,
+ :class:`numpy.float32`, :class:`numpy.int32`.
+
+ .. note:: If None, the weighted histogram returned will be None.
+ :type weights: *optional*, :class:`numpy.array`
+
+ :param weight_min:
+ Use this parameter to filter out all samples whose
+ weights are lower than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+ :type weight_min: *optional*, scalar
+
+ :param weight_max:
+ Use this parameter to filter out all samples whose
+ weights are higher than this value.
+
+ .. note:: This value will be cast to the same type
+ as *weights*.
+
+ :type weight_max: *optional*, scalar
+
+ :param last_bin_closed:
+ By default the last bin is half
+ open (i.e.: [x,y) ; x included, y
+ excluded), like all the other bins.
+ Set this parameter to true if you want
+ the LAST bin to be closed.
+ :type last_bin_closed: *optional*, :class:`python.boolean`
+
+ :param histo:
+ Use this parameter if you want to pass your
+ own histogram array instead of the one
+ created by this function. New values
+ will be added to this array. The returned array
+ will then be this one (same reference).
+
+ .. warning:: If the histo array was created by a previous
+ call to histogramnd then the user is
+ responsible for providing the same parameters
+ (*n_bins*, *histo_range*, ...).
+ :type histo: *optional*, :class:`numpy.array`
+
+ :param weighted_histo:
+ Use this parameter if you want to pass your
+ own weighted histogram array instead of
+ the created by this function. New
+ values will be added to this array. The returned array
+ will then be this one (same reference).
+
+ .. warning:: If the weighted_histo array was created by a previous
+ call to histogramnd then the user is
+ responsible for providing the same parameters
+ (*n_bins*, *histo_range*, ...).
+
+ .. warning:: if weighted_histo is not a C_CONTIGUOUS ndarray (e.g : a
+ non contiguous slice) then histogramnd will have to do make an
+ internal copy.
+ :type weighted_histo: *optional*, :class:`numpy.array`
+
+ :param wh_dtype: type of the weighted histogram array. This parameter is
+ ignored if *weighted_histo* is provided. If not provided, the
+ weighted histogram array will contain values of the same type as
+ *weights*. Allowed values are : `numpu.double` and `numpy.float32`.
+ :type wh_dtype: *optional*, numpy data type
+
+ :return: Histogram (bin counts, always returned), weighted histogram of
+ the sample (or *None* if weights is *None*) and bin edges for each
+ dimension.
+ :rtype: *tuple* (:class:`numpy.array`, :class:`numpy.array`, `tuple`) or
+ (:class:`numpy.array`, None, `tuple`)
+ """ # noqa
+
+ if wh_dtype is None:
+ wh_dtype = np.double
+ elif wh_dtype not in (np.double, np.float32):
+ raise ValueError('<wh_dtype> type not supported : {0}.'.format(wh_dtype))
+
+ if (weighted_histo is not None and
+ weighted_histo.flags['C_CONTIGUOUS'] is False):
+ raise ValueError('<weighted_histo> must be a C_CONTIGUOUS numpy array.')
+
+ if histo is not None and histo.flags['C_CONTIGUOUS'] is False:
+ raise ValueError('<histo> must be a C_CONTIGUOUS numpy array.')
+
+ s_shape = sample.shape
+
+ n_dims = 1 if len(s_shape) == 1 else s_shape[1]
+
+ if weights is not None:
+ w_shape = weights.shape
+
+ # making sure the sample and weights sizes are coherent
+ # 2 different cases : 2D sample (N,M) and 1D (N)
+ if len(w_shape) != 1 or w_shape[0] != s_shape[0]:
+ raise ValueError('<weights> must be an array whose length '
+ 'is equal to the number of samples.')
+
+ weights_type = weights.dtype
+ else:
+ weights_type = None
+
+ # just in case those arent numpy arrays
+ # (this allows the user to provide native python lists,
+ # => easier for testing)
+ i_histo_range = histo_range
+ histo_range = np.array(histo_range)
+ err_histo_range = False
+
+ if n_dims == 1:
+ if histo_range.shape == (2,):
+ pass
+ elif histo_range.shape == (1, 2):
+ histo_range.shape = -1
+ else:
+ err_histo_range = True
+ elif n_dims != 1 and histo_range.shape != (n_dims, 2):
+ err_histo_range = True
+
+ if err_histo_range:
+ raise ValueError('<histo_range> error : expected {n_dims} sets of '
+ 'lower and upper bin edges, '
+ 'got the following instead : {histo_range}. '
+ '(provided <sample> contains '
+ '{n_dims}D values)'
+ ''.format(histo_range=i_histo_range,
+ n_dims=n_dims))
+
+ # checking n_bins size
+ n_bins = np.array(n_bins, ndmin=1)
+ if len(n_bins) == 1:
+ n_bins = np.tile(n_bins, n_dims)
+ elif n_bins.shape != (n_dims,):
+ raise ValueError('n_bins must be either a scalar (same number '
+ 'of bins for all dimensions) or '
+ 'an array (number of bins for each '
+ 'dimension).')
+
+ # checking if None is in n_bins, otherwise a rather cryptic
+ # exception is thrown when calling np.zeros
+ # also testing for negative/null values
+ if np.any(np.equal(n_bins, None)) or np.any(n_bins <= 0):
+ raise ValueError('<n_bins> : only positive values allowed.')
+
+ output_shape = tuple(n_bins)
+
+ # checking the histo array, if provided
+ if histo is None:
+ histo = np.zeros(output_shape, dtype=np.uint32)
+ else:
+ if histo.shape != output_shape:
+ raise ValueError('Provided <histo> array doesn\'t have '
+ 'a shape compatible with <n_bins> '
+ ': should be {0} instead of {1}.'
+ ''.format(output_shape, histo.shape))
+ if histo.dtype != np.uint32:
+ raise ValueError('Provided <histo> array doesn\'t have '
+ 'the expected type '
+ ': should be {0} instead of {1}.'
+ ''.format(np.uint32, histo.dtype))
+
+ # checking the weighted_histo array, if provided
+ if weights_type is None:
+ # no weights provided, not creating the weighted_histo array
+ weighted_histo = None
+ elif weighted_histo is None:
+ # weights provided, but no weighted_histo, creating it
+ if wh_dtype is None:
+ wh_dtype = weights_type
+ weighted_histo = np.zeros(output_shape, dtype=wh_dtype)
+ else:
+ # weighted_histo provided, checking shape/dtype
+ if weighted_histo.shape != output_shape:
+ raise ValueError('Provided <weighted_histo> array doesn\'t have '
+ 'a shape compatible with <n_bins> '
+ ': should be {0} instead of {1}.'
+ ''.format(output_shape, weighted_histo.shape))
+ if (weighted_histo.dtype != np.float64 and
+ weighted_histo.dtype != np.float32):
+ raise ValueError('Provided <weighted_histo> array doesn\'t have '
+ 'the expected type '
+ ': should be {0} or {1} instead of {2}.'
+ ''.format(np.double,
+ np.float32,
+ weighted_histo.dtype))
+
+ option_flags = 0
+
+ if weight_min is not None:
+ option_flags |= histogramnd_c.HISTO_WEIGHT_MIN
+ else:
+ weight_min = 0
+
+ if weight_max is not None:
+ option_flags |= histogramnd_c.HISTO_WEIGHT_MAX
+ else:
+ weight_max = 0
+
+ if last_bin_closed is not None and last_bin_closed:
+ option_flags |= histogramnd_c.HISTO_LAST_BIN_CLOSED
+
+ sample_type = sample.dtype
+
+ n_elem = sample.size // n_dims
+
+ bin_edges = np.zeros(n_bins.sum() + n_bins.size, dtype=np.double)
+
+ # wanted to store the functions in a dict (with the supported types
+ # as keys, but I couldn't find a way to make it work with cdef
+ # functions. so I have to explicitly list them all...
+
+ def raise_unsupported_type():
+ raise TypeError('Case not supported - sample:{0} '
+ 'and weights:{1}.'
+ ''.format(sample_type, weights_type))
+
+ sample_c = np.ascontiguousarray(sample.reshape((sample.size,)))
+
+ weights_c = (np.ascontiguousarray(weights.reshape((weights.size,)))
+ if weights is not None else None)
+
+ histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)),
+ dtype=np.double)
+
+ n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)),
+ dtype=np.int32)
+
+ histo_c = histo.reshape((histo.size,))
+
+ if weighted_histo is not None:
+ cumul_c = weighted_histo.reshape((weighted_histo.size,))
+ else:
+ cumul_c = None
+
+ bin_edges_c = np.ascontiguousarray(bin_edges.reshape((bin_edges.size,)))
+
+ rc = 0
+
+ if weighted_histo is None or weighted_histo.dtype == np.double:
+
+ if sample_type == np.float64:
+
+ if weights_type == np.float64 or weights_type is None:
+
+ rc = _histogramnd_double_double_double(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.float32:
+
+ rc = _histogramnd_double_float_double(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.int32:
+
+ rc = _histogramnd_double_int32_t_double(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ else:
+ raise_unsupported_type()
+
+ # endif sample_type == np.float64
+ elif sample_type == np.float32:
+
+ if weights_type == np.float64 or weights_type is None:
+
+ rc = _histogramnd_float_double_double(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.float32:
+
+ rc = _histogramnd_float_float_double(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.int32:
+
+ rc = _histogramnd_float_int32_t_double(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ else:
+ raise_unsupported_type()
+
+ # endif sample_type == np.float32
+ elif sample_type == np.int32:
+
+ if weights_type == np.float64 or weights_type is None:
+
+ rc = _histogramnd_int32_t_double_double(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.float32:
+
+ rc = _histogramnd_int32_t_float_double(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.int32:
+
+ rc = _histogramnd_int32_t_int32_t_double(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ else:
+ raise_unsupported_type()
+
+ # endif sample_type == np.int32:
+ else:
+ raise_unsupported_type()
+
+ # endif weighted_histo is None or weighted_histo.dtype == np.double:
+ elif weighted_histo.dtype == np.float32:
+
+ if sample_type == np.float64:
+
+ if weights_type == np.float64 or weights_type is None:
+
+ rc = _histogramnd_double_double_float(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.float32:
+
+ rc = _histogramnd_double_float_float(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.int32:
+
+ rc = _histogramnd_double_int32_t_float(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ else:
+ raise_unsupported_type()
+
+ # endif sample_type == np.float64
+ elif sample_type == np.float32:
+
+ if weights_type == np.float64 or weights_type is None:
+
+ rc = _histogramnd_float_double_float(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.float32:
+
+ rc = _histogramnd_float_float_float(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.int32:
+
+ rc = _histogramnd_float_int32_t_float(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ else:
+ raise_unsupported_type()
+
+ # endif sample_type == np.float32
+ elif sample_type == np.int32:
+
+ if weights_type == np.float64 or weights_type is None:
+
+ rc = _histogramnd_int32_t_double_float(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.float32:
+
+ rc = _histogramnd_int32_t_float_float(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ elif weights_type == np.int32:
+
+ rc = _histogramnd_int32_t_int32_t_float(sample_c,
+ weights_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ histo_c,
+ cumul_c,
+ bin_edges_c,
+ option_flags,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ else:
+ raise_unsupported_type()
+
+ # endif sample_type == np.int32:
+ else:
+ raise_unsupported_type()
+
+ # end elseif weighted_histo.dtype == np.float32:
+ else:
+ # this isnt supposed to happen since weighted_histo type was checked earlier
+ raise_unsupported_type()
+
+ if rc != histogramnd_c.HISTO_OK:
+ if rc == histogramnd_c.HISTO_ERR_ALLOC:
+ raise MemoryError('histogramnd failed to allocate memory.')
+ else:
+ raise Exception('histogramnd returned an error : {0}'
+ ''.format(rc))
+
+ edges = []
+ offset = 0
+ for i_dim in range(n_dims):
+ edges.append(bin_edges[offset:offset + n_bins[i_dim] + 1])
+ offset += n_bins[i_dim] + 1
+
+ return histo, weighted_histo, tuple(edges)
+
+# =====================
+# double sample, double cumul
+# =====================
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_double_double_double(double[:] sample,
+ double[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ double[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ double weight_min,
+ double weight_max) nogil:
+
+ return histogramnd_c.histogramnd_double_double_double(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_double_float_double(double[:] sample,
+ float[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ double[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ float weight_min,
+ float weight_max) nogil:
+
+ return histogramnd_c.histogramnd_double_float_double(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_double_int32_t_double(double[:] sample,
+ numpy.int32_t[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ double[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ numpy.int32_t weight_min,
+ numpy.int32_t weight_max) nogil:
+
+ return histogramnd_c.histogramnd_double_int32_t_double(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+# =====================
+# float sample, double cumul
+# =====================
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_float_double_double(float[:] sample,
+ double[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ double[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ double weight_min,
+ double weight_max) nogil:
+
+ return histogramnd_c.histogramnd_float_double_double(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_float_float_double(float[:] sample,
+ float[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ double[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ float weight_min,
+ float weight_max) nogil:
+
+ return histogramnd_c.histogramnd_float_float_double(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_float_int32_t_double(float[:] sample,
+ numpy.int32_t[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ double[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ numpy.int32_t weight_min,
+ numpy.int32_t weight_max) nogil:
+
+ return histogramnd_c.histogramnd_float_int32_t_double(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+# =====================
+# numpy.int32_t sample, double cumul
+# =====================
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_int32_t_double_double(numpy.int32_t[:] sample,
+ double[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ double[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ double weight_min,
+ double weight_max) nogil:
+
+ return histogramnd_c.histogramnd_int32_t_double_double(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_int32_t_float_double(numpy.int32_t[:] sample,
+ float[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ double[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ float weight_min,
+ float weight_max) nogil:
+
+ return histogramnd_c.histogramnd_int32_t_float_double(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_int32_t_int32_t_double(numpy.int32_t[:] sample,
+ numpy.int32_t[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ double[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ numpy.int32_t weight_min,
+ numpy.int32_t weight_max) nogil:
+
+ return histogramnd_c.histogramnd_int32_t_int32_t_double(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+# =====================
+# double sample, float cumul
+# =====================
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_double_double_float(double[:] sample,
+ double[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ float[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ double weight_min,
+ double weight_max) nogil:
+
+ return histogramnd_c.histogramnd_double_double_float(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_double_float_float(double[:] sample,
+ float[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ float[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ float weight_min,
+ float weight_max) nogil:
+
+ return histogramnd_c.histogramnd_double_float_float(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_double_int32_t_float(double[:] sample,
+ numpy.int32_t[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ float[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ numpy.int32_t weight_min,
+ numpy.int32_t weight_max) nogil:
+
+ return histogramnd_c.histogramnd_double_int32_t_float(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+# =====================
+# float sample, float cumul
+# =====================
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_float_double_float(float[:] sample,
+ double[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ float[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ double weight_min,
+ double weight_max) nogil:
+
+ return histogramnd_c.histogramnd_float_double_float(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_float_float_float(float[:] sample,
+ float[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ float[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ float weight_min,
+ float weight_max) nogil:
+
+ return histogramnd_c.histogramnd_float_float_float(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_float_int32_t_float(float[:] sample,
+ numpy.int32_t[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ float[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ numpy.int32_t weight_min,
+ numpy.int32_t weight_max) nogil:
+
+ return histogramnd_c.histogramnd_float_int32_t_float(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+# =====================
+# numpy.int32_t sample, float cumul
+# =====================
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_int32_t_double_float(numpy.int32_t[:] sample,
+ double[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ float[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ double weight_min,
+ double weight_max) nogil:
+
+ return histogramnd_c.histogramnd_int32_t_double_float(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_int32_t_float_float(numpy.int32_t[:] sample,
+ float[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ float[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ float weight_min,
+ float weight_max) nogil:
+
+ return histogramnd_c.histogramnd_int32_t_float_float(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+cdef int _histogramnd_int32_t_int32_t_float(numpy.int32_t[:] sample,
+ numpy.int32_t[:] weights,
+ int n_dims,
+ int n_elem,
+ double[:] histo_range,
+ int[:] n_bins,
+ numpy.uint32_t[:] histo,
+ float[:] cumul,
+ double[:] bin_edges,
+ int option_flags,
+ numpy.int32_t weight_min,
+ numpy.int32_t weight_max) nogil:
+
+ return histogramnd_c.histogramnd_int32_t_int32_t_float(&sample[0],
+ &weights[0],
+ n_dims,
+ n_elem,
+ &histo_range[0],
+ &n_bins[0],
+ &histo[0],
+ &cumul[0],
+ &bin_edges[0],
+ option_flags,
+ weight_min,
+ weight_max)
+
+
+if __name__=='__main__':
+ pass
diff --git a/silx/math/histogramnd/chistogramnd_lut.c b/silx/math/histogramnd/chistogramnd_lut.c
new file mode 100644
index 0000000..3ef6da5
--- /dev/null
+++ b/silx/math/histogramnd/chistogramnd_lut.c
@@ -0,0 +1,48804 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__chistogramnd_lut
+#define __PYX_HAVE_API__chistogramnd_lut
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#include "pythread.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+ #if defined(__cplusplus)
+ #define CYTHON_CCOMPLEX 1
+ #elif defined(_Complex_I)
+ #define CYTHON_CCOMPLEX 1
+ #else
+ #define CYTHON_CCOMPLEX 0
+ #endif
+#endif
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #include <complex>
+ #else
+ #include <complex.h>
+ #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+ #undef _Complex_I
+ #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+ "chistogramnd_lut.pyx",
+ "__init__.pxd",
+ "stringsource",
+ "type.pxd",
+};
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":723
+ * # in Cython to enable them only on the right systems.
+ *
+ * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":724
+ *
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":725
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int64 int64_t
+ * #ctypedef npy_int96 int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96 int96_t
+ * #ctypedef npy_int128 int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":730
+ * #ctypedef npy_int128 int128_t
+ *
+ * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":731
+ *
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":732
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64 uint64_t
+ * #ctypedef npy_uint96 uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96 uint96_t
+ * #ctypedef npy_uint128 uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":737
+ * #ctypedef npy_uint128 uint128_t
+ *
+ * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_float64 float64_t
+ * #ctypedef npy_float80 float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":738
+ *
+ * ctypedef npy_float32 float32_t
+ * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80 float80_t
+ * #ctypedef npy_float128 float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong longlong_t
+ *
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":749
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_ulong uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
+ * ctypedef npy_longlong longlong_t
+ *
+ * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":752
+ *
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":753
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_intp intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ * ctypedef npy_intp intp_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp uintp_t
+ *
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":756
+ *
+ * ctypedef npy_intp intp_t
+ * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_double float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_uintp uintp_t
+ *
+ * ctypedef npy_double float_t # <<<<<<<<<<<<<<
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":759
+ *
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ *
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":760
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cfloat cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< float > __pyx_t_float_complex;
+ #else
+ typedef float _Complex __pyx_t_float_complex;
+ #endif
+#else
+ typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< double > __pyx_t_double_complex;
+ #else
+ typedef double _Complex __pyx_t_double_complex;
+ #endif
+#else
+ typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ *
+ * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":763
+ *
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":764
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cdouble complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+#define __Pyx_PyObject_DelSlice(obj, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound) \
+ __Pyx_PyObject_SetSlice(obj, (PyObject*)NULL, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound)
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(
+ PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop,
+ PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
+ int has_cstart, int has_cstop, int wraparound);
+
+#define __Pyx_SetItemInt(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_SetItemInt_Fast(o, (Py_ssize_t)i, v, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list assignment index out of range"), -1) : \
+ __Pyx_SetItemInt_Generic(o, to_py_func(i), v)))
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v);
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE int __Pyx_PyDict_Contains(PyObject* item, PyObject* dict, int eq) {
+ int result = PyDict_Contains(dict, item);
+ return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
+}
+
+#if PY_MAJOR_VERSION >= 3
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+ PyObject *value;
+ value = PyDict_GetItemWithError(d, key);
+ if (unlikely(!value)) {
+ if (!PyErr_Occurred()) {
+ PyObject* args = PyTuple_Pack(1, key);
+ if (likely(args))
+ PyErr_SetObject(PyExc_KeyError, args);
+ Py_XDECREF(args);
+ }
+ return NULL;
+ }
+ Py_INCREF(value);
+ return value;
+}
+#else
+ #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+static CYTHON_INLINE int __Pyx_IterFinish(void);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index);
+
+static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** value1, PyObject** value2,
+ int is_tuple, int has_known_size, int decref_tuple);
+
+static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name,
+ Py_ssize_t* p_orig_length, int* p_is_dict);
+static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos,
+ PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict);
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type);
+
+#define __Pyx_CyFunction_USED 1
+#include <structmember.h>
+#define __Pyx_CYFUNCTION_STATICMETHOD 0x01
+#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02
+#define __Pyx_CYFUNCTION_CCLASS 0x04
+#define __Pyx_CyFunction_GetClosure(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_closure)
+#define __Pyx_CyFunction_GetClassObj(f) \
+ (((__pyx_CyFunctionObject *) (f))->func_classobj)
+#define __Pyx_CyFunction_Defaults(type, f) \
+ ((type *)(((__pyx_CyFunctionObject *) (f))->defaults))
+#define __Pyx_CyFunction_SetDefaultsGetter(f, g) \
+ ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g)
+typedef struct {
+ PyCFunctionObject func;
+#if PY_VERSION_HEX < 0x030500A0
+ PyObject *func_weakreflist;
+#endif
+ PyObject *func_dict;
+ PyObject *func_name;
+ PyObject *func_qualname;
+ PyObject *func_doc;
+ PyObject *func_globals;
+ PyObject *func_code;
+ PyObject *func_closure;
+ PyObject *func_classobj;
+ void *defaults;
+ int defaults_pyobjects;
+ int flags;
+ PyObject *defaults_tuple;
+ PyObject *defaults_kwdict;
+ PyObject *(*defaults_getter)(PyObject *);
+ PyObject *func_annotations;
+} __pyx_CyFunctionObject;
+static PyTypeObject *__pyx_CyFunctionType = 0;
+#define __Pyx_CyFunction_NewEx(ml, flags, qualname, self, module, globals, code) \
+ __Pyx_CyFunction_New(__pyx_CyFunctionType, ml, flags, qualname, self, module, globals, code)
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *, PyMethodDef *ml,
+ int flags, PyObject* qualname,
+ PyObject *self,
+ PyObject *module, PyObject *globals,
+ PyObject* code);
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *m,
+ size_t size,
+ int pyobjects);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m,
+ PyObject *tuple);
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m,
+ PyObject *dict);
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m,
+ PyObject *dict);
+static int __Pyx_CyFunction_init(void);
+
+typedef struct {
+ __pyx_CyFunctionObject func;
+ PyObject *__signatures__;
+ PyObject *type;
+ PyObject *self;
+} __pyx_FusedFunctionObject;
+#define __pyx_FusedFunction_NewEx(ml, flags, qualname, self, module, globals, code) \
+ __pyx_FusedFunction_New(__pyx_FusedFunctionType, ml, flags, qualname, self, module, globals, code)
+static PyObject *__pyx_FusedFunction_New(PyTypeObject *type,
+ PyMethodDef *ml, int flags,
+ PyObject *qualname, PyObject *self,
+ PyObject *module, PyObject *globals,
+ PyObject *code);
+static int __pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self);
+static PyTypeObject *__pyx_FusedFunctionType = NULL;
+static int __pyx_FusedFunction_init(void);
+#define __Pyx_FusedFunction_USED
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(PyObject *);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(PyObject *);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static CYTHON_INLINE npy_int32 __Pyx_PyInt_As_npy_int32(PyObject *);
+
+static CYTHON_INLINE npy_int64 __Pyx_PyInt_As_npy_int64(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_double(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static int __Pyx_Print(PyObject*, PyObject *, int);
+#if CYTHON_COMPILING_IN_PYPY || PY_MAJOR_VERSION >= 3
+static PyObject* __pyx_print = 0;
+static PyObject* __pyx_print_kwargs = 0;
+#endif
+
+static int __Pyx_PrintOne(PyObject* stream, PyObject *o);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #define __Pyx_CREAL(z) ((z).real())
+ #define __Pyx_CIMAG(z) ((z).imag())
+ #else
+ #define __Pyx_CREAL(z) (__real__(z))
+ #define __Pyx_CIMAG(z) (__imag__(z))
+ #endif
+#else
+ #define __Pyx_CREAL(z) ((z).real)
+ #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+ #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+ #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+ #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+ #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eqf(a, b) ((a)==(b))
+ #define __Pyx_c_sumf(a, b) ((a)+(b))
+ #define __Pyx_c_difff(a, b) ((a)-(b))
+ #define __Pyx_c_prodf(a, b) ((a)*(b))
+ #define __Pyx_c_quotf(a, b) ((a)/(b))
+ #define __Pyx_c_negf(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+ #define __Pyx_c_conjf(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_absf(z) (::std::abs(z))
+ #define __Pyx_c_powf(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zerof(z) ((z)==0)
+ #define __Pyx_c_conjf(z) (conjf(z))
+ #if 1
+ #define __Pyx_c_absf(z) (cabsf(z))
+ #define __Pyx_c_powf(a, b) (cpowf(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eq(a, b) ((a)==(b))
+ #define __Pyx_c_sum(a, b) ((a)+(b))
+ #define __Pyx_c_diff(a, b) ((a)-(b))
+ #define __Pyx_c_prod(a, b) ((a)*(b))
+ #define __Pyx_c_quot(a, b) ((a)/(b))
+ #define __Pyx_c_neg(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zero(z) ((z)==(double)0)
+ #define __Pyx_c_conj(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (::std::abs(z))
+ #define __Pyx_c_pow(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zero(z) ((z)==0)
+ #define __Pyx_c_conj(z) (conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (cabs(z))
+ #define __Pyx_c_pow(a, b) (cpow(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+ #endif
+#endif
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+ #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'chistogramnd_lut' */
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t = { "float64_t", NULL, sizeof(__pyx_t_5numpy_float64_t), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t = { "float32_t", NULL, sizeof(__pyx_t_5numpy_float32_t), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t = { "int32_t", NULL, sizeof(__pyx_t_5numpy_int32_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int32_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int32_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t = { "int64_t", NULL, sizeof(__pyx_t_5numpy_int64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int64_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int16_t = { "int16_t", NULL, sizeof(__pyx_t_5numpy_int16_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int16_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int16_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t = { "uint32_t", NULL, sizeof(__pyx_t_5numpy_uint32_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint32_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint32_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_int = { "int", NULL, sizeof(int), { 0 }, 0, IS_UNSIGNED(int) ? 'U' : 'I', IS_UNSIGNED(int), 0 };
+#define __Pyx_MODULE_NAME "chistogramnd_lut"
+int __pyx_module_is_main_chistogramnd_lut = 0;
+
+/* Implementation of 'chistogramnd_lut' */
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_Exception;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_ImportError;
+static PyObject *__pyx_builtin_AttributeError;
+static PyObject *__pyx_builtin_ord;
+static PyObject *__pyx_builtin_zip;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_pf_16chistogramnd_lut_histogramnd_get_lut(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sample, PyObject *__pyx_v_histo_range, PyObject *__pyx_v_n_bins, PyObject *__pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_2histogramnd_from_lut(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_weights, PyObject *__pyx_v_histo_lut, PyObject *__pyx_v_histo, PyObject *__pyx_v_weighted_histo, PyObject *__pyx_v_shape, PyObject *__pyx_v_dtype, PyObject *__pyx_v_weight_min, PyObject *__pyx_v_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_4_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_signatures, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs, CYTHON_UNUSED PyObject *__pyx_v_defaults); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_8_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_10_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_12_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_14_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_16_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_18_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_20_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_22_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_24_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_26_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_28_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_30_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_32_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_34_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_36_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_38_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_40_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_42_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_44_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_46_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_48_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_50_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_52_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_54_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_56_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_58_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_60_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_62_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_64_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_66_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_68_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_70_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_72_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_74_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_76_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_78_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_80_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_82_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_84_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_86_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_88_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_90_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_92_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_94_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_96_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_98_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_100_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_102_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_6_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_signatures, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs, CYTHON_UNUSED PyObject *__pyx_v_defaults); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_106_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_108_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_110_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_112_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_114_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_116_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_118_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_120_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_122_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_124_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_126_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static PyObject *__pyx_pf_16chistogramnd_lut_128_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_B[] = "B";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_c[] = "c";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k_ex[] = "ex";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_np[] = "np";
+static char __pyx_k_rc[] = "rc";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k__14[] = "()";
+static char __pyx_k__16[] = "|";
+static char __pyx_k_any[] = "any";
+static char __pyx_k_end[] = "end";
+static char __pyx_k_h_c[] = "h_c";
+static char __pyx_k_lut[] = "lut";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_ord[] = "ord";
+static char __pyx_k_w_c[] = "w_c";
+static char __pyx_k_zip[] = "zip";
+static char __pyx_k_args[] = "args";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_file[] = "file";
+static char __pyx_k_kind[] = "kind";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_prod[] = "prod";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_tile[] = "tile";
+static char __pyx_k_type[] = "type";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_edges[] = "edges";
+static char __pyx_k_equal[] = "equal";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_g_max[] = "g_max";
+static char __pyx_k_g_min[] = "g_min";
+static char __pyx_k_histo[] = "histo";
+static char __pyx_k_i_dim[] = "i_dim";
+static char __pyx_k_i_lut[] = "i_lut";
+static char __pyx_k_int16[] = "int16";
+static char __pyx_k_int32[] = "int32";
+static char __pyx_k_int64[] = "int64";
+static char __pyx_k_lut_c[] = "lut_c";
+static char __pyx_k_ndmin[] = "ndmin";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_o_lut[] = "o_lut";
+static char __pyx_k_print[] = "print";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_split[] = "split";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_strip[] = "strip";
+static char __pyx_k_w_h_c[] = "w_h_c";
+static char __pyx_k_zeros[] = "zeros";
+static char __pyx_k_arange[] = "arange";
+static char __pyx_k_double[] = "double";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_kwargs[] = "kwargs";
+static char __pyx_k_n_bins[] = "n_bins";
+static char __pyx_k_n_dims[] = "n_dims";
+static char __pyx_k_n_elem[] = "n_elem";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_sample[] = "sample";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_uint32[] = "uint32";
+static char __pyx_k_uint64[] = "uint64";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_bin_idx[] = "bin_idx";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_h_lut_c[] = "h_lut_c";
+static char __pyx_k_histo_c[] = "histo_c";
+static char __pyx_k_int16_t[] = "int16_t";
+static char __pyx_k_int32_t[] = "int32_t";
+static char __pyx_k_int64_t[] = "int64_t";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_lut_idx[] = "lut_idx";
+static char __pyx_k_max_idx[] = "max_idx";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_ndarray[] = "ndarray";
+static char __pyx_k_o_histo[] = "o_histo";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_rng_max[] = "rng_max";
+static char __pyx_k_rng_min[] = "rng_min";
+static char __pyx_k_s_shape[] = "s_shape";
+static char __pyx_k_w_dtype[] = "w_dtype";
+static char __pyx_k_weights[] = "weights";
+static char __pyx_k_D_Naudet[] = "D. Naudet";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_defaults[] = "defaults";
+static char __pyx_k_elem_idx[] = "elem_idx";
+static char __pyx_k_i_n_bins[] = "i_n_bins";
+static char __pyx_k_i_n_dims[] = "i_n_dims";
+static char __pyx_k_i_sample[] = "i_sample";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_n_bins_c[] = "n_bins_c";
+static char __pyx_k_sample_c[] = "sample_c";
+static char __pyx_k_Exception[] = "Exception";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_dim_edges[] = "dim_edges";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_float32_t[] = "float32_t";
+static char __pyx_k_float64_t[] = "float64_t";
+static char __pyx_k_histo_lut[] = "histo_lut";
+static char __pyx_k_i_n_elems[] = "i_n_elems";
+static char __pyx_k_i_weights[] = "i_weights";
+static char __pyx_k_lut_dtype[] = "lut_dtype";
+static char __pyx_k_15_05_2016[] = "15/05/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_bins_range[] = "bins_range";
+static char __pyx_k_elem_coord[] = "elem_coord";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_signatures[] = "signatures";
+static char __pyx_k_weight_max[] = "weight_max";
+static char __pyx_k_weight_min[] = "weight_min";
+static char __pyx_k_ImportError[] = "ImportError";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_histo_range[] = "histo_range";
+static char __pyx_k_sample_type[] = "sample_type";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_i_weight_max[] = "i_weight_max";
+static char __pyx_k_i_weight_min[] = "i_weight_min";
+static char __pyx_k_histo_range_c[] = "histo_range_c";
+static char __pyx_k_i_histo_range[] = "i_histo_range";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_AttributeError[] = "AttributeError";
+static char __pyx_k_weighted_histo[] = "weighted_histo";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_err_histo_range[] = "err_histo_range";
+static char __pyx_k_int32_t_int16_t[] = "int32_t|int16_t";
+static char __pyx_k_int32_t_int32_t[] = "int32_t|int32_t";
+static char __pyx_k_int32_t_int64_t[] = "int32_t|int64_t";
+static char __pyx_k_int64_t_int16_t[] = "int64_t|int16_t";
+static char __pyx_k_int64_t_int32_t[] = "int64_t|int32_t";
+static char __pyx_k_int64_t_int64_t[] = "int64_t|int64_t";
+static char __pyx_k_last_bin_closed[] = "last_bin_closed";
+static char __pyx_k_chistogramnd_lut[] = "chistogramnd_lut";
+static char __pyx_k_filt_max_weights[] = "filt_max_weights";
+static char __pyx_k_filt_min_weights[] = "filt_min_weights";
+static char __pyx_k_o_weighted_histo[] = "o_weighted_histo";
+static char __pyx_k_ascontiguousarray[] = "ascontiguousarray";
+static char __pyx_k_float32_t_int16_t[] = "float32_t|int16_t";
+static char __pyx_k_float32_t_int32_t[] = "float32_t|int32_t";
+static char __pyx_k_float32_t_int64_t[] = "float32_t|int64_t";
+static char __pyx_k_float64_t_int16_t[] = "float64_t|int16_t";
+static char __pyx_k_float64_t_int32_t[] = "float64_t|int32_t";
+static char __pyx_k_float64_t_int64_t[] = "float64_t|int64_t";
+static char __pyx_k_i_filt_max_weights[] = "i_filt_max_weights";
+static char __pyx_k_i_filt_min_weights[] = "i_filt_min_weights";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_histogramnd_get_lut[] = "histogramnd_get_lut";
+static char __pyx_k_histogramnd_from_lut[] = "histogramnd_from_lut";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_int32_t_int16_t_int32_t[] = "int32_t|int16_t|int32_t";
+static char __pyx_k_int32_t_int16_t_int64_t[] = "int32_t|int16_t|int64_t";
+static char __pyx_k_int32_t_int32_t_int32_t[] = "int32_t|int32_t|int32_t";
+static char __pyx_k_int32_t_int32_t_int64_t[] = "int32_t|int32_t|int64_t";
+static char __pyx_k_int32_t_int64_t_int32_t[] = "int32_t|int64_t|int32_t";
+static char __pyx_k_int32_t_int64_t_int64_t[] = "int32_t|int64_t|int64_t";
+static char __pyx_k_int64_t_int16_t_int32_t[] = "int64_t|int16_t|int32_t";
+static char __pyx_k_int64_t_int16_t_int64_t[] = "int64_t|int16_t|int64_t";
+static char __pyx_k_int64_t_int32_t_int32_t[] = "int64_t|int32_t|int32_t";
+static char __pyx_k_int64_t_int32_t_int64_t[] = "int64_t|int32_t|int64_t";
+static char __pyx_k_int64_t_int64_t_int32_t[] = "int64_t|int64_t|int32_t";
+static char __pyx_k_int64_t_int64_t_int64_t[] = "int64_t|int64_t|int64_t";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_float32_t_int16_t_int32_t[] = "float32_t|int16_t|int32_t";
+static char __pyx_k_float32_t_int16_t_int64_t[] = "float32_t|int16_t|int64_t";
+static char __pyx_k_float32_t_int32_t_int32_t[] = "float32_t|int32_t|int32_t";
+static char __pyx_k_float32_t_int32_t_int64_t[] = "float32_t|int32_t|int64_t";
+static char __pyx_k_float32_t_int64_t_int32_t[] = "float32_t|int64_t|int32_t";
+static char __pyx_k_float32_t_int64_t_int64_t[] = "float32_t|int64_t|int64_t";
+static char __pyx_k_float64_t_int16_t_int32_t[] = "float64_t|int16_t|int32_t";
+static char __pyx_k_float64_t_int16_t_int64_t[] = "float64_t|int16_t|int64_t";
+static char __pyx_k_float64_t_int32_t_int32_t[] = "float64_t|int32_t|int32_t";
+static char __pyx_k_float64_t_int32_t_int64_t[] = "float64_t|int32_t|int64_t";
+static char __pyx_k_float64_t_int64_t_int32_t[] = "float64_t|int64_t|int32_t";
+static char __pyx_k_float64_t_int64_t_int64_t[] = "float64_t|int64_t|int64_t";
+static char __pyx_k_histogramnd_get_lut_fused[] = "_histogramnd_get_lut_fused";
+static char __pyx_k_int32_t_int16_t_float32_t[] = "int32_t|int16_t|float32_t";
+static char __pyx_k_int32_t_int16_t_float64_t[] = "int32_t|int16_t|float64_t";
+static char __pyx_k_int32_t_int32_t_float32_t[] = "int32_t|int32_t|float32_t";
+static char __pyx_k_int32_t_int32_t_float64_t[] = "int32_t|int32_t|float64_t";
+static char __pyx_k_int32_t_int64_t_float32_t[] = "int32_t|int64_t|float32_t";
+static char __pyx_k_int32_t_int64_t_float64_t[] = "int32_t|int64_t|float64_t";
+static char __pyx_k_int64_t_int16_t_float32_t[] = "int64_t|int16_t|float32_t";
+static char __pyx_k_int64_t_int16_t_float64_t[] = "int64_t|int16_t|float64_t";
+static char __pyx_k_int64_t_int32_t_float32_t[] = "int64_t|int32_t|float32_t";
+static char __pyx_k_int64_t_int32_t_float64_t[] = "int64_t|int32_t|float64_t";
+static char __pyx_k_int64_t_int64_t_float32_t[] = "int64_t|int64_t|float32_t";
+static char __pyx_k_int64_t_int64_t_float64_t[] = "int64_t|int64_t|float64_t";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_histogramnd_from_lut_fused[] = "_histogramnd_from_lut_fused";
+static char __pyx_k_No_matching_signature_found[] = "No matching signature found";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_Type_not_supported_sample_0[] = "Type not supported - sample : {0}";
+static char __pyx_k_float32_t_int16_t_float32_t[] = "float32_t|int16_t|float32_t";
+static char __pyx_k_float32_t_int16_t_float64_t[] = "float32_t|int16_t|float64_t";
+static char __pyx_k_float32_t_int32_t_float32_t[] = "float32_t|int32_t|float32_t";
+static char __pyx_k_float32_t_int32_t_float64_t[] = "float32_t|int32_t|float64_t";
+static char __pyx_k_float32_t_int64_t_float32_t[] = "float32_t|int64_t|float32_t";
+static char __pyx_k_float32_t_int64_t_float64_t[] = "float32_t|int64_t|float64_t";
+static char __pyx_k_float64_t_int16_t_float32_t[] = "float64_t|int16_t|float32_t";
+static char __pyx_k_float64_t_int16_t_float64_t[] = "float64_t|int16_t|float64_t";
+static char __pyx_k_float64_t_int32_t_float32_t[] = "float64_t|int32_t|float32_t";
+static char __pyx_k_float64_t_int32_t_float64_t[] = "float64_t|int32_t|float64_t";
+static char __pyx_k_float64_t_int64_t_float32_t[] = "float64_t|int64_t|float32_t";
+static char __pyx_k_float64_t_int64_t_float64_t[] = "float64_t|int64_t|float64_t";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_Expected_at_least_d_arguments[] = "Expected at least %d arguments";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_The_LUT_and_weights_arrays_must[] = "The LUT and weights arrays must have the same number of elements.";
+static char __pyx_k_histo_range_error_expected_n_di[] = "<histo_range> error : expected {n_dims} sets of lower and upper bin edges, got the following instead : {histo_range}. (provided <sample> contains {n_dims}D values)";
+static char __pyx_k_histogramnd_returned_an_error_0[] = "histogramnd returned an error : {0}";
+static char __pyx_k_mntdirect__scisoft_users_tvince[] = "/mntdirect/_scisoft/users/tvincent/src/silx/silx/math/histogramnd/chistogramnd_lut.pyx";
+static char __pyx_k_n_bins_only_positive_values_all[] = "<n_bins> : only positive values allowed.";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_At_least_one_of_the_following_pa[] = "At least one of the following parameters has to be provided : <shape> or <histo> or <weighted_histo>";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Case_not_supported_weights_0_and[] = "Case not supported - weights:{0} and histo:{1}.";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Function_call_with_ambiguous_arg[] = "Function call with ambiguous argument types";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_Provided_dtype_and_weighted_hist[] = "Provided <dtype> and <weighted_histo>'s dtype do not match.";
+static char __pyx_k_Provided_histo_array_doesn_t_hav[] = "Provided <histo> array doesn't have the expected type : should be {0} instead of {1}.";
+static char __pyx_k_The_histo_shape_does_not_matchth[] = "The <histo> shape does not matchthe <weighted_histo> shape.";
+static char __pyx_k_The_shape_value_does_not_matchth[] = "The <shape> value does not matchthe <histo> shape.";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_n_bins_must_be_either_a_scalar_s[] = "n_bins must be either a scalar (same number of bins for all dimensions) or an array (number of bins for each dimension).";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static char __pyx_k_The_shape_value_does_not_matchth_2[] = "The <shape> value does not matchthe <weighted_histo> shape.";
+static PyObject *__pyx_kp_s_15_05_2016;
+static PyObject *__pyx_kp_s_At_least_one_of_the_following_pa;
+static PyObject *__pyx_n_s_AttributeError;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_kp_s_Case_not_supported_weights_0_and;
+static PyObject *__pyx_kp_s_D_Naudet;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_n_s_Exception;
+static PyObject *__pyx_kp_s_Expected_at_least_d_arguments;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_kp_s_Function_call_with_ambiguous_arg;
+static PyObject *__pyx_n_s_ImportError;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_kp_s_No_matching_signature_found;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_kp_s_Provided_dtype_and_weighted_hist;
+static PyObject *__pyx_kp_s_Provided_histo_array_doesn_t_hav;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_The_LUT_and_weights_arrays_must;
+static PyObject *__pyx_kp_s_The_histo_shape_does_not_matchth;
+static PyObject *__pyx_kp_s_The_shape_value_does_not_matchth;
+static PyObject *__pyx_kp_s_The_shape_value_does_not_matchth_2;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Type_not_supported_sample_0;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_kp_s__14;
+static PyObject *__pyx_kp_s__16;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_any;
+static PyObject *__pyx_n_s_arange;
+static PyObject *__pyx_n_s_args;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_ascontiguousarray;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_bin_idx;
+static PyObject *__pyx_n_s_bins_range;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_chistogramnd_lut;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_defaults;
+static PyObject *__pyx_n_s_dim_edges;
+static PyObject *__pyx_n_s_double;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_edges;
+static PyObject *__pyx_n_s_elem_coord;
+static PyObject *__pyx_n_s_elem_idx;
+static PyObject *__pyx_n_s_end;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_equal;
+static PyObject *__pyx_n_s_err_histo_range;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_ex;
+static PyObject *__pyx_n_s_file;
+static PyObject *__pyx_n_s_filt_max_weights;
+static PyObject *__pyx_n_s_filt_min_weights;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float32_t;
+static PyObject *__pyx_kp_s_float32_t_int16_t;
+static PyObject *__pyx_kp_s_float32_t_int16_t_float32_t;
+static PyObject *__pyx_kp_s_float32_t_int16_t_float64_t;
+static PyObject *__pyx_kp_s_float32_t_int16_t_int32_t;
+static PyObject *__pyx_kp_s_float32_t_int16_t_int64_t;
+static PyObject *__pyx_kp_s_float32_t_int32_t;
+static PyObject *__pyx_kp_s_float32_t_int32_t_float32_t;
+static PyObject *__pyx_kp_s_float32_t_int32_t_float64_t;
+static PyObject *__pyx_kp_s_float32_t_int32_t_int32_t;
+static PyObject *__pyx_kp_s_float32_t_int32_t_int64_t;
+static PyObject *__pyx_kp_s_float32_t_int64_t;
+static PyObject *__pyx_kp_s_float32_t_int64_t_float32_t;
+static PyObject *__pyx_kp_s_float32_t_int64_t_float64_t;
+static PyObject *__pyx_kp_s_float32_t_int64_t_int32_t;
+static PyObject *__pyx_kp_s_float32_t_int64_t_int64_t;
+static PyObject *__pyx_n_s_float64_t;
+static PyObject *__pyx_kp_s_float64_t_int16_t;
+static PyObject *__pyx_kp_s_float64_t_int16_t_float32_t;
+static PyObject *__pyx_kp_s_float64_t_int16_t_float64_t;
+static PyObject *__pyx_kp_s_float64_t_int16_t_int32_t;
+static PyObject *__pyx_kp_s_float64_t_int16_t_int64_t;
+static PyObject *__pyx_kp_s_float64_t_int32_t;
+static PyObject *__pyx_kp_s_float64_t_int32_t_float32_t;
+static PyObject *__pyx_kp_s_float64_t_int32_t_float64_t;
+static PyObject *__pyx_kp_s_float64_t_int32_t_int32_t;
+static PyObject *__pyx_kp_s_float64_t_int32_t_int64_t;
+static PyObject *__pyx_kp_s_float64_t_int64_t;
+static PyObject *__pyx_kp_s_float64_t_int64_t_float32_t;
+static PyObject *__pyx_kp_s_float64_t_int64_t_float64_t;
+static PyObject *__pyx_kp_s_float64_t_int64_t_int32_t;
+static PyObject *__pyx_kp_s_float64_t_int64_t_int64_t;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_n_s_g_max;
+static PyObject *__pyx_n_s_g_min;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_h_c;
+static PyObject *__pyx_n_s_h_lut_c;
+static PyObject *__pyx_n_s_histo;
+static PyObject *__pyx_n_s_histo_c;
+static PyObject *__pyx_n_s_histo_lut;
+static PyObject *__pyx_n_s_histo_range;
+static PyObject *__pyx_n_s_histo_range_c;
+static PyObject *__pyx_kp_s_histo_range_error_expected_n_di;
+static PyObject *__pyx_n_s_histogramnd_from_lut;
+static PyObject *__pyx_n_s_histogramnd_from_lut_fused;
+static PyObject *__pyx_n_s_histogramnd_get_lut;
+static PyObject *__pyx_n_s_histogramnd_get_lut_fused;
+static PyObject *__pyx_kp_s_histogramnd_returned_an_error_0;
+static PyObject *__pyx_n_s_i;
+static PyObject *__pyx_n_s_i_dim;
+static PyObject *__pyx_n_s_i_filt_max_weights;
+static PyObject *__pyx_n_s_i_filt_min_weights;
+static PyObject *__pyx_n_s_i_histo_range;
+static PyObject *__pyx_n_s_i_lut;
+static PyObject *__pyx_n_s_i_n_bins;
+static PyObject *__pyx_n_s_i_n_dims;
+static PyObject *__pyx_n_s_i_n_elems;
+static PyObject *__pyx_n_s_i_sample;
+static PyObject *__pyx_n_s_i_weight_max;
+static PyObject *__pyx_n_s_i_weight_min;
+static PyObject *__pyx_n_s_i_weights;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_int16;
+static PyObject *__pyx_n_s_int16_t;
+static PyObject *__pyx_n_s_int32;
+static PyObject *__pyx_n_s_int32_t;
+static PyObject *__pyx_kp_s_int32_t_int16_t;
+static PyObject *__pyx_kp_s_int32_t_int16_t_float32_t;
+static PyObject *__pyx_kp_s_int32_t_int16_t_float64_t;
+static PyObject *__pyx_kp_s_int32_t_int16_t_int32_t;
+static PyObject *__pyx_kp_s_int32_t_int16_t_int64_t;
+static PyObject *__pyx_kp_s_int32_t_int32_t;
+static PyObject *__pyx_kp_s_int32_t_int32_t_float32_t;
+static PyObject *__pyx_kp_s_int32_t_int32_t_float64_t;
+static PyObject *__pyx_kp_s_int32_t_int32_t_int32_t;
+static PyObject *__pyx_kp_s_int32_t_int32_t_int64_t;
+static PyObject *__pyx_kp_s_int32_t_int64_t;
+static PyObject *__pyx_kp_s_int32_t_int64_t_float32_t;
+static PyObject *__pyx_kp_s_int32_t_int64_t_float64_t;
+static PyObject *__pyx_kp_s_int32_t_int64_t_int32_t;
+static PyObject *__pyx_kp_s_int32_t_int64_t_int64_t;
+static PyObject *__pyx_n_s_int64;
+static PyObject *__pyx_n_s_int64_t;
+static PyObject *__pyx_kp_s_int64_t_int16_t;
+static PyObject *__pyx_kp_s_int64_t_int16_t_float32_t;
+static PyObject *__pyx_kp_s_int64_t_int16_t_float64_t;
+static PyObject *__pyx_kp_s_int64_t_int16_t_int32_t;
+static PyObject *__pyx_kp_s_int64_t_int16_t_int64_t;
+static PyObject *__pyx_kp_s_int64_t_int32_t;
+static PyObject *__pyx_kp_s_int64_t_int32_t_float32_t;
+static PyObject *__pyx_kp_s_int64_t_int32_t_float64_t;
+static PyObject *__pyx_kp_s_int64_t_int32_t_int32_t;
+static PyObject *__pyx_kp_s_int64_t_int32_t_int64_t;
+static PyObject *__pyx_kp_s_int64_t_int64_t;
+static PyObject *__pyx_kp_s_int64_t_int64_t_float32_t;
+static PyObject *__pyx_kp_s_int64_t_int64_t_float64_t;
+static PyObject *__pyx_kp_s_int64_t_int64_t_int32_t;
+static PyObject *__pyx_kp_s_int64_t_int64_t_int64_t;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_kind;
+static PyObject *__pyx_n_s_kwargs;
+static PyObject *__pyx_n_s_last_bin_closed;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_lut;
+static PyObject *__pyx_n_s_lut_c;
+static PyObject *__pyx_n_s_lut_dtype;
+static PyObject *__pyx_n_s_lut_idx;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_max_idx;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_kp_s_mntdirect__scisoft_users_tvince;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_n_bins;
+static PyObject *__pyx_n_s_n_bins_c;
+static PyObject *__pyx_kp_s_n_bins_must_be_either_a_scalar_s;
+static PyObject *__pyx_kp_s_n_bins_only_positive_values_all;
+static PyObject *__pyx_n_s_n_dims;
+static PyObject *__pyx_n_s_n_elem;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_n_s_ndarray;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_ndmin;
+static PyObject *__pyx_n_s_np;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_o_histo;
+static PyObject *__pyx_n_s_o_lut;
+static PyObject *__pyx_n_s_o_weighted_histo;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_n_s_ord;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_n_s_print;
+static PyObject *__pyx_n_s_prod;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_rc;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_rng_max;
+static PyObject *__pyx_n_s_rng_min;
+static PyObject *__pyx_n_s_s_shape;
+static PyObject *__pyx_n_s_sample;
+static PyObject *__pyx_n_s_sample_c;
+static PyObject *__pyx_n_s_sample_type;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_signatures;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_split;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_strip;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_n_s_tile;
+static PyObject *__pyx_n_s_type;
+static PyObject *__pyx_n_s_uint32;
+static PyObject *__pyx_n_s_uint64;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_n_s_w_c;
+static PyObject *__pyx_n_s_w_dtype;
+static PyObject *__pyx_n_s_w_h_c;
+static PyObject *__pyx_n_s_weight_max;
+static PyObject *__pyx_n_s_weight_min;
+static PyObject *__pyx_n_s_weighted_histo;
+static PyObject *__pyx_n_s_weights;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_n_s_zeros;
+static PyObject *__pyx_n_s_zip;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_32768;
+static PyObject *__pyx_int_2147483648;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_slice__7;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__37;
+static PyObject *__pyx_slice__38;
+static PyObject *__pyx_slice__39;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__26;
+static PyObject *__pyx_tuple__27;
+static PyObject *__pyx_tuple__28;
+static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__30;
+static PyObject *__pyx_tuple__31;
+static PyObject *__pyx_tuple__32;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_tuple__34;
+static PyObject *__pyx_tuple__35;
+static PyObject *__pyx_tuple__36;
+static PyObject *__pyx_tuple__40;
+static PyObject *__pyx_tuple__41;
+static PyObject *__pyx_tuple__43;
+static PyObject *__pyx_tuple__45;
+static PyObject *__pyx_tuple__47;
+static PyObject *__pyx_tuple__49;
+static PyObject *__pyx_tuple__50;
+static PyObject *__pyx_tuple__51;
+static PyObject *__pyx_tuple__52;
+static PyObject *__pyx_tuple__53;
+static PyObject *__pyx_codeobj__42;
+static PyObject *__pyx_codeobj__44;
+static PyObject *__pyx_codeobj__46;
+static PyObject *__pyx_codeobj__48;
+
+/* "chistogramnd_lut.pyx":58
+ *
+ *
+ * def histogramnd_get_lut(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_16chistogramnd_lut_1histogramnd_get_lut(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_16chistogramnd_lut_histogramnd_get_lut[] = "histogramnd_get_lut(sample, histo_range, n_bins, last_bin_closed=False)\nTBD\n\n :param sample:\n The data to be histogrammed.\n Its shape must be either (N,) if it contains one dimensional\n coordinates, or an (N, D) array where the rows are the\n coordinates of points in a D dimensional space.\n The following dtypes are supported : :class:`numpy.float64`,\n :class:`numpy.float32`, :class:`numpy.int32`.\n :type sample: :class:`numpy.array`\n\n :param histo_range:\n A (N, 2) array containing the histogram range along each dimension,\n where N is the sample's number of dimensions.\n :type histo_range: array_like\n\n :param n_bins:\n The number of bins :\n * a scalar (same number of bins for all dimensions)\n * a D elements array (number of bins for each dimensions)\n :type n_bins: scalar or array_like\n\n :param last_bin_closed:\n By default the last bin is half\n open (i.e.: [x,y) ; x included, y\n excluded), like all the other bins.\n Set this parameter to true if you want\n the LAST bin to be closed.\n :type last_bin_closed: *optional*, :class:`python.boolean`\n\n :return: The indices for each sample and the histogram (bin counts).\n :rtype: tuple : (:class:`numpy.array`, :class:`numpy.array`)\n ";
+static PyMethodDef __pyx_mdef_16chistogramnd_lut_1histogramnd_get_lut = {"histogramnd_get_lut", (PyCFunction)__pyx_pw_16chistogramnd_lut_1histogramnd_get_lut, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_histogramnd_get_lut};
+static PyObject *__pyx_pw_16chistogramnd_lut_1histogramnd_get_lut(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_sample = 0;
+ PyObject *__pyx_v_histo_range = 0;
+ PyObject *__pyx_v_n_bins = 0;
+ PyObject *__pyx_v_last_bin_closed = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("histogramnd_get_lut (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_sample,&__pyx_n_s_histo_range,&__pyx_n_s_n_bins,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[4] = {0,0,0,0};
+
+ /* "chistogramnd_lut.pyx":61
+ * histo_range,
+ * n_bins,
+ * last_bin_closed=False): # <<<<<<<<<<<<<<
+ * """TBD
+ *
+ */
+ values[3] = ((PyObject *)Py_False);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("histogramnd_get_lut", 0, 3, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("histogramnd_get_lut", 0, 3, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "histogramnd_get_lut") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_sample = values[0];
+ __pyx_v_histo_range = values[1];
+ __pyx_v_n_bins = values[2];
+ __pyx_v_last_bin_closed = values[3];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("histogramnd_get_lut", 0, 3, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut.histogramnd_get_lut", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_histogramnd_get_lut(__pyx_self, __pyx_v_sample, __pyx_v_histo_range, __pyx_v_n_bins, __pyx_v_last_bin_closed);
+
+ /* "chistogramnd_lut.pyx":58
+ *
+ *
+ * def histogramnd_get_lut(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_histogramnd_get_lut(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_sample, PyObject *__pyx_v_histo_range, PyObject *__pyx_v_n_bins, PyObject *__pyx_v_last_bin_closed) {
+ PyObject *__pyx_v_s_shape = NULL;
+ PyObject *__pyx_v_n_dims = NULL;
+ PyObject *__pyx_v_i_histo_range = NULL;
+ int __pyx_v_err_histo_range;
+ PyObject *__pyx_v_sample_type = NULL;
+ PyObject *__pyx_v_n_elem = NULL;
+ PyObject *__pyx_v_lut_dtype = NULL;
+ PyObject *__pyx_v_lut = NULL;
+ PyObject *__pyx_v_histo = NULL;
+ PyObject *__pyx_v_sample_c = NULL;
+ PyObject *__pyx_v_histo_range_c = NULL;
+ PyObject *__pyx_v_n_bins_c = NULL;
+ PyObject *__pyx_v_lut_c = NULL;
+ PyObject *__pyx_v_histo_c = NULL;
+ PyObject *__pyx_v_rc = NULL;
+ CYTHON_UNUSED PyObject *__pyx_v_ex = NULL;
+ PyObject *__pyx_v_edges = NULL;
+ PyObject *__pyx_v_i_dim = NULL;
+ PyObject *__pyx_v_dim_edges = NULL;
+ PyObject *__pyx_v_rng_min = NULL;
+ PyObject *__pyx_v_rng_max = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ int __pyx_t_14;
+ PyObject *(*__pyx_t_15)(PyObject *);
+ int __pyx_t_16;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("histogramnd_get_lut", 0);
+ __Pyx_INCREF(__pyx_v_histo_range);
+ __Pyx_INCREF(__pyx_v_n_bins);
+
+ /* "chistogramnd_lut.pyx":96
+ * """
+ *
+ * s_shape = sample.shape # <<<<<<<<<<<<<<
+ *
+ * n_dims = 1 if len(s_shape) == 1 else s_shape[1]
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_s_shape = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":98
+ * s_shape = sample.shape
+ *
+ * n_dims = 1 if len(s_shape) == 1 else s_shape[1] # <<<<<<<<<<<<<<
+ *
+ * # just in case those arent numpy arrays
+ */
+ __pyx_t_2 = PyObject_Length(__pyx_v_s_shape); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (((__pyx_t_2 == 1) != 0)) {
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_t_1 = __pyx_int_1;
+ } else {
+ __pyx_t_3 = __Pyx_GetItemInt(__pyx_v_s_shape, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_t_3 = 0;
+ }
+ __pyx_v_n_dims = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":103
+ * # (this allows the user to provide native python lists,
+ * # => easier for testing)
+ * i_histo_range = histo_range # <<<<<<<<<<<<<<
+ * histo_range = np.array(histo_range)
+ * err_histo_range = False
+ */
+ __Pyx_INCREF(__pyx_v_histo_range);
+ __pyx_v_i_histo_range = __pyx_v_histo_range;
+
+ /* "chistogramnd_lut.pyx":104
+ * # => easier for testing)
+ * i_histo_range = histo_range
+ * histo_range = np.array(histo_range) # <<<<<<<<<<<<<<
+ * err_histo_range = False
+ *
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_histo_range); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ __Pyx_INCREF(__pyx_v_histo_range);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_v_histo_range);
+ __Pyx_GIVEREF(__pyx_v_histo_range);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF_SET(__pyx_v_histo_range, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":105
+ * i_histo_range = histo_range
+ * histo_range = np.array(histo_range)
+ * err_histo_range = False # <<<<<<<<<<<<<<
+ *
+ * if n_dims == 1:
+ */
+ __pyx_v_err_histo_range = 0;
+
+ /* "chistogramnd_lut.pyx":107
+ * err_histo_range = False
+ *
+ * if n_dims == 1: # <<<<<<<<<<<<<<
+ * if histo_range.shape == (2,):
+ * pass
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_n_dims, __pyx_int_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":108
+ *
+ * if n_dims == 1:
+ * if histo_range.shape == (2,): # <<<<<<<<<<<<<<
+ * pass
+ * elif histo_range.shape == (1, 2):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_tuple_, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ goto __pyx_L4;
+ }
+
+ /* "chistogramnd_lut.pyx":110
+ * if histo_range.shape == (2,):
+ * pass
+ * elif histo_range.shape == (1, 2): # <<<<<<<<<<<<<<
+ * histo_range.reshape(-1)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_1 = PyObject_RichCompare(__pyx_t_4, __pyx_tuple__2, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":111
+ * pass
+ * elif histo_range.shape == (1, 2):
+ * histo_range.reshape(-1) # <<<<<<<<<<<<<<
+ * else:
+ * err_histo_range = True
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_reshape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":113
+ * histo_range.reshape(-1)
+ * else:
+ * err_histo_range = True # <<<<<<<<<<<<<<
+ * elif n_dims != 1 and histo_range.shape != (n_dims, 2):
+ * err_histo_range = True
+ */
+ __pyx_v_err_histo_range = 1;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+
+ /* "chistogramnd_lut.pyx":114
+ * else:
+ * err_histo_range = True
+ * elif n_dims != 1 and histo_range.shape != (n_dims, 2): # <<<<<<<<<<<<<<
+ * err_histo_range = True
+ *
+ */
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_n_dims, __pyx_int_1, Py_NE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_n_dims);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_n_dims);
+ __Pyx_GIVEREF(__pyx_v_n_dims);
+ __Pyx_INCREF(__pyx_int_2);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_int_2);
+ __Pyx_GIVEREF(__pyx_int_2);
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_4, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":115
+ * err_histo_range = True
+ * elif n_dims != 1 and histo_range.shape != (n_dims, 2):
+ * err_histo_range = True # <<<<<<<<<<<<<<
+ *
+ * if err_histo_range:
+ */
+ __pyx_v_err_histo_range = 1;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "chistogramnd_lut.pyx":117
+ * err_histo_range = True
+ *
+ * if err_histo_range: # <<<<<<<<<<<<<<
+ * raise ValueError('<histo_range> error : expected {n_dims} sets of '
+ * 'lower and upper bin edges, '
+ */
+ __pyx_t_6 = (__pyx_v_err_histo_range != 0);
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":123
+ * '(provided <sample> contains '
+ * '{n_dims}D values)'
+ * ''.format(histo_range=i_histo_range, # <<<<<<<<<<<<<<
+ * n_dims=n_dims))
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_histo_range_error_expected_n_di, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_histo_range, __pyx_v_i_histo_range) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd_lut.pyx":124
+ * '{n_dims}D values)'
+ * ''.format(histo_range=i_histo_range,
+ * n_dims=n_dims)) # <<<<<<<<<<<<<<
+ *
+ * histo_range = np.double(histo_range)
+ */
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_n_dims, __pyx_v_n_dims) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd_lut.pyx":123
+ * '(provided <sample> contains '
+ * '{n_dims}D values)'
+ * ''.format(histo_range=i_histo_range, # <<<<<<<<<<<<<<
+ * n_dims=n_dims))
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_empty_tuple, __pyx_t_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":118
+ *
+ * if err_histo_range:
+ * raise ValueError('<histo_range> error : expected {n_dims} sets of ' # <<<<<<<<<<<<<<
+ * 'lower and upper bin edges, '
+ * 'got the following instead : {histo_range}. '
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_1, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd_lut.pyx":126
+ * n_dims=n_dims))
+ *
+ * histo_range = np.double(histo_range) # <<<<<<<<<<<<<<
+ *
+ * # checking n_bins size
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_double); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_histo_range); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ __Pyx_INCREF(__pyx_v_histo_range);
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_histo_range);
+ __Pyx_GIVEREF(__pyx_v_histo_range);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF_SET(__pyx_v_histo_range, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":129
+ *
+ * # checking n_bins size
+ * n_bins = np.array(n_bins, ndmin=1) # <<<<<<<<<<<<<<
+ * if len(n_bins) == 1:
+ * n_bins = np.tile(n_bins, n_dims)
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_n_bins);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_n_bins);
+ __Pyx_GIVEREF(__pyx_v_n_bins);
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_ndmin, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF_SET(__pyx_v_n_bins, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":130
+ * # checking n_bins size
+ * n_bins = np.array(n_bins, ndmin=1)
+ * if len(n_bins) == 1: # <<<<<<<<<<<<<<
+ * n_bins = np.tile(n_bins, n_dims)
+ * elif n_bins.shape != (n_dims,):
+ */
+ __pyx_t_2 = PyObject_Length(__pyx_v_n_bins); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_6 = ((__pyx_t_2 == 1) != 0);
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":131
+ * n_bins = np.array(n_bins, ndmin=1)
+ * if len(n_bins) == 1:
+ * n_bins = np.tile(n_bins, n_dims) # <<<<<<<<<<<<<<
+ * elif n_bins.shape != (n_dims,):
+ * raise ValueError('n_bins must be either a scalar (same number '
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_tile); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ __pyx_t_2 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ __pyx_t_2 = 1;
+ }
+ }
+ __pyx_t_5 = PyTuple_New(2+__pyx_t_2); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (__pyx_t_3) {
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_n_bins);
+ PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_2, __pyx_v_n_bins);
+ __Pyx_GIVEREF(__pyx_v_n_bins);
+ __Pyx_INCREF(__pyx_v_n_dims);
+ PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_2, __pyx_v_n_dims);
+ __Pyx_GIVEREF(__pyx_v_n_dims);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF_SET(__pyx_v_n_bins, __pyx_t_1);
+ __pyx_t_1 = 0;
+ goto __pyx_L8;
+ }
+
+ /* "chistogramnd_lut.pyx":132
+ * if len(n_bins) == 1:
+ * n_bins = np.tile(n_bins, n_dims)
+ * elif n_bins.shape != (n_dims,): # <<<<<<<<<<<<<<
+ * raise ValueError('n_bins must be either a scalar (same number '
+ * 'of bins for all dimensions) or '
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_n_dims);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_n_dims);
+ __Pyx_GIVEREF(__pyx_v_n_dims);
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_1, __pyx_t_4, Py_NE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":133
+ * n_bins = np.tile(n_bins, n_dims)
+ * elif n_bins.shape != (n_dims,):
+ * raise ValueError('n_bins must be either a scalar (same number ' # <<<<<<<<<<<<<<
+ * 'of bins for all dimensions) or '
+ * 'an array (number of bins for each '
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L8:;
+
+ /* "chistogramnd_lut.pyx":141
+ * # exception is thrown when calling np.zeros
+ * # also testing for negative/null values
+ * if np.any(np.equal(n_bins, None)) or np.any(n_bins <= 0): # <<<<<<<<<<<<<<
+ * raise ValueError('<n_bins> : only positive values allowed.')
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_any); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_equal); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ __pyx_t_2 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ __pyx_t_2 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_3) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_n_bins);
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_2, __pyx_v_n_bins);
+ __Pyx_GIVEREF(__pyx_v_n_bins);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_2, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_9, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_any); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_n_bins, __pyx_int_0, Py_LE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":142
+ * # also testing for negative/null values
+ * if np.any(np.equal(n_bins, None)) or np.any(n_bins <= 0):
+ * raise ValueError('<n_bins> : only positive values allowed.') # <<<<<<<<<<<<<<
+ *
+ * sample_type = sample.dtype
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd_lut.pyx":144
+ * raise ValueError('<n_bins> : only positive values allowed.')
+ *
+ * sample_type = sample.dtype # <<<<<<<<<<<<<<
+ *
+ * n_elem = sample.size // n_dims
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_dtype); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_v_sample_type = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd_lut.pyx":146
+ * sample_type = sample.dtype
+ *
+ * n_elem = sample.size // n_dims # <<<<<<<<<<<<<<
+ *
+ * if n_bins.prod(dtype=np.uint64) < 2**15:
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = PyNumber_FloorDivide(__pyx_t_5, __pyx_v_n_dims); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_n_elem = __pyx_t_9;
+ __pyx_t_9 = 0;
+
+ /* "chistogramnd_lut.pyx":148
+ * n_elem = sample.size // n_dims
+ *
+ * if n_bins.prod(dtype=np.uint64) < 2**15: # <<<<<<<<<<<<<<
+ * lut_dtype = np.int16
+ * elif n_bins.prod(dtype=np.uint64) < 2**31:
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_prod); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_uint64); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_1, __pyx_int_32768, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":149
+ *
+ * if n_bins.prod(dtype=np.uint64) < 2**15:
+ * lut_dtype = np.int16 # <<<<<<<<<<<<<<
+ * elif n_bins.prod(dtype=np.uint64) < 2**31:
+ * lut_dtype = np.int32
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_int16); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_lut_dtype = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L12;
+ }
+
+ /* "chistogramnd_lut.pyx":150
+ * if n_bins.prod(dtype=np.uint64) < 2**15:
+ * lut_dtype = np.int16
+ * elif n_bins.prod(dtype=np.uint64) < 2**31: # <<<<<<<<<<<<<<
+ * lut_dtype = np.int32
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_prod); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_uint64); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_5); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_8, __pyx_int_2147483648, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":151
+ * lut_dtype = np.int16
+ * elif n_bins.prod(dtype=np.uint64) < 2**31:
+ * lut_dtype = np.int32 # <<<<<<<<<<<<<<
+ * else:
+ * lut_dtype = np.int64
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_int32); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_lut_dtype = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L12;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":153
+ * lut_dtype = np.int32
+ * else:
+ * lut_dtype = np.int64 # <<<<<<<<<<<<<<
+ *
+ * # allocating the output arrays
+ */
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_int64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_lut_dtype = __pyx_t_5;
+ __pyx_t_5 = 0;
+ }
+ __pyx_L12:;
+
+ /* "chistogramnd_lut.pyx":156
+ *
+ * # allocating the output arrays
+ * lut = np.zeros(n_elem, dtype=lut_dtype) # <<<<<<<<<<<<<<
+ * histo = np.zeros(n_bins, dtype=np.uint32)
+ *
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_n_elem);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_n_elem);
+ __Pyx_GIVEREF(__pyx_v_n_elem);
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_v_lut_dtype) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_lut = __pyx_t_9;
+ __pyx_t_9 = 0;
+
+ /* "chistogramnd_lut.pyx":157
+ * # allocating the output arrays
+ * lut = np.zeros(n_elem, dtype=lut_dtype)
+ * histo = np.zeros(n_bins, dtype=np.uint32) # <<<<<<<<<<<<<<
+ *
+ * sample_c = np.ascontiguousarray(sample.reshape((sample.size,)))
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_zeros); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_INCREF(__pyx_v_n_bins);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_n_bins);
+ __Pyx_GIVEREF(__pyx_v_n_bins);
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_uint32); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_9, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_histo = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":159
+ * histo = np.zeros(n_bins, dtype=np.uint32)
+ *
+ * sample_c = np.ascontiguousarray(sample.reshape((sample.size,))) # <<<<<<<<<<<<<<
+ *
+ * histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)))
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_reshape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_sample, __pyx_n_s_size); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_10, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_9))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_9);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_9);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_9, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_9, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_10, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_sample_c = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":161
+ * sample_c = np.ascontiguousarray(sample.reshape((sample.size,)))
+ *
+ * histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,))) # <<<<<<<<<<<<<<
+ *
+ * n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)),
+ */
+ __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_1)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_1);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_1) {
+ __pyx_t_9 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_3); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_9);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_1); __Pyx_GIVEREF(__pyx_t_1); __pyx_t_1 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_v_histo_range_c = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":163
+ * histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)))
+ *
+ * n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)), # <<<<<<<<<<<<<<
+ * dtype=np.int32)
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_reshape); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_n_bins, __pyx_n_s_size); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (!__pyx_t_9) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_9); __Pyx_GIVEREF(__pyx_t_9); __pyx_t_9 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+
+ /* "chistogramnd_lut.pyx":164
+ *
+ * n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)),
+ * dtype=np.int32) # <<<<<<<<<<<<<<
+ *
+ * lut_c = np.ascontiguousarray(lut.reshape((lut.size,)))
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "chistogramnd_lut.pyx":163
+ * histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)))
+ *
+ * n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)), # <<<<<<<<<<<<<<
+ * dtype=np.int32)
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_8, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_n_bins_c = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd_lut.pyx":166
+ * dtype=np.int32)
+ *
+ * lut_c = np.ascontiguousarray(lut.reshape((lut.size,))) # <<<<<<<<<<<<<<
+ * histo_c = np.ascontiguousarray(histo.reshape((histo.size,)))
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_lut, __pyx_n_s_reshape); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_lut, __pyx_n_s_size); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_9); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_1 = PyTuple_New(1+1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_1, 0+1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_1, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (!__pyx_t_10) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_1 = PyTuple_New(1+1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_1, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_1, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 166; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_lut_c = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd_lut.pyx":167
+ *
+ * lut_c = np.ascontiguousarray(lut.reshape((lut.size,)))
+ * histo_c = np.ascontiguousarray(histo.reshape((histo.size,))) # <<<<<<<<<<<<<<
+ *
+ * rc = 0
+ */
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_reshape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_size); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_10) {
+ __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_GOTREF(__pyx_t_8);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_3, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_histo_c = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd_lut.pyx":169
+ * histo_c = np.ascontiguousarray(histo.reshape((histo.size,)))
+ *
+ * rc = 0 # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_v_rc = __pyx_int_0;
+
+ /* "chistogramnd_lut.pyx":171
+ * rc = 0
+ *
+ * try: # <<<<<<<<<<<<<<
+ * rc = _histogramnd_get_lut_fused(sample_c,
+ * n_dims,
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_11, &__pyx_t_12, &__pyx_t_13);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __Pyx_XGOTREF(__pyx_t_12);
+ __Pyx_XGOTREF(__pyx_t_13);
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":172
+ *
+ * try:
+ * rc = _histogramnd_get_lut_fused(sample_c, # <<<<<<<<<<<<<<
+ * n_dims,
+ * n_elem,
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_histogramnd_get_lut_fused); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "chistogramnd_lut.pyx":179
+ * lut_c,
+ * histo_c,
+ * last_bin_closed) # <<<<<<<<<<<<<<
+ * except TypeError as ex:
+ * raise TypeError('Type not supported - sample : {0}'
+ */
+ __pyx_t_3 = NULL;
+ __pyx_t_2 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ __pyx_t_2 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(8+__pyx_t_2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_3) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_sample_c);
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_2, __pyx_v_sample_c);
+ __Pyx_GIVEREF(__pyx_v_sample_c);
+ __Pyx_INCREF(__pyx_v_n_dims);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_2, __pyx_v_n_dims);
+ __Pyx_GIVEREF(__pyx_v_n_dims);
+ __Pyx_INCREF(__pyx_v_n_elem);
+ PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_2, __pyx_v_n_elem);
+ __Pyx_GIVEREF(__pyx_v_n_elem);
+ __Pyx_INCREF(__pyx_v_histo_range_c);
+ PyTuple_SET_ITEM(__pyx_t_8, 3+__pyx_t_2, __pyx_v_histo_range_c);
+ __Pyx_GIVEREF(__pyx_v_histo_range_c);
+ __Pyx_INCREF(__pyx_v_n_bins_c);
+ PyTuple_SET_ITEM(__pyx_t_8, 4+__pyx_t_2, __pyx_v_n_bins_c);
+ __Pyx_GIVEREF(__pyx_v_n_bins_c);
+ __Pyx_INCREF(__pyx_v_lut_c);
+ PyTuple_SET_ITEM(__pyx_t_8, 5+__pyx_t_2, __pyx_v_lut_c);
+ __Pyx_GIVEREF(__pyx_v_lut_c);
+ __Pyx_INCREF(__pyx_v_histo_c);
+ PyTuple_SET_ITEM(__pyx_t_8, 6+__pyx_t_2, __pyx_v_histo_c);
+ __Pyx_GIVEREF(__pyx_v_histo_c);
+ __Pyx_INCREF(__pyx_v_last_bin_closed);
+ PyTuple_SET_ITEM(__pyx_t_8, 7+__pyx_t_2, __pyx_v_last_bin_closed);
+ __Pyx_GIVEREF(__pyx_v_last_bin_closed);
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_8, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L13_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF_SET(__pyx_v_rc, __pyx_t_5);
+ __pyx_t_5 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+ __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+ goto __pyx_L20_try_end;
+ __pyx_L13_error:;
+ __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "chistogramnd_lut.pyx":180
+ * histo_c,
+ * last_bin_closed)
+ * except TypeError as ex: # <<<<<<<<<<<<<<
+ * raise TypeError('Type not supported - sample : {0}'
+ * ''.format(sample_type))
+ */
+ __pyx_t_14 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_14) {
+ __Pyx_AddTraceback("chistogramnd_lut.histogramnd_get_lut", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_1, &__pyx_t_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_1);
+ __pyx_v_ex = __pyx_t_1;
+
+ /* "chistogramnd_lut.pyx":182
+ * except TypeError as ex:
+ * raise TypeError('Type not supported - sample : {0}'
+ * ''.format(sample_type)) # <<<<<<<<<<<<<<
+ *
+ * if rc != 0:
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Type_not_supported_sample_0, __pyx_n_s_format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_9 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_9)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_9) {
+ __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_sample_type); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9); __Pyx_GIVEREF(__pyx_t_9); __pyx_t_9 = NULL;
+ __Pyx_INCREF(__pyx_v_sample_type);
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_v_sample_type);
+ __Pyx_GIVEREF(__pyx_v_sample_type);
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_10, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":181
+ * last_bin_closed)
+ * except TypeError as ex:
+ * raise TypeError('Type not supported - sample : {0}' # <<<<<<<<<<<<<<
+ * ''.format(sample_type))
+ *
+ */
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L15_except_error;}
+ }
+ goto __pyx_L15_except_error;
+ __pyx_L15_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_XGIVEREF(__pyx_t_12);
+ __Pyx_XGIVEREF(__pyx_t_13);
+ __Pyx_ExceptionReset(__pyx_t_11, __pyx_t_12, __pyx_t_13);
+ goto __pyx_L1_error;
+ __pyx_L20_try_end:;
+ }
+
+ /* "chistogramnd_lut.pyx":184
+ * ''.format(sample_type))
+ *
+ * if rc != 0: # <<<<<<<<<<<<<<
+ * raise Exception('histogramnd returned an error : {0}'
+ * ''.format(rc))
+ */
+ __pyx_t_8 = PyObject_RichCompare(__pyx_v_rc, __pyx_int_0, Py_NE); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (__pyx_t_6) {
+
+ /* "chistogramnd_lut.pyx":186
+ * if rc != 0:
+ * raise Exception('histogramnd returned an error : {0}'
+ * ''.format(rc)) # <<<<<<<<<<<<<<
+ *
+ * edges = []
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_histogramnd_returned_an_error_0, __pyx_n_s_format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_1))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_1);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_1, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_v_rc); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ __Pyx_INCREF(__pyx_v_rc);
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_v_rc);
+ __Pyx_GIVEREF(__pyx_v_rc);
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":185
+ *
+ * if rc != 0:
+ * raise Exception('histogramnd returned an error : {0}' # <<<<<<<<<<<<<<
+ * ''.format(rc))
+ *
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_Exception, __pyx_t_1, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd_lut.pyx":188
+ * ''.format(rc))
+ *
+ * edges = [] # <<<<<<<<<<<<<<
+ * histo_range = histo_range.reshape(-1)
+ * for i_dim in range(n_dims):
+ */
+ __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_edges = ((PyObject*)__pyx_t_8);
+ __pyx_t_8 = 0;
+
+ /* "chistogramnd_lut.pyx":189
+ *
+ * edges = []
+ * histo_range = histo_range.reshape(-1) # <<<<<<<<<<<<<<
+ * for i_dim in range(n_dims):
+ * dim_edges = np.zeros(n_bins[i_dim] + 1)
+ */
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_range, __pyx_n_s_reshape); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_histo_range, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":190
+ * edges = []
+ * histo_range = histo_range.reshape(-1)
+ * for i_dim in range(n_dims): # <<<<<<<<<<<<<<
+ * dim_edges = np.zeros(n_bins[i_dim] + 1)
+ * rng_min = histo_range[2 * i_dim]
+ */
+ __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_n_dims);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_n_dims);
+ __Pyx_GIVEREF(__pyx_v_n_dims);
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_t_1, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_t_8)) || PyTuple_CheckExact(__pyx_t_8)) {
+ __pyx_t_1 = __pyx_t_8; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+ __pyx_t_15 = NULL;
+ } else {
+ __pyx_t_2 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_8); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_15 = Py_TYPE(__pyx_t_1)->tp_iternext; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_15)) {
+ if (likely(PyList_CheckExact(__pyx_t_1))) {
+ if (__pyx_t_2 >= PyList_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_8 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_8); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_8 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_8); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_8 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_8 = __pyx_t_15(__pyx_t_1);
+ if (unlikely(!__pyx_t_8)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_8);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_i_dim, __pyx_t_8);
+ __pyx_t_8 = 0;
+
+ /* "chistogramnd_lut.pyx":191
+ * histo_range = histo_range.reshape(-1)
+ * for i_dim in range(n_dims):
+ * dim_edges = np.zeros(n_bins[i_dim] + 1) # <<<<<<<<<<<<<<
+ * rng_min = histo_range[2 * i_dim]
+ * rng_max = histo_range[2 * i_dim + 1]
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyObject_GetItem(__pyx_v_n_bins, __pyx_v_i_dim); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_8 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_8);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_10, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_dim_edges, __pyx_t_8);
+ __pyx_t_8 = 0;
+
+ /* "chistogramnd_lut.pyx":192
+ * for i_dim in range(n_dims):
+ * dim_edges = np.zeros(n_bins[i_dim] + 1)
+ * rng_min = histo_range[2 * i_dim] # <<<<<<<<<<<<<<
+ * rng_max = histo_range[2 * i_dim + 1]
+ * dim_edges[:-1] = (rng_min + np.arange(n_bins[i_dim]) *
+ */
+ __pyx_t_8 = PyNumber_Multiply(__pyx_int_2, __pyx_v_i_dim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_5 = PyObject_GetItem(__pyx_v_histo_range, __pyx_t_8); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_rng_min, __pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd_lut.pyx":193
+ * dim_edges = np.zeros(n_bins[i_dim] + 1)
+ * rng_min = histo_range[2 * i_dim]
+ * rng_max = histo_range[2 * i_dim + 1] # <<<<<<<<<<<<<<
+ * dim_edges[:-1] = (rng_min + np.arange(n_bins[i_dim]) *
+ * ((rng_max - rng_min) / n_bins[i_dim]))
+ */
+ __pyx_t_5 = PyNumber_Multiply(__pyx_int_2, __pyx_v_i_dim); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = PyNumber_Add(__pyx_t_5, __pyx_int_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyObject_GetItem(__pyx_v_histo_range, __pyx_t_8); if (unlikely(__pyx_t_5 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_rng_max, __pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "chistogramnd_lut.pyx":194
+ * rng_min = histo_range[2 * i_dim]
+ * rng_max = histo_range[2 * i_dim + 1]
+ * dim_edges[:-1] = (rng_min + np.arange(n_bins[i_dim]) * # <<<<<<<<<<<<<<
+ * ((rng_max - rng_min) / n_bins[i_dim]))
+ * dim_edges[-1] = rng_max
+ */
+ __pyx_t_8 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_8, __pyx_n_s_arange); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyObject_GetItem(__pyx_v_n_bins, __pyx_v_i_dim); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_3 = PyTuple_New(1+1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_3, 0+1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_3, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+
+ /* "chistogramnd_lut.pyx":195
+ * rng_max = histo_range[2 * i_dim + 1]
+ * dim_edges[:-1] = (rng_min + np.arange(n_bins[i_dim]) *
+ * ((rng_max - rng_min) / n_bins[i_dim])) # <<<<<<<<<<<<<<
+ * dim_edges[-1] = rng_max
+ * edges.append(dim_edges)
+ */
+ __pyx_t_10 = PyNumber_Subtract(__pyx_v_rng_max, __pyx_v_rng_min); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_3 = PyObject_GetItem(__pyx_v_n_bins, __pyx_v_i_dim); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = __Pyx_PyNumber_Divide(__pyx_t_10, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "chistogramnd_lut.pyx":194
+ * rng_min = histo_range[2 * i_dim]
+ * rng_max = histo_range[2 * i_dim + 1]
+ * dim_edges[:-1] = (rng_min + np.arange(n_bins[i_dim]) * # <<<<<<<<<<<<<<
+ * ((rng_max - rng_min) / n_bins[i_dim]))
+ * dim_edges[-1] = rng_max
+ */
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_5, __pyx_t_8); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyNumber_Add(__pyx_v_rng_min, __pyx_t_3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__Pyx_PyObject_SetSlice(__pyx_v_dim_edges, __pyx_t_8, 0, -1, NULL, NULL, &__pyx_slice__7, 0, 1, 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "chistogramnd_lut.pyx":196
+ * dim_edges[:-1] = (rng_min + np.arange(n_bins[i_dim]) *
+ * ((rng_max - rng_min) / n_bins[i_dim]))
+ * dim_edges[-1] = rng_max # <<<<<<<<<<<<<<
+ * edges.append(dim_edges)
+ *
+ */
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dim_edges, -1, __pyx_v_rng_max, long, 1, __Pyx_PyInt_From_long, 0, 1, 1) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd_lut.pyx":197
+ * ((rng_max - rng_min) / n_bins[i_dim]))
+ * dim_edges[-1] = rng_max
+ * edges.append(dim_edges) # <<<<<<<<<<<<<<
+ *
+ * return lut, histo, tuple(edges)
+ */
+ __pyx_t_16 = __Pyx_PyList_Append(__pyx_v_edges, __pyx_v_dim_edges); if (unlikely(__pyx_t_16 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd_lut.pyx":190
+ * edges = []
+ * histo_range = histo_range.reshape(-1)
+ * for i_dim in range(n_dims): # <<<<<<<<<<<<<<
+ * dim_edges = np.zeros(n_bins[i_dim] + 1)
+ * rng_min = histo_range[2 * i_dim]
+ */
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":199
+ * edges.append(dim_edges)
+ *
+ * return lut, histo, tuple(edges) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_AsTuple(__pyx_v_edges); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_lut);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_lut);
+ __Pyx_GIVEREF(__pyx_v_lut);
+ __Pyx_INCREF(__pyx_v_histo);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_v_histo);
+ __Pyx_GIVEREF(__pyx_v_histo);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":58
+ *
+ *
+ * def histogramnd_get_lut(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("chistogramnd_lut.histogramnd_get_lut", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_s_shape);
+ __Pyx_XDECREF(__pyx_v_n_dims);
+ __Pyx_XDECREF(__pyx_v_i_histo_range);
+ __Pyx_XDECREF(__pyx_v_sample_type);
+ __Pyx_XDECREF(__pyx_v_n_elem);
+ __Pyx_XDECREF(__pyx_v_lut_dtype);
+ __Pyx_XDECREF(__pyx_v_lut);
+ __Pyx_XDECREF(__pyx_v_histo);
+ __Pyx_XDECREF(__pyx_v_sample_c);
+ __Pyx_XDECREF(__pyx_v_histo_range_c);
+ __Pyx_XDECREF(__pyx_v_n_bins_c);
+ __Pyx_XDECREF(__pyx_v_lut_c);
+ __Pyx_XDECREF(__pyx_v_histo_c);
+ __Pyx_XDECREF(__pyx_v_rc);
+ __Pyx_XDECREF(__pyx_v_ex);
+ __Pyx_XDECREF(__pyx_v_edges);
+ __Pyx_XDECREF(__pyx_v_i_dim);
+ __Pyx_XDECREF(__pyx_v_dim_edges);
+ __Pyx_XDECREF(__pyx_v_rng_min);
+ __Pyx_XDECREF(__pyx_v_rng_max);
+ __Pyx_XDECREF(__pyx_v_histo_range);
+ __Pyx_XDECREF(__pyx_v_n_bins);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "chistogramnd_lut.pyx":206
+ *
+ *
+ * def histogramnd_from_lut(weights, # <<<<<<<<<<<<<<
+ * histo_lut,
+ * histo=None,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_16chistogramnd_lut_3histogramnd_from_lut(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_16chistogramnd_lut_2histogramnd_from_lut[] = "histogramnd_from_lut(weights, histo_lut, histo=None, weighted_histo=None, shape=None, dtype=None, weight_min=None, weight_max=None)\n\n dtype ignored if weighted_histo provided\n ";
+static PyMethodDef __pyx_mdef_16chistogramnd_lut_3histogramnd_from_lut = {"histogramnd_from_lut", (PyCFunction)__pyx_pw_16chistogramnd_lut_3histogramnd_from_lut, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_2histogramnd_from_lut};
+static PyObject *__pyx_pw_16chistogramnd_lut_3histogramnd_from_lut(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_weights = 0;
+ PyObject *__pyx_v_histo_lut = 0;
+ PyObject *__pyx_v_histo = 0;
+ PyObject *__pyx_v_weighted_histo = 0;
+ PyObject *__pyx_v_shape = 0;
+ PyObject *__pyx_v_dtype = 0;
+ PyObject *__pyx_v_weight_min = 0;
+ PyObject *__pyx_v_weight_max = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("histogramnd_from_lut (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_weights,&__pyx_n_s_histo_lut,&__pyx_n_s_histo,&__pyx_n_s_weighted_histo,&__pyx_n_s_shape,&__pyx_n_s_dtype,&__pyx_n_s_weight_min,&__pyx_n_s_weight_max,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+
+ /* "chistogramnd_lut.pyx":208
+ * def histogramnd_from_lut(weights,
+ * histo_lut,
+ * histo=None, # <<<<<<<<<<<<<<
+ * weighted_histo=None,
+ * shape=None,
+ */
+ values[2] = ((PyObject *)Py_None);
+
+ /* "chistogramnd_lut.pyx":209
+ * histo_lut,
+ * histo=None,
+ * weighted_histo=None, # <<<<<<<<<<<<<<
+ * shape=None,
+ * dtype=None,
+ */
+ values[3] = ((PyObject *)Py_None);
+
+ /* "chistogramnd_lut.pyx":210
+ * histo=None,
+ * weighted_histo=None,
+ * shape=None, # <<<<<<<<<<<<<<
+ * dtype=None,
+ * weight_min=None,
+ */
+ values[4] = ((PyObject *)Py_None);
+
+ /* "chistogramnd_lut.pyx":211
+ * weighted_histo=None,
+ * shape=None,
+ * dtype=None, # <<<<<<<<<<<<<<
+ * weight_min=None,
+ * weight_max=None):
+ */
+ values[5] = ((PyObject *)Py_None);
+
+ /* "chistogramnd_lut.pyx":212
+ * shape=None,
+ * dtype=None,
+ * weight_min=None, # <<<<<<<<<<<<<<
+ * weight_max=None):
+ * """
+ */
+ values[6] = ((PyObject *)Py_None);
+
+ /* "chistogramnd_lut.pyx":213
+ * dtype=None,
+ * weight_min=None,
+ * weight_max=None): # <<<<<<<<<<<<<<
+ * """
+ * dtype ignored if weighted_histo provided
+ */
+ values[7] = ((PyObject *)Py_None);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_histo_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("histogramnd_from_lut", 0, 2, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_histo);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weighted_histo);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ case 5:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype);
+ if (value) { values[5] = value; kw_args--; }
+ }
+ case 6:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weight_min);
+ if (value) { values[6] = value; kw_args--; }
+ }
+ case 7:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_weight_max);
+ if (value) { values[7] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "histogramnd_from_lut") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_weights = values[0];
+ __pyx_v_histo_lut = values[1];
+ __pyx_v_histo = values[2];
+ __pyx_v_weighted_histo = values[3];
+ __pyx_v_shape = values[4];
+ __pyx_v_dtype = values[5];
+ __pyx_v_weight_min = values[6];
+ __pyx_v_weight_max = values[7];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("histogramnd_from_lut", 0, 2, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut.histogramnd_from_lut", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_2histogramnd_from_lut(__pyx_self, __pyx_v_weights, __pyx_v_histo_lut, __pyx_v_histo, __pyx_v_weighted_histo, __pyx_v_shape, __pyx_v_dtype, __pyx_v_weight_min, __pyx_v_weight_max);
+
+ /* "chistogramnd_lut.pyx":206
+ *
+ *
+ * def histogramnd_from_lut(weights, # <<<<<<<<<<<<<<
+ * histo_lut,
+ * histo=None,
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_2histogramnd_from_lut(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_weights, PyObject *__pyx_v_histo_lut, PyObject *__pyx_v_histo, PyObject *__pyx_v_weighted_histo, PyObject *__pyx_v_shape, PyObject *__pyx_v_dtype, PyObject *__pyx_v_weight_min, PyObject *__pyx_v_weight_max) {
+ PyObject *__pyx_v_w_dtype = NULL;
+ PyObject *__pyx_v_w_c = NULL;
+ PyObject *__pyx_v_h_c = NULL;
+ PyObject *__pyx_v_w_h_c = NULL;
+ PyObject *__pyx_v_h_lut_c = NULL;
+ CYTHON_UNUSED long __pyx_v_rc;
+ int __pyx_v_filt_min_weights;
+ int __pyx_v_filt_max_weights;
+ PyObject *__pyx_v_ex = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ Py_ssize_t __pyx_t_9;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ PyObject *__pyx_t_12 = NULL;
+ PyObject *__pyx_t_13 = NULL;
+ PyObject *__pyx_t_14 = NULL;
+ PyObject *__pyx_t_15 = NULL;
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ int __pyx_t_18;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("histogramnd_from_lut", 0);
+ __Pyx_INCREF(__pyx_v_histo);
+ __Pyx_INCREF(__pyx_v_weighted_histo);
+ __Pyx_INCREF(__pyx_v_shape);
+ __Pyx_INCREF(__pyx_v_dtype);
+ __Pyx_INCREF(__pyx_v_weight_min);
+ __Pyx_INCREF(__pyx_v_weight_max);
+
+ /* "chistogramnd_lut.pyx":218
+ * """
+ *
+ * if histo is None and weighted_histo is None: # <<<<<<<<<<<<<<
+ * if shape is None:
+ * raise ValueError('At least one of the following parameters has to '
+ */
+ __pyx_t_2 = (__pyx_v_histo == Py_None);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_weighted_histo == Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":219
+ *
+ * if histo is None and weighted_histo is None:
+ * if shape is None: # <<<<<<<<<<<<<<
+ * raise ValueError('At least one of the following parameters has to '
+ * 'be provided : <shape> or <histo> or '
+ */
+ __pyx_t_1 = (__pyx_v_shape == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd_lut.pyx":220
+ * if histo is None and weighted_histo is None:
+ * if shape is None:
+ * raise ValueError('At least one of the following parameters has to ' # <<<<<<<<<<<<<<
+ * 'be provided : <shape> or <histo> or '
+ * '<weighted_histo>')
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "chistogramnd_lut.pyx":224
+ * '<weighted_histo>')
+ *
+ * if shape is not None: # <<<<<<<<<<<<<<
+ * if histo is not None and list(histo.shape) != list(shape):
+ * raise ValueError('The <shape> value does not match'
+ */
+ __pyx_t_2 = (__pyx_v_shape != Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":225
+ *
+ * if shape is not None:
+ * if histo is not None and list(histo.shape) != list(shape): # <<<<<<<<<<<<<<
+ * raise ValueError('The <shape> value does not match'
+ * 'the <histo> shape.')
+ */
+ __pyx_t_2 = (__pyx_v_histo != Py_None);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_5, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_4, __pyx_t_6, Py_NE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":226
+ * if shape is not None:
+ * if histo is not None and list(histo.shape) != list(shape):
+ * raise ValueError('The <shape> value does not match' # <<<<<<<<<<<<<<
+ * 'the <histo> shape.')
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_Raise(__pyx_t_5, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd_lut.pyx":229
+ * 'the <histo> shape.')
+ *
+ * if(weighted_histo is not None and # <<<<<<<<<<<<<<
+ * list(weighted_histo.shape) != list(shape)):
+ * raise ValueError('The <shape> value does not match'
+ */
+ __pyx_t_3 = (__pyx_v_weighted_histo != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L12_bool_binop_done;
+ }
+
+ /* "chistogramnd_lut.pyx":230
+ *
+ * if(weighted_histo is not None and
+ * list(weighted_histo.shape) != list(shape)): # <<<<<<<<<<<<<<
+ * raise ValueError('The <shape> value does not match'
+ * 'the <weighted_histo> shape.')
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_t_4, Py_NE); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L12_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":231
+ * if(weighted_histo is not None and
+ * list(weighted_histo.shape) != list(shape)):
+ * raise ValueError('The <shape> value does not match' # <<<<<<<<<<<<<<
+ * 'the <weighted_histo> shape.')
+ * else:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":234
+ * 'the <weighted_histo> shape.')
+ * else:
+ * if histo is not None: # <<<<<<<<<<<<<<
+ * shape = histo.shape
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_histo != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd_lut.pyx":235
+ * else:
+ * if histo is not None:
+ * shape = histo.shape # <<<<<<<<<<<<<<
+ * else:
+ * shape = weighted_histo.shape
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF_SET(__pyx_v_shape, __pyx_t_6);
+ __pyx_t_6 = 0;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":237
+ * shape = histo.shape
+ * else:
+ * shape = weighted_histo.shape # <<<<<<<<<<<<<<
+ *
+ * if histo is not None:
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 237; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF_SET(__pyx_v_shape, __pyx_t_6);
+ __pyx_t_6 = 0;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L7:;
+
+ /* "chistogramnd_lut.pyx":239
+ * shape = weighted_histo.shape
+ *
+ * if histo is not None: # <<<<<<<<<<<<<<
+ * if histo.dtype != np.uint32:
+ * raise ValueError('Provided <histo> array doesn\'t have '
+ */
+ __pyx_t_2 = (__pyx_v_histo != Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":240
+ *
+ * if histo is not None:
+ * if histo.dtype != np.uint32: # <<<<<<<<<<<<<<
+ * raise ValueError('Provided <histo> array doesn\'t have '
+ * 'the expected type '
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_uint32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_6, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":244
+ * 'the expected type '
+ * ': should be {0} instead of {1}.'
+ * ''.format(np.uint32, histo.dtype)) # <<<<<<<<<<<<<<
+ *
+ * if weighted_histo is not None:
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Provided_histo_array_doesn_t_hav, __pyx_n_s_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_uint32); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_8 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_10 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ if (__pyx_t_8) {
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_7 = 0;
+ __pyx_t_6 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_10, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "chistogramnd_lut.pyx":241
+ * if histo is not None:
+ * if histo.dtype != np.uint32:
+ * raise ValueError('Provided <histo> array doesn\'t have ' # <<<<<<<<<<<<<<
+ * 'the expected type '
+ * ': should be {0} instead of {1}.'
+ */
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd_lut.pyx":246
+ * ''.format(np.uint32, histo.dtype))
+ *
+ * if weighted_histo is not None: # <<<<<<<<<<<<<<
+ * if histo.shape != weighted_histo.shape:
+ * raise ValueError('The <histo> shape does not match'
+ */
+ __pyx_t_1 = (__pyx_v_weighted_histo != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd_lut.pyx":247
+ *
+ * if weighted_histo is not None:
+ * if histo.shape != weighted_histo.shape: # <<<<<<<<<<<<<<
+ * raise ValueError('The <histo> shape does not match'
+ * 'the <weighted_histo> shape.')
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_shape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_10 = PyObject_RichCompare(__pyx_t_4, __pyx_t_5, Py_NE); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd_lut.pyx":248
+ * if weighted_histo is not None:
+ * if histo.shape != weighted_histo.shape:
+ * raise ValueError('The <histo> shape does not match' # <<<<<<<<<<<<<<
+ * 'the <weighted_histo> shape.')
+ * else:
+ */
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":251
+ * 'the <weighted_histo> shape.')
+ * else:
+ * histo = np.zeros(shape, dtype=np.uint32) # <<<<<<<<<<<<<<
+ *
+ * w_dtype = weights.dtype
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_uint32); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_10, __pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF_SET(__pyx_v_histo, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __pyx_L15:;
+
+ /* "chistogramnd_lut.pyx":253
+ * histo = np.zeros(shape, dtype=np.uint32)
+ *
+ * w_dtype = weights.dtype # <<<<<<<<<<<<<<
+ *
+ * if dtype is None:
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_dtype); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_w_dtype = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "chistogramnd_lut.pyx":255
+ * w_dtype = weights.dtype
+ *
+ * if dtype is None: # <<<<<<<<<<<<<<
+ * if weighted_histo is None:
+ * dtype = w_dtype
+ */
+ __pyx_t_2 = (__pyx_v_dtype == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":256
+ *
+ * if dtype is None:
+ * if weighted_histo is None: # <<<<<<<<<<<<<<
+ * dtype = w_dtype
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_weighted_histo == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd_lut.pyx":257
+ * if dtype is None:
+ * if weighted_histo is None:
+ * dtype = w_dtype # <<<<<<<<<<<<<<
+ * else:
+ * dtype = weighted_histo.dtype
+ */
+ __Pyx_INCREF(__pyx_v_w_dtype);
+ __Pyx_DECREF_SET(__pyx_v_dtype, __pyx_v_w_dtype);
+ goto __pyx_L20;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":259
+ * dtype = w_dtype
+ * else:
+ * dtype = weighted_histo.dtype # <<<<<<<<<<<<<<
+ * elif weighted_histo is not None:
+ * if weighted_histo.dtype != dtype:
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF_SET(__pyx_v_dtype, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __pyx_L20:;
+ goto __pyx_L19;
+ }
+
+ /* "chistogramnd_lut.pyx":260
+ * else:
+ * dtype = weighted_histo.dtype
+ * elif weighted_histo is not None: # <<<<<<<<<<<<<<
+ * if weighted_histo.dtype != dtype:
+ * raise ValueError('Provided <dtype> and <weighted_histo>\'s dtype'
+ */
+ __pyx_t_2 = (__pyx_v_weighted_histo != Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":261
+ * dtype = weighted_histo.dtype
+ * elif weighted_histo is not None:
+ * if weighted_histo.dtype != dtype: # <<<<<<<<<<<<<<
+ * raise ValueError('Provided <dtype> and <weighted_histo>\'s dtype'
+ * ' do not match.')
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_7, __pyx_v_dtype, Py_NE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":262
+ * elif weighted_histo is not None:
+ * if weighted_histo.dtype != dtype:
+ * raise ValueError('Provided <dtype> and <weighted_histo>\'s dtype' # <<<<<<<<<<<<<<
+ * ' do not match.')
+ * dtype = weighted_histo.dtype
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd_lut.pyx":264
+ * raise ValueError('Provided <dtype> and <weighted_histo>\'s dtype'
+ * ' do not match.')
+ * dtype = weighted_histo.dtype # <<<<<<<<<<<<<<
+ *
+ * if weighted_histo is None:
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF_SET(__pyx_v_dtype, __pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L19;
+ }
+ __pyx_L19:;
+
+ /* "chistogramnd_lut.pyx":266
+ * dtype = weighted_histo.dtype
+ *
+ * if weighted_histo is None: # <<<<<<<<<<<<<<
+ * weighted_histo = np.zeros(shape, dtype=dtype)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_weighted_histo == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd_lut.pyx":267
+ *
+ * if weighted_histo is None:
+ * weighted_histo = np.zeros(shape, dtype=dtype) # <<<<<<<<<<<<<<
+ *
+ * if histo_lut.size != weights.size:
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_zeros); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ __pyx_t_10 = PyDict_New(); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ if (PyDict_SetItem(__pyx_t_10, __pyx_n_s_dtype, __pyx_v_dtype) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_4, __pyx_t_10); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_DECREF_SET(__pyx_v_weighted_histo, __pyx_t_5);
+ __pyx_t_5 = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "chistogramnd_lut.pyx":269
+ * weighted_histo = np.zeros(shape, dtype=dtype)
+ *
+ * if histo_lut.size != weights.size: # <<<<<<<<<<<<<<
+ * raise ValueError('The LUT and weights arrays must have the same '
+ * 'number of elements.')
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_lut, __pyx_n_s_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_size); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_t_10, Py_NE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_2) {
+
+ /* "chistogramnd_lut.pyx":270
+ *
+ * if histo_lut.size != weights.size:
+ * raise ValueError('The LUT and weights arrays must have the same ' # <<<<<<<<<<<<<<
+ * 'number of elements.')
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "chistogramnd_lut.pyx":273
+ * 'number of elements.')
+ *
+ * w_c = np.ascontiguousarray(weights.reshape((weights.size,))) # <<<<<<<<<<<<<<
+ *
+ * h_c = np.ascontiguousarray(histo.reshape((histo.size,)))
+ */
+ __pyx_t_10 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_reshape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_size); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_8); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_GOTREF(__pyx_t_10);
+ } else {
+ __pyx_t_11 = PyTuple_New(1+1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_11, 0+1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_11, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_10); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_11 = PyTuple_New(1+1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_11, 0+1, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_11, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_w_c = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":275
+ * w_c = np.ascontiguousarray(weights.reshape((weights.size,)))
+ *
+ * h_c = np.ascontiguousarray(histo.reshape((histo.size,))) # <<<<<<<<<<<<<<
+ *
+ * w_h_c = np.ascontiguousarray(weighted_histo.reshape((weighted_histo.size,))) # noqa
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_reshape); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_size); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_10))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_10);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_10, function);
+ }
+ }
+ if (!__pyx_t_7) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_8); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_11))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_11);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_11, function);
+ }
+ }
+ if (!__pyx_t_10) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_11, __pyx_t_5); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 275; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_v_h_c = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":277
+ * h_c = np.ascontiguousarray(histo.reshape((histo.size,)))
+ *
+ * w_h_c = np.ascontiguousarray(weighted_histo.reshape((weighted_histo.size,))) # noqa # <<<<<<<<<<<<<<
+ *
+ * h_lut_c = np.ascontiguousarray(histo_lut.reshape((histo_lut.size,)))
+ */
+ __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_reshape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_weighted_histo, __pyx_n_s_size); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ __pyx_t_10 = 0;
+ __pyx_t_10 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_10) {
+ __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_8); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_GOTREF(__pyx_t_11);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_t_11); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ __pyx_t_11 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_w_h_c = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":279
+ * w_h_c = np.ascontiguousarray(weighted_histo.reshape((weighted_histo.size,))) # noqa
+ *
+ * h_lut_c = np.ascontiguousarray(histo_lut.reshape((histo_lut.size,))) # <<<<<<<<<<<<<<
+ *
+ * rc = 0
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_ascontiguousarray); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_lut, __pyx_n_s_reshape); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo_lut, __pyx_n_s_size); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_11))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_11);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_11, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_6 = __Pyx_PyObject_CallOneArg(__pyx_t_11, __pyx_t_8); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_GOTREF(__pyx_t_6);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_10, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __pyx_t_11 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_11)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_11);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ }
+ }
+ if (!__pyx_t_11) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_6); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_10 = PyTuple_New(1+1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_11); __Pyx_GIVEREF(__pyx_t_11); __pyx_t_11 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_10, 0+1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_10, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 279; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_h_lut_c = __pyx_t_4;
+ __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":281
+ * h_lut_c = np.ascontiguousarray(histo_lut.reshape((histo_lut.size,)))
+ *
+ * rc = 0 # <<<<<<<<<<<<<<
+ *
+ * if weight_min is None:
+ */
+ __pyx_v_rc = 0;
+
+ /* "chistogramnd_lut.pyx":283
+ * rc = 0
+ *
+ * if weight_min is None: # <<<<<<<<<<<<<<
+ * weight_min = 0
+ * filt_min_weights = False
+ */
+ __pyx_t_2 = (__pyx_v_weight_min == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "chistogramnd_lut.pyx":284
+ *
+ * if weight_min is None:
+ * weight_min = 0 # <<<<<<<<<<<<<<
+ * filt_min_weights = False
+ * else:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __Pyx_DECREF_SET(__pyx_v_weight_min, __pyx_int_0);
+
+ /* "chistogramnd_lut.pyx":285
+ * if weight_min is None:
+ * weight_min = 0
+ * filt_min_weights = False # <<<<<<<<<<<<<<
+ * else:
+ * filt_min_weights = True
+ */
+ __pyx_v_filt_min_weights = 0;
+ goto __pyx_L24;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":287
+ * filt_min_weights = False
+ * else:
+ * filt_min_weights = True # <<<<<<<<<<<<<<
+ *
+ * if weight_max is None:
+ */
+ __pyx_v_filt_min_weights = 1;
+ }
+ __pyx_L24:;
+
+ /* "chistogramnd_lut.pyx":289
+ * filt_min_weights = True
+ *
+ * if weight_max is None: # <<<<<<<<<<<<<<
+ * weight_max = 0
+ * filt_max_weights = False
+ */
+ __pyx_t_1 = (__pyx_v_weight_max == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "chistogramnd_lut.pyx":290
+ *
+ * if weight_max is None:
+ * weight_max = 0 # <<<<<<<<<<<<<<
+ * filt_max_weights = False
+ * else:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __Pyx_DECREF_SET(__pyx_v_weight_max, __pyx_int_0);
+
+ /* "chistogramnd_lut.pyx":291
+ * if weight_max is None:
+ * weight_max = 0
+ * filt_max_weights = False # <<<<<<<<<<<<<<
+ * else:
+ * filt_max_weights = True
+ */
+ __pyx_v_filt_max_weights = 0;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":293
+ * filt_max_weights = False
+ * else:
+ * filt_max_weights = True # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_filt_max_weights = 1;
+ }
+ __pyx_L25:;
+
+ /* "chistogramnd_lut.pyx":295
+ * filt_max_weights = True
+ *
+ * try: # <<<<<<<<<<<<<<
+ * _histogramnd_from_lut_fused(w_c,
+ * h_lut_c,
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_12, &__pyx_t_13, &__pyx_t_14);
+ __Pyx_XGOTREF(__pyx_t_12);
+ __Pyx_XGOTREF(__pyx_t_13);
+ __Pyx_XGOTREF(__pyx_t_14);
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":296
+ *
+ * try:
+ * _histogramnd_from_lut_fused(w_c, # <<<<<<<<<<<<<<
+ * h_lut_c,
+ * h_c,
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_histogramnd_from_lut_fused); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "chistogramnd_lut.pyx":300
+ * h_c,
+ * w_h_c,
+ * weights.size, # <<<<<<<<<<<<<<
+ * filt_min_weights,
+ * w_dtype.type(weight_min),
+ */
+ __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_size); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 300; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+
+ /* "chistogramnd_lut.pyx":301
+ * w_h_c,
+ * weights.size,
+ * filt_min_weights, # <<<<<<<<<<<<<<
+ * w_dtype.type(weight_min),
+ * filt_max_weights,
+ */
+ __pyx_t_6 = __Pyx_PyBool_FromLong(__pyx_v_filt_min_weights); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "chistogramnd_lut.pyx":302
+ * weights.size,
+ * filt_min_weights,
+ * w_dtype.type(weight_min), # <<<<<<<<<<<<<<
+ * filt_max_weights,
+ * w_dtype.type(weight_max))
+ */
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_w_dtype, __pyx_n_s_type); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_v_weight_min); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ } else {
+ __pyx_t_15 = PyTuple_New(1+1); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+ PyTuple_SET_ITEM(__pyx_t_15, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ __Pyx_INCREF(__pyx_v_weight_min);
+ PyTuple_SET_ITEM(__pyx_t_15, 0+1, __pyx_v_weight_min);
+ __Pyx_GIVEREF(__pyx_v_weight_min);
+ __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_15, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "chistogramnd_lut.pyx":303
+ * filt_min_weights,
+ * w_dtype.type(weight_min),
+ * filt_max_weights, # <<<<<<<<<<<<<<
+ * w_dtype.type(weight_max))
+ * except TypeError as ex:
+ */
+ __pyx_t_8 = __Pyx_PyBool_FromLong(__pyx_v_filt_max_weights); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+
+ /* "chistogramnd_lut.pyx":304
+ * w_dtype.type(weight_min),
+ * filt_max_weights,
+ * w_dtype.type(weight_max)) # <<<<<<<<<<<<<<
+ * except TypeError as ex:
+ * print(ex)
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_w_dtype, __pyx_n_s_type); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_16 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_16)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ }
+ }
+ if (!__pyx_t_16) {
+ __pyx_t_15 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_weight_max); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+ } else {
+ __pyx_t_17 = PyTuple_New(1+1); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ PyTuple_SET_ITEM(__pyx_t_17, 0, __pyx_t_16); __Pyx_GIVEREF(__pyx_t_16); __pyx_t_16 = NULL;
+ __Pyx_INCREF(__pyx_v_weight_max);
+ PyTuple_SET_ITEM(__pyx_t_17, 0+1, __pyx_v_weight_max);
+ __Pyx_GIVEREF(__pyx_v_weight_max);
+ __pyx_t_15 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_17, NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+ __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_17 = PyTuple_New(9+__pyx_t_9); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_17, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_w_c);
+ PyTuple_SET_ITEM(__pyx_t_17, 0+__pyx_t_9, __pyx_v_w_c);
+ __Pyx_GIVEREF(__pyx_v_w_c);
+ __Pyx_INCREF(__pyx_v_h_lut_c);
+ PyTuple_SET_ITEM(__pyx_t_17, 1+__pyx_t_9, __pyx_v_h_lut_c);
+ __Pyx_GIVEREF(__pyx_v_h_lut_c);
+ __Pyx_INCREF(__pyx_v_h_c);
+ PyTuple_SET_ITEM(__pyx_t_17, 2+__pyx_t_9, __pyx_v_h_c);
+ __Pyx_GIVEREF(__pyx_v_h_c);
+ __Pyx_INCREF(__pyx_v_w_h_c);
+ PyTuple_SET_ITEM(__pyx_t_17, 3+__pyx_t_9, __pyx_v_w_h_c);
+ __Pyx_GIVEREF(__pyx_v_w_h_c);
+ PyTuple_SET_ITEM(__pyx_t_17, 4+__pyx_t_9, __pyx_t_10);
+ __Pyx_GIVEREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_17, 5+__pyx_t_9, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_17, 6+__pyx_t_9, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_17, 7+__pyx_t_9, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_17, 8+__pyx_t_9, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ __pyx_t_10 = 0;
+ __pyx_t_6 = 0;
+ __pyx_t_11 = 0;
+ __pyx_t_8 = 0;
+ __pyx_t_15 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_17, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L26_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0;
+ __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0;
+ __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
+ goto __pyx_L33_try_end;
+ __pyx_L26_error:;
+ __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0;
+ __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":305
+ * filt_max_weights,
+ * w_dtype.type(weight_max))
+ * except TypeError as ex: # <<<<<<<<<<<<<<
+ * print(ex)
+ * raise TypeError('Case not supported - weights:{0} '
+ */
+ __pyx_t_18 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_18) {
+ __Pyx_AddTraceback("chistogramnd_lut.histogramnd_from_lut", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_7, &__pyx_t_17) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_17);
+ __Pyx_INCREF(__pyx_t_7);
+ __pyx_v_ex = __pyx_t_7;
+
+ /* "chistogramnd_lut.pyx":306
+ * w_dtype.type(weight_max))
+ * except TypeError as ex:
+ * print(ex) # <<<<<<<<<<<<<<
+ * raise TypeError('Case not supported - weights:{0} '
+ * 'and histo:{1}.'
+ */
+ if (__Pyx_PrintOne(0, __pyx_v_ex) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+
+ /* "chistogramnd_lut.pyx":309
+ * raise TypeError('Case not supported - weights:{0} '
+ * 'and histo:{1}.'
+ * ''.format(weights.dtype, histo.dtype)) # <<<<<<<<<<<<<<
+ *
+ * return histo, weighted_histo
+ */
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_Case_not_supported_weights_0_and, __pyx_n_s_format); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_weights, __pyx_n_s_dtype); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_histo, __pyx_n_s_dtype); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_10 = NULL;
+ __pyx_t_9 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_8))) {
+ __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_8);
+ if (likely(__pyx_t_10)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8);
+ __Pyx_INCREF(__pyx_t_10);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_8, function);
+ __pyx_t_9 = 1;
+ }
+ }
+ __pyx_t_5 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (__pyx_t_10) {
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_10); __Pyx_GIVEREF(__pyx_t_10); __pyx_t_10 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_9, __pyx_t_11);
+ __Pyx_GIVEREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_9, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_11 = 0;
+ __pyx_t_6 = 0;
+ __pyx_t_15 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_5, NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+
+ /* "chistogramnd_lut.pyx":307
+ * except TypeError as ex:
+ * print(ex)
+ * raise TypeError('Case not supported - weights:{0} ' # <<<<<<<<<<<<<<
+ * 'and histo:{1}.'
+ * ''.format(weights.dtype, histo.dtype))
+ */
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_15);
+ __Pyx_GIVEREF(__pyx_t_15);
+ __pyx_t_15 = 0;
+ __pyx_t_15 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_8, NULL); if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+ __Pyx_GOTREF(__pyx_t_15);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_Raise(__pyx_t_15, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L28_except_error;}
+ }
+ goto __pyx_L28_except_error;
+ __pyx_L28_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_12);
+ __Pyx_XGIVEREF(__pyx_t_13);
+ __Pyx_XGIVEREF(__pyx_t_14);
+ __Pyx_ExceptionReset(__pyx_t_12, __pyx_t_13, __pyx_t_14);
+ goto __pyx_L1_error;
+ __pyx_L33_try_end:;
+ }
+
+ /* "chistogramnd_lut.pyx":311
+ * ''.format(weights.dtype, histo.dtype))
+ *
+ * return histo, weighted_histo # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_17 = PyTuple_New(2); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ __Pyx_INCREF(__pyx_v_histo);
+ PyTuple_SET_ITEM(__pyx_t_17, 0, __pyx_v_histo);
+ __Pyx_GIVEREF(__pyx_v_histo);
+ __Pyx_INCREF(__pyx_v_weighted_histo);
+ PyTuple_SET_ITEM(__pyx_t_17, 1, __pyx_v_weighted_histo);
+ __Pyx_GIVEREF(__pyx_v_weighted_histo);
+ __pyx_r = __pyx_t_17;
+ __pyx_t_17 = 0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":206
+ *
+ *
+ * def histogramnd_from_lut(weights, # <<<<<<<<<<<<<<
+ * histo_lut,
+ * histo=None,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_XDECREF(__pyx_t_15);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_AddTraceback("chistogramnd_lut.histogramnd_from_lut", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_w_dtype);
+ __Pyx_XDECREF(__pyx_v_w_c);
+ __Pyx_XDECREF(__pyx_v_h_c);
+ __Pyx_XDECREF(__pyx_v_w_h_c);
+ __Pyx_XDECREF(__pyx_v_h_lut_c);
+ __Pyx_XDECREF(__pyx_v_ex);
+ __Pyx_XDECREF(__pyx_v_histo);
+ __Pyx_XDECREF(__pyx_v_weighted_histo);
+ __Pyx_XDECREF(__pyx_v_shape);
+ __Pyx_XDECREF(__pyx_v_dtype);
+ __Pyx_XDECREF(__pyx_v_weight_min);
+ __Pyx_XDECREF(__pyx_v_weight_max);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_16chistogramnd_lut_5_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused[] = "_histogramnd_from_lut_fused(signatures, args, kwargs, defaults)";
+static PyMethodDef __pyx_mdef_16chistogramnd_lut_5_histogramnd_from_lut_fused = {"_histogramnd_from_lut_fused", (PyCFunction)__pyx_pw_16chistogramnd_lut_5_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_pw_16chistogramnd_lut_5_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_signatures = 0;
+ PyObject *__pyx_v_args = 0;
+ PyObject *__pyx_v_kwargs = 0;
+ CYTHON_UNUSED PyObject *__pyx_v_defaults = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__pyx_fused_cpdef (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_signatures,&__pyx_n_s_args,&__pyx_n_s_kwargs,&__pyx_n_s_defaults,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_signatures)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_args)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kwargs)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_defaults)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_fused_cpdef") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_signatures = values[0];
+ __pyx_v_args = values[1];
+ __pyx_v_kwargs = values[2];
+ __pyx_v_defaults = values[3];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut.__pyx_fused_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_4_histogramnd_from_lut_fused(__pyx_self, __pyx_v_signatures, __pyx_v_args, __pyx_v_kwargs, __pyx_v_defaults);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_4_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_signatures, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs, CYTHON_UNUSED PyObject *__pyx_v_defaults) {
+ PyObject *__pyx_v_dest_sig = NULL;
+ PyObject *__pyx_v_ndarray = 0;
+ PyObject *__pyx_v_numpy = NULL;
+ __Pyx_memviewslice __pyx_v_memslice;
+ Py_ssize_t __pyx_v_itemsize;
+ int __pyx_v_dtype_signed;
+ char __pyx_v_kind;
+ int __pyx_v____pyx_int32_t_is_signed;
+ int __pyx_v____pyx_int16_t_is_signed;
+ int __pyx_v____pyx_int64_t_is_signed;
+ PyObject *__pyx_v_arg = NULL;
+ PyObject *__pyx_v_dtype = NULL;
+ PyObject *__pyx_v_arg_base = NULL;
+ PyObject *__pyx_v_candidates = NULL;
+ PyObject *__pyx_v_sig = NULL;
+ int __pyx_v_match_found;
+ PyObject *__pyx_v_src_type = NULL;
+ PyObject *__pyx_v_dst_type = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ char __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ PyObject *(*__pyx_t_15)(PyObject *);
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ PyObject *__pyx_t_18 = NULL;
+ PyObject *(*__pyx_t_19)(PyObject *);
+ int __pyx_t_20;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused", 0);
+ __Pyx_INCREF(__pyx_v_kwargs);
+ __pyx_t_1 = PyList_New(3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(Py_None);
+ PyList_SET_ITEM(__pyx_t_1, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(Py_None);
+ PyList_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(Py_None);
+ PyList_SET_ITEM(__pyx_t_1, 2, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_v_dest_sig = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = (__pyx_v_kwargs == Py_None);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF_SET(__pyx_v_kwargs, __pyx_t_1);
+ __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+ {
+ __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_6);
+ /*try:*/ {
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_numpy = __pyx_t_1;
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_numpy, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(PyType_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "type", Py_TYPE(__pyx_t_1)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __pyx_v_ndarray = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_7 = PyErr_ExceptionMatches(__pyx_builtin_ImportError) || PyErr_ExceptionMatches(__pyx_builtin_AttributeError) || PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_7) {
+ __Pyx_AddTraceback("chistogramnd_lut.__pyx_fused_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_8, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_INCREF(Py_None);
+ __Pyx_XDECREF_SET(__pyx_v_ndarray, ((PyObject*)Py_None));
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L5_exception_handled;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
+ goto __pyx_L1_error;
+ __pyx_L5_exception_handled:;
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
+ __pyx_L11_try_end:;
+ }
+ __pyx_v_itemsize = -1;
+ __pyx_v____pyx_int32_t_is_signed = (((__pyx_t_5numpy_int32_t)-1) < 0);
+ __pyx_v____pyx_int16_t_is_signed = (((__pyx_t_5numpy_int16_t)-1) < 0);
+ __pyx_v____pyx_int64_t_is_signed = (((__pyx_t_5numpy_int64_t)-1) < 0);
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((0 < __pyx_t_10) != 0);
+ if (__pyx_t_3) {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = PyTuple_GET_ITEM(((PyObject*)__pyx_v_args), 0);
+ __Pyx_INCREF(__pyx_t_9);
+ __pyx_v_arg = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L14;
+ }
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = (__Pyx_PyDict_Contains(__pyx_n_s_i_weights, ((PyObject*)__pyx_v_kwargs), Py_EQ)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = __Pyx_PyDict_GetItem(((PyObject*)__pyx_v_kwargs), __pyx_n_s_i_weights); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_v_arg = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_8 = __Pyx_PyString_Format(__pyx_kp_s_Expected_at_least_d_arguments, __pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L14:;
+ if (0) {
+ goto __pyx_L15;
+ }
+ /*else*/ {
+ while (1) {
+ if (!1) break;
+ __pyx_t_2 = (__pyx_v_ndarray != ((PyObject*)Py_None));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_arg, __pyx_v_ndarray);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_dtype); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_dtype = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L19;
+ }
+ __pyx_t_2 = (__pyx_memoryview_check(__pyx_v_arg) != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_base); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_arg_base = __pyx_t_8;
+ __pyx_t_8 = 0;
+ __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_arg_base, __pyx_v_ndarray);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg_base, __pyx_n_s_dtype); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_dtype = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __pyx_v_dtype = Py_None;
+ }
+ __pyx_L20:;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __pyx_v_dtype = Py_None;
+ }
+ __pyx_L19:;
+ __pyx_v_itemsize = -1;
+ __pyx_t_3 = (__pyx_v_dtype != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_itemsize = __pyx_t_10;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_11 = __Pyx_PyInt_As_char(__pyx_t_8); if (unlikely((__pyx_t_11 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_kind = __pyx_t_11;
+ __pyx_v_dtype_signed = (__pyx_v_kind == 'i');
+ switch (__pyx_v_kind) {
+ case 'i':
+ case 'u':
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_int32_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v____pyx_int32_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_int64_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L27_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L27_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v____pyx_int64_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L27_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ break;
+ case 'f':
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_float64_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L31_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L31_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_float32_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L34_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L34_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ break;
+ case 'c':
+ break;
+ case 'O':
+ break;
+ default: break;
+ }
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L37_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_float64_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L37_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L36;
+ }
+ __pyx_L36:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L41_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_float32_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L41_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L40;
+ }
+ __pyx_L40:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L45_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int32_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L45_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L44;
+ }
+ __pyx_L44:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L49_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int64_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L49_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L48;
+ }
+ __pyx_L48:;
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, Py_None, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_L17_break:;
+ }
+ __pyx_L15:;
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((1 < __pyx_t_10) != 0);
+ if (__pyx_t_2) {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = PyTuple_GET_ITEM(((PyObject*)__pyx_v_args), 1);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_DECREF_SET(__pyx_v_arg, __pyx_t_8);
+ __pyx_t_8 = 0;
+ goto __pyx_L52;
+ }
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_2 = (__Pyx_PyDict_Contains(__pyx_n_s_i_lut, ((PyObject*)__pyx_v_kwargs), Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = __Pyx_PyDict_GetItem(((PyObject*)__pyx_v_kwargs), __pyx_n_s_i_lut); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF_SET(__pyx_v_arg, __pyx_t_8);
+ __pyx_t_8 = 0;
+ goto __pyx_L52;
+ }
+ /*else*/ {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_8 = PyInt_FromSsize_t(__pyx_t_10); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Expected_at_least_d_arguments, __pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_8, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L52:;
+ if (0) {
+ goto __pyx_L53;
+ }
+ /*else*/ {
+ while (1) {
+ if (!1) break;
+ __pyx_t_3 = (__pyx_v_ndarray != ((PyObject*)Py_None));
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_arg, __pyx_v_ndarray);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, __pyx_t_9);
+ __pyx_t_9 = 0;
+ goto __pyx_L57;
+ }
+ __pyx_t_3 = (__pyx_memoryview_check(__pyx_v_arg) != 0);
+ if (__pyx_t_3) {
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_base); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF_SET(__pyx_v_arg_base, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_arg_base, __pyx_v_ndarray);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg_base, __pyx_n_s_dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, __pyx_t_9);
+ __pyx_t_9 = 0;
+ goto __pyx_L58;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, Py_None);
+ }
+ __pyx_L58:;
+ goto __pyx_L57;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, Py_None);
+ }
+ __pyx_L57:;
+ __pyx_v_itemsize = -1;
+ __pyx_t_2 = (__pyx_v_dtype != Py_None);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_itemsize = __pyx_t_10;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_8, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_11 = __Pyx_PyInt_As_char(__pyx_t_9); if (unlikely((__pyx_t_11 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_kind = __pyx_t_11;
+ __pyx_v_dtype_signed = (__pyx_v_kind == 'i');
+ switch (__pyx_v_kind) {
+ case 'i':
+ case 'u':
+ __pyx_t_2 = (((sizeof(__pyx_t_5numpy_int64_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L61_bool_binop_done;
+ }
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_2 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L61_bool_binop_done;
+ }
+ __pyx_t_2 = ((!((__pyx_v____pyx_int64_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L61_bool_binop_done:;
+ if (__pyx_t_3) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ __pyx_t_2 = (((sizeof(__pyx_t_5numpy_int32_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L65_bool_binop_done;
+ }
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_2 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L65_bool_binop_done;
+ }
+ __pyx_t_2 = ((!((__pyx_v____pyx_int32_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L65_bool_binop_done:;
+ if (__pyx_t_3) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ __pyx_t_2 = (((sizeof(__pyx_t_5numpy_int16_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L69_bool_binop_done;
+ }
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_2 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L69_bool_binop_done;
+ }
+ __pyx_t_2 = ((!((__pyx_v____pyx_int16_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L69_bool_binop_done:;
+ if (__pyx_t_3) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int16_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ break;
+ case 'f':
+ break;
+ case 'c':
+ break;
+ case 'O':
+ break;
+ default: break;
+ }
+ goto __pyx_L59;
+ }
+ __pyx_L59:;
+ goto __pyx_L56;
+ }
+ __pyx_L56:;
+ __pyx_t_2 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L73_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int64_t))) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L73_bool_binop_done:;
+ if (__pyx_t_3) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(__pyx_v_arg);
+ __pyx_t_3 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_3) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L72;
+ }
+ __pyx_L72:;
+ __pyx_t_2 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L77_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int32_t))) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L77_bool_binop_done:;
+ if (__pyx_t_3) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_arg);
+ __pyx_t_3 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_3) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L76;
+ }
+ __pyx_L76:;
+ __pyx_t_2 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L81_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int16_t))) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L81_bool_binop_done:;
+ if (__pyx_t_3) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(__pyx_v_arg);
+ __pyx_t_3 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_3) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int16_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L80;
+ }
+ __pyx_L80:;
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, Py_None, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ __pyx_L55_break:;
+ }
+ __pyx_L53:;
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((3 < __pyx_t_10) != 0);
+ if (__pyx_t_3) {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = PyTuple_GET_ITEM(((PyObject*)__pyx_v_args), 3);
+ __Pyx_INCREF(__pyx_t_9);
+ __Pyx_DECREF_SET(__pyx_v_arg, __pyx_t_9);
+ __pyx_t_9 = 0;
+ goto __pyx_L84;
+ }
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = (__Pyx_PyDict_Contains(__pyx_n_s_o_weighted_histo, ((PyObject*)__pyx_v_kwargs), Py_EQ)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = __Pyx_PyDict_GetItem(((PyObject*)__pyx_v_kwargs), __pyx_n_s_o_weighted_histo); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF_SET(__pyx_v_arg, __pyx_t_9);
+ __pyx_t_9 = 0;
+ goto __pyx_L84;
+ }
+ /*else*/ {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_8 = __Pyx_PyString_Format(__pyx_kp_s_Expected_at_least_d_arguments, __pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L84:;
+ if (0) {
+ goto __pyx_L85;
+ }
+ /*else*/ {
+ while (1) {
+ if (!1) break;
+ __pyx_t_2 = (__pyx_v_ndarray != ((PyObject*)Py_None));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_arg, __pyx_v_ndarray);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_dtype); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, __pyx_t_8);
+ __pyx_t_8 = 0;
+ goto __pyx_L89;
+ }
+ __pyx_t_2 = (__pyx_memoryview_check(__pyx_v_arg) != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_base); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_XDECREF_SET(__pyx_v_arg_base, __pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_arg_base, __pyx_v_ndarray);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg_base, __pyx_n_s_dtype); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, __pyx_t_8);
+ __pyx_t_8 = 0;
+ goto __pyx_L90;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, Py_None);
+ }
+ __pyx_L90:;
+ goto __pyx_L89;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, Py_None);
+ }
+ __pyx_L89:;
+ __pyx_v_itemsize = -1;
+ __pyx_t_3 = (__pyx_v_dtype != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_itemsize = __pyx_t_10;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_11 = __Pyx_PyInt_As_char(__pyx_t_8); if (unlikely((__pyx_t_11 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_kind = __pyx_t_11;
+ __pyx_v_dtype_signed = (__pyx_v_kind == 'i');
+ switch (__pyx_v_kind) {
+ case 'i':
+ case 'u':
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_int32_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L93_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L93_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v____pyx_int32_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L93_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 2, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L87_break;
+ }
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_int64_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L97_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L97_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v____pyx_int64_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L97_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 2, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L87_break;
+ }
+ break;
+ case 'f':
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_float64_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L101_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L101_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 2, __pyx_n_s_float64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L87_break;
+ }
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_float32_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L104_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L104_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 2, __pyx_n_s_float32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L87_break;
+ }
+ break;
+ case 'c':
+ break;
+ case 'O':
+ break;
+ default: break;
+ }
+ goto __pyx_L91;
+ }
+ __pyx_L91:;
+ goto __pyx_L88;
+ }
+ __pyx_L88:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L107_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_float64_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L107_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 2, __pyx_n_s_float64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L87_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L106;
+ }
+ __pyx_L106:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L111_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_float32_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L111_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 2, __pyx_n_s_float32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L87_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L110;
+ }
+ __pyx_L110:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L115_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int32_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L115_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 2, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L87_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L114;
+ }
+ __pyx_L114:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L119_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int64_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L119_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 2, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L87_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L118;
+ }
+ __pyx_L118:;
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 2, Py_None, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L87_break;
+ }
+ __pyx_L87_break:;
+ }
+ __pyx_L85:;
+ __pyx_t_8 = PyList_New(0); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_candidates = ((PyObject*)__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_10 = 0;
+ if (unlikely(__pyx_v_signatures == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = __Pyx_dict_iterator(((PyObject*)__pyx_v_signatures), 1, ((PyObject *)NULL), (&__pyx_t_12), (&__pyx_t_7)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_8);
+ __pyx_t_8 = __pyx_t_9;
+ __pyx_t_9 = 0;
+ while (1) {
+ __pyx_t_13 = __Pyx_dict_iter_next(__pyx_t_8, __pyx_t_12, &__pyx_t_10, &__pyx_t_9, NULL, NULL, __pyx_t_7);
+ if (unlikely(__pyx_t_13 == 0)) break;
+ if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF_SET(__pyx_v_sig, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_match_found = 0;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_sig, __pyx_n_s_strip); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_split); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_dest_sig);
+ PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_dest_sig);
+ __Pyx_GIVEREF(__pyx_v_dest_sig);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_zip, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+ __pyx_t_9 = __pyx_t_1; __Pyx_INCREF(__pyx_t_9); __pyx_t_14 = 0;
+ __pyx_t_15 = NULL;
+ } else {
+ __pyx_t_14 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_15 = Py_TYPE(__pyx_t_9)->tp_iternext; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_15)) {
+ if (likely(PyList_CheckExact(__pyx_t_9))) {
+ if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_9)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_14); __Pyx_INCREF(__pyx_t_1); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_9, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_14 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_14); __Pyx_INCREF(__pyx_t_1); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_9, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_1 = __pyx_t_15(__pyx_t_9);
+ if (unlikely(!__pyx_t_1)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ }
+ if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_16 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_17 = PyTuple_GET_ITEM(sequence, 1);
+ } else {
+ __pyx_t_16 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_17 = PyList_GET_ITEM(sequence, 1);
+ }
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(__pyx_t_17);
+ #else
+ __pyx_t_16 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ Py_ssize_t index = -1;
+ __pyx_t_18 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_18);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_19 = Py_TYPE(__pyx_t_18)->tp_iternext;
+ index = 0; __pyx_t_16 = __pyx_t_19(__pyx_t_18); if (unlikely(!__pyx_t_16)) goto __pyx_L126_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_16);
+ index = 1; __pyx_t_17 = __pyx_t_19(__pyx_t_18); if (unlikely(!__pyx_t_17)) goto __pyx_L126_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_17);
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_19(__pyx_t_18), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_19 = NULL;
+ __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
+ goto __pyx_L127_unpacking_done;
+ __pyx_L126_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
+ __pyx_t_19 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_L127_unpacking_done:;
+ }
+ __Pyx_XDECREF_SET(__pyx_v_src_type, __pyx_t_16);
+ __pyx_t_16 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_dst_type, __pyx_t_17);
+ __pyx_t_17 = 0;
+ __pyx_t_2 = (__pyx_v_dst_type != Py_None);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_src_type, __pyx_v_dst_type, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_3) {
+ __pyx_v_match_found = 1;
+ goto __pyx_L129;
+ }
+ /*else*/ {
+ __pyx_v_match_found = 0;
+ goto __pyx_L125_break;
+ }
+ __pyx_L129:;
+ goto __pyx_L128;
+ }
+ __pyx_L128:;
+ }
+ __pyx_L125_break:;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_3 = (__pyx_v_match_found != 0);
+ if (__pyx_t_3) {
+ __pyx_t_20 = __Pyx_PyList_Append(__pyx_v_candidates, __pyx_v_sig); if (unlikely(__pyx_t_20 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L130;
+ }
+ __pyx_L130:;
+ }
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = (__pyx_v_candidates != Py_None) && (PyList_GET_SIZE(__pyx_v_candidates) != 0);
+ __pyx_t_2 = ((!__pyx_t_3) != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_12 = PyList_GET_SIZE(__pyx_v_candidates); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((__pyx_t_12 > 1) != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+ __Pyx_XDECREF(__pyx_r);
+ if (unlikely(__pyx_v_signatures == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = __Pyx_PyDict_GetItem(((PyObject*)__pyx_v_signatures), PyList_GET_ITEM(__pyx_v_candidates, 0)); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_r = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L0;
+ }
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_18);
+ __Pyx_AddTraceback("chistogramnd_lut.__pyx_fused_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_dest_sig);
+ __Pyx_XDECREF(__pyx_v_ndarray);
+ __Pyx_XDECREF(__pyx_v_numpy);
+ __Pyx_XDECREF(__pyx_v_arg);
+ __Pyx_XDECREF(__pyx_v_dtype);
+ __Pyx_XDECREF(__pyx_v_arg_base);
+ __Pyx_XDECREF(__pyx_v_candidates);
+ __Pyx_XDECREF(__pyx_v_sig);
+ __Pyx_XDECREF(__pyx_v_src_type);
+ __Pyx_XDECREF(__pyx_v_dst_type);
+ __Pyx_XDECREF(__pyx_v_kwargs);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_0_0__pyx_pw_16chistogramnd_lut_9_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_0_0__pyx_mdef_16chistogramnd_lut_9_histogramnd_from_lut_fused = {"__pyx_fuse_0_0_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_0_0__pyx_pw_16chistogramnd_lut_9_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_0_0__pyx_pw_16chistogramnd_lut_9_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_8_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_8_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_0_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_0_1__pyx_pw_16chistogramnd_lut_11_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_0_1__pyx_mdef_16chistogramnd_lut_11_histogramnd_from_lut_fused = {"__pyx_fuse_0_0_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_0_1__pyx_pw_16chistogramnd_lut_11_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_0_1__pyx_pw_16chistogramnd_lut_11_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_10_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_10_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_0_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_0_2__pyx_pw_16chistogramnd_lut_13_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_0_2__pyx_mdef_16chistogramnd_lut_13_histogramnd_from_lut_fused = {"__pyx_fuse_0_0_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_0_2__pyx_pw_16chistogramnd_lut_13_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_0_2__pyx_pw_16chistogramnd_lut_13_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_12_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_12_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_0_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_0_3__pyx_pw_16chistogramnd_lut_15_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_0_3__pyx_mdef_16chistogramnd_lut_15_histogramnd_from_lut_fused = {"__pyx_fuse_0_0_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_0_3__pyx_pw_16chistogramnd_lut_15_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_0_3__pyx_pw_16chistogramnd_lut_15_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_14_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_14_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_0_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_1_0__pyx_pw_16chistogramnd_lut_17_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_1_0__pyx_mdef_16chistogramnd_lut_17_histogramnd_from_lut_fused = {"__pyx_fuse_0_1_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_1_0__pyx_pw_16chistogramnd_lut_17_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_1_0__pyx_pw_16chistogramnd_lut_17_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_16_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_16_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_1_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_1_1__pyx_pw_16chistogramnd_lut_19_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_1_1__pyx_mdef_16chistogramnd_lut_19_histogramnd_from_lut_fused = {"__pyx_fuse_0_1_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_1_1__pyx_pw_16chistogramnd_lut_19_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_1_1__pyx_pw_16chistogramnd_lut_19_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_18_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_18_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_1_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_1_2__pyx_pw_16chistogramnd_lut_21_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_1_2__pyx_mdef_16chistogramnd_lut_21_histogramnd_from_lut_fused = {"__pyx_fuse_0_1_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_1_2__pyx_pw_16chistogramnd_lut_21_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_1_2__pyx_pw_16chistogramnd_lut_21_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_20_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_20_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_1_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_1_3__pyx_pw_16chistogramnd_lut_23_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_1_3__pyx_mdef_16chistogramnd_lut_23_histogramnd_from_lut_fused = {"__pyx_fuse_0_1_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_1_3__pyx_pw_16chistogramnd_lut_23_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_1_3__pyx_pw_16chistogramnd_lut_23_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_22_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_22_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_1_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_2_0__pyx_pw_16chistogramnd_lut_25_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_2_0__pyx_mdef_16chistogramnd_lut_25_histogramnd_from_lut_fused = {"__pyx_fuse_0_2_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_2_0__pyx_pw_16chistogramnd_lut_25_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_2_0__pyx_pw_16chistogramnd_lut_25_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_24_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_24_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_2_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_2_1__pyx_pw_16chistogramnd_lut_27_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_2_1__pyx_mdef_16chistogramnd_lut_27_histogramnd_from_lut_fused = {"__pyx_fuse_0_2_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_2_1__pyx_pw_16chistogramnd_lut_27_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_2_1__pyx_pw_16chistogramnd_lut_27_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_26_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_26_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_2_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_2_2__pyx_pw_16chistogramnd_lut_29_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_2_2__pyx_mdef_16chistogramnd_lut_29_histogramnd_from_lut_fused = {"__pyx_fuse_0_2_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_2_2__pyx_pw_16chistogramnd_lut_29_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_2_2__pyx_pw_16chistogramnd_lut_29_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_28_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_28_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_2_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_2_3__pyx_pw_16chistogramnd_lut_31_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_2_3__pyx_mdef_16chistogramnd_lut_31_histogramnd_from_lut_fused = {"__pyx_fuse_0_2_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_0_2_3__pyx_pw_16chistogramnd_lut_31_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_0_2_3__pyx_pw_16chistogramnd_lut_31_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsDouble(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_30_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_30_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_2_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_0_0__pyx_pw_16chistogramnd_lut_33_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_0_0__pyx_mdef_16chistogramnd_lut_33_histogramnd_from_lut_fused = {"__pyx_fuse_1_0_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_0_0__pyx_pw_16chistogramnd_lut_33_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_0_0__pyx_pw_16chistogramnd_lut_33_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_32_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_32_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_0_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_0_1__pyx_pw_16chistogramnd_lut_35_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_0_1__pyx_mdef_16chistogramnd_lut_35_histogramnd_from_lut_fused = {"__pyx_fuse_1_0_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_0_1__pyx_pw_16chistogramnd_lut_35_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_0_1__pyx_pw_16chistogramnd_lut_35_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_34_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_34_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_0_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_0_2__pyx_pw_16chistogramnd_lut_37_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_0_2__pyx_mdef_16chistogramnd_lut_37_histogramnd_from_lut_fused = {"__pyx_fuse_1_0_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_0_2__pyx_pw_16chistogramnd_lut_37_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_0_2__pyx_pw_16chistogramnd_lut_37_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_36_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_36_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_0_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_0_3__pyx_pw_16chistogramnd_lut_39_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_0_3__pyx_mdef_16chistogramnd_lut_39_histogramnd_from_lut_fused = {"__pyx_fuse_1_0_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_0_3__pyx_pw_16chistogramnd_lut_39_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_0_3__pyx_pw_16chistogramnd_lut_39_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_38_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_38_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_0_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_1_0__pyx_pw_16chistogramnd_lut_41_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_1_0__pyx_mdef_16chistogramnd_lut_41_histogramnd_from_lut_fused = {"__pyx_fuse_1_1_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_1_0__pyx_pw_16chistogramnd_lut_41_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_1_0__pyx_pw_16chistogramnd_lut_41_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_40_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_40_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_1_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_1_1__pyx_pw_16chistogramnd_lut_43_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_1_1__pyx_mdef_16chistogramnd_lut_43_histogramnd_from_lut_fused = {"__pyx_fuse_1_1_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_1_1__pyx_pw_16chistogramnd_lut_43_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_1_1__pyx_pw_16chistogramnd_lut_43_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_42_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_42_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_1_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_1_2__pyx_pw_16chistogramnd_lut_45_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_1_2__pyx_mdef_16chistogramnd_lut_45_histogramnd_from_lut_fused = {"__pyx_fuse_1_1_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_1_2__pyx_pw_16chistogramnd_lut_45_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_1_2__pyx_pw_16chistogramnd_lut_45_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_44_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_44_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_1_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_1_3__pyx_pw_16chistogramnd_lut_47_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_1_3__pyx_mdef_16chistogramnd_lut_47_histogramnd_from_lut_fused = {"__pyx_fuse_1_1_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_1_3__pyx_pw_16chistogramnd_lut_47_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_1_3__pyx_pw_16chistogramnd_lut_47_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_46_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_46_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_1_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_2_0__pyx_pw_16chistogramnd_lut_49_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_2_0__pyx_mdef_16chistogramnd_lut_49_histogramnd_from_lut_fused = {"__pyx_fuse_1_2_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_2_0__pyx_pw_16chistogramnd_lut_49_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_2_0__pyx_pw_16chistogramnd_lut_49_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_48_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_48_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_2_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_2_1__pyx_pw_16chistogramnd_lut_51_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_2_1__pyx_mdef_16chistogramnd_lut_51_histogramnd_from_lut_fused = {"__pyx_fuse_1_2_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_2_1__pyx_pw_16chistogramnd_lut_51_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_2_1__pyx_pw_16chistogramnd_lut_51_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_50_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_50_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_2_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_2_2__pyx_pw_16chistogramnd_lut_53_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_2_2__pyx_mdef_16chistogramnd_lut_53_histogramnd_from_lut_fused = {"__pyx_fuse_1_2_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_2_2__pyx_pw_16chistogramnd_lut_53_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_2_2__pyx_pw_16chistogramnd_lut_53_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_52_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_52_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_2_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_2_3__pyx_pw_16chistogramnd_lut_55_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_2_3__pyx_mdef_16chistogramnd_lut_55_histogramnd_from_lut_fused = {"__pyx_fuse_1_2_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_1_2_3__pyx_pw_16chistogramnd_lut_55_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_1_2_3__pyx_pw_16chistogramnd_lut_55_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_float32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __pyx_PyFloat_AsFloat(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __pyx_PyFloat_AsFloat(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_float32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_54_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_54_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_float32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_2_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_0_0__pyx_pw_16chistogramnd_lut_57_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_0_0__pyx_mdef_16chistogramnd_lut_57_histogramnd_from_lut_fused = {"__pyx_fuse_2_0_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_0_0__pyx_pw_16chistogramnd_lut_57_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_0_0__pyx_pw_16chistogramnd_lut_57_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_56_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_56_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_0_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_0_1__pyx_pw_16chistogramnd_lut_59_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_0_1__pyx_mdef_16chistogramnd_lut_59_histogramnd_from_lut_fused = {"__pyx_fuse_2_0_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_0_1__pyx_pw_16chistogramnd_lut_59_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_0_1__pyx_pw_16chistogramnd_lut_59_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_58_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_58_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_0_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_0_2__pyx_pw_16chistogramnd_lut_61_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_0_2__pyx_mdef_16chistogramnd_lut_61_histogramnd_from_lut_fused = {"__pyx_fuse_2_0_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_0_2__pyx_pw_16chistogramnd_lut_61_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_0_2__pyx_pw_16chistogramnd_lut_61_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_60_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_60_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_0_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_0_3__pyx_pw_16chistogramnd_lut_63_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_0_3__pyx_mdef_16chistogramnd_lut_63_histogramnd_from_lut_fused = {"__pyx_fuse_2_0_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_0_3__pyx_pw_16chistogramnd_lut_63_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_0_3__pyx_pw_16chistogramnd_lut_63_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_62_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_62_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_0_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_1_0__pyx_pw_16chistogramnd_lut_65_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_1_0__pyx_mdef_16chistogramnd_lut_65_histogramnd_from_lut_fused = {"__pyx_fuse_2_1_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_1_0__pyx_pw_16chistogramnd_lut_65_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_1_0__pyx_pw_16chistogramnd_lut_65_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_64_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_64_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_1_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_1_1__pyx_pw_16chistogramnd_lut_67_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_1_1__pyx_mdef_16chistogramnd_lut_67_histogramnd_from_lut_fused = {"__pyx_fuse_2_1_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_1_1__pyx_pw_16chistogramnd_lut_67_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_1_1__pyx_pw_16chistogramnd_lut_67_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_66_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_66_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_1_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_1_2__pyx_pw_16chistogramnd_lut_69_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_1_2__pyx_mdef_16chistogramnd_lut_69_histogramnd_from_lut_fused = {"__pyx_fuse_2_1_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_1_2__pyx_pw_16chistogramnd_lut_69_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_1_2__pyx_pw_16chistogramnd_lut_69_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_68_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_68_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_1_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_1_3__pyx_pw_16chistogramnd_lut_71_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_1_3__pyx_mdef_16chistogramnd_lut_71_histogramnd_from_lut_fused = {"__pyx_fuse_2_1_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_1_3__pyx_pw_16chistogramnd_lut_71_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_1_3__pyx_pw_16chistogramnd_lut_71_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_70_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_70_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_1_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_2_0__pyx_pw_16chistogramnd_lut_73_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_2_0__pyx_mdef_16chistogramnd_lut_73_histogramnd_from_lut_fused = {"__pyx_fuse_2_2_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_2_0__pyx_pw_16chistogramnd_lut_73_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_2_0__pyx_pw_16chistogramnd_lut_73_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_72_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_72_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_2_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_2_1__pyx_pw_16chistogramnd_lut_75_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_2_1__pyx_mdef_16chistogramnd_lut_75_histogramnd_from_lut_fused = {"__pyx_fuse_2_2_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_2_1__pyx_pw_16chistogramnd_lut_75_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_2_1__pyx_pw_16chistogramnd_lut_75_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_74_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_74_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_2_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_2_2__pyx_pw_16chistogramnd_lut_77_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_2_2__pyx_mdef_16chistogramnd_lut_77_histogramnd_from_lut_fused = {"__pyx_fuse_2_2_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_2_2__pyx_pw_16chistogramnd_lut_77_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_2_2__pyx_pw_16chistogramnd_lut_77_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_76_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_76_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_2_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_2_3__pyx_pw_16chistogramnd_lut_79_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_2_3__pyx_mdef_16chistogramnd_lut_79_histogramnd_from_lut_fused = {"__pyx_fuse_2_2_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_2_2_3__pyx_pw_16chistogramnd_lut_79_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_2_2_3__pyx_pw_16chistogramnd_lut_79_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int32_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int32(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int32(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int32)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_78_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_78_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int32_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_2_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_0_0__pyx_pw_16chistogramnd_lut_81_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_0_0__pyx_mdef_16chistogramnd_lut_81_histogramnd_from_lut_fused = {"__pyx_fuse_3_0_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_0_0__pyx_pw_16chistogramnd_lut_81_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_0_0__pyx_pw_16chistogramnd_lut_81_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_80_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_80_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_0_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_0_1__pyx_pw_16chistogramnd_lut_83_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_0_1__pyx_mdef_16chistogramnd_lut_83_histogramnd_from_lut_fused = {"__pyx_fuse_3_0_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_0_1__pyx_pw_16chistogramnd_lut_83_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_0_1__pyx_pw_16chistogramnd_lut_83_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_82_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_82_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_0_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_0_2__pyx_pw_16chistogramnd_lut_85_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_0_2__pyx_mdef_16chistogramnd_lut_85_histogramnd_from_lut_fused = {"__pyx_fuse_3_0_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_0_2__pyx_pw_16chistogramnd_lut_85_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_0_2__pyx_pw_16chistogramnd_lut_85_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_84_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_84_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_0_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_0_3__pyx_pw_16chistogramnd_lut_87_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_0_3__pyx_mdef_16chistogramnd_lut_87_histogramnd_from_lut_fused = {"__pyx_fuse_3_0_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_0_3__pyx_pw_16chistogramnd_lut_87_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_0_3__pyx_pw_16chistogramnd_lut_87_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_86_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_86_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int64_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int64_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_0_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_1_0__pyx_pw_16chistogramnd_lut_89_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_1_0__pyx_mdef_16chistogramnd_lut_89_histogramnd_from_lut_fused = {"__pyx_fuse_3_1_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_1_0__pyx_pw_16chistogramnd_lut_89_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_1_0__pyx_pw_16chistogramnd_lut_89_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_88_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_88_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_1_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_1_1__pyx_pw_16chistogramnd_lut_91_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_1_1__pyx_mdef_16chistogramnd_lut_91_histogramnd_from_lut_fused = {"__pyx_fuse_3_1_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_1_1__pyx_pw_16chistogramnd_lut_91_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_1_1__pyx_pw_16chistogramnd_lut_91_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_90_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_90_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_1_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_1_2__pyx_pw_16chistogramnd_lut_93_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_1_2__pyx_mdef_16chistogramnd_lut_93_histogramnd_from_lut_fused = {"__pyx_fuse_3_1_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_1_2__pyx_pw_16chistogramnd_lut_93_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_1_2__pyx_pw_16chistogramnd_lut_93_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_92_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_92_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_1_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_1_3__pyx_pw_16chistogramnd_lut_95_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_1_3__pyx_mdef_16chistogramnd_lut_95_histogramnd_from_lut_fused = {"__pyx_fuse_3_1_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_1_3__pyx_pw_16chistogramnd_lut_95_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_1_3__pyx_pw_16chistogramnd_lut_95_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_94_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_94_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int32_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int32_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_1_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_2_0__pyx_pw_16chistogramnd_lut_97_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_2_0__pyx_mdef_16chistogramnd_lut_97_histogramnd_from_lut_fused = {"__pyx_fuse_3_2_0_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_2_0__pyx_pw_16chistogramnd_lut_97_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_2_0__pyx_pw_16chistogramnd_lut_97_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_96_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_96_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_2_0_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float64_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_2_1__pyx_pw_16chistogramnd_lut_99_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_2_1__pyx_mdef_16chistogramnd_lut_99_histogramnd_from_lut_fused = {"__pyx_fuse_3_2_1_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_2_1__pyx_pw_16chistogramnd_lut_99_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_2_1__pyx_pw_16chistogramnd_lut_99_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_98_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_98_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_2_1_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_float32_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_2_2__pyx_pw_16chistogramnd_lut_101_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_2_2__pyx_mdef_16chistogramnd_lut_101_histogramnd_from_lut_fused = {"__pyx_fuse_3_2_2_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_2_2__pyx_pw_16chistogramnd_lut_101_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_2_2__pyx_pw_16chistogramnd_lut_101_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_100_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_100_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_2_2_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int32_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_2_3__pyx_pw_16chistogramnd_lut_103_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_2_3__pyx_mdef_16chistogramnd_lut_103_histogramnd_from_lut_fused = {"__pyx_fuse_3_2_3_histogramnd_from_lut_fused", (PyCFunction)__pyx_fuse_3_2_3__pyx_pw_16chistogramnd_lut_103_histogramnd_from_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_4_histogramnd_from_lut_fused};
+static PyObject *__pyx_fuse_3_2_3__pyx_pw_16chistogramnd_lut_103_histogramnd_from_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_weights = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_weighted_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_elems;
+ int __pyx_v_i_filt_min_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_min;
+ int __pyx_v_i_filt_max_weights;
+ __pyx_t_5numpy_int64_t __pyx_v_i_weight_max;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_from_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_weights,&__pyx_n_s_i_lut,&__pyx_n_s_o_histo,&__pyx_n_s_o_weighted_histo,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_filt_min_weights,&__pyx_n_s_i_weight_min,&__pyx_n_s_i_filt_max_weights,&__pyx_n_s_i_weight_max,0};
+ PyObject* values[9] = {0,0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weights)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_weighted_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_min_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_min)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_filt_max_weights)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 8:
+ if (likely((values[8] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_weight_max)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, 8); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_from_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 9) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
+ }
+ __pyx_v_i_weights = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_weights.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_i_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 324; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[2]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 325; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_weighted_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[3]); if (unlikely(!__pyx_v_o_weighted_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[4]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 327; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_min_weights = __Pyx_PyObject_IsTrue(values[5]); if (unlikely((__pyx_v_i_filt_min_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_min = __Pyx_PyInt_As_npy_int64(values[6]); if (unlikely((__pyx_v_i_weight_min == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_filt_max_weights = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_i_filt_max_weights == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 330; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_weight_max = __Pyx_PyInt_As_npy_int64(values[8]); if (unlikely((__pyx_v_i_weight_max == (npy_int64)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_from_lut_fused", 1, 9, 9, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_from_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_102_histogramnd_from_lut_fused(__pyx_self, __pyx_v_i_weights, __pyx_v_i_lut, __pyx_v_o_histo, __pyx_v_o_weighted_histo, __pyx_v_i_n_elems, __pyx_v_i_filt_min_weights, __pyx_v_i_weight_min, __pyx_v_i_filt_max_weights, __pyx_v_i_weight_max);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_102_histogramnd_from_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_weights, __Pyx_memviewslice __pyx_v_i_lut, __Pyx_memviewslice __pyx_v_o_histo, __Pyx_memviewslice __pyx_v_o_weighted_histo, int __pyx_v_i_n_elems, int __pyx_v_i_filt_min_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_min, int __pyx_v_i_filt_max_weights, __pyx_t_5numpy_int64_t __pyx_v_i_weight_max) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ __pyx_t_5numpy_int16_t __pyx_t_9;
+ int __pyx_t_10;
+ int __pyx_t_11;
+ __pyx_t_5numpy_int16_t __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_2_3_histogramnd_from_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":333
+ * weights_t i_weight_max):
+ * with nogil:
+ * for i in range(i_n_elems): # <<<<<<<<<<<<<<
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ */
+ __pyx_t_1 = __pyx_v_i_n_elems;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":334
+ * with nogil:
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0): # <<<<<<<<<<<<<<
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ */
+ __pyx_t_3 = __pyx_v_i;
+ __pyx_t_4 = (((*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_3 * __pyx_v_i_lut.strides[0]) ))) >= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":335
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min: # <<<<<<<<<<<<<<
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_min_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L10_bool_binop_done;
+ }
+ __pyx_t_6 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_6 * __pyx_v_i_weights.strides[0]) ))) < __pyx_v_i_weight_min) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L10_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":336
+ * if (i_lut[i] >= 0):
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue # <<<<<<<<<<<<<<
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":337
+ * if i_filt_min_weights and i_weights[i] < i_weight_min:
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max: # <<<<<<<<<<<<<<
+ * continue
+ * o_histo[i_lut[i]] += 1
+ */
+ __pyx_t_5 = (__pyx_v_i_filt_max_weights != 0);
+ if (__pyx_t_5) {
+ } else {
+ __pyx_t_4 = __pyx_t_5;
+ goto __pyx_L13_bool_binop_done;
+ }
+ __pyx_t_7 = __pyx_v_i;
+ __pyx_t_5 = (((*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_7 * __pyx_v_i_weights.strides[0]) ))) > __pyx_v_i_weight_max) != 0);
+ __pyx_t_4 = __pyx_t_5;
+ __pyx_L13_bool_binop_done:;
+ if (__pyx_t_4) {
+
+ /* "chistogramnd_lut.pyx":338
+ * continue
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue # <<<<<<<<<<<<<<
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ */
+ goto __pyx_L6_continue;
+ }
+
+ /* "chistogramnd_lut.pyx":339
+ * if i_filt_max_weights and i_weights[i] > i_weight_max:
+ * continue
+ * o_histo[i_lut[i]] += 1 # <<<<<<<<<<<<<<
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+ *
+ */
+ __pyx_t_8 = __pyx_v_i;
+ __pyx_t_9 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_8 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_9 * __pyx_v_o_histo.strides[0]) )) += 1;
+
+ /* "chistogramnd_lut.pyx":340
+ * continue
+ * o_histo[i_lut[i]] += 1
+ * o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_t_11 = __pyx_v_i;
+ __pyx_t_12 = (*((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_i_lut.data + __pyx_t_11 * __pyx_v_i_lut.strides[0]) )));
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_weighted_histo.data + __pyx_t_12 * __pyx_v_o_weighted_histo.strides[0]) )) += ((__pyx_t_5numpy_int64_t)(*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_weights.data + __pyx_t_10 * __pyx_v_i_weights.strides[0]) ))));
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ __pyx_L6_continue:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":332
+ * bint i_filt_max_weights,
+ * weights_t i_weight_max):
+ * with nogil: # <<<<<<<<<<<<<<
+ * for i in range(i_n_elems):
+ * if (i_lut[i] >= 0):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_weights, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_weighted_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_16chistogramnd_lut_7_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused[] = "_histogramnd_get_lut_fused(signatures, args, kwargs, defaults)";
+static PyMethodDef __pyx_mdef_16chistogramnd_lut_7_histogramnd_get_lut_fused = {"_histogramnd_get_lut_fused", (PyCFunction)__pyx_pw_16chistogramnd_lut_7_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_pw_16chistogramnd_lut_7_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_signatures = 0;
+ PyObject *__pyx_v_args = 0;
+ PyObject *__pyx_v_kwargs = 0;
+ CYTHON_UNUSED PyObject *__pyx_v_defaults = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__pyx_fused_cpdef (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_signatures,&__pyx_n_s_args,&__pyx_n_s_kwargs,&__pyx_n_s_defaults,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_signatures)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_args)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kwargs)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_defaults)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__pyx_fused_cpdef") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_signatures = values[0];
+ __pyx_v_args = values[1];
+ __pyx_v_kwargs = values[2];
+ __pyx_v_defaults = values[3];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__pyx_fused_cpdef", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut.__pyx_fused_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_6_histogramnd_get_lut_fused(__pyx_self, __pyx_v_signatures, __pyx_v_args, __pyx_v_kwargs, __pyx_v_defaults);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_6_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_signatures, PyObject *__pyx_v_args, PyObject *__pyx_v_kwargs, CYTHON_UNUSED PyObject *__pyx_v_defaults) {
+ PyObject *__pyx_v_dest_sig = NULL;
+ PyObject *__pyx_v_ndarray = 0;
+ PyObject *__pyx_v_numpy = NULL;
+ __Pyx_memviewslice __pyx_v_memslice;
+ Py_ssize_t __pyx_v_itemsize;
+ int __pyx_v_dtype_signed;
+ char __pyx_v_kind;
+ int __pyx_v____pyx_int32_t_is_signed;
+ int __pyx_v____pyx_int64_t_is_signed;
+ int __pyx_v____pyx_int16_t_is_signed;
+ PyObject *__pyx_v_arg = NULL;
+ PyObject *__pyx_v_dtype = NULL;
+ PyObject *__pyx_v_arg_base = NULL;
+ PyObject *__pyx_v_candidates = NULL;
+ PyObject *__pyx_v_sig = NULL;
+ int __pyx_v_match_found;
+ PyObject *__pyx_v_src_type = NULL;
+ PyObject *__pyx_v_dst_type = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ char __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_t_13;
+ Py_ssize_t __pyx_t_14;
+ PyObject *(*__pyx_t_15)(PyObject *);
+ PyObject *__pyx_t_16 = NULL;
+ PyObject *__pyx_t_17 = NULL;
+ PyObject *__pyx_t_18 = NULL;
+ PyObject *(*__pyx_t_19)(PyObject *);
+ int __pyx_t_20;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused", 0);
+ __Pyx_INCREF(__pyx_v_kwargs);
+ __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(Py_None);
+ PyList_SET_ITEM(__pyx_t_1, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(Py_None);
+ PyList_SET_ITEM(__pyx_t_1, 1, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __pyx_v_dest_sig = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = (__pyx_v_kwargs == Py_None);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF_SET(__pyx_v_kwargs, __pyx_t_1);
+ __pyx_t_1 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+ {
+ __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_6);
+ /*try:*/ {
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_numpy = __pyx_t_1;
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_numpy, __pyx_n_s_ndarray); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(PyType_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "type", Py_TYPE(__pyx_t_1)->tp_name), 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __pyx_v_ndarray = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_7 = PyErr_ExceptionMatches(__pyx_builtin_ImportError) || PyErr_ExceptionMatches(__pyx_builtin_AttributeError) || PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_7) {
+ __Pyx_AddTraceback("chistogramnd_lut.__pyx_fused_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_8, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_INCREF(Py_None);
+ __Pyx_XDECREF_SET(__pyx_v_ndarray, ((PyObject*)Py_None));
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L5_exception_handled;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
+ goto __pyx_L1_error;
+ __pyx_L5_exception_handled:;
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
+ __pyx_L11_try_end:;
+ }
+ __pyx_v_itemsize = -1;
+ __pyx_v____pyx_int32_t_is_signed = (((__pyx_t_5numpy_int32_t)-1) < 0);
+ __pyx_v____pyx_int64_t_is_signed = (((__pyx_t_5numpy_int64_t)-1) < 0);
+ __pyx_v____pyx_int16_t_is_signed = (((__pyx_t_5numpy_int16_t)-1) < 0);
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((0 < __pyx_t_10) != 0);
+ if (__pyx_t_3) {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = PyTuple_GET_ITEM(((PyObject*)__pyx_v_args), 0);
+ __Pyx_INCREF(__pyx_t_9);
+ __pyx_v_arg = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L14;
+ }
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = (__Pyx_PyDict_Contains(__pyx_n_s_i_sample, ((PyObject*)__pyx_v_kwargs), Py_EQ)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = __Pyx_PyDict_GetItem(((PyObject*)__pyx_v_kwargs), __pyx_n_s_i_sample); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_v_arg = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_8 = __Pyx_PyString_Format(__pyx_kp_s_Expected_at_least_d_arguments, __pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_8, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L14:;
+ if (0) {
+ goto __pyx_L15;
+ }
+ /*else*/ {
+ while (1) {
+ if (!1) break;
+ __pyx_t_2 = (__pyx_v_ndarray != ((PyObject*)Py_None));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_arg, __pyx_v_ndarray);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_dtype); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_dtype = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L19;
+ }
+ __pyx_t_2 = (__pyx_memoryview_check(__pyx_v_arg) != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_base); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_arg_base = __pyx_t_8;
+ __pyx_t_8 = 0;
+ __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_arg_base, __pyx_v_ndarray);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg_base, __pyx_n_s_dtype); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_v_dtype = __pyx_t_8;
+ __pyx_t_8 = 0;
+ goto __pyx_L20;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __pyx_v_dtype = Py_None;
+ }
+ __pyx_L20:;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __pyx_v_dtype = Py_None;
+ }
+ __pyx_L19:;
+ __pyx_v_itemsize = -1;
+ __pyx_t_3 = (__pyx_v_dtype != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_itemsize = __pyx_t_10;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8);
+ __Pyx_GIVEREF(__pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_9, NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_11 = __Pyx_PyInt_As_char(__pyx_t_8); if (unlikely((__pyx_t_11 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_v_kind = __pyx_t_11;
+ __pyx_v_dtype_signed = (__pyx_v_kind == 'i');
+ switch (__pyx_v_kind) {
+ case 'i':
+ case 'u':
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_int32_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L23_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v____pyx_int32_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L23_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_int64_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L27_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L27_bool_binop_done;
+ }
+ __pyx_t_3 = ((!((__pyx_v____pyx_int64_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L27_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ break;
+ case 'f':
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_float64_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L31_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L31_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_t_3 = (((sizeof(__pyx_t_5numpy_float32_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L34_bool_binop_done;
+ }
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_8); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_3 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L34_bool_binop_done:;
+ if (__pyx_t_2) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ break;
+ case 'c':
+ break;
+ case 'O':
+ break;
+ default: break;
+ }
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L37_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_float64_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L37_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L36;
+ }
+ __pyx_L36:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L41_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_float32_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L41_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_float32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L40;
+ }
+ __pyx_L40:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L45_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int32_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L45_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L44;
+ }
+ __pyx_L44:;
+ __pyx_t_3 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_2 = __pyx_t_3;
+ goto __pyx_L49_bool_binop_done;
+ }
+ __pyx_t_3 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int64_t))) != 0);
+ __pyx_t_2 = __pyx_t_3;
+ __pyx_L49_bool_binop_done:;
+ if (__pyx_t_2) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(__pyx_v_arg);
+ __pyx_t_2 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_2) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L48;
+ }
+ __pyx_L48:;
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 0, Py_None, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L17_break;
+ }
+ __pyx_L17_break:;
+ }
+ __pyx_L15:;
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = ((5 < __pyx_t_10) != 0);
+ if (__pyx_t_2) {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = PyTuple_GET_ITEM(((PyObject*)__pyx_v_args), 5);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_DECREF_SET(__pyx_v_arg, __pyx_t_8);
+ __pyx_t_8 = 0;
+ goto __pyx_L52;
+ }
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_2 = (__Pyx_PyDict_Contains(__pyx_n_s_o_lut, ((PyObject*)__pyx_v_kwargs), Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ if (unlikely(__pyx_v_kwargs == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = __Pyx_PyDict_GetItem(((PyObject*)__pyx_v_kwargs), __pyx_n_s_o_lut); if (unlikely(__pyx_t_8 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF_SET(__pyx_v_arg, __pyx_t_8);
+ __pyx_t_8 = 0;
+ goto __pyx_L52;
+ }
+ /*else*/ {
+ if (unlikely(__pyx_v_args == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = PyTuple_GET_SIZE(((PyObject*)__pyx_v_args)); if (unlikely(__pyx_t_10 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_8 = PyInt_FromSsize_t(__pyx_t_10); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Expected_at_least_d_arguments, __pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_8, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L52:;
+ if (0) {
+ goto __pyx_L53;
+ }
+ /*else*/ {
+ while (1) {
+ if (!1) break;
+ __pyx_t_3 = (__pyx_v_ndarray != ((PyObject*)Py_None));
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_arg, __pyx_v_ndarray);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, __pyx_t_9);
+ __pyx_t_9 = 0;
+ goto __pyx_L57;
+ }
+ __pyx_t_3 = (__pyx_memoryview_check(__pyx_v_arg) != 0);
+ if (__pyx_t_3) {
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_base); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF_SET(__pyx_v_arg_base, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_arg_base, __pyx_v_ndarray);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg_base, __pyx_n_s_dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, __pyx_t_9);
+ __pyx_t_9 = 0;
+ goto __pyx_L58;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, Py_None);
+ }
+ __pyx_L58:;
+ goto __pyx_L57;
+ }
+ /*else*/ {
+ __Pyx_INCREF(Py_None);
+ __Pyx_XDECREF_SET(__pyx_v_dtype, Py_None);
+ }
+ __pyx_L57:;
+ __pyx_v_itemsize = -1;
+ __pyx_t_2 = (__pyx_v_dtype != Py_None);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_itemsize = __pyx_t_10;
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_dtype, __pyx_n_s_kind); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_8 = PyTuple_New(1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ord, __pyx_t_8, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_11 = __Pyx_PyInt_As_char(__pyx_t_9); if (unlikely((__pyx_t_11 == (char)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_kind = __pyx_t_11;
+ __pyx_v_dtype_signed = (__pyx_v_kind == 'i');
+ switch (__pyx_v_kind) {
+ case 'i':
+ case 'u':
+ __pyx_t_2 = (((sizeof(__pyx_t_5numpy_int64_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L61_bool_binop_done;
+ }
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_2 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L61_bool_binop_done;
+ }
+ __pyx_t_2 = ((!((__pyx_v____pyx_int64_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L61_bool_binop_done:;
+ if (__pyx_t_3) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ __pyx_t_2 = (((sizeof(__pyx_t_5numpy_int32_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L65_bool_binop_done;
+ }
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_2 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L65_bool_binop_done;
+ }
+ __pyx_t_2 = ((!((__pyx_v____pyx_int32_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L65_bool_binop_done:;
+ if (__pyx_t_3) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ __pyx_t_2 = (((sizeof(__pyx_t_5numpy_int16_t)) == __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L69_bool_binop_done;
+ }
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_arg, __pyx_n_s_ndim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_2 = ((((Py_ssize_t)__pyx_t_10) == 1) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L69_bool_binop_done;
+ }
+ __pyx_t_2 = ((!((__pyx_v____pyx_int16_t_is_signed ^ __pyx_v_dtype_signed) != 0)) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L69_bool_binop_done:;
+ if (__pyx_t_3) {
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int16_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ break;
+ case 'f':
+ break;
+ case 'c':
+ break;
+ case 'O':
+ break;
+ default: break;
+ }
+ goto __pyx_L59;
+ }
+ __pyx_L59:;
+ goto __pyx_L56;
+ }
+ __pyx_L56:;
+ __pyx_t_2 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L73_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int64_t))) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L73_bool_binop_done:;
+ if (__pyx_t_3) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(__pyx_v_arg);
+ __pyx_t_3 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_3) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int64_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L72;
+ }
+ __pyx_L72:;
+ __pyx_t_2 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L77_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int32_t))) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L77_bool_binop_done:;
+ if (__pyx_t_3) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(__pyx_v_arg);
+ __pyx_t_3 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_3) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int32_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L76;
+ }
+ __pyx_L76:;
+ __pyx_t_2 = ((__pyx_v_itemsize == -1) != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_3 = __pyx_t_2;
+ goto __pyx_L81_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_itemsize == (sizeof(__pyx_t_5numpy_int16_t))) != 0);
+ __pyx_t_3 = __pyx_t_2;
+ __pyx_L81_bool_binop_done:;
+ if (__pyx_t_3) {
+ __pyx_v_memslice = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(__pyx_v_arg);
+ __pyx_t_3 = (__pyx_v_memslice.memview != 0);
+ if (__pyx_t_3) {
+ __PYX_XDEC_MEMVIEW((&__pyx_v_memslice), 1);
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, __pyx_n_s_int16_t, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ /*else*/ {
+ PyErr_Clear();
+ }
+ goto __pyx_L80;
+ }
+ __pyx_L80:;
+ if (unlikely(__Pyx_SetItemInt(__pyx_v_dest_sig, 1, Py_None, long, 1, __Pyx_PyInt_From_long, 1, 0, 0) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L55_break;
+ }
+ __pyx_L55_break:;
+ }
+ __pyx_L53:;
+ __pyx_t_9 = PyList_New(0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_v_candidates = ((PyObject*)__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_10 = 0;
+ if (unlikely(__pyx_v_signatures == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_8 = __Pyx_dict_iterator(((PyObject*)__pyx_v_signatures), 1, ((PyObject *)NULL), (&__pyx_t_12), (&__pyx_t_7)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __pyx_t_9 = __pyx_t_8;
+ __pyx_t_8 = 0;
+ while (1) {
+ __pyx_t_13 = __Pyx_dict_iter_next(__pyx_t_9, __pyx_t_12, &__pyx_t_10, &__pyx_t_8, NULL, NULL, __pyx_t_7);
+ if (unlikely(__pyx_t_13 == 0)) break;
+ if (unlikely(__pyx_t_13 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_XDECREF_SET(__pyx_v_sig, __pyx_t_8);
+ __pyx_t_8 = 0;
+ __pyx_v_match_found = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_sig, __pyx_n_s_strip); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_split); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_tuple__21, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_dest_sig);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_v_dest_sig);
+ __Pyx_GIVEREF(__pyx_v_dest_sig);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_zip, __pyx_t_8, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+ __pyx_t_8 = __pyx_t_1; __Pyx_INCREF(__pyx_t_8); __pyx_t_14 = 0;
+ __pyx_t_15 = NULL;
+ } else {
+ __pyx_t_14 = -1; __pyx_t_8 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __pyx_t_15 = Py_TYPE(__pyx_t_8)->tp_iternext; if (unlikely(!__pyx_t_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_15)) {
+ if (likely(PyList_CheckExact(__pyx_t_8))) {
+ if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_8)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyList_GET_ITEM(__pyx_t_8, __pyx_t_14); __Pyx_INCREF(__pyx_t_1); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_8, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_14 >= PyTuple_GET_SIZE(__pyx_t_8)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_8, __pyx_t_14); __Pyx_INCREF(__pyx_t_1); __pyx_t_14++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_1 = PySequence_ITEM(__pyx_t_8, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_1 = __pyx_t_15(__pyx_t_8);
+ if (unlikely(!__pyx_t_1)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ }
+ if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyTuple_CheckExact(sequence))) {
+ __pyx_t_16 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_17 = PyTuple_GET_ITEM(sequence, 1);
+ } else {
+ __pyx_t_16 = PyList_GET_ITEM(sequence, 0);
+ __pyx_t_17 = PyList_GET_ITEM(sequence, 1);
+ }
+ __Pyx_INCREF(__pyx_t_16);
+ __Pyx_INCREF(__pyx_t_17);
+ #else
+ __pyx_t_16 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_16);
+ __pyx_t_17 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_17);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ Py_ssize_t index = -1;
+ __pyx_t_18 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_18);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_19 = Py_TYPE(__pyx_t_18)->tp_iternext;
+ index = 0; __pyx_t_16 = __pyx_t_19(__pyx_t_18); if (unlikely(!__pyx_t_16)) goto __pyx_L88_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_16);
+ index = 1; __pyx_t_17 = __pyx_t_19(__pyx_t_18); if (unlikely(!__pyx_t_17)) goto __pyx_L88_unpacking_failed;
+ __Pyx_GOTREF(__pyx_t_17);
+ if (__Pyx_IternextUnpackEndCheck(__pyx_t_19(__pyx_t_18), 2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_19 = NULL;
+ __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
+ goto __pyx_L89_unpacking_done;
+ __pyx_L88_unpacking_failed:;
+ __Pyx_DECREF(__pyx_t_18); __pyx_t_18 = 0;
+ __pyx_t_19 = NULL;
+ if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_L89_unpacking_done:;
+ }
+ __Pyx_XDECREF_SET(__pyx_v_src_type, __pyx_t_16);
+ __pyx_t_16 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_dst_type, __pyx_t_17);
+ __pyx_t_17 = 0;
+ __pyx_t_3 = (__pyx_v_dst_type != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ if (__pyx_t_2) {
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_src_type, __pyx_v_dst_type, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_2) {
+ __pyx_v_match_found = 1;
+ goto __pyx_L91;
+ }
+ /*else*/ {
+ __pyx_v_match_found = 0;
+ goto __pyx_L87_break;
+ }
+ __pyx_L91:;
+ goto __pyx_L90;
+ }
+ __pyx_L90:;
+ }
+ __pyx_L87_break:;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __pyx_t_2 = (__pyx_v_match_found != 0);
+ if (__pyx_t_2) {
+ __pyx_t_20 = __Pyx_PyList_Append(__pyx_v_candidates, __pyx_v_sig); if (unlikely(__pyx_t_20 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L92;
+ }
+ __pyx_L92:;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_t_2 = (__pyx_v_candidates != Py_None) && (PyList_GET_SIZE(__pyx_v_candidates) != 0);
+ __pyx_t_3 = ((!__pyx_t_2) != 0);
+ if (__pyx_t_3) {
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_12 = PyList_GET_SIZE(__pyx_v_candidates); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((__pyx_t_12 > 1) != 0);
+ if (__pyx_t_3) {
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+ __Pyx_XDECREF(__pyx_r);
+ if (unlikely(__pyx_v_signatures == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_9 = __Pyx_PyDict_GetItem(((PyObject*)__pyx_v_signatures), PyList_GET_ITEM(__pyx_v_candidates, 0)); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_r = __pyx_t_9;
+ __pyx_t_9 = 0;
+ goto __pyx_L0;
+ }
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_16);
+ __Pyx_XDECREF(__pyx_t_17);
+ __Pyx_XDECREF(__pyx_t_18);
+ __Pyx_AddTraceback("chistogramnd_lut.__pyx_fused_cpdef", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_dest_sig);
+ __Pyx_XDECREF(__pyx_v_ndarray);
+ __Pyx_XDECREF(__pyx_v_numpy);
+ __Pyx_XDECREF(__pyx_v_arg);
+ __Pyx_XDECREF(__pyx_v_dtype);
+ __Pyx_XDECREF(__pyx_v_arg_base);
+ __Pyx_XDECREF(__pyx_v_candidates);
+ __Pyx_XDECREF(__pyx_v_sig);
+ __Pyx_XDECREF(__pyx_v_src_type);
+ __Pyx_XDECREF(__pyx_v_dst_type);
+ __Pyx_XDECREF(__pyx_v_kwargs);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_0__pyx_pw_16chistogramnd_lut_107_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_0__pyx_mdef_16chistogramnd_lut_107_histogramnd_get_lut_fused = {"__pyx_fuse_0_0_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_0_0__pyx_pw_16chistogramnd_lut_107_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_0_0__pyx_pw_16chistogramnd_lut_107_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_106_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_106_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_float64_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_0_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0.0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_1__pyx_pw_16chistogramnd_lut_109_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_1__pyx_mdef_16chistogramnd_lut_109_histogramnd_get_lut_fused = {"__pyx_fuse_0_1_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_0_1__pyx_pw_16chistogramnd_lut_109_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_0_1__pyx_pw_16chistogramnd_lut_109_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_108_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_108_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_float64_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_1_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0.0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_0_2__pyx_pw_16chistogramnd_lut_111_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_0_2__pyx_mdef_16chistogramnd_lut_111_histogramnd_get_lut_fused = {"__pyx_fuse_0_2_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_0_2__pyx_pw_16chistogramnd_lut_111_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_0_2__pyx_pw_16chistogramnd_lut_111_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_110_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_110_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_float64_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_0_2_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0.0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_float64_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_0__pyx_pw_16chistogramnd_lut_113_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_0__pyx_mdef_16chistogramnd_lut_113_histogramnd_get_lut_fused = {"__pyx_fuse_1_0_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_1_0__pyx_pw_16chistogramnd_lut_113_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_1_0__pyx_pw_16chistogramnd_lut_113_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_112_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_112_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_float32_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_0_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0.0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_1__pyx_pw_16chistogramnd_lut_115_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_1__pyx_mdef_16chistogramnd_lut_115_histogramnd_get_lut_fused = {"__pyx_fuse_1_1_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_1_1__pyx_pw_16chistogramnd_lut_115_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_1_1__pyx_pw_16chistogramnd_lut_115_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_114_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_114_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_float32_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_1_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0.0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_1_2__pyx_pw_16chistogramnd_lut_117_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_1_2__pyx_mdef_16chistogramnd_lut_117_histogramnd_get_lut_fused = {"__pyx_fuse_1_2_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_1_2__pyx_pw_16chistogramnd_lut_117_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_1_2__pyx_pw_16chistogramnd_lut_117_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_116_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_116_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_float32_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_1_2_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0.0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_float32_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_0__pyx_pw_16chistogramnd_lut_119_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_0__pyx_mdef_16chistogramnd_lut_119_histogramnd_get_lut_fused = {"__pyx_fuse_2_0_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_2_0__pyx_pw_16chistogramnd_lut_119_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_2_0__pyx_pw_16chistogramnd_lut_119_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_118_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_118_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_int32_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_0_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_1__pyx_pw_16chistogramnd_lut_121_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_1__pyx_mdef_16chistogramnd_lut_121_histogramnd_get_lut_fused = {"__pyx_fuse_2_1_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_2_1__pyx_pw_16chistogramnd_lut_121_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_2_1__pyx_pw_16chistogramnd_lut_121_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_120_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_120_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_int32_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_1_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_2_2__pyx_pw_16chistogramnd_lut_123_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_2_2__pyx_mdef_16chistogramnd_lut_123_histogramnd_get_lut_fused = {"__pyx_fuse_2_2_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_2_2__pyx_pw_16chistogramnd_lut_123_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_2_2__pyx_pw_16chistogramnd_lut_123_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_122_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_122_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_int32_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_2_2_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_0__pyx_pw_16chistogramnd_lut_125_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_0__pyx_mdef_16chistogramnd_lut_125_histogramnd_get_lut_fused = {"__pyx_fuse_3_0_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_3_0__pyx_pw_16chistogramnd_lut_125_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_3_0__pyx_pw_16chistogramnd_lut_125_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_124_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_124_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_int64_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_0_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_1__pyx_pw_16chistogramnd_lut_127_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_1__pyx_mdef_16chistogramnd_lut_127_histogramnd_get_lut_fused = {"__pyx_fuse_3_1_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_3_1__pyx_pw_16chistogramnd_lut_127_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_3_1__pyx_pw_16chistogramnd_lut_127_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_126_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_126_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_int64_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_1_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_fuse_3_2__pyx_pw_16chistogramnd_lut_129_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_fuse_3_2__pyx_mdef_16chistogramnd_lut_129_histogramnd_get_lut_fused = {"__pyx_fuse_3_2_histogramnd_get_lut_fused", (PyCFunction)__pyx_fuse_3_2__pyx_pw_16chistogramnd_lut_129_histogramnd_get_lut_fused, METH_VARARGS|METH_KEYWORDS, __pyx_doc_16chistogramnd_lut_6_histogramnd_get_lut_fused};
+static PyObject *__pyx_fuse_3_2__pyx_pw_16chistogramnd_lut_129_histogramnd_get_lut_fused(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_i_sample = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_i_n_dims;
+ int __pyx_v_i_n_elems;
+ __Pyx_memviewslice __pyx_v_i_histo_range = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_i_n_bins = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_lut = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_o_histo = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_v_last_bin_closed;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_histogramnd_get_lut_fused (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_i_sample,&__pyx_n_s_i_n_dims,&__pyx_n_s_i_n_elems,&__pyx_n_s_i_histo_range,&__pyx_n_s_i_n_bins,&__pyx_n_s_o_lut,&__pyx_n_s_o_histo,&__pyx_n_s_last_bin_closed,0};
+ PyObject* values[8] = {0,0,0,0,0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ case 7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ case 6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_sample)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_dims)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_elems)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_histo_range)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 4:
+ if (likely((values[4] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_i_n_bins)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 5:
+ if (likely((values[5] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_lut)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 6:
+ if (likely((values[6] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_o_histo)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 6); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 7:
+ if (likely((values[7] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_last_bin_closed)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, 7); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_histogramnd_get_lut_fused") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 8) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+ values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+ values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
+ }
+ __pyx_v_i_sample = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_i_sample.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_dims = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_i_n_dims == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_elems = __Pyx_PyInt_As_int(values[2]); if (unlikely((__pyx_v_i_n_elems == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_histo_range = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[3]); if (unlikely(!__pyx_v_i_histo_range.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_i_n_bins = __Pyx_PyObject_to_MemoryviewSlice_ds_int(values[4]); if (unlikely(!__pyx_v_i_n_bins.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 356; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_lut = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(values[5]); if (unlikely(!__pyx_v_o_lut.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_o_histo = __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(values[6]); if (unlikely(!__pyx_v_o_histo.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 358; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_last_bin_closed = __Pyx_PyObject_IsTrue(values[7]); if (unlikely((__pyx_v_last_bin_closed == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 359; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_histogramnd_get_lut_fused", 1, 8, 8, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("chistogramnd_lut._histogramnd_get_lut_fused", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_16chistogramnd_lut_128_histogramnd_get_lut_fused(__pyx_self, __pyx_v_i_sample, __pyx_v_i_n_dims, __pyx_v_i_n_elems, __pyx_v_i_histo_range, __pyx_v_i_n_bins, __pyx_v_o_lut, __pyx_v_o_histo, __pyx_v_last_bin_closed);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_16chistogramnd_lut_128_histogramnd_get_lut_fused(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_i_sample, int __pyx_v_i_n_dims, int __pyx_v_i_n_elems, __Pyx_memviewslice __pyx_v_i_histo_range, __Pyx_memviewslice __pyx_v_i_n_bins, __Pyx_memviewslice __pyx_v_o_lut, __Pyx_memviewslice __pyx_v_o_histo, int __pyx_v_last_bin_closed) {
+ int __pyx_v_i;
+ long __pyx_v_elem_idx;
+ long __pyx_v_max_idx;
+ long __pyx_v_lut_idx;
+ long __pyx_v_bin_idx;
+ __pyx_t_5numpy_int64_t __pyx_v_elem_coord;
+ double __pyx_v_g_min[50];
+ double __pyx_v_g_max[50];
+ double __pyx_v_bins_range[50];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ long __pyx_t_3;
+ long __pyx_t_4;
+ int __pyx_t_5;
+ long __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ long __pyx_t_11;
+ long __pyx_t_12;
+ __Pyx_RefNannySetupContext("__pyx_fuse_3_2_histogramnd_get_lut_fused", 0);
+
+ /* "chistogramnd_lut.pyx":362
+ *
+ * cdef:
+ * int i = 0 # <<<<<<<<<<<<<<
+ * long elem_idx = 0
+ * long max_idx = 0
+ */
+ __pyx_v_i = 0;
+
+ /* "chistogramnd_lut.pyx":363
+ * cdef:
+ * int i = 0
+ * long elem_idx = 0 # <<<<<<<<<<<<<<
+ * long max_idx = 0
+ * long lut_idx = -1
+ */
+ __pyx_v_elem_idx = 0;
+
+ /* "chistogramnd_lut.pyx":364
+ * int i = 0
+ * long elem_idx = 0
+ * long max_idx = 0 # <<<<<<<<<<<<<<
+ * long lut_idx = -1
+ *
+ */
+ __pyx_v_max_idx = 0;
+
+ /* "chistogramnd_lut.pyx":365
+ * long elem_idx = 0
+ * long max_idx = 0
+ * long lut_idx = -1 # <<<<<<<<<<<<<<
+ *
+ * # computed bin index (i_sample -> grid)
+ */
+ __pyx_v_lut_idx = -1;
+
+ /* "chistogramnd_lut.pyx":368
+ *
+ * # computed bin index (i_sample -> grid)
+ * long bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * sample_t elem_coord = 0
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":370
+ * long bin_idx = 0
+ *
+ * sample_t elem_coord = 0 # <<<<<<<<<<<<<<
+ *
+ * double[50] g_min
+ */
+ __pyx_v_elem_coord = 0;
+
+ /* "chistogramnd_lut.pyx":376
+ * double[50] bins_range
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":377
+ *
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i] # <<<<<<<<<<<<<<
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i]
+ */
+ __pyx_t_3 = (2 * __pyx_v_i);
+ (__pyx_v_g_min[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_3 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":378
+ * for i in range(i_n_dims):
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1] # <<<<<<<<<<<<<<
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ */
+ __pyx_t_4 = ((2 * __pyx_v_i) + 1);
+ (__pyx_v_g_max[__pyx_v_i]) = (*((double *) ( /* dim=0 */ (__pyx_v_i_histo_range.data + __pyx_t_4 * __pyx_v_i_histo_range.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":379
+ * g_min[i] = i_histo_range[2*i]
+ * g_max[i] = i_histo_range[2*i+1]
+ * bins_range[i] = g_max[i] - g_min[i] # <<<<<<<<<<<<<<
+ *
+ * elem_idx = 0 - i_n_dims
+ */
+ (__pyx_v_bins_range[__pyx_v_i]) = ((__pyx_v_g_max[__pyx_v_i]) - (__pyx_v_g_min[__pyx_v_i]));
+ }
+
+ /* "chistogramnd_lut.pyx":381
+ * bins_range[i] = g_max[i] - g_min[i]
+ *
+ * elem_idx = 0 - i_n_dims # <<<<<<<<<<<<<<
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ */
+ __pyx_v_elem_idx = (0 - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":382
+ *
+ * elem_idx = 0 - i_n_dims
+ * max_idx = i_n_elems * i_n_dims - i_n_dims # <<<<<<<<<<<<<<
+ *
+ * with nogil:
+ */
+ __pyx_v_max_idx = ((__pyx_v_i_n_elems * __pyx_v_i_n_dims) - __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+
+ /* "chistogramnd_lut.pyx":385
+ *
+ * with nogil:
+ * while elem_idx < max_idx: # <<<<<<<<<<<<<<
+ * elem_idx += i_n_dims
+ * lut_idx += 1
+ */
+ while (1) {
+ __pyx_t_5 = ((__pyx_v_elem_idx < __pyx_v_max_idx) != 0);
+ if (!__pyx_t_5) break;
+
+ /* "chistogramnd_lut.pyx":386
+ * with nogil:
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims # <<<<<<<<<<<<<<
+ * lut_idx += 1
+ *
+ */
+ __pyx_v_elem_idx = (__pyx_v_elem_idx + __pyx_v_i_n_dims);
+
+ /* "chistogramnd_lut.pyx":387
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ * lut_idx += 1 # <<<<<<<<<<<<<<
+ *
+ * bin_idx = 0
+ */
+ __pyx_v_lut_idx = (__pyx_v_lut_idx + 1);
+
+ /* "chistogramnd_lut.pyx":389
+ * lut_idx += 1
+ *
+ * bin_idx = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(i_n_dims):
+ */
+ __pyx_v_bin_idx = 0;
+
+ /* "chistogramnd_lut.pyx":391
+ * bin_idx = 0
+ *
+ * for i in range(i_n_dims): # <<<<<<<<<<<<<<
+ * elem_coord = i_sample[elem_idx+i]
+ * # =====================
+ */
+ __pyx_t_1 = __pyx_v_i_n_dims;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "chistogramnd_lut.pyx":392
+ *
+ * for i in range(i_n_dims):
+ * elem_coord = i_sample[elem_idx+i] # <<<<<<<<<<<<<<
+ * # =====================
+ * # Element is rejected if any of the following is NOT true :
+ */
+ __pyx_t_6 = (__pyx_v_elem_idx + __pyx_v_i);
+ __pyx_v_elem_coord = (*((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_i_sample.data + __pyx_t_6 * __pyx_v_i_sample.strides[0]) )));
+
+ /* "chistogramnd_lut.pyx":399
+ * # 3. coordinate==maximum value and last_bin_closed is True
+ * # =====================
+ * if elem_coord < g_min[i]: # <<<<<<<<<<<<<<
+ * bin_idx = -1
+ * break
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_min[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":400
+ * # =====================
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":401
+ * if elem_coord < g_min[i]:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * # Here we make the assumption that most of the time
+ */
+ goto __pyx_L11_break;
+ }
+
+ /* "chistogramnd_lut.pyx":408
+ * # than coordinates higher or equal to the max
+ * # (two tests)
+ * if elem_coord < g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ */
+ __pyx_t_5 = ((__pyx_v_elem_coord < (__pyx_v_g_max[__pyx_v_i])) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_t_7 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":410
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) / # <<<<<<<<<<<<<<
+ * bins_range[i]))
+ * else:
+ */
+ __pyx_t_8 = __pyx_v_i;
+
+ /* "chistogramnd_lut.pyx":409
+ * # (two tests)
+ * if elem_coord < g_max[i]:
+ * bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa # <<<<<<<<<<<<<<
+ * (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ * bins_range[i]))
+ */
+ __pyx_v_bin_idx = ((long)((__pyx_v_bin_idx * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_7 * __pyx_v_i_n_bins.strides[0]) )))) + (((__pyx_v_elem_coord - (__pyx_v_g_min[__pyx_v_i])) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_8 * __pyx_v_i_n_bins.strides[0]) )))) / (__pyx_v_bins_range[__pyx_v_i]))));
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":416
+ * # put it in the last bin
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]: # <<<<<<<<<<<<<<
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ */
+ __pyx_t_9 = (__pyx_v_last_bin_closed != 0);
+ if (__pyx_t_9) {
+ } else {
+ __pyx_t_5 = __pyx_t_9;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_9 = ((__pyx_v_elem_coord == (__pyx_v_g_max[__pyx_v_i])) != 0);
+ __pyx_t_5 = __pyx_t_9;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":417
+ * # else : discard
+ * if last_bin_closed and elem_coord == g_max[i]:
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1 # <<<<<<<<<<<<<<
+ * else:
+ * bin_idx = -1
+ */
+ __pyx_t_10 = __pyx_v_i;
+ __pyx_v_bin_idx = (((__pyx_v_bin_idx + 1) * (*((int *) ( /* dim=0 */ (__pyx_v_i_n_bins.data + __pyx_t_10 * __pyx_v_i_n_bins.strides[0]) )))) - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "chistogramnd_lut.pyx":419
+ * bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ * else:
+ * bin_idx = -1 # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_bin_idx = -1;
+
+ /* "chistogramnd_lut.pyx":420
+ * else:
+ * bin_idx = -1
+ * break # <<<<<<<<<<<<<<
+ *
+ * o_lut[lut_idx] = bin_idx
+ */
+ goto __pyx_L11_break;
+ }
+ __pyx_L14:;
+ }
+ __pyx_L13:;
+ }
+ __pyx_L11_break:;
+
+ /* "chistogramnd_lut.pyx":422
+ * break
+ *
+ * o_lut[lut_idx] = bin_idx # <<<<<<<<<<<<<<
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1
+ */
+ __pyx_t_11 = __pyx_v_lut_idx;
+ *((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_o_lut.data + __pyx_t_11 * __pyx_v_o_lut.strides[0]) )) = __pyx_v_bin_idx;
+
+ /* "chistogramnd_lut.pyx":423
+ *
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0: # <<<<<<<<<<<<<<
+ * o_histo[bin_idx] += 1
+ *
+ */
+ __pyx_t_5 = ((__pyx_v_bin_idx >= 0) != 0);
+ if (__pyx_t_5) {
+
+ /* "chistogramnd_lut.pyx":424
+ * o_lut[lut_idx] = bin_idx
+ * if bin_idx >= 0:
+ * o_histo[bin_idx] += 1 # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_t_12 = __pyx_v_bin_idx;
+ *((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_o_histo.data + __pyx_t_12 * __pyx_v_o_histo.strides[0]) )) += 1;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":384
+ * max_idx = i_n_elems * i_n_dims - i_n_dims
+ *
+ * with nogil: # <<<<<<<<<<<<<<
+ * while elem_idx < max_idx:
+ * elem_idx += i_n_dims
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L7;
+ }
+ __pyx_L7:;
+ }
+ }
+
+ /* "chistogramnd_lut.pyx":426
+ * o_histo[bin_idx] += 1
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_r = __pyx_int_0;
+ goto __pyx_L0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_sample, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_histo_range, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_i_n_bins, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_lut, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_o_histo, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_copy_shape;
+ int __pyx_v_i;
+ int __pyx_v_ndim;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ int __pyx_v_t;
+ char *__pyx_v_f;
+ PyArray_Descr *__pyx_v_descr = 0;
+ int __pyx_v_offset;
+ int __pyx_v_hasfields;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":200
+ * # of flags
+ *
+ * if info == NULL: return # <<<<<<<<<<<<<<
+ *
+ * cdef int copy_shape, i, ndim
+ */
+ __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+ if (__pyx_t_1) {
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":204
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ *
+ * ndim = PyArray_NDIM(self)
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<<
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":208
+ * ndim = PyArray_NDIM(self)
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * copy_shape = 1
+ * else:
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * copy_shape = 1 # <<<<<<<<<<<<<<
+ * else:
+ * copy_shape = 0
+ */
+ __pyx_v_copy_shape = 1;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ * copy_shape = 1
+ * else:
+ * copy_shape = 0 # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+ __pyx_v_copy_shape = 0;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":213
+ * copy_shape = 0
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L6_bool_binop_done;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L9_bool_binop_done;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<<
+ * info.ndim = ndim
+ * if copy_shape:
+ */
+ __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim # <<<<<<<<<<<<<<
+ * if copy_shape:
+ * # Allocate new buffer for strides and shape info.
+ */
+ __pyx_v_info->ndim = __pyx_v_ndim;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":223
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim
+ * if copy_shape: # <<<<<<<<<<<<<<
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ */
+ __pyx_t_1 = (__pyx_v_copy_shape != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2) # <<<<<<<<<<<<<<
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":227
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+ __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":228
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ */
+ __pyx_t_4 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<<
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ */
+ (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+ (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+ }
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self) # <<<<<<<<<<<<<<
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self) # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ */
+ __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+ }
+ __pyx_L11:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":234
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<<
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ *
+ */
+ __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<<
+ *
+ * cdef int t
+ */
+ __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *
+ * cdef int t
+ * cdef char* f = NULL # <<<<<<<<<<<<<<
+ * cdef dtype descr = self.descr
+ * cdef list stack
+ */
+ __pyx_v_f = NULL;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":240
+ * cdef int t
+ * cdef char* f = NULL
+ * cdef dtype descr = self.descr # <<<<<<<<<<<<<<
+ * cdef list stack
+ * cdef int offset
+ */
+ __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":244
+ * cdef int offset
+ *
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<<
+ *
+ * if not hasfields and not copy_shape:
+ */
+ __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":246
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ *
+ * if not hasfields and not copy_shape: # <<<<<<<<<<<<<<
+ * # do not call releasebuffer
+ * info.obj = None
+ */
+ __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":248
+ * if not hasfields and not copy_shape:
+ * # do not call releasebuffer
+ * info.obj = None # <<<<<<<<<<<<<<
+ * else:
+ * # need to call releasebuffer
+ */
+ __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = Py_None;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":251
+ * else:
+ * # need to call releasebuffer
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * if not hasfields:
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+ }
+ __pyx_L14:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":253
+ * info.obj = self
+ *
+ * if not hasfields: # <<<<<<<<<<<<<<
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":254
+ *
+ * if not hasfields:
+ * t = descr.type_num # <<<<<<<<<<<<<<
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ */
+ __pyx_t_4 = __pyx_v_descr->type_num;
+ __pyx_v_t = __pyx_t_4;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":255
+ * if not hasfields:
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+ if (!__pyx_t_2) {
+ goto __pyx_L20_next_or;
+ } else {
+ }
+ __pyx_t_2 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_L20_next_or:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L19_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ switch (__pyx_v_t) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ */
+ case NPY_BYTE:
+ __pyx_v_f = __pyx_k_b;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ */
+ case NPY_UBYTE:
+ __pyx_v_f = __pyx_k_B;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ */
+ case NPY_SHORT:
+ __pyx_v_f = __pyx_k_h;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ */
+ case NPY_USHORT:
+ __pyx_v_f = __pyx_k_H;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ */
+ case NPY_INT:
+ __pyx_v_f = __pyx_k_i;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ */
+ case NPY_UINT:
+ __pyx_v_f = __pyx_k_I;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ */
+ case NPY_LONG:
+ __pyx_v_f = __pyx_k_l;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ */
+ case NPY_ULONG:
+ __pyx_v_f = __pyx_k_L;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ */
+ case NPY_LONGLONG:
+ __pyx_v_f = __pyx_k_q;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ */
+ case NPY_ULONGLONG:
+ __pyx_v_f = __pyx_k_Q;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ */
+ case NPY_FLOAT:
+ __pyx_v_f = __pyx_k_f;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ */
+ case NPY_DOUBLE:
+ __pyx_v_f = __pyx_k_d;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ */
+ case NPY_LONGDOUBLE:
+ __pyx_v_f = __pyx_k_g;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+ case NPY_CFLOAT:
+ __pyx_v_f = __pyx_k_Zf;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O"
+ */
+ case NPY_CDOUBLE:
+ __pyx_v_f = __pyx_k_Zd;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ */
+ case NPY_CLONGDOUBLE:
+ __pyx_v_f = __pyx_k_Zg;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ case NPY_OBJECT:
+ __pyx_v_f = __pyx_k_O;
+ break;
+ default:
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * info.format = f
+ * return
+ */
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ break;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f # <<<<<<<<<<<<<<
+ * return
+ * else:
+ */
+ __pyx_v_info->format = __pyx_v_f;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":278
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f
+ * return # <<<<<<<<<<<<<<
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ * return
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<<
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ */
+ __pyx_v_info->format = ((char *)malloc(255));
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":281
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<<
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1,
+ */
+ (__pyx_v_info->format[0]) = '^';
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":282
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0 # <<<<<<<<<<<<<<
+ * f = _util_dtypestring(descr, info.format + 1,
+ * info.format + _buffer_format_string_len,
+ */
+ __pyx_v_offset = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<<
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ */
+ __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_7;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":286
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<<
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+ (__pyx_v_f[0]) = '\x00';
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+ __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":289
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<<
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":290
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format) # <<<<<<<<<<<<<<
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides)
+ */
+ free(__pyx_v_info->format);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * stdlib.free(info.strides)
+ * # info.shape was stored after info.strides in the same block
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides) # <<<<<<<<<<<<<<
+ * # info.shape was stored after info.strides in the same block
+ *
+ */
+ free(__pyx_v_info->strides);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":769
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ * return PyArray_MultiIterNew(1, <void*>a) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":772
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":775
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":778
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":781
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e) # <<<<<<<<<<<<<<
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+ PyArray_Descr *__pyx_v_child = 0;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ PyObject *__pyx_v_fields = 0;
+ PyObject *__pyx_v_childname = NULL;
+ PyObject *__pyx_v_new_offset = NULL;
+ PyObject *__pyx_v_t = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":790
+ * cdef int delta_offset
+ * cdef tuple i
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * cdef tuple fields
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":791
+ * cdef tuple i
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ * cdef tuple fields
+ *
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ if (unlikely(__pyx_v_descr->names == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+ for (;;) {
+ if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":795
+ *
+ * for childname in descr.names:
+ * fields = descr.fields[childname] # <<<<<<<<<<<<<<
+ * child, new_offset = fields
+ *
+ */
+ __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":796
+ * for childname in descr.names:
+ * fields = descr.fields[childname]
+ * child, new_offset = fields # <<<<<<<<<<<<<<
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+ if (likely(__pyx_v_fields != Py_None)) {
+ PyObject* sequence = __pyx_v_fields;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ #else
+ __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ #endif
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+ __pyx_t_3 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ * child, new_offset = fields
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+ if (!__pyx_t_7) {
+ goto __pyx_L8_next_or;
+ } else {
+ }
+ __pyx_t_7 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_L8_next_or:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * # One could encode it in the format string and have Cython
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":813
+ *
+ * # Output padding bytes
+ * while offset[0] < new_offset: # <<<<<<<<<<<<<<
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ */
+ while (1) {
+ __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (!__pyx_t_6) break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":814
+ * # Output padding bytes
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<<
+ * f += 1
+ * offset[0] += 1
+ */
+ (__pyx_v_f[0]) = 120;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":815
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte
+ * f += 1 # <<<<<<<<<<<<<<
+ * offset[0] += 1
+ *
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ * offset[0] += 1 # <<<<<<<<<<<<<<
+ *
+ * offset[0] += child.itemsize
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ * offset[0] += 1
+ *
+ * offset[0] += child.itemsize # <<<<<<<<<<<<<<
+ *
+ * if not PyDataType_HASFIELDS(child):
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":820
+ * offset[0] += child.itemsize
+ *
+ * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<<
+ * t = child.type_num
+ * if end - f < 5:
+ */
+ __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ *
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num # <<<<<<<<<<<<<<
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.")
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":822
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num
+ * if end - f < 5: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short.")
+ *
+ */
+ __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 98;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":827
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 66;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":828
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 104;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 72;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 105;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 73;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 108;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 76;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 113;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 81;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 102;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 100;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 103;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 102;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 100;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 103;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 79;
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * f += 1
+ * else:
+ */
+ __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L15:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * f += 1 # <<<<<<<<<<<<<<
+ * else:
+ * # Cython ignores struct boundary information ("T{...}"),
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":849
+ * # Cython ignores struct boundary information ("T{...}"),
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<<
+ * return f
+ *
+ */
+ __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_9;
+ }
+ __pyx_L13:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":850
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset)
+ * return f # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_f;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_child);
+ __Pyx_XDECREF(__pyx_v_fields);
+ __Pyx_XDECREF(__pyx_v_childname);
+ __Pyx_XDECREF(__pyx_v_new_offset);
+ __Pyx_XDECREF(__pyx_v_t);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+ PyObject *__pyx_v_baseptr;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("set_array_base", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ * cdef PyObject* baseptr
+ * if base is None: # <<<<<<<<<<<<<<
+ * baseptr = NULL
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_base == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * cdef PyObject* baseptr
+ * if base is None:
+ * baseptr = NULL # <<<<<<<<<<<<<<
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ */
+ __pyx_v_baseptr = NULL;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ * baseptr = NULL
+ * else:
+ * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<<
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ */
+ Py_INCREF(__pyx_v_base);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base # <<<<<<<<<<<<<<
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr
+ */
+ __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":973
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base) # <<<<<<<<<<<<<<
+ * arr.base = baseptr
+ *
+ */
+ Py_XDECREF(__pyx_v_arr->base);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr # <<<<<<<<<<<<<<
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ */
+ __pyx_v_arr->base = __pyx_v_baseptr;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("get_array_base", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL: # <<<<<<<<<<<<<<
+ * return None
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":978
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL:
+ * return None # <<<<<<<<<<<<<<
+ * else:
+ * return <object>arr.base
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ * return None
+ * else:
+ * return <object>arr.base # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+ __pyx_r = ((PyObject *)__pyx_v_arr->base);
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__34, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__35, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__36, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__37);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__37);
+ __Pyx_GIVEREF(__pyx_slice__37);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__38); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__39);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__39);
+ __Pyx_GIVEREF(__pyx_slice__39);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__40, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "chistogramnd_lut.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "chistogramnd_lut.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "chistogramnd_lut.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "chistogramnd_lut._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "chistogramnd_lut",
+ 0, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_15_05_2016, __pyx_k_15_05_2016, sizeof(__pyx_k_15_05_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_At_least_one_of_the_following_pa, __pyx_k_At_least_one_of_the_following_pa, sizeof(__pyx_k_At_least_one_of_the_following_pa), 0, 0, 1, 0},
+ {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_kp_s_Case_not_supported_weights_0_and, __pyx_k_Case_not_supported_weights_0_and, sizeof(__pyx_k_Case_not_supported_weights_0_and), 0, 0, 1, 0},
+ {&__pyx_kp_s_D_Naudet, __pyx_k_D_Naudet, sizeof(__pyx_k_D_Naudet), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_n_s_Exception, __pyx_k_Exception, sizeof(__pyx_k_Exception), 0, 0, 1, 1},
+ {&__pyx_kp_s_Expected_at_least_d_arguments, __pyx_k_Expected_at_least_d_arguments, sizeof(__pyx_k_Expected_at_least_d_arguments), 0, 0, 1, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+ {&__pyx_kp_s_Function_call_with_ambiguous_arg, __pyx_k_Function_call_with_ambiguous_arg, sizeof(__pyx_k_Function_call_with_ambiguous_arg), 0, 0, 1, 0},
+ {&__pyx_n_s_ImportError, __pyx_k_ImportError, sizeof(__pyx_k_ImportError), 0, 0, 1, 1},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_kp_s_No_matching_signature_found, __pyx_k_No_matching_signature_found, sizeof(__pyx_k_No_matching_signature_found), 0, 0, 1, 0},
+ {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_kp_s_Provided_dtype_and_weighted_hist, __pyx_k_Provided_dtype_and_weighted_hist, sizeof(__pyx_k_Provided_dtype_and_weighted_hist), 0, 0, 1, 0},
+ {&__pyx_kp_s_Provided_histo_array_doesn_t_hav, __pyx_k_Provided_histo_array_doesn_t_hav, sizeof(__pyx_k_Provided_histo_array_doesn_t_hav), 0, 0, 1, 0},
+ {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_The_LUT_and_weights_arrays_must, __pyx_k_The_LUT_and_weights_arrays_must, sizeof(__pyx_k_The_LUT_and_weights_arrays_must), 0, 0, 1, 0},
+ {&__pyx_kp_s_The_histo_shape_does_not_matchth, __pyx_k_The_histo_shape_does_not_matchth, sizeof(__pyx_k_The_histo_shape_does_not_matchth), 0, 0, 1, 0},
+ {&__pyx_kp_s_The_shape_value_does_not_matchth, __pyx_k_The_shape_value_does_not_matchth, sizeof(__pyx_k_The_shape_value_does_not_matchth), 0, 0, 1, 0},
+ {&__pyx_kp_s_The_shape_value_does_not_matchth_2, __pyx_k_The_shape_value_does_not_matchth_2, sizeof(__pyx_k_The_shape_value_does_not_matchth_2), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Type_not_supported_sample_0, __pyx_k_Type_not_supported_sample_0, sizeof(__pyx_k_Type_not_supported_sample_0), 0, 0, 1, 0},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_kp_s__14, __pyx_k__14, sizeof(__pyx_k__14), 0, 0, 1, 0},
+ {&__pyx_kp_s__16, __pyx_k__16, sizeof(__pyx_k__16), 0, 0, 1, 0},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_any, __pyx_k_any, sizeof(__pyx_k_any), 0, 0, 1, 1},
+ {&__pyx_n_s_arange, __pyx_k_arange, sizeof(__pyx_k_arange), 0, 0, 1, 1},
+ {&__pyx_n_s_args, __pyx_k_args, sizeof(__pyx_k_args), 0, 0, 1, 1},
+ {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+ {&__pyx_n_s_ascontiguousarray, __pyx_k_ascontiguousarray, sizeof(__pyx_k_ascontiguousarray), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_bin_idx, __pyx_k_bin_idx, sizeof(__pyx_k_bin_idx), 0, 0, 1, 1},
+ {&__pyx_n_s_bins_range, __pyx_k_bins_range, sizeof(__pyx_k_bins_range), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_chistogramnd_lut, __pyx_k_chistogramnd_lut, sizeof(__pyx_k_chistogramnd_lut), 0, 0, 1, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_defaults, __pyx_k_defaults, sizeof(__pyx_k_defaults), 0, 0, 1, 1},
+ {&__pyx_n_s_dim_edges, __pyx_k_dim_edges, sizeof(__pyx_k_dim_edges), 0, 0, 1, 1},
+ {&__pyx_n_s_double, __pyx_k_double, sizeof(__pyx_k_double), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_edges, __pyx_k_edges, sizeof(__pyx_k_edges), 0, 0, 1, 1},
+ {&__pyx_n_s_elem_coord, __pyx_k_elem_coord, sizeof(__pyx_k_elem_coord), 0, 0, 1, 1},
+ {&__pyx_n_s_elem_idx, __pyx_k_elem_idx, sizeof(__pyx_k_elem_idx), 0, 0, 1, 1},
+ {&__pyx_n_s_end, __pyx_k_end, sizeof(__pyx_k_end), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_equal, __pyx_k_equal, sizeof(__pyx_k_equal), 0, 0, 1, 1},
+ {&__pyx_n_s_err_histo_range, __pyx_k_err_histo_range, sizeof(__pyx_k_err_histo_range), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_ex, __pyx_k_ex, sizeof(__pyx_k_ex), 0, 0, 1, 1},
+ {&__pyx_n_s_file, __pyx_k_file, sizeof(__pyx_k_file), 0, 0, 1, 1},
+ {&__pyx_n_s_filt_max_weights, __pyx_k_filt_max_weights, sizeof(__pyx_k_filt_max_weights), 0, 0, 1, 1},
+ {&__pyx_n_s_filt_min_weights, __pyx_k_filt_min_weights, sizeof(__pyx_k_filt_min_weights), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_float32_t, __pyx_k_float32_t, sizeof(__pyx_k_float32_t), 0, 0, 1, 1},
+ {&__pyx_kp_s_float32_t_int16_t, __pyx_k_float32_t_int16_t, sizeof(__pyx_k_float32_t_int16_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int16_t_float32_t, __pyx_k_float32_t_int16_t_float32_t, sizeof(__pyx_k_float32_t_int16_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int16_t_float64_t, __pyx_k_float32_t_int16_t_float64_t, sizeof(__pyx_k_float32_t_int16_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int16_t_int32_t, __pyx_k_float32_t_int16_t_int32_t, sizeof(__pyx_k_float32_t_int16_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int16_t_int64_t, __pyx_k_float32_t_int16_t_int64_t, sizeof(__pyx_k_float32_t_int16_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int32_t, __pyx_k_float32_t_int32_t, sizeof(__pyx_k_float32_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int32_t_float32_t, __pyx_k_float32_t_int32_t_float32_t, sizeof(__pyx_k_float32_t_int32_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int32_t_float64_t, __pyx_k_float32_t_int32_t_float64_t, sizeof(__pyx_k_float32_t_int32_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int32_t_int32_t, __pyx_k_float32_t_int32_t_int32_t, sizeof(__pyx_k_float32_t_int32_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int32_t_int64_t, __pyx_k_float32_t_int32_t_int64_t, sizeof(__pyx_k_float32_t_int32_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int64_t, __pyx_k_float32_t_int64_t, sizeof(__pyx_k_float32_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int64_t_float32_t, __pyx_k_float32_t_int64_t_float32_t, sizeof(__pyx_k_float32_t_int64_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int64_t_float64_t, __pyx_k_float32_t_int64_t_float64_t, sizeof(__pyx_k_float32_t_int64_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int64_t_int32_t, __pyx_k_float32_t_int64_t_int32_t, sizeof(__pyx_k_float32_t_int64_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float32_t_int64_t_int64_t, __pyx_k_float32_t_int64_t_int64_t, sizeof(__pyx_k_float32_t_int64_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_n_s_float64_t, __pyx_k_float64_t, sizeof(__pyx_k_float64_t), 0, 0, 1, 1},
+ {&__pyx_kp_s_float64_t_int16_t, __pyx_k_float64_t_int16_t, sizeof(__pyx_k_float64_t_int16_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int16_t_float32_t, __pyx_k_float64_t_int16_t_float32_t, sizeof(__pyx_k_float64_t_int16_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int16_t_float64_t, __pyx_k_float64_t_int16_t_float64_t, sizeof(__pyx_k_float64_t_int16_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int16_t_int32_t, __pyx_k_float64_t_int16_t_int32_t, sizeof(__pyx_k_float64_t_int16_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int16_t_int64_t, __pyx_k_float64_t_int16_t_int64_t, sizeof(__pyx_k_float64_t_int16_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int32_t, __pyx_k_float64_t_int32_t, sizeof(__pyx_k_float64_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int32_t_float32_t, __pyx_k_float64_t_int32_t_float32_t, sizeof(__pyx_k_float64_t_int32_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int32_t_float64_t, __pyx_k_float64_t_int32_t_float64_t, sizeof(__pyx_k_float64_t_int32_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int32_t_int32_t, __pyx_k_float64_t_int32_t_int32_t, sizeof(__pyx_k_float64_t_int32_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int32_t_int64_t, __pyx_k_float64_t_int32_t_int64_t, sizeof(__pyx_k_float64_t_int32_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int64_t, __pyx_k_float64_t_int64_t, sizeof(__pyx_k_float64_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int64_t_float32_t, __pyx_k_float64_t_int64_t_float32_t, sizeof(__pyx_k_float64_t_int64_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int64_t_float64_t, __pyx_k_float64_t_int64_t_float64_t, sizeof(__pyx_k_float64_t_int64_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int64_t_int32_t, __pyx_k_float64_t_int64_t_int32_t, sizeof(__pyx_k_float64_t_int64_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_float64_t_int64_t_int64_t, __pyx_k_float64_t_int64_t_int64_t, sizeof(__pyx_k_float64_t_int64_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_n_s_g_max, __pyx_k_g_max, sizeof(__pyx_k_g_max), 0, 0, 1, 1},
+ {&__pyx_n_s_g_min, __pyx_k_g_min, sizeof(__pyx_k_g_min), 0, 0, 1, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_h_c, __pyx_k_h_c, sizeof(__pyx_k_h_c), 0, 0, 1, 1},
+ {&__pyx_n_s_h_lut_c, __pyx_k_h_lut_c, sizeof(__pyx_k_h_lut_c), 0, 0, 1, 1},
+ {&__pyx_n_s_histo, __pyx_k_histo, sizeof(__pyx_k_histo), 0, 0, 1, 1},
+ {&__pyx_n_s_histo_c, __pyx_k_histo_c, sizeof(__pyx_k_histo_c), 0, 0, 1, 1},
+ {&__pyx_n_s_histo_lut, __pyx_k_histo_lut, sizeof(__pyx_k_histo_lut), 0, 0, 1, 1},
+ {&__pyx_n_s_histo_range, __pyx_k_histo_range, sizeof(__pyx_k_histo_range), 0, 0, 1, 1},
+ {&__pyx_n_s_histo_range_c, __pyx_k_histo_range_c, sizeof(__pyx_k_histo_range_c), 0, 0, 1, 1},
+ {&__pyx_kp_s_histo_range_error_expected_n_di, __pyx_k_histo_range_error_expected_n_di, sizeof(__pyx_k_histo_range_error_expected_n_di), 0, 0, 1, 0},
+ {&__pyx_n_s_histogramnd_from_lut, __pyx_k_histogramnd_from_lut, sizeof(__pyx_k_histogramnd_from_lut), 0, 0, 1, 1},
+ {&__pyx_n_s_histogramnd_from_lut_fused, __pyx_k_histogramnd_from_lut_fused, sizeof(__pyx_k_histogramnd_from_lut_fused), 0, 0, 1, 1},
+ {&__pyx_n_s_histogramnd_get_lut, __pyx_k_histogramnd_get_lut, sizeof(__pyx_k_histogramnd_get_lut), 0, 0, 1, 1},
+ {&__pyx_n_s_histogramnd_get_lut_fused, __pyx_k_histogramnd_get_lut_fused, sizeof(__pyx_k_histogramnd_get_lut_fused), 0, 0, 1, 1},
+ {&__pyx_kp_s_histogramnd_returned_an_error_0, __pyx_k_histogramnd_returned_an_error_0, sizeof(__pyx_k_histogramnd_returned_an_error_0), 0, 0, 1, 0},
+ {&__pyx_n_s_i, __pyx_k_i, sizeof(__pyx_k_i), 0, 0, 1, 1},
+ {&__pyx_n_s_i_dim, __pyx_k_i_dim, sizeof(__pyx_k_i_dim), 0, 0, 1, 1},
+ {&__pyx_n_s_i_filt_max_weights, __pyx_k_i_filt_max_weights, sizeof(__pyx_k_i_filt_max_weights), 0, 0, 1, 1},
+ {&__pyx_n_s_i_filt_min_weights, __pyx_k_i_filt_min_weights, sizeof(__pyx_k_i_filt_min_weights), 0, 0, 1, 1},
+ {&__pyx_n_s_i_histo_range, __pyx_k_i_histo_range, sizeof(__pyx_k_i_histo_range), 0, 0, 1, 1},
+ {&__pyx_n_s_i_lut, __pyx_k_i_lut, sizeof(__pyx_k_i_lut), 0, 0, 1, 1},
+ {&__pyx_n_s_i_n_bins, __pyx_k_i_n_bins, sizeof(__pyx_k_i_n_bins), 0, 0, 1, 1},
+ {&__pyx_n_s_i_n_dims, __pyx_k_i_n_dims, sizeof(__pyx_k_i_n_dims), 0, 0, 1, 1},
+ {&__pyx_n_s_i_n_elems, __pyx_k_i_n_elems, sizeof(__pyx_k_i_n_elems), 0, 0, 1, 1},
+ {&__pyx_n_s_i_sample, __pyx_k_i_sample, sizeof(__pyx_k_i_sample), 0, 0, 1, 1},
+ {&__pyx_n_s_i_weight_max, __pyx_k_i_weight_max, sizeof(__pyx_k_i_weight_max), 0, 0, 1, 1},
+ {&__pyx_n_s_i_weight_min, __pyx_k_i_weight_min, sizeof(__pyx_k_i_weight_min), 0, 0, 1, 1},
+ {&__pyx_n_s_i_weights, __pyx_k_i_weights, sizeof(__pyx_k_i_weights), 0, 0, 1, 1},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_int16, __pyx_k_int16, sizeof(__pyx_k_int16), 0, 0, 1, 1},
+ {&__pyx_n_s_int16_t, __pyx_k_int16_t, sizeof(__pyx_k_int16_t), 0, 0, 1, 1},
+ {&__pyx_n_s_int32, __pyx_k_int32, sizeof(__pyx_k_int32), 0, 0, 1, 1},
+ {&__pyx_n_s_int32_t, __pyx_k_int32_t, sizeof(__pyx_k_int32_t), 0, 0, 1, 1},
+ {&__pyx_kp_s_int32_t_int16_t, __pyx_k_int32_t_int16_t, sizeof(__pyx_k_int32_t_int16_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int16_t_float32_t, __pyx_k_int32_t_int16_t_float32_t, sizeof(__pyx_k_int32_t_int16_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int16_t_float64_t, __pyx_k_int32_t_int16_t_float64_t, sizeof(__pyx_k_int32_t_int16_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int16_t_int32_t, __pyx_k_int32_t_int16_t_int32_t, sizeof(__pyx_k_int32_t_int16_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int16_t_int64_t, __pyx_k_int32_t_int16_t_int64_t, sizeof(__pyx_k_int32_t_int16_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int32_t, __pyx_k_int32_t_int32_t, sizeof(__pyx_k_int32_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int32_t_float32_t, __pyx_k_int32_t_int32_t_float32_t, sizeof(__pyx_k_int32_t_int32_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int32_t_float64_t, __pyx_k_int32_t_int32_t_float64_t, sizeof(__pyx_k_int32_t_int32_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int32_t_int32_t, __pyx_k_int32_t_int32_t_int32_t, sizeof(__pyx_k_int32_t_int32_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int32_t_int64_t, __pyx_k_int32_t_int32_t_int64_t, sizeof(__pyx_k_int32_t_int32_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int64_t, __pyx_k_int32_t_int64_t, sizeof(__pyx_k_int32_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int64_t_float32_t, __pyx_k_int32_t_int64_t_float32_t, sizeof(__pyx_k_int32_t_int64_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int64_t_float64_t, __pyx_k_int32_t_int64_t_float64_t, sizeof(__pyx_k_int32_t_int64_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int64_t_int32_t, __pyx_k_int32_t_int64_t_int32_t, sizeof(__pyx_k_int32_t_int64_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int32_t_int64_t_int64_t, __pyx_k_int32_t_int64_t_int64_t, sizeof(__pyx_k_int32_t_int64_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_n_s_int64, __pyx_k_int64, sizeof(__pyx_k_int64), 0, 0, 1, 1},
+ {&__pyx_n_s_int64_t, __pyx_k_int64_t, sizeof(__pyx_k_int64_t), 0, 0, 1, 1},
+ {&__pyx_kp_s_int64_t_int16_t, __pyx_k_int64_t_int16_t, sizeof(__pyx_k_int64_t_int16_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int16_t_float32_t, __pyx_k_int64_t_int16_t_float32_t, sizeof(__pyx_k_int64_t_int16_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int16_t_float64_t, __pyx_k_int64_t_int16_t_float64_t, sizeof(__pyx_k_int64_t_int16_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int16_t_int32_t, __pyx_k_int64_t_int16_t_int32_t, sizeof(__pyx_k_int64_t_int16_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int16_t_int64_t, __pyx_k_int64_t_int16_t_int64_t, sizeof(__pyx_k_int64_t_int16_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int32_t, __pyx_k_int64_t_int32_t, sizeof(__pyx_k_int64_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int32_t_float32_t, __pyx_k_int64_t_int32_t_float32_t, sizeof(__pyx_k_int64_t_int32_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int32_t_float64_t, __pyx_k_int64_t_int32_t_float64_t, sizeof(__pyx_k_int64_t_int32_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int32_t_int32_t, __pyx_k_int64_t_int32_t_int32_t, sizeof(__pyx_k_int64_t_int32_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int32_t_int64_t, __pyx_k_int64_t_int32_t_int64_t, sizeof(__pyx_k_int64_t_int32_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int64_t, __pyx_k_int64_t_int64_t, sizeof(__pyx_k_int64_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int64_t_float32_t, __pyx_k_int64_t_int64_t_float32_t, sizeof(__pyx_k_int64_t_int64_t_float32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int64_t_float64_t, __pyx_k_int64_t_int64_t_float64_t, sizeof(__pyx_k_int64_t_int64_t_float64_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int64_t_int32_t, __pyx_k_int64_t_int64_t_int32_t, sizeof(__pyx_k_int64_t_int64_t_int32_t), 0, 0, 1, 0},
+ {&__pyx_kp_s_int64_t_int64_t_int64_t, __pyx_k_int64_t_int64_t_int64_t, sizeof(__pyx_k_int64_t_int64_t_int64_t), 0, 0, 1, 0},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_kind, __pyx_k_kind, sizeof(__pyx_k_kind), 0, 0, 1, 1},
+ {&__pyx_n_s_kwargs, __pyx_k_kwargs, sizeof(__pyx_k_kwargs), 0, 0, 1, 1},
+ {&__pyx_n_s_last_bin_closed, __pyx_k_last_bin_closed, sizeof(__pyx_k_last_bin_closed), 0, 0, 1, 1},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_lut, __pyx_k_lut, sizeof(__pyx_k_lut), 0, 0, 1, 1},
+ {&__pyx_n_s_lut_c, __pyx_k_lut_c, sizeof(__pyx_k_lut_c), 0, 0, 1, 1},
+ {&__pyx_n_s_lut_dtype, __pyx_k_lut_dtype, sizeof(__pyx_k_lut_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_lut_idx, __pyx_k_lut_idx, sizeof(__pyx_k_lut_idx), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_max_idx, __pyx_k_max_idx, sizeof(__pyx_k_max_idx), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_k_mntdirect__scisoft_users_tvince, sizeof(__pyx_k_mntdirect__scisoft_users_tvince), 0, 0, 1, 0},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_n_bins, __pyx_k_n_bins, sizeof(__pyx_k_n_bins), 0, 0, 1, 1},
+ {&__pyx_n_s_n_bins_c, __pyx_k_n_bins_c, sizeof(__pyx_k_n_bins_c), 0, 0, 1, 1},
+ {&__pyx_kp_s_n_bins_must_be_either_a_scalar_s, __pyx_k_n_bins_must_be_either_a_scalar_s, sizeof(__pyx_k_n_bins_must_be_either_a_scalar_s), 0, 0, 1, 0},
+ {&__pyx_kp_s_n_bins_only_positive_values_all, __pyx_k_n_bins_only_positive_values_all, sizeof(__pyx_k_n_bins_only_positive_values_all), 0, 0, 1, 0},
+ {&__pyx_n_s_n_dims, __pyx_k_n_dims, sizeof(__pyx_k_n_dims), 0, 0, 1, 1},
+ {&__pyx_n_s_n_elem, __pyx_k_n_elem, sizeof(__pyx_k_n_elem), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_n_s_ndarray, __pyx_k_ndarray, sizeof(__pyx_k_ndarray), 0, 0, 1, 1},
+ {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+ {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_ndmin, __pyx_k_ndmin, sizeof(__pyx_k_ndmin), 0, 0, 1, 1},
+ {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_o_histo, __pyx_k_o_histo, sizeof(__pyx_k_o_histo), 0, 0, 1, 1},
+ {&__pyx_n_s_o_lut, __pyx_k_o_lut, sizeof(__pyx_k_o_lut), 0, 0, 1, 1},
+ {&__pyx_n_s_o_weighted_histo, __pyx_k_o_weighted_histo, sizeof(__pyx_k_o_weighted_histo), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_n_s_ord, __pyx_k_ord, sizeof(__pyx_k_ord), 0, 0, 1, 1},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_n_s_print, __pyx_k_print, sizeof(__pyx_k_print), 0, 0, 1, 1},
+ {&__pyx_n_s_prod, __pyx_k_prod, sizeof(__pyx_k_prod), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_rc, __pyx_k_rc, sizeof(__pyx_k_rc), 0, 0, 1, 1},
+ {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+ {&__pyx_n_s_rng_max, __pyx_k_rng_max, sizeof(__pyx_k_rng_max), 0, 0, 1, 1},
+ {&__pyx_n_s_rng_min, __pyx_k_rng_min, sizeof(__pyx_k_rng_min), 0, 0, 1, 1},
+ {&__pyx_n_s_s_shape, __pyx_k_s_shape, sizeof(__pyx_k_s_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_sample, __pyx_k_sample, sizeof(__pyx_k_sample), 0, 0, 1, 1},
+ {&__pyx_n_s_sample_c, __pyx_k_sample_c, sizeof(__pyx_k_sample_c), 0, 0, 1, 1},
+ {&__pyx_n_s_sample_type, __pyx_k_sample_type, sizeof(__pyx_k_sample_type), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_signatures, __pyx_k_signatures, sizeof(__pyx_k_signatures), 0, 0, 1, 1},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_split, __pyx_k_split, sizeof(__pyx_k_split), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_strip, __pyx_k_strip, sizeof(__pyx_k_strip), 0, 0, 1, 1},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_n_s_tile, __pyx_k_tile, sizeof(__pyx_k_tile), 0, 0, 1, 1},
+ {&__pyx_n_s_type, __pyx_k_type, sizeof(__pyx_k_type), 0, 0, 1, 1},
+ {&__pyx_n_s_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 0, 1, 1},
+ {&__pyx_n_s_uint64, __pyx_k_uint64, sizeof(__pyx_k_uint64), 0, 0, 1, 1},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_n_s_w_c, __pyx_k_w_c, sizeof(__pyx_k_w_c), 0, 0, 1, 1},
+ {&__pyx_n_s_w_dtype, __pyx_k_w_dtype, sizeof(__pyx_k_w_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_w_h_c, __pyx_k_w_h_c, sizeof(__pyx_k_w_h_c), 0, 0, 1, 1},
+ {&__pyx_n_s_weight_max, __pyx_k_weight_max, sizeof(__pyx_k_weight_max), 0, 0, 1, 1},
+ {&__pyx_n_s_weight_min, __pyx_k_weight_min, sizeof(__pyx_k_weight_min), 0, 0, 1, 1},
+ {&__pyx_n_s_weighted_histo, __pyx_k_weighted_histo, sizeof(__pyx_k_weighted_histo), 0, 0, 1, 1},
+ {&__pyx_n_s_weights, __pyx_k_weights, sizeof(__pyx_k_weights), 0, 0, 1, 1},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {&__pyx_n_s_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 0, 0, 1, 1},
+ {&__pyx_n_s_zip, __pyx_k_zip, sizeof(__pyx_k_zip), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Exception = __Pyx_GetBuiltinName(__pyx_n_s_Exception); if (!__pyx_builtin_Exception) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ImportError = __Pyx_GetBuiltinName(__pyx_n_s_ImportError); if (!__pyx_builtin_ImportError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ord = __Pyx_GetBuiltinName(__pyx_n_s_ord); if (!__pyx_builtin_ord) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_zip = __Pyx_GetBuiltinName(__pyx_n_s_zip); if (!__pyx_builtin_zip) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "chistogramnd_lut.pyx":108
+ *
+ * if n_dims == 1:
+ * if histo_range.shape == (2,): # <<<<<<<<<<<<<<
+ * pass
+ * elif histo_range.shape == (1, 2):
+ */
+ __pyx_tuple_ = PyTuple_Pack(1, __pyx_int_2); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "chistogramnd_lut.pyx":110
+ * if histo_range.shape == (2,):
+ * pass
+ * elif histo_range.shape == (1, 2): # <<<<<<<<<<<<<<
+ * histo_range.reshape(-1)
+ * else:
+ */
+ __pyx_tuple__2 = PyTuple_Pack(2, __pyx_int_1, __pyx_int_2); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "chistogramnd_lut.pyx":111
+ * pass
+ * elif histo_range.shape == (1, 2):
+ * histo_range.reshape(-1) # <<<<<<<<<<<<<<
+ * else:
+ * err_histo_range = True
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "chistogramnd_lut.pyx":133
+ * n_bins = np.tile(n_bins, n_dims)
+ * elif n_bins.shape != (n_dims,):
+ * raise ValueError('n_bins must be either a scalar (same number ' # <<<<<<<<<<<<<<
+ * 'of bins for all dimensions) or '
+ * 'an array (number of bins for each '
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_n_bins_must_be_either_a_scalar_s); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "chistogramnd_lut.pyx":142
+ * # also testing for negative/null values
+ * if np.any(np.equal(n_bins, None)) or np.any(n_bins <= 0):
+ * raise ValueError('<n_bins> : only positive values allowed.') # <<<<<<<<<<<<<<
+ *
+ * sample_type = sample.dtype
+ */
+ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_n_bins_only_positive_values_all); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "chistogramnd_lut.pyx":189
+ *
+ * edges = []
+ * histo_range = histo_range.reshape(-1) # <<<<<<<<<<<<<<
+ * for i_dim in range(n_dims):
+ * dim_edges = np.zeros(n_bins[i_dim] + 1)
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 189; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+
+ /* "chistogramnd_lut.pyx":194
+ * rng_min = histo_range[2 * i_dim]
+ * rng_max = histo_range[2 * i_dim + 1]
+ * dim_edges[:-1] = (rng_min + np.arange(n_bins[i_dim]) * # <<<<<<<<<<<<<<
+ * ((rng_max - rng_min) / n_bins[i_dim]))
+ * dim_edges[-1] = rng_max
+ */
+ __pyx_slice__7 = PySlice_New(Py_None, __pyx_int_neg_1, Py_None); if (unlikely(!__pyx_slice__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__7);
+ __Pyx_GIVEREF(__pyx_slice__7);
+
+ /* "chistogramnd_lut.pyx":220
+ * if histo is None and weighted_histo is None:
+ * if shape is None:
+ * raise ValueError('At least one of the following parameters has to ' # <<<<<<<<<<<<<<
+ * 'be provided : <shape> or <histo> or '
+ * '<weighted_histo>')
+ */
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_At_least_one_of_the_following_pa); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "chistogramnd_lut.pyx":226
+ * if shape is not None:
+ * if histo is not None and list(histo.shape) != list(shape):
+ * raise ValueError('The <shape> value does not match' # <<<<<<<<<<<<<<
+ * 'the <histo> shape.')
+ *
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_The_shape_value_does_not_matchth); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "chistogramnd_lut.pyx":231
+ * if(weighted_histo is not None and
+ * list(weighted_histo.shape) != list(shape)):
+ * raise ValueError('The <shape> value does not match' # <<<<<<<<<<<<<<
+ * 'the <weighted_histo> shape.')
+ * else:
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_The_shape_value_does_not_matchth_2); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+
+ /* "chistogramnd_lut.pyx":248
+ * if weighted_histo is not None:
+ * if histo.shape != weighted_histo.shape:
+ * raise ValueError('The <histo> shape does not match' # <<<<<<<<<<<<<<
+ * 'the <weighted_histo> shape.')
+ * else:
+ */
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_The_histo_shape_does_not_matchth); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+
+ /* "chistogramnd_lut.pyx":262
+ * elif weighted_histo is not None:
+ * if weighted_histo.dtype != dtype:
+ * raise ValueError('Provided <dtype> and <weighted_histo>\'s dtype' # <<<<<<<<<<<<<<
+ * ' do not match.')
+ * dtype = weighted_histo.dtype
+ */
+ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_Provided_dtype_and_weighted_hist); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__12);
+ __Pyx_GIVEREF(__pyx_tuple__12);
+
+ /* "chistogramnd_lut.pyx":270
+ *
+ * if histo_lut.size != weights.size:
+ * raise ValueError('The LUT and weights arrays must have the same ' # <<<<<<<<<<<<<<
+ * 'number of elements.')
+ *
+ */
+ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_The_LUT_and_weights_arrays_must); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__13);
+ __Pyx_GIVEREF(__pyx_tuple__13);
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s__14); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s__16); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_No_matching_signature_found); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+ __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_Function_call_with_ambiguous_arg); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__19);
+ __Pyx_GIVEREF(__pyx_tuple__19);
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s__14); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+ __pyx_tuple__21 = PyTuple_Pack(1, __pyx_kp_s__16); if (unlikely(!__pyx_tuple__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__21);
+ __Pyx_GIVEREF(__pyx_tuple__21);
+ __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_No_matching_signature_found); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__22);
+ __Pyx_GIVEREF(__pyx_tuple__22);
+ __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_Function_call_with_ambiguous_arg); if (unlikely(!__pyx_tuple__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__23);
+ __Pyx_GIVEREF(__pyx_tuple__23);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__24);
+ __Pyx_GIVEREF(__pyx_tuple__24);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__25);
+ __Pyx_GIVEREF(__pyx_tuple__25);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__26);
+ __Pyx_GIVEREF(__pyx_tuple__26);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__27)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__27);
+ __Pyx_GIVEREF(__pyx_tuple__27);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__28)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__28);
+ __Pyx_GIVEREF(__pyx_tuple__28);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__29)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__29);
+ __Pyx_GIVEREF(__pyx_tuple__29);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__30)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__30);
+ __Pyx_GIVEREF(__pyx_tuple__30);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__31)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__31);
+ __Pyx_GIVEREF(__pyx_tuple__31);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__32)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__32);
+ __Pyx_GIVEREF(__pyx_tuple__32);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__33 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__33);
+ __Pyx_GIVEREF(__pyx_tuple__33);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__34 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__34)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__34);
+ __Pyx_GIVEREF(__pyx_tuple__34);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__35 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__35)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__35);
+ __Pyx_GIVEREF(__pyx_tuple__35);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__36 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__36)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__36);
+ __Pyx_GIVEREF(__pyx_tuple__36);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__37 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__37)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__37);
+ __Pyx_GIVEREF(__pyx_slice__37);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__38 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__38)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__38);
+ __Pyx_GIVEREF(__pyx_slice__38);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__39 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__39)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__39);
+ __Pyx_GIVEREF(__pyx_slice__39);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__40 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__40)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__40);
+ __Pyx_GIVEREF(__pyx_tuple__40);
+
+ /* "chistogramnd_lut.pyx":58
+ *
+ *
+ * def histogramnd_get_lut(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+ __pyx_tuple__41 = PyTuple_Pack(25, __pyx_n_s_sample, __pyx_n_s_histo_range, __pyx_n_s_n_bins, __pyx_n_s_last_bin_closed, __pyx_n_s_s_shape, __pyx_n_s_n_dims, __pyx_n_s_i_histo_range, __pyx_n_s_err_histo_range, __pyx_n_s_sample_type, __pyx_n_s_n_elem, __pyx_n_s_lut_dtype, __pyx_n_s_lut, __pyx_n_s_histo, __pyx_n_s_sample_c, __pyx_n_s_histo_range_c, __pyx_n_s_n_bins_c, __pyx_n_s_lut_c, __pyx_n_s_histo_c, __pyx_n_s_rc, __pyx_n_s_ex, __pyx_n_s_edges, __pyx_n_s_i_dim, __pyx_n_s_dim_edges, __pyx_n_s_rng_min, __pyx_n_s_rng_max); if (unlikely(!__pyx_tuple__41)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__41);
+ __Pyx_GIVEREF(__pyx_tuple__41);
+ __pyx_codeobj__42 = (PyObject*)__Pyx_PyCode_New(4, 0, 25, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__41, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_histogramnd_get_lut, 58, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__42)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd_lut.pyx":206
+ *
+ *
+ * def histogramnd_from_lut(weights, # <<<<<<<<<<<<<<
+ * histo_lut,
+ * histo=None,
+ */
+ __pyx_tuple__43 = PyTuple_Pack(17, __pyx_n_s_weights, __pyx_n_s_histo_lut, __pyx_n_s_histo, __pyx_n_s_weighted_histo, __pyx_n_s_shape, __pyx_n_s_dtype, __pyx_n_s_weight_min, __pyx_n_s_weight_max, __pyx_n_s_w_dtype, __pyx_n_s_w_c, __pyx_n_s_h_c, __pyx_n_s_w_h_c, __pyx_n_s_h_lut_c, __pyx_n_s_rc, __pyx_n_s_filt_min_weights, __pyx_n_s_filt_max_weights, __pyx_n_s_ex); if (unlikely(!__pyx_tuple__43)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__43);
+ __Pyx_GIVEREF(__pyx_tuple__43);
+ __pyx_codeobj__44 = (PyObject*)__Pyx_PyCode_New(8, 0, 17, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__43, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_histogramnd_from_lut, 206, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+ __pyx_tuple__45 = PyTuple_Pack(10, __pyx_n_s_i_weights, __pyx_n_s_i_lut, __pyx_n_s_o_histo, __pyx_n_s_o_weighted_histo, __pyx_n_s_i_n_elems, __pyx_n_s_i_filt_min_weights, __pyx_n_s_i_weight_min, __pyx_n_s_i_filt_max_weights, __pyx_n_s_i_weight_max, __pyx_n_s_i); if (unlikely(!__pyx_tuple__45)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__45);
+ __Pyx_GIVEREF(__pyx_tuple__45);
+ __pyx_codeobj__46 = (PyObject*)__Pyx_PyCode_New(9, 0, 10, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__45, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_histogramnd_from_lut_fused, 323, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+ __pyx_tuple__47 = PyTuple_Pack(17, __pyx_n_s_i_sample, __pyx_n_s_i_n_dims, __pyx_n_s_i_n_elems, __pyx_n_s_i_histo_range, __pyx_n_s_i_n_bins, __pyx_n_s_o_lut, __pyx_n_s_o_histo, __pyx_n_s_last_bin_closed, __pyx_n_s_i, __pyx_n_s_elem_idx, __pyx_n_s_max_idx, __pyx_n_s_lut_idx, __pyx_n_s_bin_idx, __pyx_n_s_elem_coord, __pyx_n_s_g_min, __pyx_n_s_g_max, __pyx_n_s_bins_range); if (unlikely(!__pyx_tuple__47)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__47);
+ __Pyx_GIVEREF(__pyx_tuple__47);
+ __pyx_codeobj__48 = (PyObject*)__Pyx_PyCode_New(8, 0, 17, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__47, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_mntdirect__scisoft_users_tvince, __pyx_n_s_histogramnd_get_lut_fused, 352, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__48)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__49 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__49)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__49);
+ __Pyx_GIVEREF(__pyx_tuple__49);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__50 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__50)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__50);
+ __Pyx_GIVEREF(__pyx_tuple__50);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__51 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__51)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__51);
+ __Pyx_GIVEREF(__pyx_tuple__51);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__52 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__52)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__52);
+ __Pyx_GIVEREF(__pyx_tuple__52);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__53 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__53)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__53);
+ __Pyx_GIVEREF(__pyx_tuple__53);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_32768 = PyInt_FromLong(32768L); if (unlikely(!__pyx_int_32768)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_2147483648 = PyInt_FromString((char *)"2147483648", 0, 0); if (unlikely(!__pyx_int_2147483648)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initchistogramnd_lut(void); /*proto*/
+PyMODINIT_FUNC initchistogramnd_lut(void)
+#else
+PyMODINIT_FUNC PyInit_chistogramnd_lut(void); /*proto*/
+PyMODINIT_FUNC PyInit_chistogramnd_lut(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_chistogramnd_lut(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("chistogramnd_lut", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_chistogramnd_lut) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "chistogramnd_lut")) {
+ if (unlikely(PyDict_SetItemString(modules, "chistogramnd_lut", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type",
+ #if CYTHON_COMPILING_IN_PYPY
+ sizeof(PyTypeObject),
+ #else
+ sizeof(PyHeapTypeObject),
+ #endif
+ 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "chistogramnd_lut.pyx":25
+ * # ############################################################################*[inserted by cython to avoid comment closer]/
+ *
+ * __authors__ = ["D. Naudet"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "15/05/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_D_Naudet);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_D_Naudet);
+ __Pyx_GIVEREF(__pyx_kp_s_D_Naudet);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 25; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":26
+ *
+ * __authors__ = ["D. Naudet"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "15/05/2016"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 26; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd_lut.pyx":27
+ * __authors__ = ["D. Naudet"]
+ * __license__ = "MIT"
+ * __date__ = "15/05/2016" # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_15_05_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "chistogramnd_lut.pyx":32
+ * cimport numpy as np # noqa
+ * cimport cython
+ * import numpy as np # <<<<<<<<<<<<<<
+ *
+ * ctypedef fused sample_t:
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":58
+ *
+ *
+ * def histogramnd_get_lut(sample, # <<<<<<<<<<<<<<
+ * histo_range,
+ * n_bins,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_16chistogramnd_lut_1histogramnd_get_lut, NULL, __pyx_n_s_chistogramnd_lut); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_histogramnd_get_lut, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":206
+ *
+ *
+ * def histogramnd_from_lut(weights, # <<<<<<<<<<<<<<
+ * histo_lut,
+ * histo=None,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_16chistogramnd_lut_3histogramnd_from_lut, NULL, __pyx_n_s_chistogramnd_lut); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_histogramnd_from_lut, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "chistogramnd_lut.pyx":323
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_from_lut_fused(weights_t[:] i_weights, # <<<<<<<<<<<<<<
+ * lut_t[:] i_lut,
+ * np.uint32_t[:] o_histo,
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_0_0__pyx_mdef_16chistogramnd_lut_9_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int64_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_0_1__pyx_mdef_16chistogramnd_lut_11_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int64_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_0_2__pyx_mdef_16chistogramnd_lut_13_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int64_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_0_3__pyx_mdef_16chistogramnd_lut_15_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int64_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_1_0__pyx_mdef_16chistogramnd_lut_17_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int32_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_1_1__pyx_mdef_16chistogramnd_lut_19_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int32_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_1_2__pyx_mdef_16chistogramnd_lut_21_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int32_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_1_3__pyx_mdef_16chistogramnd_lut_23_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int32_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_2_0__pyx_mdef_16chistogramnd_lut_25_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int16_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_2_1__pyx_mdef_16chistogramnd_lut_27_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int16_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_2_2__pyx_mdef_16chistogramnd_lut_29_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int16_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_2_3__pyx_mdef_16chistogramnd_lut_31_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float64_t_int16_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_0_0__pyx_mdef_16chistogramnd_lut_33_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int64_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_0_1__pyx_mdef_16chistogramnd_lut_35_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int64_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_0_2__pyx_mdef_16chistogramnd_lut_37_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int64_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_0_3__pyx_mdef_16chistogramnd_lut_39_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int64_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_1_0__pyx_mdef_16chistogramnd_lut_41_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int32_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_1_1__pyx_mdef_16chistogramnd_lut_43_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int32_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_1_2__pyx_mdef_16chistogramnd_lut_45_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int32_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_1_3__pyx_mdef_16chistogramnd_lut_47_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int32_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_2_0__pyx_mdef_16chistogramnd_lut_49_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int16_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_2_1__pyx_mdef_16chistogramnd_lut_51_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int16_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_2_2__pyx_mdef_16chistogramnd_lut_53_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int16_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_2_3__pyx_mdef_16chistogramnd_lut_55_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_float32_t_int16_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_0_0__pyx_mdef_16chistogramnd_lut_57_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int64_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_0_1__pyx_mdef_16chistogramnd_lut_59_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int64_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_0_2__pyx_mdef_16chistogramnd_lut_61_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int64_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_0_3__pyx_mdef_16chistogramnd_lut_63_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int64_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_1_0__pyx_mdef_16chistogramnd_lut_65_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int32_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_1_1__pyx_mdef_16chistogramnd_lut_67_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int32_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_1_2__pyx_mdef_16chistogramnd_lut_69_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int32_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_1_3__pyx_mdef_16chistogramnd_lut_71_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int32_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_2_0__pyx_mdef_16chistogramnd_lut_73_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int16_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_2_1__pyx_mdef_16chistogramnd_lut_75_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int16_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_2_2__pyx_mdef_16chistogramnd_lut_77_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int16_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_2_3__pyx_mdef_16chistogramnd_lut_79_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int32_t_int16_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_0_0__pyx_mdef_16chistogramnd_lut_81_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int64_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_0_1__pyx_mdef_16chistogramnd_lut_83_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int64_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_0_2__pyx_mdef_16chistogramnd_lut_85_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int64_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_0_3__pyx_mdef_16chistogramnd_lut_87_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int64_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_1_0__pyx_mdef_16chistogramnd_lut_89_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int32_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_1_1__pyx_mdef_16chistogramnd_lut_91_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int32_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_1_2__pyx_mdef_16chistogramnd_lut_93_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int32_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_1_3__pyx_mdef_16chistogramnd_lut_95_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int32_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_2_0__pyx_mdef_16chistogramnd_lut_97_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int16_t_float64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_2_1__pyx_mdef_16chistogramnd_lut_99_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int16_t_float32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_2_2__pyx_mdef_16chistogramnd_lut_101_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int16_t_int32_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_2_3__pyx_mdef_16chistogramnd_lut_103_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_1, __pyx_kp_s_int64_t_int16_t_int64_t, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_FusedFunction_NewEx(&__pyx_mdef_16chistogramnd_lut_5_histogramnd_from_lut_fused, 0, __pyx_n_s_histogramnd_from_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__46)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_2, __pyx_empty_tuple);
+ ((__pyx_FusedFunctionObject *) __pyx_t_2)->__signatures__ = __pyx_t_1;
+ __Pyx_GIVEREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_histogramnd_from_lut_fused, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 323; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "chistogramnd_lut.pyx":352
+ * @cython.nonecheck(False)
+ * @cython.cdivision(True)
+ * def _histogramnd_get_lut_fused(sample_t[:] i_sample, # <<<<<<<<<<<<<<
+ * int i_n_dims,
+ * int i_n_elems,
+ */
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_0__pyx_mdef_16chistogramnd_lut_107_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_float64_t_int64_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_1__pyx_mdef_16chistogramnd_lut_109_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_float64_t_int32_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_0_2__pyx_mdef_16chistogramnd_lut_111_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_float64_t_int16_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_0__pyx_mdef_16chistogramnd_lut_113_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_float32_t_int64_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_1__pyx_mdef_16chistogramnd_lut_115_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_float32_t_int32_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_1_2__pyx_mdef_16chistogramnd_lut_117_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_float32_t_int16_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_0__pyx_mdef_16chistogramnd_lut_119_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_int32_t_int64_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_1__pyx_mdef_16chistogramnd_lut_121_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_int32_t_int32_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_2_2__pyx_mdef_16chistogramnd_lut_123_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_int32_t_int16_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_0__pyx_mdef_16chistogramnd_lut_125_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_int64_t_int64_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_1__pyx_mdef_16chistogramnd_lut_127_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_int64_t_int32_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_fuse_3_2__pyx_mdef_16chistogramnd_lut_129_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ if (PyDict_SetItem(__pyx_t_3, __pyx_kp_s_int64_t_int16_t, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __pyx_FusedFunction_NewEx(&__pyx_mdef_16chistogramnd_lut_7_histogramnd_get_lut_fused, 0, __pyx_n_s_histogramnd_get_lut_fused, NULL, __pyx_n_s_chistogramnd_lut, __pyx_d, ((PyObject *)__pyx_codeobj__48)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_empty_tuple);
+ ((__pyx_FusedFunctionObject *) __pyx_t_4)->__signatures__ = __pyx_t_3;
+ __Pyx_GIVEREF(__pyx_t_3);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_histogramnd_get_lut_fused, __pyx_t_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "chistogramnd_lut.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * # /[inserted by cython to avoid comment start]*##########################################################################
+ * # Copyright (C) 2016-2017 European Synchrotron Radiation Facility
+ */
+ __pyx_t_5 = PyDict_New(); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_5 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__49, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__50, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__51, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__52, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__53, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "__pyxutil":2
+ *
+ * cdef extern from *: # <<<<<<<<<<<<<<
+ * void __pyx_PyErr_Clear "PyErr_Clear" ()
+ * __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(object)
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init chistogramnd_lut", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init chistogramnd_lut");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(
+ PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop,
+ PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
+ int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyMappingMethods* mp;
+#if PY_MAJOR_VERSION < 3
+ PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
+ if (likely(ms && ms->sq_ass_slice)) {
+ if (!has_cstart) {
+ if (_py_start && (*_py_start != Py_None)) {
+ cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
+ if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+ } else
+ cstart = 0;
+ }
+ if (!has_cstop) {
+ if (_py_stop && (*_py_stop != Py_None)) {
+ cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
+ if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+ } else
+ cstop = PY_SSIZE_T_MAX;
+ }
+ if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
+ Py_ssize_t l = ms->sq_length(obj);
+ if (likely(l >= 0)) {
+ if (cstop < 0) {
+ cstop += l;
+ if (cstop < 0) cstop = 0;
+ }
+ if (cstart < 0) {
+ cstart += l;
+ if (cstart < 0) cstart = 0;
+ }
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ goto bad;
+ }
+ }
+ return ms->sq_ass_slice(obj, cstart, cstop, value);
+ }
+#endif
+ mp = Py_TYPE(obj)->tp_as_mapping;
+ if (likely(mp && mp->mp_ass_subscript))
+#endif
+ {
+ int result;
+ PyObject *py_slice, *py_start, *py_stop;
+ if (_py_slice) {
+ py_slice = *_py_slice;
+ } else {
+ PyObject* owned_start = NULL;
+ PyObject* owned_stop = NULL;
+ if (_py_start) {
+ py_start = *_py_start;
+ } else {
+ if (has_cstart) {
+ owned_start = py_start = PyInt_FromSsize_t(cstart);
+ if (unlikely(!py_start)) goto bad;
+ } else
+ py_start = Py_None;
+ }
+ if (_py_stop) {
+ py_stop = *_py_stop;
+ } else {
+ if (has_cstop) {
+ owned_stop = py_stop = PyInt_FromSsize_t(cstop);
+ if (unlikely(!py_stop)) {
+ Py_XDECREF(owned_start);
+ goto bad;
+ }
+ } else
+ py_stop = Py_None;
+ }
+ py_slice = PySlice_New(py_start, py_stop, Py_None);
+ Py_XDECREF(owned_start);
+ Py_XDECREF(owned_stop);
+ if (unlikely(!py_slice)) goto bad;
+ }
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = mp->mp_ass_subscript(obj, py_slice, value);
+#else
+ result = value ? PyObject_SetItem(obj, py_slice, value) : PyObject_DelItem(obj, py_slice);
+#endif
+ if (!_py_slice) {
+ Py_DECREF(py_slice);
+ }
+ return result;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "'%.200s' object does not support slice %.10s",
+ Py_TYPE(obj)->tp_name, value ? "assignment" : "deletion");
+bad:
+ return -1;
+}
+
+static CYTHON_INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) {
+ int r;
+ if (!j) return -1;
+ r = PyObject_SetItem(o, j, v);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = (!wraparound) ? i : ((likely(i >= 0)) ? i : i + PyList_GET_SIZE(o));
+ if ((!boundscheck) || likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
+ PyObject* old = PyList_GET_ITEM(o, n);
+ Py_INCREF(v);
+ PyList_SET_ITEM(o, n, v);
+ Py_DECREF(old);
+ return 1;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_ass_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return -1;
+ }
+ }
+ return m->sq_ass_item(o, i, v);
+ }
+ }
+#else
+#if CYTHON_COMPILING_IN_PYPY
+ if (is_list || (PySequence_Check(o) && !PyDict_Check(o))) {
+#else
+ if (is_list || PySequence_Check(o)) {
+#endif
+ return PySequence_SetItem(o, i, v);
+ }
+#endif
+ return __Pyx_SetItemInt_Generic(o, PyInt_FromSsize_t(i), v);
+}
+
+static CYTHON_INLINE int __Pyx_IterFinish(void) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* exc_type = tstate->curexc_type;
+ if (unlikely(exc_type)) {
+ if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
+ PyObject *exc_value, *exc_tb;
+ exc_value = tstate->curexc_value;
+ exc_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+ Py_DECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(exc_tb);
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#else
+ if (unlikely(PyErr_Occurred())) {
+ if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
+ PyErr_Clear();
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) {
+ PyObject *method, *result = NULL;
+ method = __Pyx_PyObject_GetAttrStr(obj, method_name);
+ if (unlikely(!method)) goto bad;
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (likely(PyMethod_Check(method))) {
+ PyObject *self = PyMethod_GET_SELF(method);
+ if (likely(self)) {
+ PyObject *function = PyMethod_GET_FUNCTION(method);
+ result = __Pyx_PyObject_CallOneArg(function, self);
+ Py_DECREF(method);
+ return result;
+ }
+ }
+#endif
+ result = __Pyx_PyObject_CallNoArg(method);
+ Py_DECREF(method);
+bad:
+ return result;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
+ if (unlikely(retval)) {
+ Py_DECREF(retval);
+ __Pyx_RaiseTooManyValuesError(expected);
+ return -1;
+ } else {
+ return __Pyx_IterFinish();
+ }
+ return 0;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) {
+ if (t == Py_None) {
+ __Pyx_RaiseNoneNotIterableError();
+ } else if (PyTuple_GET_SIZE(t) < index) {
+ __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t));
+ } else {
+ __Pyx_RaiseTooManyValuesError(index);
+ }
+}
+
+static CYTHON_INLINE int __Pyx_unpack_tuple2(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2,
+ int is_tuple, int has_known_size, int decref_tuple) {
+ Py_ssize_t index;
+ PyObject *value1 = NULL, *value2 = NULL, *iter = NULL;
+ if (!is_tuple && unlikely(!PyTuple_Check(tuple))) {
+ iternextfunc iternext;
+ iter = PyObject_GetIter(tuple);
+ if (unlikely(!iter)) goto bad;
+ if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; }
+ iternext = Py_TYPE(iter)->tp_iternext;
+ value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; }
+ value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; }
+ if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad;
+ Py_DECREF(iter);
+ } else {
+ if (!has_known_size && unlikely(PyTuple_GET_SIZE(tuple) != 2)) {
+ __Pyx_UnpackTupleError(tuple, 2);
+ goto bad;
+ }
+#if CYTHON_COMPILING_IN_PYPY
+ value1 = PySequence_ITEM(tuple, 0);
+ if (unlikely(!value1)) goto bad;
+ value2 = PySequence_ITEM(tuple, 1);
+ if (unlikely(!value2)) goto bad;
+#else
+ value1 = PyTuple_GET_ITEM(tuple, 0);
+ value2 = PyTuple_GET_ITEM(tuple, 1);
+ Py_INCREF(value1);
+ Py_INCREF(value2);
+#endif
+ if (decref_tuple) { Py_DECREF(tuple); }
+ }
+ *pvalue1 = value1;
+ *pvalue2 = value2;
+ return 0;
+unpacking_failed:
+ if (!has_known_size && __Pyx_IterFinish() == 0)
+ __Pyx_RaiseNeedMoreValuesError(index);
+bad:
+ Py_XDECREF(iter);
+ Py_XDECREF(value1);
+ Py_XDECREF(value2);
+ if (decref_tuple) { Py_XDECREF(tuple); }
+ return -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name,
+ Py_ssize_t* p_orig_length, int* p_source_is_dict) {
+ is_dict = is_dict || likely(PyDict_CheckExact(iterable));
+ *p_source_is_dict = is_dict;
+#if !CYTHON_COMPILING_IN_PYPY
+ if (is_dict) {
+ *p_orig_length = PyDict_Size(iterable);
+ Py_INCREF(iterable);
+ return iterable;
+ }
+#endif
+ *p_orig_length = 0;
+ if (method_name) {
+ PyObject* iter;
+ iterable = __Pyx_PyObject_CallMethod0(iterable, method_name);
+ if (!iterable)
+ return NULL;
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable))
+ return iterable;
+#endif
+ iter = PyObject_GetIter(iterable);
+ Py_DECREF(iterable);
+ return iter;
+ }
+ return PyObject_GetIter(iterable);
+}
+static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* iter_obj, Py_ssize_t orig_length, Py_ssize_t* ppos,
+ PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) {
+ PyObject* next_item;
+#if !CYTHON_COMPILING_IN_PYPY
+ if (source_is_dict) {
+ PyObject *key, *value;
+ if (unlikely(orig_length != PyDict_Size(iter_obj))) {
+ PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration");
+ return -1;
+ }
+ if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) {
+ return 0;
+ }
+ if (pitem) {
+ PyObject* tuple = PyTuple_New(2);
+ if (unlikely(!tuple)) {
+ return -1;
+ }
+ Py_INCREF(key);
+ Py_INCREF(value);
+ PyTuple_SET_ITEM(tuple, 0, key);
+ PyTuple_SET_ITEM(tuple, 1, value);
+ *pitem = tuple;
+ } else {
+ if (pkey) {
+ Py_INCREF(key);
+ *pkey = key;
+ }
+ if (pvalue) {
+ Py_INCREF(value);
+ *pvalue = value;
+ }
+ }
+ return 1;
+ } else if (PyTuple_CheckExact(iter_obj)) {
+ Py_ssize_t pos = *ppos;
+ if (unlikely(pos >= PyTuple_GET_SIZE(iter_obj))) return 0;
+ *ppos = pos + 1;
+ next_item = PyTuple_GET_ITEM(iter_obj, pos);
+ Py_INCREF(next_item);
+ } else if (PyList_CheckExact(iter_obj)) {
+ Py_ssize_t pos = *ppos;
+ if (unlikely(pos >= PyList_GET_SIZE(iter_obj))) return 0;
+ *ppos = pos + 1;
+ next_item = PyList_GET_ITEM(iter_obj, pos);
+ Py_INCREF(next_item);
+ } else
+#endif
+ {
+ next_item = PyIter_Next(iter_obj);
+ if (unlikely(!next_item)) {
+ return __Pyx_IterFinish();
+ }
+ }
+ if (pitem) {
+ *pitem = next_item;
+ } else if (pkey && pvalue) {
+ if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1))
+ return -1;
+ } else if (pkey) {
+ *pkey = next_item;
+ } else {
+ *pvalue = next_item;
+ }
+ return 1;
+}
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+static PyTypeObject* __Pyx_FetchCommonType(PyTypeObject* type) {
+ PyObject* fake_module;
+ PyTypeObject* cached_type = NULL;
+ fake_module = PyImport_AddModule((char*) "_cython_" CYTHON_ABI);
+ if (!fake_module) return NULL;
+ Py_INCREF(fake_module);
+ cached_type = (PyTypeObject*) PyObject_GetAttrString(fake_module, type->tp_name);
+ if (cached_type) {
+ if (!PyType_Check((PyObject*)cached_type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s is not a type object",
+ type->tp_name);
+ goto bad;
+ }
+ if (cached_type->tp_basicsize != type->tp_basicsize) {
+ PyErr_Format(PyExc_TypeError,
+ "Shared Cython type %.200s has the wrong size, try recompiling",
+ type->tp_name);
+ goto bad;
+ }
+ } else {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError)) goto bad;
+ PyErr_Clear();
+ if (PyType_Ready(type) < 0) goto bad;
+ if (PyObject_SetAttrString(fake_module, type->tp_name, (PyObject*) type) < 0)
+ goto bad;
+ Py_INCREF(type);
+ cached_type = type;
+ }
+done:
+ Py_DECREF(fake_module);
+ return cached_type;
+bad:
+ Py_XDECREF(cached_type);
+ cached_type = NULL;
+ goto done;
+}
+
+static PyObject *
+__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, CYTHON_UNUSED void *closure)
+{
+ if (unlikely(op->func_doc == NULL)) {
+ if (op->func.m_ml->ml_doc) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_doc = PyUnicode_FromString(op->func.m_ml->ml_doc);
+#else
+ op->func_doc = PyString_FromString(op->func.m_ml->ml_doc);
+#endif
+ if (unlikely(op->func_doc == NULL))
+ return NULL;
+ } else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+ Py_INCREF(op->func_doc);
+ return op->func_doc;
+}
+static int
+__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp = op->func_doc;
+ if (value == NULL) {
+ value = Py_None;
+ }
+ Py_INCREF(value);
+ op->func_doc = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_name == NULL)) {
+#if PY_MAJOR_VERSION >= 3
+ op->func_name = PyUnicode_InternFromString(op->func.m_ml->ml_name);
+#else
+ op->func_name = PyString_InternFromString(op->func.m_ml->ml_name);
+#endif
+ if (unlikely(op->func_name == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_name);
+ return op->func_name;
+}
+static int
+__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__name__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_name;
+ Py_INCREF(value);
+ op->func_name = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_qualname);
+ return op->func_qualname;
+}
+static int
+__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+#if PY_MAJOR_VERSION >= 3
+ if (unlikely(value == NULL || !PyUnicode_Check(value))) {
+#else
+ if (unlikely(value == NULL || !PyString_Check(value))) {
+#endif
+ PyErr_SetString(PyExc_TypeError,
+ "__qualname__ must be set to a string object");
+ return -1;
+ }
+ tmp = op->func_qualname;
+ Py_INCREF(value);
+ op->func_qualname = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_self(__pyx_CyFunctionObject *m, CYTHON_UNUSED void *closure)
+{
+ PyObject *self;
+ self = m->func_closure;
+ if (self == NULL)
+ self = Py_None;
+ Py_INCREF(self);
+ return self;
+}
+static PyObject *
+__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op)
+{
+ if (unlikely(op->func_dict == NULL)) {
+ op->func_dict = PyDict_New();
+ if (unlikely(op->func_dict == NULL))
+ return NULL;
+ }
+ Py_INCREF(op->func_dict);
+ return op->func_dict;
+}
+static int
+__Pyx_CyFunction_set_dict(__pyx_CyFunctionObject *op, PyObject *value)
+{
+ PyObject *tmp;
+ if (unlikely(value == NULL)) {
+ PyErr_SetString(PyExc_TypeError,
+ "function's dictionary may not be deleted");
+ return -1;
+ }
+ if (unlikely(!PyDict_Check(value))) {
+ PyErr_SetString(PyExc_TypeError,
+ "setting function's dictionary to a non-dict");
+ return -1;
+ }
+ tmp = op->func_dict;
+ Py_INCREF(value);
+ op->func_dict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op)
+{
+ Py_INCREF(op->func_globals);
+ return op->func_globals;
+}
+static PyObject *
+__Pyx_CyFunction_get_closure(CYTHON_UNUSED __pyx_CyFunctionObject *op)
+{
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+static PyObject *
+__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op)
+{
+ PyObject* result = (op->func_code) ? op->func_code : Py_None;
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) {
+ PyObject *res = op->defaults_getter((PyObject *) op);
+ if (unlikely(!res))
+ return -1;
+ op->defaults_tuple = PyTuple_GET_ITEM(res, 0);
+ Py_INCREF(op->defaults_tuple);
+ op->defaults_kwdict = PyTuple_GET_ITEM(res, 1);
+ Py_INCREF(op->defaults_kwdict);
+ Py_DECREF(res);
+ return 0;
+}
+static int
+__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyTuple_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__defaults__ must be set to a tuple object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_tuple;
+ op->defaults_tuple = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_tuple;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_tuple;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value) {
+ value = Py_None;
+ } else if (value != Py_None && !PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__kwdefaults__ must be set to a dict object");
+ return -1;
+ }
+ Py_INCREF(value);
+ tmp = op->defaults_kwdict;
+ op->defaults_kwdict = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->defaults_kwdict;
+ if (unlikely(!result)) {
+ if (op->defaults_getter) {
+ if (__Pyx_CyFunction_init_defaults(op) < 0) return NULL;
+ result = op->defaults_kwdict;
+ } else {
+ result = Py_None;
+ }
+ }
+ Py_INCREF(result);
+ return result;
+}
+static int
+__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value) {
+ PyObject* tmp;
+ if (!value || value == Py_None) {
+ value = NULL;
+ } else if (!PyDict_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "__annotations__ must be set to a dict object");
+ return -1;
+ }
+ Py_XINCREF(value);
+ tmp = op->func_annotations;
+ op->func_annotations = value;
+ Py_XDECREF(tmp);
+ return 0;
+}
+static PyObject *
+__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op) {
+ PyObject* result = op->func_annotations;
+ if (unlikely(!result)) {
+ result = PyDict_New();
+ if (unlikely(!result)) return NULL;
+ op->func_annotations = result;
+ }
+ Py_INCREF(result);
+ return result;
+}
+static PyGetSetDef __pyx_CyFunction_getsets[] = {
+ {(char *) "func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0},
+ {(char *) "func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0},
+ {(char *) "__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0},
+ {(char *) "__self__", (getter)__Pyx_CyFunction_get_self, 0, 0, 0},
+ {(char *) "func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)__Pyx_CyFunction_set_dict, 0, 0},
+ {(char *) "func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0},
+ {(char *) "func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0},
+ {(char *) "func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0},
+ {(char *) "func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0},
+ {(char *) "__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0},
+ {(char *) "__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+#ifndef PY_WRITE_RESTRICTED
+#define PY_WRITE_RESTRICTED WRITE_RESTRICTED
+#endif
+static PyMemberDef __pyx_CyFunction_members[] = {
+ {(char *) "__module__", T_OBJECT, offsetof(__pyx_CyFunctionObject, func.m_module), PY_WRITE_RESTRICTED, 0},
+ {0, 0, 0, 0, 0}
+};
+static PyObject *
+__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, CYTHON_UNUSED PyObject *args)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromString(m->func.m_ml->ml_name);
+#else
+ return PyString_FromString(m->func.m_ml->ml_name);
+#endif
+}
+static PyMethodDef __pyx_CyFunction_methods[] = {
+ {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0},
+ {0, 0, 0, 0}
+};
+#if PY_VERSION_HEX < 0x030500A0
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist)
+#else
+#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func.m_weakreflist)
+#endif
+static PyObject *__Pyx_CyFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags, PyObject* qualname,
+ PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) {
+ __pyx_CyFunctionObject *op = PyObject_GC_New(__pyx_CyFunctionObject, type);
+ if (op == NULL)
+ return NULL;
+ op->flags = flags;
+ __Pyx_CyFunction_weakreflist(op) = NULL;
+ op->func.m_ml = ml;
+ op->func.m_self = (PyObject *) op;
+ Py_XINCREF(closure);
+ op->func_closure = closure;
+ Py_XINCREF(module);
+ op->func.m_module = module;
+ op->func_dict = NULL;
+ op->func_name = NULL;
+ Py_INCREF(qualname);
+ op->func_qualname = qualname;
+ op->func_doc = NULL;
+ op->func_classobj = NULL;
+ op->func_globals = globals;
+ Py_INCREF(op->func_globals);
+ Py_XINCREF(code);
+ op->func_code = code;
+ op->defaults_pyobjects = 0;
+ op->defaults = NULL;
+ op->defaults_tuple = NULL;
+ op->defaults_kwdict = NULL;
+ op->defaults_getter = NULL;
+ op->func_annotations = NULL;
+ PyObject_GC_Track(op);
+ return (PyObject *) op;
+}
+static int
+__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m)
+{
+ Py_CLEAR(m->func_closure);
+ Py_CLEAR(m->func.m_module);
+ Py_CLEAR(m->func_dict);
+ Py_CLEAR(m->func_name);
+ Py_CLEAR(m->func_qualname);
+ Py_CLEAR(m->func_doc);
+ Py_CLEAR(m->func_globals);
+ Py_CLEAR(m->func_code);
+ Py_CLEAR(m->func_classobj);
+ Py_CLEAR(m->defaults_tuple);
+ Py_CLEAR(m->defaults_kwdict);
+ Py_CLEAR(m->func_annotations);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_XDECREF(pydefaults[i]);
+ PyMem_Free(m->defaults);
+ m->defaults = NULL;
+ }
+ return 0;
+}
+static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m)
+{
+ PyObject_GC_UnTrack(m);
+ if (__Pyx_CyFunction_weakreflist(m) != NULL)
+ PyObject_ClearWeakRefs((PyObject *) m);
+ __Pyx_CyFunction_clear(m);
+ PyObject_GC_Del(m);
+}
+static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg)
+{
+ Py_VISIT(m->func_closure);
+ Py_VISIT(m->func.m_module);
+ Py_VISIT(m->func_dict);
+ Py_VISIT(m->func_name);
+ Py_VISIT(m->func_qualname);
+ Py_VISIT(m->func_doc);
+ Py_VISIT(m->func_globals);
+ Py_VISIT(m->func_code);
+ Py_VISIT(m->func_classobj);
+ Py_VISIT(m->defaults_tuple);
+ Py_VISIT(m->defaults_kwdict);
+ if (m->defaults) {
+ PyObject **pydefaults = __Pyx_CyFunction_Defaults(PyObject *, m);
+ int i;
+ for (i = 0; i < m->defaults_pyobjects; i++)
+ Py_VISIT(pydefaults[i]);
+ }
+ return 0;
+}
+static PyObject *__Pyx_CyFunction_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ if (m->flags & __Pyx_CYFUNCTION_STATICMETHOD) {
+ Py_INCREF(func);
+ return func;
+ }
+ if (m->flags & __Pyx_CYFUNCTION_CLASSMETHOD) {
+ if (type == NULL)
+ type = (PyObject *)(Py_TYPE(obj));
+ return __Pyx_PyMethod_New(func, type, (PyObject *)(Py_TYPE(type)));
+ }
+ if (obj == Py_None)
+ obj = NULL;
+ return __Pyx_PyMethod_New(func, obj, type);
+}
+static PyObject*
+__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromFormat("<cyfunction %U at %p>",
+ op->func_qualname, (void *)op);
+#else
+ return PyString_FromFormat("<cyfunction %s at %p>",
+ PyString_AsString(op->func_qualname), (void *)op);
+#endif
+}
+#if CYTHON_COMPILING_IN_PYPY
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyCFunctionObject* f = (PyCFunctionObject*)func;
+ PyCFunction meth = PyCFunction_GET_FUNCTION(func);
+ PyObject *self = PyCFunction_GET_SELF(func);
+ Py_ssize_t size;
+ switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) {
+ case METH_VARARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0)
+ return (*meth)(self, arg);
+ break;
+ case METH_VARARGS | METH_KEYWORDS:
+ return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
+ case METH_NOARGS:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 0)
+ return (*meth)(self, NULL);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes no arguments (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ case METH_O:
+ if (likely(kw == NULL) || PyDict_Size(kw) == 0) {
+ size = PyTuple_GET_SIZE(arg);
+ if (size == 1)
+ return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes exactly one argument (%zd given)",
+ f->m_ml->ml_name, size);
+ return NULL;
+ }
+ break;
+ default:
+ PyErr_SetString(PyExc_SystemError, "Bad call flags in "
+ "__Pyx_CyFunction_Call. METH_OLDARGS is no "
+ "longer supported!");
+ return NULL;
+ }
+ PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+ f->m_ml->ml_name);
+ return NULL;
+}
+#else
+static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ return PyCFunction_Call(func, arg, kw);
+}
+#endif
+static PyTypeObject __pyx_CyFunctionType_type = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "cython_function_or_method",
+ sizeof(__pyx_CyFunctionObject),
+ 0,
+ (destructor) __Pyx_CyFunction_dealloc,
+ 0,
+ 0,
+ 0,
+#if PY_MAJOR_VERSION < 3
+ 0,
+#else
+ 0,
+#endif
+ (reprfunc) __Pyx_CyFunction_repr,
+ 0,
+ 0,
+ 0,
+ 0,
+ __Pyx_CyFunction_Call,
+ 0,
+ 0,
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ 0,
+ (traverseproc) __Pyx_CyFunction_traverse,
+ (inquiry) __Pyx_CyFunction_clear,
+ 0,
+#if PY_VERSION_HEX < 0x030500A0
+ offsetof(__pyx_CyFunctionObject, func_weakreflist),
+#else
+ offsetof(PyCFunctionObject, m_weakreflist),
+#endif
+ 0,
+ 0,
+ __pyx_CyFunction_methods,
+ __pyx_CyFunction_members,
+ __pyx_CyFunction_getsets,
+ 0,
+ 0,
+ __Pyx_CyFunction_descr_get,
+ 0,
+ offsetof(__pyx_CyFunctionObject, func_dict),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ 0,
+#endif
+};
+static int __Pyx_CyFunction_init(void) {
+#if !CYTHON_COMPILING_IN_PYPY
+ __pyx_CyFunctionType_type.tp_call = PyCFunction_Call;
+#endif
+ __pyx_CyFunctionType = __Pyx_FetchCommonType(&__pyx_CyFunctionType_type);
+ if (__pyx_CyFunctionType == NULL) {
+ return -1;
+ }
+ return 0;
+}
+static CYTHON_INLINE void *__Pyx_CyFunction_InitDefaults(PyObject *func, size_t size, int pyobjects) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults = PyMem_Malloc(size);
+ if (!m->defaults)
+ return PyErr_NoMemory();
+ memset(m->defaults, 0, size);
+ m->defaults_pyobjects = pyobjects;
+ return m->defaults;
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_tuple = tuple;
+ Py_INCREF(tuple);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->defaults_kwdict = dict;
+ Py_INCREF(dict);
+}
+static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) {
+ __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func;
+ m->func_annotations = dict;
+ Py_INCREF(dict);
+}
+
+static PyObject *
+__pyx_FusedFunction_New(PyTypeObject *type, PyMethodDef *ml, int flags,
+ PyObject *qualname, PyObject *self,
+ PyObject *module, PyObject *globals,
+ PyObject *code)
+{
+ __pyx_FusedFunctionObject *fusedfunc =
+ (__pyx_FusedFunctionObject *) __Pyx_CyFunction_New(type, ml, flags, qualname,
+ self, module, globals, code);
+ if (!fusedfunc)
+ return NULL;
+ fusedfunc->__signatures__ = NULL;
+ fusedfunc->type = NULL;
+ fusedfunc->self = NULL;
+ return (PyObject *) fusedfunc;
+}
+static void __pyx_FusedFunction_dealloc(__pyx_FusedFunctionObject *self) {
+ __pyx_FusedFunction_clear(self);
+ __pyx_FusedFunctionType->tp_free((PyObject *) self);
+}
+static int
+__pyx_FusedFunction_traverse(__pyx_FusedFunctionObject *self,
+ visitproc visit,
+ void *arg)
+{
+ Py_VISIT(self->self);
+ Py_VISIT(self->type);
+ Py_VISIT(self->__signatures__);
+ return __Pyx_CyFunction_traverse((__pyx_CyFunctionObject *) self, visit, arg);
+}
+static int
+__pyx_FusedFunction_clear(__pyx_FusedFunctionObject *self)
+{
+ Py_CLEAR(self->self);
+ Py_CLEAR(self->type);
+ Py_CLEAR(self->__signatures__);
+ return __Pyx_CyFunction_clear((__pyx_CyFunctionObject *) self);
+}
+static PyObject *
+__pyx_FusedFunction_descr_get(PyObject *self, PyObject *obj, PyObject *type)
+{
+ __pyx_FusedFunctionObject *func, *meth;
+ func = (__pyx_FusedFunctionObject *) self;
+ if (func->self || func->func.flags & __Pyx_CYFUNCTION_STATICMETHOD) {
+ Py_INCREF(self);
+ return self;
+ }
+ if (obj == Py_None)
+ obj = NULL;
+ meth = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_NewEx(
+ ((PyCFunctionObject *) func)->m_ml,
+ ((__pyx_CyFunctionObject *) func)->flags,
+ ((__pyx_CyFunctionObject *) func)->func_qualname,
+ ((__pyx_CyFunctionObject *) func)->func_closure,
+ ((PyCFunctionObject *) func)->m_module,
+ ((__pyx_CyFunctionObject *) func)->func_globals,
+ ((__pyx_CyFunctionObject *) func)->func_code);
+ if (!meth)
+ return NULL;
+ Py_XINCREF(func->func.func_classobj);
+ meth->func.func_classobj = func->func.func_classobj;
+ Py_XINCREF(func->__signatures__);
+ meth->__signatures__ = func->__signatures__;
+ Py_XINCREF(type);
+ meth->type = type;
+ Py_XINCREF(func->func.defaults_tuple);
+ meth->func.defaults_tuple = func->func.defaults_tuple;
+ if (func->func.flags & __Pyx_CYFUNCTION_CLASSMETHOD)
+ obj = type;
+ Py_XINCREF(obj);
+ meth->self = obj;
+ return (PyObject *) meth;
+}
+static PyObject *
+_obj_to_str(PyObject *obj)
+{
+ if (PyType_Check(obj))
+ return PyObject_GetAttr(obj, __pyx_n_s_name_2);
+ else
+ return PyObject_Str(obj);
+}
+static PyObject *
+__pyx_FusedFunction_getitem(__pyx_FusedFunctionObject *self, PyObject *idx)
+{
+ PyObject *signature = NULL;
+ PyObject *unbound_result_func;
+ PyObject *result_func = NULL;
+ if (self->__signatures__ == NULL) {
+ PyErr_SetString(PyExc_TypeError, "Function is not fused");
+ return NULL;
+ }
+ if (PyTuple_Check(idx)) {
+ PyObject *list = PyList_New(0);
+ Py_ssize_t n = PyTuple_GET_SIZE(idx);
+ PyObject *string = NULL;
+ PyObject *sep = NULL;
+ int i;
+ if (!list)
+ return NULL;
+ for (i = 0; i < n; i++) {
+ PyObject *item = PyTuple_GET_ITEM(idx, i);
+ string = _obj_to_str(item);
+ if (!string || PyList_Append(list, string) < 0)
+ goto __pyx_err;
+ Py_DECREF(string);
+ }
+ sep = PyUnicode_FromString("|");
+ if (sep)
+ signature = PyUnicode_Join(sep, list);
+__pyx_err:
+;
+ Py_DECREF(list);
+ Py_XDECREF(sep);
+ } else {
+ signature = _obj_to_str(idx);
+ }
+ if (!signature)
+ return NULL;
+ unbound_result_func = PyObject_GetItem(self->__signatures__, signature);
+ if (unbound_result_func) {
+ if (self->self || self->type) {
+ __pyx_FusedFunctionObject *unbound = (__pyx_FusedFunctionObject *) unbound_result_func;
+ Py_CLEAR(unbound->func.func_classobj);
+ Py_XINCREF(self->func.func_classobj);
+ unbound->func.func_classobj = self->func.func_classobj;
+ result_func = __pyx_FusedFunction_descr_get(unbound_result_func,
+ self->self, self->type);
+ } else {
+ result_func = unbound_result_func;
+ Py_INCREF(result_func);
+ }
+ }
+ Py_DECREF(signature);
+ Py_XDECREF(unbound_result_func);
+ return result_func;
+}
+static PyObject *
+__pyx_FusedFunction_callfunction(PyObject *func, PyObject *args, PyObject *kw)
+{
+ __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func;
+ PyObject *result;
+ int static_specialized = (cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD &&
+ !((__pyx_FusedFunctionObject *) func)->__signatures__);
+ if (cyfunc->flags & __Pyx_CYFUNCTION_CCLASS && !static_specialized) {
+ Py_ssize_t argc;
+ PyObject *new_args;
+ PyObject *self;
+ PyObject *m_self;
+ argc = PyTuple_GET_SIZE(args);
+ new_args = PyTuple_GetSlice(args, 1, argc);
+ if (!new_args)
+ return NULL;
+ self = PyTuple_GetItem(args, 0);
+ if (!self)
+ return NULL;
+ m_self = cyfunc->func.m_self;
+ cyfunc->func.m_self = self;
+ result = __Pyx_CyFunction_Call(func, new_args, kw);
+ cyfunc->func.m_self = m_self;
+ Py_DECREF(new_args);
+ } else {
+ result = __Pyx_CyFunction_Call(func, args, kw);
+ }
+ return result;
+}
+static PyObject *
+__pyx_FusedFunction_call(PyObject *func, PyObject *args, PyObject *kw)
+{
+ __pyx_FusedFunctionObject *binding_func = (__pyx_FusedFunctionObject *) func;
+ Py_ssize_t argc = PyTuple_GET_SIZE(args);
+ PyObject *new_args = NULL;
+ __pyx_FusedFunctionObject *new_func = NULL;
+ PyObject *result = NULL;
+ PyObject *self = NULL;
+ int is_staticmethod = binding_func->func.flags & __Pyx_CYFUNCTION_STATICMETHOD;
+ int is_classmethod = binding_func->func.flags & __Pyx_CYFUNCTION_CLASSMETHOD;
+ if (binding_func->self) {
+ Py_ssize_t i;
+ new_args = PyTuple_New(argc + 1);
+ if (!new_args)
+ return NULL;
+ self = binding_func->self;
+ Py_INCREF(self);
+ PyTuple_SET_ITEM(new_args, 0, self);
+ for (i = 0; i < argc; i++) {
+ PyObject *item = PyTuple_GET_ITEM(args, i);
+ Py_INCREF(item);
+ PyTuple_SET_ITEM(new_args, i + 1, item);
+ }
+ args = new_args;
+ } else if (binding_func->type) {
+ if (argc < 1) {
+ PyErr_SetString(PyExc_TypeError, "Need at least one argument, 0 given.");
+ return NULL;
+ }
+ self = PyTuple_GET_ITEM(args, 0);
+ }
+ if (self && !is_classmethod && !is_staticmethod &&
+ !PyObject_IsInstance(self, binding_func->type)) {
+ PyErr_Format(PyExc_TypeError,
+ "First argument should be of type %.200s, got %.200s.",
+ ((PyTypeObject *) binding_func->type)->tp_name,
+ self->ob_type->tp_name);
+ goto __pyx_err;
+ }
+ if (binding_func->__signatures__) {
+ PyObject *tup = PyTuple_Pack(4, binding_func->__signatures__, args,
+ kw == NULL ? Py_None : kw,
+ binding_func->func.defaults_tuple);
+ if (!tup)
+ goto __pyx_err;
+ new_func = (__pyx_FusedFunctionObject *) __pyx_FusedFunction_callfunction(func, tup, NULL);
+ Py_DECREF(tup);
+ if (!new_func)
+ goto __pyx_err;
+ Py_XINCREF(binding_func->func.func_classobj);
+ Py_CLEAR(new_func->func.func_classobj);
+ new_func->func.func_classobj = binding_func->func.func_classobj;
+ func = (PyObject *) new_func;
+ }
+ result = __pyx_FusedFunction_callfunction(func, args, kw);
+__pyx_err:
+ Py_XDECREF(new_args);
+ Py_XDECREF((PyObject *) new_func);
+ return result;
+}
+static PyMemberDef __pyx_FusedFunction_members[] = {
+ {(char *) "__signatures__",
+ T_OBJECT,
+ offsetof(__pyx_FusedFunctionObject, __signatures__),
+ READONLY,
+ 0},
+ {0, 0, 0, 0, 0},
+};
+static PyMappingMethods __pyx_FusedFunction_mapping_methods = {
+ 0,
+ (binaryfunc) __pyx_FusedFunction_getitem,
+ 0,
+};
+static PyTypeObject __pyx_FusedFunctionType_type = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "fused_cython_function",
+ sizeof(__pyx_FusedFunctionObject),
+ 0,
+ (destructor) __pyx_FusedFunction_dealloc,
+ 0,
+ 0,
+ 0,
+#if PY_MAJOR_VERSION < 3
+ 0,
+#else
+ 0,
+#endif
+ 0,
+ 0,
+ 0,
+ &__pyx_FusedFunction_mapping_methods,
+ 0,
+ (ternaryfunc) __pyx_FusedFunction_call,
+ 0,
+ 0,
+ 0,
+ 0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
+ 0,
+ (traverseproc) __pyx_FusedFunction_traverse,
+ (inquiry) __pyx_FusedFunction_clear,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_FusedFunction_members,
+ __pyx_CyFunction_getsets,
+ &__pyx_CyFunctionType_type,
+ 0,
+ __pyx_FusedFunction_descr_get,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if PY_VERSION_HEX >= 0x030400a1
+ 0,
+#endif
+};
+static int __pyx_FusedFunction_init(void) {
+ __pyx_FusedFunctionType = __Pyx_FetchCommonType(&__pyx_FusedFunctionType_type);
+ if (__pyx_FusedFunctionType == NULL) {
+ return -1;
+ }
+ return 0;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float64_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_float64_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_float32_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int32_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int64_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_int16_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_int16_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_nn___pyx_t_5numpy_uint32_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static CYTHON_INLINE npy_int32 __Pyx_PyInt_As_npy_int32(PyObject *x) {
+ const npy_int32 neg_one = (npy_int32) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(npy_int32) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (npy_int32) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(npy_int32, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(npy_int32) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(npy_int32) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(npy_int32, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(npy_int32, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(npy_int32) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, long, PyLong_AsLong(x))
+ } else if (sizeof(npy_int32) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int32, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ npy_int32 val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (npy_int32) -1;
+ }
+ } else {
+ npy_int32 val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (npy_int32) -1;
+ val = __Pyx_PyInt_As_npy_int32(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to npy_int32");
+ return (npy_int32) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to npy_int32");
+ return (npy_int32) -1;
+}
+
+static CYTHON_INLINE npy_int64 __Pyx_PyInt_As_npy_int64(PyObject *x) {
+ const npy_int64 neg_one = (npy_int64) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(npy_int64) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int64, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (npy_int64) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(npy_int64, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(npy_int64) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(npy_int64) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int64, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(npy_int64, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(npy_int64, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(npy_int64) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int64, long, PyLong_AsLong(x))
+ } else if (sizeof(npy_int64) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(npy_int64, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ npy_int64 val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (npy_int64) -1;
+ }
+ } else {
+ npy_int64 val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (npy_int64) -1;
+ val = __Pyx_PyInt_As_npy_int64(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to npy_int64");
+ return (npy_int64) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to npy_int64");
+ return (npy_int64) -1;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_double(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_double, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_int(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_int, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+#if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3
+static PyObject *__Pyx_GetStdout(void) {
+ PyObject *f = PySys_GetObject((char *)"stdout");
+ if (!f) {
+ PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
+ }
+ return f;
+}
+static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
+ int i;
+ if (!f) {
+ if (!(f = __Pyx_GetStdout()))
+ return -1;
+ }
+ Py_INCREF(f);
+ for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
+ PyObject* v;
+ if (PyFile_SoftSpace(f, 1)) {
+ if (PyFile_WriteString(" ", f) < 0)
+ goto error;
+ }
+ v = PyTuple_GET_ITEM(arg_tuple, i);
+ if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
+ goto error;
+ if (PyString_Check(v)) {
+ char *s = PyString_AsString(v);
+ Py_ssize_t len = PyString_Size(v);
+ if (len > 0) {
+ switch (s[len-1]) {
+ case ' ': break;
+ case '\f': case '\r': case '\n': case '\t': case '\v':
+ PyFile_SoftSpace(f, 0);
+ break;
+ default: break;
+ }
+ }
+ }
+ }
+ if (newline) {
+ if (PyFile_WriteString("\n", f) < 0)
+ goto error;
+ PyFile_SoftSpace(f, 0);
+ }
+ Py_DECREF(f);
+ return 0;
+error:
+ Py_DECREF(f);
+ return -1;
+}
+#else
+static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
+ PyObject* kwargs = 0;
+ PyObject* result = 0;
+ PyObject* end_string;
+ if (unlikely(!__pyx_print)) {
+ __pyx_print = PyObject_GetAttr(__pyx_b, __pyx_n_s_print);
+ if (!__pyx_print)
+ return -1;
+ }
+ if (stream) {
+ kwargs = PyDict_New();
+ if (unlikely(!kwargs))
+ return -1;
+ if (unlikely(PyDict_SetItem(kwargs, __pyx_n_s_file, stream) < 0))
+ goto bad;
+ if (!newline) {
+ end_string = PyUnicode_FromStringAndSize(" ", 1);
+ if (unlikely(!end_string))
+ goto bad;
+ if (PyDict_SetItem(kwargs, __pyx_n_s_end, end_string) < 0) {
+ Py_DECREF(end_string);
+ goto bad;
+ }
+ Py_DECREF(end_string);
+ }
+ } else if (!newline) {
+ if (unlikely(!__pyx_print_kwargs)) {
+ __pyx_print_kwargs = PyDict_New();
+ if (unlikely(!__pyx_print_kwargs))
+ return -1;
+ end_string = PyUnicode_FromStringAndSize(" ", 1);
+ if (unlikely(!end_string))
+ return -1;
+ if (PyDict_SetItem(__pyx_print_kwargs, __pyx_n_s_end, end_string) < 0) {
+ Py_DECREF(end_string);
+ return -1;
+ }
+ Py_DECREF(end_string);
+ }
+ kwargs = __pyx_print_kwargs;
+ }
+ result = PyObject_Call(__pyx_print, arg_tuple, kwargs);
+ if (unlikely(kwargs) && (kwargs != __pyx_print_kwargs))
+ Py_DECREF(kwargs);
+ if (!result)
+ return -1;
+ Py_DECREF(result);
+ return 0;
+bad:
+ if (kwargs != __pyx_print_kwargs)
+ Py_XDECREF(kwargs);
+ return -1;
+}
+#endif
+
+#if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3
+static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
+ if (!f) {
+ if (!(f = __Pyx_GetStdout()))
+ return -1;
+ }
+ Py_INCREF(f);
+ if (PyFile_SoftSpace(f, 0)) {
+ if (PyFile_WriteString(" ", f) < 0)
+ goto error;
+ }
+ if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
+ goto error;
+ if (PyFile_WriteString("\n", f) < 0)
+ goto error;
+ Py_DECREF(f);
+ return 0;
+error:
+ Py_DECREF(f);
+ return -1;
+ /* the line below is just to avoid C compiler
+ * warnings about unused functions */
+ return __Pyx_Print(f, NULL, 0);
+}
+#else
+static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
+ int res;
+ PyObject* arg_tuple = PyTuple_Pack(1, o);
+ if (unlikely(!arg_tuple))
+ return -1;
+ res = __Pyx_Print(stream, arg_tuple, 1);
+ Py_DECREF(arg_tuple);
+ return res;
+}
+#endif
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
+ const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
+ char* char_start = PyBytes_AS_STRING(bytes);
+ char* pos;
+ for (pos=char_start; pos < char_start+length; pos++) {
+ if (character == pos[0]) return 1;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return ::std::complex< float >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return x + y*(__pyx_t_float_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ __pyx_t_float_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrtf(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypotf(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ float denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(a, a);
+ case 3:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, a);
+ case 4:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_absf(a);
+ theta = atan2f(a.imag, a.real);
+ }
+ lnr = logf(r);
+ z_r = expf(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cosf(z_theta);
+ z.imag = z_r * sinf(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return ::std::complex< double >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return x + y*(__pyx_t_double_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ __pyx_t_double_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrt(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypot(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ double denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(a, a);
+ case 3:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, a);
+ case 4:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_abs(a);
+ theta = atan2(a.imag, a.real);
+ }
+ lnr = log(r);
+ z_r = exp(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cos(z_theta);
+ z.imag = z_r * sin(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+ PyObject *py_name = 0;
+ PyObject *py_module = 0;
+ py_name = __Pyx_PyIdentifier_FromString(name);
+ if (!py_name)
+ goto bad;
+ py_module = PyImport_Import(py_name);
+ Py_DECREF(py_name);
+ return py_module;
+bad:
+ Py_XDECREF(py_name);
+ return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+ size_t size, int strict)
+{
+ PyObject *py_module = 0;
+ PyObject *result = 0;
+ PyObject *py_name = 0;
+ char warning[200];
+ Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+ PyObject *py_basicsize;
+#endif
+ py_module = __Pyx_ImportModule(module_name);
+ if (!py_module)
+ goto bad;
+ py_name = __Pyx_PyIdentifier_FromString(class_name);
+ if (!py_name)
+ goto bad;
+ result = PyObject_GetAttr(py_module, py_name);
+ Py_DECREF(py_name);
+ py_name = 0;
+ Py_DECREF(py_module);
+ py_module = 0;
+ if (!result)
+ goto bad;
+ if (!PyType_Check(result)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.%.200s is not a type object",
+ module_name, class_name);
+ goto bad;
+ }
+#ifndef Py_LIMITED_API
+ basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+ py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+ if (!py_basicsize)
+ goto bad;
+ basicsize = PyLong_AsSsize_t(py_basicsize);
+ Py_DECREF(py_basicsize);
+ py_basicsize = 0;
+ if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+ goto bad;
+#endif
+ if (!strict && (size_t)basicsize > size) {
+ PyOS_snprintf(warning, sizeof(warning),
+ "%s.%s size changed, may indicate binary incompatibility",
+ module_name, class_name);
+ if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+ }
+ else if ((size_t)basicsize != size) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s.%.200s has the wrong size, try recompiling",
+ module_name, class_name);
+ goto bad;
+ }
+ return (PyTypeObject *)result;
+bad:
+ Py_XDECREF(py_module);
+ Py_XDECREF(result);
+ return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/math/histogramnd/chistogramnd_lut.pyx b/silx/math/histogramnd/chistogramnd_lut.pyx
new file mode 100644
index 0000000..e1ceb7e
--- /dev/null
+++ b/silx/math/histogramnd/chistogramnd_lut.pyx
@@ -0,0 +1,426 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+
+__authors__ = ["D. Naudet"]
+__license__ = "MIT"
+__date__ = "15/05/2016"
+
+
+cimport numpy as np # noqa
+cimport cython
+import numpy as np
+
+ctypedef fused sample_t:
+ np.float64_t
+ np.float32_t
+ np.int32_t
+ np.int64_t
+
+ctypedef fused cumul_t:
+ np.float64_t
+ np.float32_t
+ np.int32_t
+ np.int64_t
+
+ctypedef fused weights_t:
+ np.float64_t
+ np.float32_t
+ np.int32_t
+ np.int64_t
+
+ctypedef fused lut_t:
+ np.int64_t
+ np.int32_t
+ np.int16_t
+
+
+def histogramnd_get_lut(sample,
+ histo_range,
+ n_bins,
+ last_bin_closed=False):
+ """TBD
+
+ :param sample:
+ The data to be histogrammed.
+ Its shape must be either (N,) if it contains one dimensional
+ coordinates, or an (N, D) array where the rows are the
+ coordinates of points in a D dimensional space.
+ The following dtypes are supported : :class:`numpy.float64`,
+ :class:`numpy.float32`, :class:`numpy.int32`.
+ :type sample: :class:`numpy.array`
+
+ :param histo_range:
+ A (N, 2) array containing the histogram range along each dimension,
+ where N is the sample's number of dimensions.
+ :type histo_range: array_like
+
+ :param n_bins:
+ The number of bins :
+ * a scalar (same number of bins for all dimensions)
+ * a D elements array (number of bins for each dimensions)
+ :type n_bins: scalar or array_like
+
+ :param last_bin_closed:
+ By default the last bin is half
+ open (i.e.: [x,y) ; x included, y
+ excluded), like all the other bins.
+ Set this parameter to true if you want
+ the LAST bin to be closed.
+ :type last_bin_closed: *optional*, :class:`python.boolean`
+
+ :return: The indices for each sample and the histogram (bin counts).
+ :rtype: tuple : (:class:`numpy.array`, :class:`numpy.array`)
+ """
+
+ s_shape = sample.shape
+
+ n_dims = 1 if len(s_shape) == 1 else s_shape[1]
+
+ # just in case those arent numpy arrays
+ # (this allows the user to provide native python lists,
+ # => easier for testing)
+ i_histo_range = histo_range
+ histo_range = np.array(histo_range)
+ err_histo_range = False
+
+ if n_dims == 1:
+ if histo_range.shape == (2,):
+ pass
+ elif histo_range.shape == (1, 2):
+ histo_range.reshape(-1)
+ else:
+ err_histo_range = True
+ elif n_dims != 1 and histo_range.shape != (n_dims, 2):
+ err_histo_range = True
+
+ if err_histo_range:
+ raise ValueError('<histo_range> error : expected {n_dims} sets of '
+ 'lower and upper bin edges, '
+ 'got the following instead : {histo_range}. '
+ '(provided <sample> contains '
+ '{n_dims}D values)'
+ ''.format(histo_range=i_histo_range,
+ n_dims=n_dims))
+
+ histo_range = np.double(histo_range)
+
+ # checking n_bins size
+ n_bins = np.array(n_bins, ndmin=1)
+ if len(n_bins) == 1:
+ n_bins = np.tile(n_bins, n_dims)
+ elif n_bins.shape != (n_dims,):
+ raise ValueError('n_bins must be either a scalar (same number '
+ 'of bins for all dimensions) or '
+ 'an array (number of bins for each '
+ 'dimension).')
+
+ # checking if None is in n_bins, otherwise a rather cryptic
+ # exception is thrown when calling np.zeros
+ # also testing for negative/null values
+ if np.any(np.equal(n_bins, None)) or np.any(n_bins <= 0):
+ raise ValueError('<n_bins> : only positive values allowed.')
+
+ sample_type = sample.dtype
+
+ n_elem = sample.size // n_dims
+
+ if n_bins.prod(dtype=np.uint64) < 2**15:
+ lut_dtype = np.int16
+ elif n_bins.prod(dtype=np.uint64) < 2**31:
+ lut_dtype = np.int32
+ else:
+ lut_dtype = np.int64
+
+ # allocating the output arrays
+ lut = np.zeros(n_elem, dtype=lut_dtype)
+ histo = np.zeros(n_bins, dtype=np.uint32)
+
+ sample_c = np.ascontiguousarray(sample.reshape((sample.size,)))
+
+ histo_range_c = np.ascontiguousarray(histo_range.reshape((histo_range.size,)))
+
+ n_bins_c = np.ascontiguousarray(n_bins.reshape((n_bins.size,)),
+ dtype=np.int32)
+
+ lut_c = np.ascontiguousarray(lut.reshape((lut.size,)))
+ histo_c = np.ascontiguousarray(histo.reshape((histo.size,)))
+
+ rc = 0
+
+ try:
+ rc = _histogramnd_get_lut_fused(sample_c,
+ n_dims,
+ n_elem,
+ histo_range_c,
+ n_bins_c,
+ lut_c,
+ histo_c,
+ last_bin_closed)
+ except TypeError as ex:
+ raise TypeError('Type not supported - sample : {0}'
+ ''.format(sample_type))
+
+ if rc != 0:
+ raise Exception('histogramnd returned an error : {0}'
+ ''.format(rc))
+
+ edges = []
+ histo_range = histo_range.reshape(-1)
+ for i_dim in range(n_dims):
+ dim_edges = np.zeros(n_bins[i_dim] + 1)
+ rng_min = histo_range[2 * i_dim]
+ rng_max = histo_range[2 * i_dim + 1]
+ dim_edges[:-1] = (rng_min + np.arange(n_bins[i_dim]) *
+ ((rng_max - rng_min) / n_bins[i_dim]))
+ dim_edges[-1] = rng_max
+ edges.append(dim_edges)
+
+ return lut, histo, tuple(edges)
+
+
+# =====================
+# =====================
+
+
+def histogramnd_from_lut(weights,
+ histo_lut,
+ histo=None,
+ weighted_histo=None,
+ shape=None,
+ dtype=None,
+ weight_min=None,
+ weight_max=None):
+ """
+ dtype ignored if weighted_histo provided
+ """
+
+ if histo is None and weighted_histo is None:
+ if shape is None:
+ raise ValueError('At least one of the following parameters has to '
+ 'be provided : <shape> or <histo> or '
+ '<weighted_histo>')
+
+ if shape is not None:
+ if histo is not None and list(histo.shape) != list(shape):
+ raise ValueError('The <shape> value does not match'
+ 'the <histo> shape.')
+
+ if(weighted_histo is not None and
+ list(weighted_histo.shape) != list(shape)):
+ raise ValueError('The <shape> value does not match'
+ 'the <weighted_histo> shape.')
+ else:
+ if histo is not None:
+ shape = histo.shape
+ else:
+ shape = weighted_histo.shape
+
+ if histo is not None:
+ if histo.dtype != np.uint32:
+ raise ValueError('Provided <histo> array doesn\'t have '
+ 'the expected type '
+ ': should be {0} instead of {1}.'
+ ''.format(np.uint32, histo.dtype))
+
+ if weighted_histo is not None:
+ if histo.shape != weighted_histo.shape:
+ raise ValueError('The <histo> shape does not match'
+ 'the <weighted_histo> shape.')
+ else:
+ histo = np.zeros(shape, dtype=np.uint32)
+
+ w_dtype = weights.dtype
+
+ if dtype is None:
+ if weighted_histo is None:
+ dtype = w_dtype
+ else:
+ dtype = weighted_histo.dtype
+ elif weighted_histo is not None:
+ if weighted_histo.dtype != dtype:
+ raise ValueError('Provided <dtype> and <weighted_histo>\'s dtype'
+ ' do not match.')
+ dtype = weighted_histo.dtype
+
+ if weighted_histo is None:
+ weighted_histo = np.zeros(shape, dtype=dtype)
+
+ if histo_lut.size != weights.size:
+ raise ValueError('The LUT and weights arrays must have the same '
+ 'number of elements.')
+
+ w_c = np.ascontiguousarray(weights.reshape((weights.size,)))
+
+ h_c = np.ascontiguousarray(histo.reshape((histo.size,)))
+
+ w_h_c = np.ascontiguousarray(weighted_histo.reshape((weighted_histo.size,))) # noqa
+
+ h_lut_c = np.ascontiguousarray(histo_lut.reshape((histo_lut.size,)))
+
+ rc = 0
+
+ if weight_min is None:
+ weight_min = 0
+ filt_min_weights = False
+ else:
+ filt_min_weights = True
+
+ if weight_max is None:
+ weight_max = 0
+ filt_max_weights = False
+ else:
+ filt_max_weights = True
+
+ try:
+ _histogramnd_from_lut_fused(w_c,
+ h_lut_c,
+ h_c,
+ w_h_c,
+ weights.size,
+ filt_min_weights,
+ w_dtype.type(weight_min),
+ filt_max_weights,
+ w_dtype.type(weight_max))
+ except TypeError as ex:
+ print(ex)
+ raise TypeError('Case not supported - weights:{0} '
+ 'and histo:{1}.'
+ ''.format(weights.dtype, histo.dtype))
+
+ return histo, weighted_histo
+
+
+# =====================
+# =====================
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+@cython.cdivision(True)
+def _histogramnd_from_lut_fused(weights_t[:] i_weights,
+ lut_t[:] i_lut,
+ np.uint32_t[:] o_histo,
+ cumul_t[:] o_weighted_histo,
+ int i_n_elems,
+ bint i_filt_min_weights,
+ weights_t i_weight_min,
+ bint i_filt_max_weights,
+ weights_t i_weight_max):
+ with nogil:
+ for i in range(i_n_elems):
+ if (i_lut[i] >= 0):
+ if i_filt_min_weights and i_weights[i] < i_weight_min:
+ continue
+ if i_filt_max_weights and i_weights[i] > i_weight_max:
+ continue
+ o_histo[i_lut[i]] += 1
+ o_weighted_histo[i_lut[i]] += <cumul_t>i_weights[i] # noqa
+
+
+# =====================
+# =====================
+
+
+@cython.wraparound(False)
+@cython.boundscheck(False)
+@cython.initializedcheck(False)
+@cython.nonecheck(False)
+@cython.cdivision(True)
+def _histogramnd_get_lut_fused(sample_t[:] i_sample,
+ int i_n_dims,
+ int i_n_elems,
+ double[:] i_histo_range,
+ int[:] i_n_bins,
+ lut_t[:] o_lut,
+ np.uint32_t[:] o_histo,
+ bint last_bin_closed):
+
+ cdef:
+ int i = 0
+ long elem_idx = 0
+ long max_idx = 0
+ long lut_idx = -1
+
+ # computed bin index (i_sample -> grid)
+ long bin_idx = 0
+
+ sample_t elem_coord = 0
+
+ double[50] g_min
+ double[50] g_max
+ double[50] bins_range
+
+ for i in range(i_n_dims):
+ g_min[i] = i_histo_range[2*i]
+ g_max[i] = i_histo_range[2*i+1]
+ bins_range[i] = g_max[i] - g_min[i]
+
+ elem_idx = 0 - i_n_dims
+ max_idx = i_n_elems * i_n_dims - i_n_dims
+
+ with nogil:
+ while elem_idx < max_idx:
+ elem_idx += i_n_dims
+ lut_idx += 1
+
+ bin_idx = 0
+
+ for i in range(i_n_dims):
+ elem_coord = i_sample[elem_idx+i]
+ # =====================
+ # Element is rejected if any of the following is NOT true :
+ # 1. coordinate is >= than the minimum value
+ # 2. coordinate is <= than the maximum value
+ # 3. coordinate==maximum value and last_bin_closed is True
+ # =====================
+ if elem_coord < g_min[i]:
+ bin_idx = -1
+ break
+
+ # Here we make the assumption that most of the time
+ # there will be more coordinates inside the grid interval
+ # (one test)
+ # than coordinates higher or equal to the max
+ # (two tests)
+ if elem_coord < g_max[i]:
+ bin_idx = <long>(bin_idx * i_n_bins[i] + # noqa
+ (((elem_coord - g_min[i]) * i_n_bins[i]) /
+ bins_range[i]))
+ else:
+ # if equal and the last bin is closed :
+ # put it in the last bin
+ # else : discard
+ if last_bin_closed and elem_coord == g_max[i]:
+ bin_idx = (bin_idx + 1) * i_n_bins[i] - 1
+ else:
+ bin_idx = -1
+ break
+
+ o_lut[lut_idx] = bin_idx
+ if bin_idx >= 0:
+ o_histo[bin_idx] += 1
+
+ return 0
diff --git a/silx/math/histogramnd/histogramnd_c.pxd b/silx/math/histogramnd/histogramnd_c.pxd
new file mode 100644
index 0000000..b92b4b7
--- /dev/null
+++ b/silx/math/histogramnd/histogramnd_c.pxd
@@ -0,0 +1,299 @@
+# 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.
+#
+# ############################################################################*/
+
+__authors__ = ["D. Naudet"]
+__license__ = "MIT"
+__date__ = "01/02/2016"
+
+cimport numpy
+
+cdef extern from "include/histogramnd_c.h":
+
+ ctypedef enum histo_opt_type:
+ HISTO_NONE
+ HISTO_WEIGHT_MIN
+ HISTO_WEIGHT_MAX
+ HISTO_LAST_BIN_CLOSED
+
+ ctypedef enum histo_rc_t:
+ HISTO_OK
+ HISTO_ERR_ALLOC
+
+ # =====================
+ # double sample, double cumul
+ # =====================
+
+ int histogramnd_double_double_double(double *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ double *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max) nogil
+
+ int histogramnd_double_float_double(double *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ double *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max) nogil
+
+ int histogramnd_double_int32_t_double(double *i_sample,
+ numpy.int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ double *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ numpy.int32_t i_weight_min,
+ numpy.int32_t i_weight_max) nogil
+
+ # =====================
+ # float sample, double cumul
+ # =====================
+
+ int histogramnd_float_double_double(float *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ double *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max) nogil
+
+ int histogramnd_float_float_double(float *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ double *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max) nogil
+
+ int histogramnd_float_int32_t_double(float *i_sample,
+ numpy.int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ double *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ numpy.int32_t i_weight_min,
+ numpy.int32_t i_weight_max) nogil
+
+ # =====================
+ # numpy.int32_t sample, double cumul
+ # =====================
+
+ int histogramnd_int32_t_double_double(numpy.int32_t *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ double *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max) nogil
+
+ int histogramnd_int32_t_float_double(numpy.int32_t *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ double *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max) nogil
+
+ int histogramnd_int32_t_int32_t_double(numpy.int32_t *i_sample,
+ numpy.int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ double *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ numpy.int32_t i_weight_min,
+ numpy.int32_t i_weight_max) nogil
+
+ # =====================
+ # double sample, float cumul
+ # =====================
+
+ int histogramnd_double_double_float(double *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ float *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max) nogil
+
+ int histogramnd_double_float_float(double *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ float *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max) nogil
+
+ int histogramnd_double_int32_t_float(double *i_sample,
+ numpy.int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ float *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ numpy.int32_t i_weight_min,
+ numpy.int32_t i_weight_max) nogil
+
+ # =====================
+ # float sample, float cumul
+ # =====================
+
+ int histogramnd_float_double_float(float *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ float *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max) nogil
+
+ int histogramnd_float_float_float(float *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ float *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max) nogil
+
+ int histogramnd_float_int32_t_float(float *i_sample,
+ numpy.int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ float *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ numpy.int32_t i_weight_min,
+ numpy.int32_t i_weight_max) nogil
+
+ # =====================
+ # numpy.int32_t sample, float cumul
+ # =====================
+
+ int histogramnd_int32_t_double_float(numpy.int32_t *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ float *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max) nogil
+
+ int histogramnd_int32_t_float_float(numpy.int32_t *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ float *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max) nogil
+
+ int histogramnd_int32_t_int32_t_float(numpy.int32_t *i_sample,
+ numpy.int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ numpy.uint32_t *o_histo,
+ float *o_cumul,
+ double * bin_edges,
+ int i_opt_flags,
+ numpy.int32_t i_weight_min,
+ numpy.int32_t i_weight_max) nogil
diff --git a/silx/math/histogramnd/include/histogramnd_c.h b/silx/math/histogramnd/include/histogramnd_c.h
new file mode 100644
index 0000000..abe464f
--- /dev/null
+++ b/silx/math/histogramnd/include/histogramnd_c.h
@@ -0,0 +1,313 @@
+/*##########################################################################
+# 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.
+#
+# ############################################################################*/
+
+#ifndef HISTOGRAMND_C_H
+#define HISTOGRAMND_C_H
+
+/* checking for MSVC version because VS 2008 doesnt fully support C99
+ so inttypes.h and stdint.h are not provided with the compiler. */
+#if defined(_MSC_VER) && _MSC_VER < 1600
+ #include "msvc/stdint.h"
+#else
+ #include <inttypes.h>
+#endif
+
+#include "templates.h"
+
+/** Allowed flag values for the i_opt_flags arguments.
+ */
+typedef enum {
+ HISTO_NONE = 0, /**< No options. */
+ HISTO_WEIGHT_MIN = 1, /**< Filter weights with i_weight_min. */
+ HISTO_WEIGHT_MAX = 1<<1, /**< Filter weights with i_weight_max. */
+ HISTO_LAST_BIN_CLOSED = 1<<2 /**< Last bin is closed. */
+} histo_opt_type;
+
+/** Return codees for the histogramnd function.
+ */
+typedef enum {
+ HISTO_OK = 0, /**< No error. */
+ HISTO_ERR_ALLOC /**< Failed to allocate memory. */
+} histo_rc_t;
+
+/*=====================
+ * double sample, double cumul
+ * ====================
+*/
+
+int histogramnd_double_double_double(double *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ double *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max);
+
+int histogramnd_double_float_double(double *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ double *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max);
+
+int histogramnd_double_int32_t_double(double *i_sample,
+ int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ double *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ int32_t i_weight_min,
+ int32_t i_weight_max);
+
+/*=====================
+ * float sample, double cumul
+ * ====================
+*/
+int histogramnd_float_double_double(float *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ double *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max);
+
+int histogramnd_float_float_double(float *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ double *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max);
+
+int histogramnd_float_int32_t_double(float *i_sample,
+ int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ double *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ int32_t i_weight_min,
+ int32_t i_weight_max);
+
+/*=====================
+ * int32_t sample, double cumul
+ * ====================
+*/
+int histogramnd_int32_t_double_double(int32_t *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ double *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max);
+
+int histogramnd_int32_t_float_double(int32_t *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ double *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max);
+
+int histogramnd_int32_t_int32_t_double(int32_t *i_sample,
+ int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ double *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ int32_t i_weight_min,
+ int32_t i_weight_max);
+
+/*=====================
+ * double sample, float cumul
+ * ====================
+*/
+
+int histogramnd_double_double_float(double *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ float *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max);
+
+int histogramnd_double_float_float(double *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ float *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max);
+
+int histogramnd_double_int32_t_float(double *i_sample,
+ int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ float *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ int32_t i_weight_min,
+ int32_t i_weight_max);
+
+/*=====================
+ * float sample, float cumul
+ * ====================
+*/
+int histogramnd_float_double_float(float *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ float *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max);
+
+int histogramnd_float_float_float(float *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ float *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max);
+
+int histogramnd_float_int32_t_float(float *i_sample,
+ int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ float *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ int32_t i_weight_min,
+ int32_t i_weight_max);
+
+/*=====================
+ * int32_t sample, double cumul
+ * ====================
+*/
+int histogramnd_int32_t_double_float(int32_t *i_sample,
+ double *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ float *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ double i_weight_min,
+ double i_weight_max);
+
+int histogramnd_int32_t_float_float(int32_t *i_sample,
+ float *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ float *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ float i_weight_min,
+ float i_weight_max);
+
+int histogramnd_int32_t_int32_t_float(int32_t *i_sample,
+ int32_t *i_weigths,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bin,
+ uint32_t *o_histo,
+ float *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ int32_t i_weight_min,
+ int32_t i_weight_max);
+
+#endif /* #define HISTOGRAMND_C_H */
diff --git a/silx/math/histogramnd/include/msvc/stdint.h b/silx/math/histogramnd/include/msvc/stdint.h
new file mode 100644
index 0000000..e236bb0
--- /dev/null
+++ b/silx/math/histogramnd/include/msvc/stdint.h
@@ -0,0 +1,247 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef char int8_t;
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef __int8 int8_t;
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/silx/math/histogramnd/include/templates.h b/silx/math/histogramnd/include/templates.h
new file mode 100644
index 0000000..490eed3
--- /dev/null
+++ b/silx/math/histogramnd/include/templates.h
@@ -0,0 +1,30 @@
+/*##########################################################################
+# 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.
+#
+# ############################################################################*/
+
+#ifndef TEMPLATES_H_
+#define TEMPLATES_H_
+
+#define CONCAT(X,Y,Z,T) X##_##Y##_##Z##_##T
+#define TEMPLATE(X,Y,Z,T) CONCAT(X,Y,Z,T)
+
+#endif
diff --git a/silx/math/histogramnd/src/histogramnd_c.c b/silx/math/histogramnd/src/histogramnd_c.c
new file mode 100644
index 0000000..fc9d77e
--- /dev/null
+++ b/silx/math/histogramnd/src/histogramnd_c.c
@@ -0,0 +1,301 @@
+/*##########################################################################
+# 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.
+#
+# ############################################################################*/
+
+#include "histogramnd_c.h"
+
+/*=====================
+ * double sample, double cumul
+ * =====================
+*/
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T double
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T double
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T double
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T double
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T float
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T double
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T double
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T int32_t
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T double
+#include "histogramnd_template.c"
+
+/*=====================
+ * float sample, double cumul
+ * =====================
+*/
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T float
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T double
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T double
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T float
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T float
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T double
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T float
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T int32_t
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T double
+#include "histogramnd_template.c"
+
+/*=====================
+ * int32_t sample, double cumul
+ * =====================
+*/
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T int32_t
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T double
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T double
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T int32_t
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T float
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T double
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T int32_t
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T int32_t
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T double
+#include "histogramnd_template.c"
+
+
+/*=====================
+ * double sample, float cumul
+ * =====================
+*/
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T double
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T double
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T float
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T double
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T float
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T float
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T double
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T int32_t
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T float
+#include "histogramnd_template.c"
+
+/*=====================
+ * float sample, float cumul
+ * =====================
+*/
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T float
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T double
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T float
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T float
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T float
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T float
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T float
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T int32_t
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T float
+#include "histogramnd_template.c"
+
+/*=====================
+ * int32_t sample, float cumul
+ * =====================
+*/
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T int32_t
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T double
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T float
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T int32_t
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T float
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T float
+#include "histogramnd_template.c"
+
+#ifdef HISTO_SAMPLE_T
+#undef HISTO_SAMPLE_T
+#endif
+#define HISTO_SAMPLE_T int32_t
+#ifdef HISTO_WEIGHT_T
+#undef HISTO_WEIGHT_T
+#endif
+#define HISTO_WEIGHT_T int32_t
+#ifdef HISTO_CUMUL_T
+#undef HISTO_CUMUL_T
+#endif
+#define HISTO_CUMUL_T float
+#include "histogramnd_template.c"
diff --git a/silx/math/histogramnd/src/histogramnd_template.c b/silx/math/histogramnd/src/histogramnd_template.c
new file mode 100644
index 0000000..0276bb4
--- /dev/null
+++ b/silx/math/histogramnd/src/histogramnd_template.c
@@ -0,0 +1,260 @@
+/*##########################################################################
+# 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.
+#
+# ############################################################################*/
+
+#include "templates.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdarg.h>
+
+#ifdef HISTO_SAMPLE_T
+#ifdef HISTO_WEIGHT_T
+#ifdef HISTO_CUMUL_T
+
+int TEMPLATE(histogramnd, HISTO_SAMPLE_T, HISTO_WEIGHT_T, HISTO_CUMUL_T)
+ (HISTO_SAMPLE_T *i_sample,
+ HISTO_WEIGHT_T *i_weights,
+ int i_n_dim,
+ int i_n_elem,
+ double *i_bin_ranges,
+ int *i_n_bins,
+ uint32_t *o_histo,
+ HISTO_CUMUL_T *o_cumul,
+ double *o_bin_edges,
+ int i_opt_flags,
+ HISTO_WEIGHT_T i_weight_min,
+ HISTO_WEIGHT_T i_weight_max)
+{
+ /* some counters */
+ int i = 0, j = 0;
+ long elem_idx = 0;
+
+ HISTO_WEIGHT_T * weight_ptr = 0;
+ HISTO_SAMPLE_T elem_coord = 0.;
+
+ /* computed bin index (i_sample -> grid) */
+ long bin_idx = 0;
+
+ double * g_min = 0;
+ double * g_max = 0;
+ double * range = 0;
+
+ /* ================================
+ * Parsing options, if any.
+ * ================================
+ */
+
+ int filt_min_weight = 0;
+ int filt_max_weight = 0;
+ int last_bin_closed = 0;
+
+ /* Testing the option flags */
+ if(i_opt_flags & HISTO_WEIGHT_MIN)
+ {
+ filt_min_weight = 1;
+ }
+
+ if(i_opt_flags & HISTO_WEIGHT_MAX)
+ {
+ filt_max_weight = 1;
+ }
+
+ if(i_opt_flags & HISTO_LAST_BIN_CLOSED)
+ {
+ last_bin_closed = 1;
+ }
+
+ /* storing the min & max bin coordinates in their own arrays because
+ * i_bin_ranges = [[min0, max0], [min1, max1], ...]
+ * (mostly for the sake of clarity)
+ * (maybe faster access too?)
+ */
+ g_min = (double *) malloc(i_n_dim *sizeof(double));
+ g_max = (double *) malloc(i_n_dim * sizeof(double));
+ /* range used to convert from i_coords to bin indices in the grid */
+ range = (double *) malloc(i_n_dim * sizeof(double));
+
+ if(!g_min || !g_max || !range)
+ {
+ free(g_min);
+ free(g_max);
+ free(range);
+ return HISTO_ERR_ALLOC;
+ }
+
+ j = 0;
+ for(i=0; i<i_n_dim; i++)
+ {
+ g_min[i] = i_bin_ranges[i*2];
+ g_max[i] = i_bin_ranges[i*2+1];
+ range[i] = g_max[i]-g_min[i];
+
+ for(bin_idx=0; bin_idx<i_n_bins[i]; j++, bin_idx++)
+ {
+ o_bin_edges[j] = g_min[i] +
+ bin_idx * (range[i] / i_n_bins[i]);
+ }
+ o_bin_edges[j++] = g_max[i];
+ }
+
+ weight_ptr = i_weights;
+
+ if(!i_weights)
+ {
+ /* if weights are not provided there no point in trying to filter them
+ * (!! careful if you change this, some code below relies on it !!)
+ */
+ filt_min_weight = 0;
+ filt_max_weight = 0;
+
+ /* If the weights array is not provided then there is no point
+ * updating the weighted histogram, only the bin counts (o_histo)
+ * will be filled.
+ * (!! careful if you change this, some code below relies on it !!)
+ */
+ o_cumul = 0;
+ }
+
+ /* tried to use pointers instead of indices here, but it didn't
+ * seem any faster (probably because the compiler
+ * optimizes stuff anyway),
+ * so i'm keeping the "indices" version, for the sake of clarity
+ */
+ for(elem_idx=0;
+ elem_idx<i_n_elem*i_n_dim;
+ elem_idx+=i_n_dim, weight_ptr++)
+ {
+ /* no testing the validity of weight_ptr here, because if it is NULL
+ * then filt_min_weight/filt_max_weight will be 0.
+ * (see code above)
+ */
+ if(filt_min_weight && *weight_ptr<i_weight_min)
+ {
+ continue;
+ }
+ if(filt_max_weight && *weight_ptr>i_weight_max)
+ {
+ continue;
+ }
+
+ bin_idx = 0;
+
+ for(i=0; i<i_n_dim; i++)
+ {
+ elem_coord = i_sample[elem_idx+i];
+
+ /* =====================
+ * Element is rejected if any of the following is NOT true :
+ * 1. coordinate is >= than the minimum value
+ * 2. coordinate is <= than the maximum value
+ * 3. coordinate==maximum value and last_bin_closed is True
+ * =====================
+ */
+ if(elem_coord<g_min[i])
+ {
+ bin_idx = -1;
+ break;
+ }
+
+ /* Here we make the assumption that most of the time
+ * there will be more coordinates inside the grid interval
+ * (one test)
+ * than coordinates higher or equal to the max
+ * (two tests)
+ */
+ if(elem_coord<g_max[i])
+ {
+ /* Warning : the following factorization seems to
+ * increase the effect of precision error.
+ * bin_idx = (long)floor(
+ * (bin_idx +
+ * (elem_coord-g_min[i])/range[i]) *
+ * i_n_bins[i]
+ * );
+ */
+
+ /* Not using floor to speed up things.
+ * We don't (?) need all the error checking provided by
+ * the built-in floor().
+ * Also the value is supposed to be always positive.
+ */
+ bin_idx = bin_idx * i_n_bins[i] +
+ (long)(
+ ((elem_coord-g_min[i]) * i_n_bins[i]) /
+ range[i]
+ );
+ }
+ else /* ===> elem_coord>=g_max[i] */
+ {
+ /* if equal and the last bin is closed :
+ * put it in the last bin
+ * else : discard
+ */
+ if(last_bin_closed && elem_coord==g_max[i])
+ {
+ bin_idx = (bin_idx + 1) * i_n_bins[i] - 1;
+ }
+ else
+ {
+ bin_idx = -1;
+ break;
+ }
+ } /* if(elem_coord<g_max[i]) */
+
+ } /* for(i=0; i<i_n_dim; i++) */
+
+ /* element is out of the grid */
+ if(bin_idx==-1)
+ {
+ continue;
+ }
+
+ if(o_histo)
+ {
+ o_histo[bin_idx] += 1;
+ }
+ if(o_cumul)
+ {
+ /* not testing the pointer since o_cumul is null if
+ * i_weights is null.
+ */
+ o_cumul[bin_idx] += (HISTO_CUMUL_T) *weight_ptr;
+ }
+
+ } /* for(elem_idx=0; elem_idx<i_n_elem*i_n_dim; elem_idx+=i_n_dim) */
+
+ free(g_min);
+ free(g_max);
+ free(range);
+
+ /* For now just returning 0 (OK) since all the checks are done in
+ * python. This might change later if people want to call this
+ * function directly from C (might have to implement error codes).
+ */
+ return HISTO_OK;
+}
+
+#endif
+#endif
+#endif
diff --git a/silx/math/marchingcubes/marchingcubes.cpp b/silx/math/marchingcubes/marchingcubes.cpp
new file mode 100644
index 0000000..e97d8f2
--- /dev/null
+++ b/silx/math/marchingcubes/marchingcubes.cpp
@@ -0,0 +1,21483 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__marchingcubes
+#define __PYX_HAVE_API__marchingcubes
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#include <vector>
+#include "ios"
+#include "new"
+#include "stdexcept"
+#include "typeinfo"
+#include "mc.hpp"
+#include "pythread.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+ #if defined(__cplusplus)
+ #define CYTHON_CCOMPLEX 1
+ #elif defined(_Complex_I)
+ #define CYTHON_CCOMPLEX 1
+ #else
+ #define CYTHON_CCOMPLEX 0
+ #endif
+#endif
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #include <complex>
+ #else
+ #include <complex.h>
+ #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+ #undef _Complex_I
+ #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+ "marchingcubes.pyx",
+ "__init__.pxd",
+ "stringsource",
+ "stringsource",
+ "stringsource",
+ "type.pxd",
+};
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":723
+ * # in Cython to enable them only on the right systems.
+ *
+ * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":724
+ *
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":725
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int64 int64_t
+ * #ctypedef npy_int96 int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96 int96_t
+ * #ctypedef npy_int128 int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":730
+ * #ctypedef npy_int128 int128_t
+ *
+ * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":731
+ *
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":732
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64 uint64_t
+ * #ctypedef npy_uint96 uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96 uint96_t
+ * #ctypedef npy_uint128 uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":737
+ * #ctypedef npy_uint128 uint128_t
+ *
+ * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_float64 float64_t
+ * #ctypedef npy_float80 float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":738
+ *
+ * ctypedef npy_float32 float32_t
+ * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80 float80_t
+ * #ctypedef npy_float128 float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong longlong_t
+ *
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":749
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_ulong uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
+ * ctypedef npy_longlong longlong_t
+ *
+ * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":752
+ *
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":753
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_intp intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ * ctypedef npy_intp intp_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp uintp_t
+ *
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":756
+ *
+ * ctypedef npy_intp intp_t
+ * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_double float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_uintp uintp_t
+ *
+ * ctypedef npy_double float_t # <<<<<<<<<<<<<<
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":759
+ *
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ *
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":760
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cfloat cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< float > __pyx_t_float_complex;
+ #else
+ typedef float _Complex __pyx_t_float_complex;
+ #endif
+#else
+ typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< double > __pyx_t_double_complex;
+ #else
+ typedef double _Complex __pyx_t_double_complex;
+ #endif
+#else
+ typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_obj_13marchingcubes_MarchingCubes;
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ *
+ * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":763
+ *
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":764
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cdouble complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "marchingcubes.pyx":56
+ *
+ *
+ * cdef class MarchingCubes: # <<<<<<<<<<<<<<
+ * """Compute isosurface using marching cubes algorithm.
+ *
+ */
+struct __pyx_obj_13marchingcubes_MarchingCubes {
+ PyObject_HEAD
+ MarchingCubes<float,float> *c_mc;
+};
+
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+static void __Pyx_RaiseBufferIndexError(int axis);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+static PyObject *__Pyx_GetNameInClass(PyObject *nmspace, PyObject *name);
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+#ifndef __Pyx_CppExn2PyErr
+#include <new>
+#include <typeinfo>
+#include <stdexcept>
+#include <ios>
+static void __Pyx_CppExn2PyErr() {
+ try {
+ if (PyErr_Occurred())
+ ; // let the latest Python exn pass through and ignore the current one
+ else
+ throw;
+ } catch (const std::bad_alloc& exn) {
+ PyErr_SetString(PyExc_MemoryError, exn.what());
+ } catch (const std::bad_cast& exn) {
+ PyErr_SetString(PyExc_TypeError, exn.what());
+ } catch (const std::domain_error& exn) {
+ PyErr_SetString(PyExc_ValueError, exn.what());
+ } catch (const std::invalid_argument& exn) {
+ PyErr_SetString(PyExc_ValueError, exn.what());
+ } catch (const std::ios_base::failure& exn) {
+ PyErr_SetString(PyExc_IOError, exn.what());
+ } catch (const std::out_of_range& exn) {
+ PyErr_SetString(PyExc_IndexError, exn.what());
+ } catch (const std::overflow_error& exn) {
+ PyErr_SetString(PyExc_OverflowError, exn.what());
+ } catch (const std::range_error& exn) {
+ PyErr_SetString(PyExc_ArithmeticError, exn.what());
+ } catch (const std::underflow_error& exn) {
+ PyErr_SetString(PyExc_ArithmeticError, exn.what());
+ } catch (const std::exception& exn) {
+ PyErr_SetString(PyExc_RuntimeError, exn.what());
+ }
+ catch (...)
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Unknown exception");
+ }
+}
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value);
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #define __Pyx_CREAL(z) ((z).real())
+ #define __Pyx_CIMAG(z) ((z).imag())
+ #else
+ #define __Pyx_CREAL(z) (__real__(z))
+ #define __Pyx_CIMAG(z) (__imag__(z))
+ #endif
+#else
+ #define __Pyx_CREAL(z) ((z).real)
+ #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+ #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+ #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+ #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+ #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eqf(a, b) ((a)==(b))
+ #define __Pyx_c_sumf(a, b) ((a)+(b))
+ #define __Pyx_c_difff(a, b) ((a)-(b))
+ #define __Pyx_c_prodf(a, b) ((a)*(b))
+ #define __Pyx_c_quotf(a, b) ((a)/(b))
+ #define __Pyx_c_negf(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+ #define __Pyx_c_conjf(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_absf(z) (::std::abs(z))
+ #define __Pyx_c_powf(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zerof(z) ((z)==0)
+ #define __Pyx_c_conjf(z) (conjf(z))
+ #if 1
+ #define __Pyx_c_absf(z) (cabsf(z))
+ #define __Pyx_c_powf(a, b) (cpowf(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eq(a, b) ((a)==(b))
+ #define __Pyx_c_sum(a, b) ((a)+(b))
+ #define __Pyx_c_diff(a, b) ((a)-(b))
+ #define __Pyx_c_prod(a, b) ((a)*(b))
+ #define __Pyx_c_quot(a, b) ((a)/(b))
+ #define __Pyx_c_neg(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zero(z) ((z)==(double)0)
+ #define __Pyx_c_conj(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (::std::abs(z))
+ #define __Pyx_c_pow(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zero(z) ((z)==0)
+ #define __Pyx_c_conj(z) (conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (cabs(z))
+ #define __Pyx_c_pow(a, b) (cpow(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_float(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+ #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'libcpp.vector' */
+
+/* Module declarations from 'libcpp' */
+
+/* Module declarations from 'mc' */
+
+/* Module declarations from 'marchingcubes' */
+static PyTypeObject *__pyx_ptype_13marchingcubes_MarchingCubes = 0;
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static PyObject *__pyx_convert_vector_to_py_float(const std::vector<float> &); /*proto*/
+static PyObject *__pyx_convert_vector_to_py_unsigned_int(const std::vector<unsigned int> &); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t = { "float32_t", NULL, sizeof(__pyx_t_5numpy_float32_t), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_float = { "float", NULL, sizeof(float), { 0 }, 0, 'R', 0, 0 };
+#define __Pyx_MODULE_NAME "marchingcubes"
+int __pyx_module_is_main_marchingcubes = 0;
+
+/* Implementation of 'marchingcubes' */
+static PyObject *__pyx_builtin_property;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static int __pyx_pf_13marchingcubes_13MarchingCubes___cinit__(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_isolevel, PyObject *__pyx_v_invert_normals, PyObject *__pyx_v_sampling); /* proto */
+static void __pyx_pf_13marchingcubes_13MarchingCubes_2__dealloc__(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_4__getitem__(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self, PyObject *__pyx_v_key); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_6process(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self, PyArrayObject *__pyx_v_data); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_8process_slice(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self, PyArrayObject *__pyx_v_slice0, PyArrayObject *__pyx_v_slice1); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_10finish_process(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_12reset(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_14shape(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_16sampling(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_18isolevel(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_20invert_normals(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_22get_vertices(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_24get_normals(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_26get_indices(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_13marchingcubes_MarchingCubes(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_B[] = "B";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_c[] = "c";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_data[] = "data";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_ravel[] = "ravel";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_slice0[] = "slice0";
+static char __pyx_k_slice1[] = "slice1";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_uint32[] = "uint32";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_process[] = "process";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_isolevel[] = "isolevel";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_property[] = "property";
+static char __pyx_k_sampling[] = "sampling";
+static char __pyx_k_T_Vincent[] = "T. Vincent";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_05_09_2016[] = "05/09/2016";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_get_indices[] = "get_indices";
+static char __pyx_k_get_normals[] = "get_normals";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_get_vertices[] = "get_vertices";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_invert_normals[] = "invert_normals";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_Index_out_of_range[] = "Index out of range";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_This_module_provides_marching_cu[] = "This module provides marching cubes implementation.\n\nIt provides a :class:`MarchingCubes` class allowing to build an isosurface\nfrom data provided as a 3D data set or slice by slice.\n";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static PyObject *__pyx_kp_s_05_09_2016;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Index_out_of_range;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_T_Vincent;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_data;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_n_s_get_indices;
+static PyObject *__pyx_n_s_get_normals;
+static PyObject *__pyx_n_s_get_vertices;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_invert_normals;
+static PyObject *__pyx_n_s_isolevel;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_n_s_process;
+static PyObject *__pyx_n_s_property;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_ravel;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_sampling;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_slice0;
+static PyObject *__pyx_n_s_slice1;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_n_s_uint32;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_2;
+static PyObject *__pyx_int_3;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__19;
+static PyObject *__pyx_slice__20;
+static PyObject *__pyx_slice__21;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__23;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__26;
+static PyObject *__pyx_tuple__27;
+
+/* "marchingcubes.pyx":115
+ * cdef mc.MarchingCubes[float, float] * c_mc # Pointer to the C++ instance
+ *
+ * def __cinit__(self, data=None, isolevel=None, # <<<<<<<<<<<<<<
+ * invert_normals=True, sampling=(1, 1, 1)):
+ * self.c_mc = new mc.MarchingCubes[float, float](isolevel)
+ */
+
+/* Python wrapper */
+static int __pyx_pw_13marchingcubes_13MarchingCubes_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_13marchingcubes_13MarchingCubes_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ PyObject *__pyx_v_isolevel = 0;
+ PyObject *__pyx_v_invert_normals = 0;
+ PyObject *__pyx_v_sampling = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_isolevel,&__pyx_n_s_invert_normals,&__pyx_n_s_sampling,0};
+ PyObject* values[4] = {0,0,0,0};
+ values[0] = ((PyObject *)Py_None);
+ values[1] = ((PyObject *)Py_None);
+
+ /* "marchingcubes.pyx":116
+ *
+ * def __cinit__(self, data=None, isolevel=None,
+ * invert_normals=True, sampling=(1, 1, 1)): # <<<<<<<<<<<<<<
+ * self.c_mc = new mc.MarchingCubes[float, float](isolevel)
+ * self.c_mc.invert_normals = bool(invert_normals)
+ */
+ values[2] = ((PyObject *)Py_True);
+ values[3] = ((PyObject *)__pyx_tuple_);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data);
+ if (value) { values[0] = value; kw_args--; }
+ }
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_isolevel);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_invert_normals);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_sampling);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = values[0];
+ __pyx_v_isolevel = values[1];
+ __pyx_v_invert_normals = values[2];
+ __pyx_v_sampling = values[3];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes___cinit__(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self), __pyx_v_data, __pyx_v_isolevel, __pyx_v_invert_normals, __pyx_v_sampling);
+
+ /* "marchingcubes.pyx":115
+ * cdef mc.MarchingCubes[float, float] * c_mc # Pointer to the C++ instance
+ *
+ * def __cinit__(self, data=None, isolevel=None, # <<<<<<<<<<<<<<
+ * invert_normals=True, sampling=(1, 1, 1)):
+ * self.c_mc = new mc.MarchingCubes[float, float](isolevel)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_13marchingcubes_13MarchingCubes___cinit__(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self, PyObject *__pyx_v_data, PyObject *__pyx_v_isolevel, PyObject *__pyx_v_invert_normals, PyObject *__pyx_v_sampling) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ float __pyx_t_1;
+ MarchingCubes<float,float> *__pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ unsigned int __pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "marchingcubes.pyx":117
+ * def __cinit__(self, data=None, isolevel=None,
+ * invert_normals=True, sampling=(1, 1, 1)):
+ * self.c_mc = new mc.MarchingCubes[float, float](isolevel) # <<<<<<<<<<<<<<
+ * self.c_mc.invert_normals = bool(invert_normals)
+ * self.c_mc.sampling[0] = sampling[0]
+ */
+ __pyx_t_1 = __pyx_PyFloat_AsFloat(__pyx_v_isolevel); if (unlikely((__pyx_t_1 == (float)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ try {
+ __pyx_t_2 = new MarchingCubes<float,float> (__pyx_t_1);
+ } catch(...) {
+ __Pyx_CppExn2PyErr();
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_self->c_mc = __pyx_t_2;
+
+ /* "marchingcubes.pyx":118
+ * invert_normals=True, sampling=(1, 1, 1)):
+ * self.c_mc = new mc.MarchingCubes[float, float](isolevel)
+ * self.c_mc.invert_normals = bool(invert_normals) # <<<<<<<<<<<<<<
+ * self.c_mc.sampling[0] = sampling[0]
+ * self.c_mc.sampling[1] = sampling[1]
+ */
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_invert_normals); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->c_mc->invert_normals = (!(!__pyx_t_3));
+
+ /* "marchingcubes.pyx":119
+ * self.c_mc = new mc.MarchingCubes[float, float](isolevel)
+ * self.c_mc.invert_normals = bool(invert_normals)
+ * self.c_mc.sampling[0] = sampling[0] # <<<<<<<<<<<<<<
+ * self.c_mc.sampling[1] = sampling[1]
+ * self.c_mc.sampling[2] = sampling[2]
+ */
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_sampling, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_As_unsigned_int(__pyx_t_4); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ (__pyx_v_self->c_mc->sampling[0]) = __pyx_t_5;
+
+ /* "marchingcubes.pyx":120
+ * self.c_mc.invert_normals = bool(invert_normals)
+ * self.c_mc.sampling[0] = sampling[0]
+ * self.c_mc.sampling[1] = sampling[1] # <<<<<<<<<<<<<<
+ * self.c_mc.sampling[2] = sampling[2]
+ *
+ */
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_sampling, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_As_unsigned_int(__pyx_t_4); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ (__pyx_v_self->c_mc->sampling[1]) = __pyx_t_5;
+
+ /* "marchingcubes.pyx":121
+ * self.c_mc.sampling[0] = sampling[0]
+ * self.c_mc.sampling[1] = sampling[1]
+ * self.c_mc.sampling[2] = sampling[2] # <<<<<<<<<<<<<<
+ *
+ * if data is not None:
+ */
+ __pyx_t_4 = __Pyx_GetItemInt(__pyx_v_sampling, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_4 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyInt_As_unsigned_int(__pyx_t_4); if (unlikely((__pyx_t_5 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ (__pyx_v_self->c_mc->sampling[2]) = __pyx_t_5;
+
+ /* "marchingcubes.pyx":123
+ * self.c_mc.sampling[2] = sampling[2]
+ *
+ * if data is not None: # <<<<<<<<<<<<<<
+ * self.process(data)
+ *
+ */
+ __pyx_t_3 = (__pyx_v_data != Py_None);
+ __pyx_t_6 = (__pyx_t_3 != 0);
+ if (__pyx_t_6) {
+
+ /* "marchingcubes.pyx":124
+ *
+ * if data is not None:
+ * self.process(data) # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(self):
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_process); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_8 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_8)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_8);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ }
+ }
+ if (!__pyx_t_8) {
+ __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_data); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ } else {
+ __pyx_t_9 = PyTuple_New(1+1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_8); __Pyx_GIVEREF(__pyx_t_8); __pyx_t_8 = NULL;
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_9, 0+1, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_9, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "marchingcubes.pyx":115
+ * cdef mc.MarchingCubes[float, float] * c_mc # Pointer to the C++ instance
+ *
+ * def __cinit__(self, data=None, isolevel=None, # <<<<<<<<<<<<<<
+ * invert_normals=True, sampling=(1, 1, 1)):
+ * self.c_mc = new mc.MarchingCubes[float, float](isolevel)
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":126
+ * self.process(data)
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * del self.c_mc
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_pw_13marchingcubes_13MarchingCubes_3__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_13marchingcubes_13MarchingCubes_3__dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_pf_13marchingcubes_13MarchingCubes_2__dealloc__(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_13marchingcubes_13MarchingCubes_2__dealloc__(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "marchingcubes.pyx":127
+ *
+ * def __dealloc__(self):
+ * del self.c_mc # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, key):
+ */
+ delete __pyx_v_self->c_mc;
+
+ /* "marchingcubes.pyx":126
+ * self.process(data)
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * del self.c_mc
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "marchingcubes.pyx":129
+ * del self.c_mc
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Allows to unpack object as a single liner:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_4__getitem__[] = "Allows to unpack object as a single liner:\n\n vertices, normals, indices = MarchingCubes(...)\n ";
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_13marchingcubes_13MarchingCubes_4__getitem__;
+#endif
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_5__getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_key) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_4__getitem__(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self), ((PyObject *)__pyx_v_key));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_4__getitem__(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self, PyObject *__pyx_v_key) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "marchingcubes.pyx":134
+ * vertices, normals, indices = MarchingCubes(...)
+ * """
+ * if key == 0: # <<<<<<<<<<<<<<
+ * return self.get_vertices()
+ * elif key == 1:
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_key, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_2) {
+
+ /* "marchingcubes.pyx":135
+ * """
+ * if key == 0:
+ * return self.get_vertices() # <<<<<<<<<<<<<<
+ * elif key == 1:
+ * return self.get_normals()
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_vertices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "marchingcubes.pyx":136
+ * if key == 0:
+ * return self.get_vertices()
+ * elif key == 1: # <<<<<<<<<<<<<<
+ * return self.get_normals()
+ * elif key == 2:
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_key, __pyx_int_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_2) {
+
+ /* "marchingcubes.pyx":137
+ * return self.get_vertices()
+ * elif key == 1:
+ * return self.get_normals() # <<<<<<<<<<<<<<
+ * elif key == 2:
+ * return self.get_indices()
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_normals); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "marchingcubes.pyx":138
+ * elif key == 1:
+ * return self.get_normals()
+ * elif key == 2: # <<<<<<<<<<<<<<
+ * return self.get_indices()
+ * else:
+ */
+ __pyx_t_1 = PyObject_RichCompare(__pyx_v_key, __pyx_int_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_2) {
+
+ /* "marchingcubes.pyx":139
+ * return self.get_normals()
+ * elif key == 2:
+ * return self.get_indices() # <<<<<<<<<<<<<<
+ * else:
+ * raise IndexError("Index out of range")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_get_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ } else {
+ __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "marchingcubes.pyx":141
+ * return self.get_indices()
+ * else:
+ * raise IndexError("Index out of range") # <<<<<<<<<<<<<<
+ *
+ * def process(self, cnumpy.ndarray[cnumpy.float32_t, ndim=3, mode='c'] data):
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "marchingcubes.pyx":129
+ * del self.c_mc
+ *
+ * def __getitem__(self, key): # <<<<<<<<<<<<<<
+ * """Allows to unpack object as a single liner:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":143
+ * raise IndexError("Index out of range")
+ *
+ * def process(self, cnumpy.ndarray[cnumpy.float32_t, ndim=3, mode='c'] data): # <<<<<<<<<<<<<<
+ * """Compute an isosurface from a 3D scalar field.
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_7process(PyObject *__pyx_v_self, PyObject *__pyx_v_data); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_6process[] = "MarchingCubes.process(self, ndarray data)\nCompute an isosurface from a 3D scalar field.\n\n This builds vertices, normals and indices arrays.\n Vertices and normals coordinates are in the same order as input array,\n i.e., (dim 0, dim 1, dim 2).\n\n :param numpy.ndarray data: 3D scalar field\n ";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_7process(PyObject *__pyx_v_self, PyObject *__pyx_v_data) {
+ CYTHON_UNUSED int __pyx_lineno = 0;
+ CYTHON_UNUSED const char *__pyx_filename = NULL;
+ CYTHON_UNUSED int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("process (wrapper)", 0);
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_data), __pyx_ptype_5numpy_ndarray, 1, "data", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_6process(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self), ((PyArrayObject *)__pyx_v_data));
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_6process(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self, PyArrayObject *__pyx_v_data) {
+ __Pyx_memviewslice __pyx_v_c_data = { 0, 0, { 0 }, { 0 }, { 0 } };
+ unsigned int __pyx_v_depth;
+ unsigned int __pyx_v_height;
+ unsigned int __pyx_v_width;
+ __Pyx_LocalBuf_ND __pyx_pybuffernd_data;
+ __Pyx_Buffer __pyx_pybuffer_data;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ __Pyx_memviewslice __pyx_t_5 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("process", 0);
+ __pyx_pybuffer_data.pybuffer.buf = NULL;
+ __pyx_pybuffer_data.refcount = 0;
+ __pyx_pybuffernd_data.data = NULL;
+ __pyx_pybuffernd_data.rcbuffer = &__pyx_pybuffer_data;
+ {
+ __Pyx_BufFmt_StackElem __pyx_stack[1];
+ if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_data.rcbuffer->pybuffer, (PyObject*)__pyx_v_data, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 3, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_pybuffernd_data.diminfo[0].strides = __pyx_pybuffernd_data.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_data.diminfo[0].shape = __pyx_pybuffernd_data.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_data.diminfo[1].strides = __pyx_pybuffernd_data.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_data.diminfo[1].shape = __pyx_pybuffernd_data.rcbuffer->pybuffer.shape[1]; __pyx_pybuffernd_data.diminfo[2].strides = __pyx_pybuffernd_data.rcbuffer->pybuffer.strides[2]; __pyx_pybuffernd_data.diminfo[2].shape = __pyx_pybuffernd_data.rcbuffer->pybuffer.shape[2];
+
+ /* "marchingcubes.pyx":152
+ * :param numpy.ndarray data: 3D scalar field
+ * """
+ * cdef float[:] c_data = numpy.ravel(data) # <<<<<<<<<<<<<<
+ * cdef unsigned int depth, height, width
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ravel); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_data)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ __Pyx_INCREF(((PyObject *)__pyx_v_data));
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, ((PyObject *)__pyx_v_data));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_data));
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_t_1);
+ if (unlikely(!__pyx_t_5.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_c_data = __pyx_t_5;
+ __pyx_t_5.memview = NULL;
+ __pyx_t_5.data = NULL;
+
+ /* "marchingcubes.pyx":155
+ * cdef unsigned int depth, height, width
+ *
+ * depth = data.shape[0] # <<<<<<<<<<<<<<
+ * height = data.shape[1]
+ * width = data.shape[2]
+ */
+ __pyx_v_depth = (__pyx_v_data->dimensions[0]);
+
+ /* "marchingcubes.pyx":156
+ *
+ * depth = data.shape[0]
+ * height = data.shape[1] # <<<<<<<<<<<<<<
+ * width = data.shape[2]
+ *
+ */
+ __pyx_v_height = (__pyx_v_data->dimensions[1]);
+
+ /* "marchingcubes.pyx":157
+ * depth = data.shape[0]
+ * height = data.shape[1]
+ * width = data.shape[2] # <<<<<<<<<<<<<<
+ *
+ * self.c_mc.process(&c_data[0], depth, height, width)
+ */
+ __pyx_v_width = (__pyx_v_data->dimensions[2]);
+
+ /* "marchingcubes.pyx":159
+ * width = data.shape[2]
+ *
+ * self.c_mc.process(&c_data[0], depth, height, width) # <<<<<<<<<<<<<<
+ *
+ * def process_slice(self,
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_7 = -1;
+ if (__pyx_t_6 < 0) {
+ __pyx_t_6 += __pyx_v_c_data.shape[0];
+ if (unlikely(__pyx_t_6 < 0)) __pyx_t_7 = 0;
+ } else if (unlikely(__pyx_t_6 >= __pyx_v_c_data.shape[0])) __pyx_t_7 = 0;
+ if (unlikely(__pyx_t_7 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_7);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ try {
+ __pyx_v_self->c_mc->process((&(*((float *) ( /* dim=0 */ (__pyx_v_c_data.data + __pyx_t_6 * __pyx_v_c_data.strides[0]) )))), __pyx_v_depth, __pyx_v_height, __pyx_v_width);
+ } catch(...) {
+ __Pyx_CppExn2PyErr();
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "marchingcubes.pyx":143
+ * raise IndexError("Index out of range")
+ *
+ * def process(self, cnumpy.ndarray[cnumpy.float32_t, ndim=3, mode='c'] data): # <<<<<<<<<<<<<<
+ * """Compute an isosurface from a 3D scalar field.
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_5, 1);
+ { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
+ __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_data.rcbuffer->pybuffer);
+ __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.process", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ goto __pyx_L2;
+ __pyx_L0:;
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_data.rcbuffer->pybuffer);
+ __pyx_L2:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_c_data, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":161
+ * self.c_mc.process(&c_data[0], depth, height, width)
+ *
+ * def process_slice(self, # <<<<<<<<<<<<<<
+ * cnumpy.ndarray[cnumpy.float32_t, ndim=2, mode='c'] slice0,
+ * cnumpy.ndarray[cnumpy.float32_t, ndim=2, mode='c'] slice1):
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_9process_slice(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_8process_slice[] = "MarchingCubes.process_slice(self, ndarray slice0, ndarray slice1)\nProcess a new slice to build the isosurface.\n\n :param numpy.ndarray slice0: Slice previously provided as slice1.\n :param numpy.ndarray slice1: Slice to process.\n ";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_9process_slice(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyArrayObject *__pyx_v_slice0 = 0;
+ PyArrayObject *__pyx_v_slice1 = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("process_slice (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_slice0,&__pyx_n_s_slice1,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_slice0)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_slice1)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("process_slice", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "process_slice") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_slice0 = ((PyArrayObject *)values[0]);
+ __pyx_v_slice1 = ((PyArrayObject *)values[1]);
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("process_slice", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.process_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_slice0), __pyx_ptype_5numpy_ndarray, 1, "slice0", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_slice1), __pyx_ptype_5numpy_ndarray, 1, "slice1", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_8process_slice(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self), __pyx_v_slice0, __pyx_v_slice1);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_8process_slice(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self, PyArrayObject *__pyx_v_slice0, PyArrayObject *__pyx_v_slice1) {
+ __Pyx_memviewslice __pyx_v_c_slice0 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_c_slice1 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_LocalBuf_ND __pyx_pybuffernd_slice0;
+ __Pyx_Buffer __pyx_pybuffer_slice0;
+ __Pyx_LocalBuf_ND __pyx_pybuffernd_slice1;
+ __Pyx_Buffer __pyx_pybuffer_slice1;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ __Pyx_memviewslice __pyx_t_5 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_t_6 = { 0, 0, { 0 }, { 0 }, { 0 } };
+ int __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("process_slice", 0);
+ __pyx_pybuffer_slice0.pybuffer.buf = NULL;
+ __pyx_pybuffer_slice0.refcount = 0;
+ __pyx_pybuffernd_slice0.data = NULL;
+ __pyx_pybuffernd_slice0.rcbuffer = &__pyx_pybuffer_slice0;
+ __pyx_pybuffer_slice1.pybuffer.buf = NULL;
+ __pyx_pybuffer_slice1.refcount = 0;
+ __pyx_pybuffernd_slice1.data = NULL;
+ __pyx_pybuffernd_slice1.rcbuffer = &__pyx_pybuffer_slice1;
+ {
+ __Pyx_BufFmt_StackElem __pyx_stack[1];
+ if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_slice0.rcbuffer->pybuffer, (PyObject*)__pyx_v_slice0, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_pybuffernd_slice0.diminfo[0].strides = __pyx_pybuffernd_slice0.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_slice0.diminfo[0].shape = __pyx_pybuffernd_slice0.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_slice0.diminfo[1].strides = __pyx_pybuffernd_slice0.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_slice0.diminfo[1].shape = __pyx_pybuffernd_slice0.rcbuffer->pybuffer.shape[1];
+ {
+ __Pyx_BufFmt_StackElem __pyx_stack[1];
+ if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_slice1.rcbuffer->pybuffer, (PyObject*)__pyx_v_slice1, &__Pyx_TypeInfo_nn___pyx_t_5numpy_float32_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_pybuffernd_slice1.diminfo[0].strides = __pyx_pybuffernd_slice1.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_slice1.diminfo[0].shape = __pyx_pybuffernd_slice1.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_slice1.diminfo[1].strides = __pyx_pybuffernd_slice1.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_slice1.diminfo[1].shape = __pyx_pybuffernd_slice1.rcbuffer->pybuffer.shape[1];
+
+ /* "marchingcubes.pyx":169
+ * :param numpy.ndarray slice1: Slice to process.
+ * """
+ * assert slice0.shape[0] == slice1.shape[0] # <<<<<<<<<<<<<<
+ * assert slice0.shape[1] == slice1.shape[1]
+ *
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!(((__pyx_v_slice0->dimensions[0]) == (__pyx_v_slice1->dimensions[0])) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "marchingcubes.pyx":170
+ * """
+ * assert slice0.shape[0] == slice1.shape[0]
+ * assert slice0.shape[1] == slice1.shape[1] # <<<<<<<<<<<<<<
+ *
+ * cdef float[:] c_slice0 = numpy.ravel(slice0)
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!(((__pyx_v_slice0->dimensions[1]) == (__pyx_v_slice1->dimensions[1])) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "marchingcubes.pyx":172
+ * assert slice0.shape[1] == slice1.shape[1]
+ *
+ * cdef float[:] c_slice0 = numpy.ravel(slice0) # <<<<<<<<<<<<<<
+ * cdef float[:] c_slice1 = numpy.ravel(slice1)
+ *
+ */
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_ravel); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, ((PyObject *)__pyx_v_slice0)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ __Pyx_INCREF(((PyObject *)__pyx_v_slice0));
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, ((PyObject *)__pyx_v_slice0));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_slice0));
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_5 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_t_1);
+ if (unlikely(!__pyx_t_5.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_c_slice0 = __pyx_t_5;
+ __pyx_t_5.memview = NULL;
+ __pyx_t_5.data = NULL;
+
+ /* "marchingcubes.pyx":173
+ *
+ * cdef float[:] c_slice0 = numpy.ravel(slice0)
+ * cdef float[:] c_slice1 = numpy.ravel(slice1) # <<<<<<<<<<<<<<
+ *
+ * if self.c_mc.depth == 0:
+ */
+ __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_ravel); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_3)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_3) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_4, ((PyObject *)__pyx_v_slice1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_2 = PyTuple_New(1+1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3); __Pyx_GIVEREF(__pyx_t_3); __pyx_t_3 = NULL;
+ __Pyx_INCREF(((PyObject *)__pyx_v_slice1));
+ PyTuple_SET_ITEM(__pyx_t_2, 0+1, ((PyObject *)__pyx_v_slice1));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_slice1));
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_ds_float(__pyx_t_1);
+ if (unlikely(!__pyx_t_6.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_c_slice1 = __pyx_t_6;
+ __pyx_t_6.memview = NULL;
+ __pyx_t_6.data = NULL;
+
+ /* "marchingcubes.pyx":175
+ * cdef float[:] c_slice1 = numpy.ravel(slice1)
+ *
+ * if self.c_mc.depth == 0: # <<<<<<<<<<<<<<
+ * # Starts a new isosurface, bootstrap with slice size
+ * self.c_mc.set_slice_size(slice1.shape[0], slice1.shape[1])
+ */
+ __pyx_t_7 = ((__pyx_v_self->c_mc->depth == 0) != 0);
+ if (__pyx_t_7) {
+
+ /* "marchingcubes.pyx":177
+ * if self.c_mc.depth == 0:
+ * # Starts a new isosurface, bootstrap with slice size
+ * self.c_mc.set_slice_size(slice1.shape[0], slice1.shape[1]) # <<<<<<<<<<<<<<
+ *
+ * assert slice1.shape[0] == self.c_mc.height
+ */
+ __pyx_v_self->c_mc->set_slice_size((__pyx_v_slice1->dimensions[0]), (__pyx_v_slice1->dimensions[1]));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "marchingcubes.pyx":179
+ * self.c_mc.set_slice_size(slice1.shape[0], slice1.shape[1])
+ *
+ * assert slice1.shape[0] == self.c_mc.height # <<<<<<<<<<<<<<
+ * assert slice1.shape[1] == self.c_mc.width
+ *
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!(((__pyx_v_slice1->dimensions[0]) == __pyx_v_self->c_mc->height) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "marchingcubes.pyx":180
+ *
+ * assert slice1.shape[0] == self.c_mc.height
+ * assert slice1.shape[1] == self.c_mc.width # <<<<<<<<<<<<<<
+ *
+ * self.c_mc.process_slice(&c_slice0[0], &c_slice1[0])
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!(((__pyx_v_slice1->dimensions[1]) == __pyx_v_self->c_mc->width) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "marchingcubes.pyx":182
+ * assert slice1.shape[1] == self.c_mc.width
+ *
+ * self.c_mc.process_slice(&c_slice0[0], &c_slice1[0]) # <<<<<<<<<<<<<<
+ *
+ * def finish_process(self):
+ */
+ __pyx_t_8 = 0;
+ __pyx_t_9 = -1;
+ if (__pyx_t_8 < 0) {
+ __pyx_t_8 += __pyx_v_c_slice0.shape[0];
+ if (unlikely(__pyx_t_8 < 0)) __pyx_t_9 = 0;
+ } else if (unlikely(__pyx_t_8 >= __pyx_v_c_slice0.shape[0])) __pyx_t_9 = 0;
+ if (unlikely(__pyx_t_9 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_9);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_10 = 0;
+ __pyx_t_9 = -1;
+ if (__pyx_t_10 < 0) {
+ __pyx_t_10 += __pyx_v_c_slice1.shape[0];
+ if (unlikely(__pyx_t_10 < 0)) __pyx_t_9 = 0;
+ } else if (unlikely(__pyx_t_10 >= __pyx_v_c_slice1.shape[0])) __pyx_t_9 = 0;
+ if (unlikely(__pyx_t_9 != -1)) {
+ __Pyx_RaiseBufferIndexError(__pyx_t_9);
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ try {
+ __pyx_v_self->c_mc->process_slice((&(*((float *) ( /* dim=0 */ (__pyx_v_c_slice0.data + __pyx_t_8 * __pyx_v_c_slice0.strides[0]) )))), (&(*((float *) ( /* dim=0 */ (__pyx_v_c_slice1.data + __pyx_t_10 * __pyx_v_c_slice1.strides[0]) )))));
+ } catch(...) {
+ __Pyx_CppExn2PyErr();
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "marchingcubes.pyx":161
+ * self.c_mc.process(&c_data[0], depth, height, width)
+ *
+ * def process_slice(self, # <<<<<<<<<<<<<<
+ * cnumpy.ndarray[cnumpy.float32_t, ndim=2, mode='c'] slice0,
+ * cnumpy.ndarray[cnumpy.float32_t, ndim=2, mode='c'] slice1):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_5, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
+ { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
+ __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_slice0.rcbuffer->pybuffer);
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_slice1.rcbuffer->pybuffer);
+ __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.process_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ goto __pyx_L2;
+ __pyx_L0:;
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_slice0.rcbuffer->pybuffer);
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_slice1.rcbuffer->pybuffer);
+ __pyx_L2:;
+ __PYX_XDEC_MEMVIEW(&__pyx_v_c_slice0, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_c_slice1, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":184
+ * self.c_mc.process_slice(&c_slice0[0], &c_slice1[0])
+ *
+ * def finish_process(self): # <<<<<<<<<<<<<<
+ * """Clear internal cache after processing slice by slice."""
+ * self.c_mc.finish_process()
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_11finish_process(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_10finish_process[] = "MarchingCubes.finish_process(self)\nClear internal cache after processing slice by slice.";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_11finish_process(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("finish_process (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_10finish_process(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_10finish_process(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("finish_process", 0);
+
+ /* "marchingcubes.pyx":186
+ * def finish_process(self):
+ * """Clear internal cache after processing slice by slice."""
+ * self.c_mc.finish_process() # <<<<<<<<<<<<<<
+ *
+ * def reset(self):
+ */
+ __pyx_v_self->c_mc->finish_process();
+
+ /* "marchingcubes.pyx":184
+ * self.c_mc.process_slice(&c_slice0[0], &c_slice1[0])
+ *
+ * def finish_process(self): # <<<<<<<<<<<<<<
+ * """Clear internal cache after processing slice by slice."""
+ * self.c_mc.finish_process()
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":188
+ * self.c_mc.finish_process()
+ *
+ * def reset(self): # <<<<<<<<<<<<<<
+ * """Reset internal resources including computed isosurface info."""
+ * self.c_mc.reset()
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_12reset[] = "MarchingCubes.reset(self)\nReset internal resources including computed isosurface info.";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_13reset(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("reset (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_12reset(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_12reset(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("reset", 0);
+
+ /* "marchingcubes.pyx":190
+ * def reset(self):
+ * """Reset internal resources including computed isosurface info."""
+ * self.c_mc.reset() # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __pyx_v_self->c_mc->reset();
+
+ /* "marchingcubes.pyx":188
+ * self.c_mc.finish_process()
+ *
+ * def reset(self): # <<<<<<<<<<<<<<
+ * """Reset internal resources including computed isosurface info."""
+ * self.c_mc.reset()
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":194
+ * @cython.embedsignature(False)
+ * @property
+ * def shape(self): # <<<<<<<<<<<<<<
+ * """The shape of the processed scalar field (depth, height, width)."""
+ * return self.c_mc.depth, self.c_mc.height, self.c_mc.width
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_15shape(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_14shape[] = "The shape of the processed scalar field (depth, height, width).";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_15shape(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("shape (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_14shape(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_14shape(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("shape", 0);
+
+ /* "marchingcubes.pyx":196
+ * def shape(self):
+ * """The shape of the processed scalar field (depth, height, width)."""
+ * return self.c_mc.depth, self.c_mc.height, self.c_mc.width # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->c_mc->depth); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->c_mc->height); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->c_mc->width); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "marchingcubes.pyx":194
+ * @cython.embedsignature(False)
+ * @property
+ * def shape(self): # <<<<<<<<<<<<<<
+ * """The shape of the processed scalar field (depth, height, width)."""
+ * return self.c_mc.depth, self.c_mc.height, self.c_mc.width
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.shape", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":200
+ * @cython.embedsignature(False)
+ * @property
+ * def sampling(self): # <<<<<<<<<<<<<<
+ * """The sampling over each dimension (depth, height, width).
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_17sampling(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_16sampling[] = "The sampling over each dimension (depth, height, width).\n\n Default: 1, 1, 1\n ";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_17sampling(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("sampling (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_16sampling(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_16sampling(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("sampling", 0);
+
+ /* "marchingcubes.pyx":205
+ * Default: 1, 1, 1
+ * """
+ * return (self.c_mc.sampling[0], # <<<<<<<<<<<<<<
+ * self.c_mc.sampling[1],
+ * self.c_mc.sampling[2])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_unsigned_int((__pyx_v_self->c_mc->sampling[0])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "marchingcubes.pyx":206
+ * """
+ * return (self.c_mc.sampling[0],
+ * self.c_mc.sampling[1], # <<<<<<<<<<<<<<
+ * self.c_mc.sampling[2])
+ *
+ */
+ __pyx_t_2 = __Pyx_PyInt_From_unsigned_int((__pyx_v_self->c_mc->sampling[1])); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+
+ /* "marchingcubes.pyx":207
+ * return (self.c_mc.sampling[0],
+ * self.c_mc.sampling[1],
+ * self.c_mc.sampling[2]) # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __pyx_t_3 = __Pyx_PyInt_From_unsigned_int((__pyx_v_self->c_mc->sampling[2])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "marchingcubes.pyx":205
+ * Default: 1, 1, 1
+ * """
+ * return (self.c_mc.sampling[0], # <<<<<<<<<<<<<<
+ * self.c_mc.sampling[1],
+ * self.c_mc.sampling[2])
+ */
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "marchingcubes.pyx":200
+ * @cython.embedsignature(False)
+ * @property
+ * def sampling(self): # <<<<<<<<<<<<<<
+ * """The sampling over each dimension (depth, height, width).
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.sampling", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":211
+ * @cython.embedsignature(False)
+ * @property
+ * def isolevel(self): # <<<<<<<<<<<<<<
+ * """The iso-level at which to generate the isosurface"""
+ * return self.c_mc.isolevel
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_19isolevel(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_18isolevel[] = "The iso-level at which to generate the isosurface";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_19isolevel(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("isolevel (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_18isolevel(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_18isolevel(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("isolevel", 0);
+
+ /* "marchingcubes.pyx":213
+ * def isolevel(self):
+ * """The iso-level at which to generate the isosurface"""
+ * return self.c_mc.isolevel # <<<<<<<<<<<<<<
+ *
+ * @cython.embedsignature(False)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyFloat_FromDouble(__pyx_v_self->c_mc->isolevel); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "marchingcubes.pyx":211
+ * @cython.embedsignature(False)
+ * @property
+ * def isolevel(self): # <<<<<<<<<<<<<<
+ * """The iso-level at which to generate the isosurface"""
+ * return self.c_mc.isolevel
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.isolevel", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":217
+ * @cython.embedsignature(False)
+ * @property
+ * def invert_normals(self): # <<<<<<<<<<<<<<
+ * """True to use gradient descent as normals."""
+ * return self.c_mc.invert_normals
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_21invert_normals(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_20invert_normals[] = "True to use gradient descent as normals.";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_21invert_normals(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("invert_normals (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_20invert_normals(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_20invert_normals(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("invert_normals", 0);
+
+ /* "marchingcubes.pyx":219
+ * def invert_normals(self):
+ * """True to use gradient descent as normals."""
+ * return self.c_mc.invert_normals # <<<<<<<<<<<<<<
+ *
+ * def get_vertices(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->c_mc->invert_normals); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "marchingcubes.pyx":217
+ * @cython.embedsignature(False)
+ * @property
+ * def invert_normals(self): # <<<<<<<<<<<<<<
+ * """True to use gradient descent as normals."""
+ * return self.c_mc.invert_normals
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.invert_normals", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":221
+ * return self.c_mc.invert_normals
+ *
+ * def get_vertices(self): # <<<<<<<<<<<<<<
+ * """Vertices currently computed (ndarray of dim NbVertices x 3)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_23get_vertices(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_22get_vertices[] = "MarchingCubes.get_vertices(self)\nVertices currently computed (ndarray of dim NbVertices x 3)\n\n Order is dim0, dim1, dim2 (i.e., z, y, x if dim0 is depth).\n ";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_23get_vertices(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("get_vertices (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_22get_vertices(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_22get_vertices(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_vertices", 0);
+
+ /* "marchingcubes.pyx":226
+ * Order is dim0, dim1, dim2 (i.e., z, y, x if dim0 is depth).
+ * """
+ * return numpy.array(self.c_mc.vertices).reshape(-1, 3) # <<<<<<<<<<<<<<
+ *
+ * def get_normals(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_convert_vector_to_py_float(__pyx_v_self->c_mc->vertices); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "marchingcubes.pyx":221
+ * return self.c_mc.invert_normals
+ *
+ * def get_vertices(self): # <<<<<<<<<<<<<<
+ * """Vertices currently computed (ndarray of dim NbVertices x 3)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.get_vertices", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":228
+ * return numpy.array(self.c_mc.vertices).reshape(-1, 3)
+ *
+ * def get_normals(self): # <<<<<<<<<<<<<<
+ * """Normals currently computed (ndarray of dim NbVertices x 3)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_25get_normals(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_24get_normals[] = "MarchingCubes.get_normals(self)\nNormals currently computed (ndarray of dim NbVertices x 3)\n\n Order is dim0, dim1, dim2 (i.e., z, y, x if dim0 is depth).\n ";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_25get_normals(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("get_normals (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_24get_normals(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_24get_normals(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_normals", 0);
+
+ /* "marchingcubes.pyx":233
+ * Order is dim0, dim1, dim2 (i.e., z, y, x if dim0 is depth).
+ * """
+ * return numpy.array(self.c_mc.normals).reshape(-1, 3) # <<<<<<<<<<<<<<
+ *
+ * def get_indices(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_array); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = __pyx_convert_vector_to_py_float(__pyx_v_self->c_mc->normals); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_reshape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "marchingcubes.pyx":228
+ * return numpy.array(self.c_mc.vertices).reshape(-1, 3)
+ *
+ * def get_normals(self): # <<<<<<<<<<<<<<
+ * """Normals currently computed (ndarray of dim NbVertices x 3)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.get_normals", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "marchingcubes.pyx":235
+ * return numpy.array(self.c_mc.normals).reshape(-1, 3)
+ *
+ * def get_indices(self): # <<<<<<<<<<<<<<
+ * """Triangle indices currently computed (ndarray of dim NbTriangles x 3)
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_27get_indices(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_13marchingcubes_13MarchingCubes_26get_indices[] = "MarchingCubes.get_indices(self)\nTriangle indices currently computed (ndarray of dim NbTriangles x 3)\n ";
+static PyObject *__pyx_pw_13marchingcubes_13MarchingCubes_27get_indices(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("get_indices (wrapper)", 0);
+ __pyx_r = __pyx_pf_13marchingcubes_13MarchingCubes_26get_indices(((struct __pyx_obj_13marchingcubes_MarchingCubes *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_13marchingcubes_13MarchingCubes_26get_indices(struct __pyx_obj_13marchingcubes_MarchingCubes *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_indices", 0);
+
+ /* "marchingcubes.pyx":238
+ * """Triangle indices currently computed (ndarray of dim NbTriangles x 3)
+ * """
+ * return numpy.array(self.c_mc.indices, # <<<<<<<<<<<<<<
+ * dtype=numpy.uint32).reshape(-1, 3)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __pyx_convert_vector_to_py_unsigned_int(__pyx_v_self->c_mc->indices); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "marchingcubes.pyx":239
+ * """
+ * return numpy.array(self.c_mc.indices,
+ * dtype=numpy.uint32).reshape(-1, 3) # <<<<<<<<<<<<<<
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_uint32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "marchingcubes.pyx":238
+ * """Triangle indices currently computed (ndarray of dim NbTriangles x 3)
+ * """
+ * return numpy.array(self.c_mc.indices, # <<<<<<<<<<<<<<
+ * dtype=numpy.uint32).reshape(-1, 3)
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "marchingcubes.pyx":239
+ * """
+ * return numpy.array(self.c_mc.indices,
+ * dtype=numpy.uint32).reshape(-1, 3) # <<<<<<<<<<<<<<
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_reshape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "marchingcubes.pyx":235
+ * return numpy.array(self.c_mc.normals).reshape(-1, 3)
+ *
+ * def get_indices(self): # <<<<<<<<<<<<<<
+ * """Triangle indices currently computed (ndarray of dim NbTriangles x 3)
+ * """
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("marchingcubes.MarchingCubes.get_indices", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_copy_shape;
+ int __pyx_v_i;
+ int __pyx_v_ndim;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ int __pyx_v_t;
+ char *__pyx_v_f;
+ PyArray_Descr *__pyx_v_descr = 0;
+ int __pyx_v_offset;
+ int __pyx_v_hasfields;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":200
+ * # of flags
+ *
+ * if info == NULL: return # <<<<<<<<<<<<<<
+ *
+ * cdef int copy_shape, i, ndim
+ */
+ __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+ if (__pyx_t_1) {
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":204
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ *
+ * ndim = PyArray_NDIM(self)
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<<
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":208
+ * ndim = PyArray_NDIM(self)
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * copy_shape = 1
+ * else:
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * copy_shape = 1 # <<<<<<<<<<<<<<
+ * else:
+ * copy_shape = 0
+ */
+ __pyx_v_copy_shape = 1;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ * copy_shape = 1
+ * else:
+ * copy_shape = 0 # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+ __pyx_v_copy_shape = 0;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":213
+ * copy_shape = 0
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L6_bool_binop_done;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L9_bool_binop_done;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<<
+ * info.ndim = ndim
+ * if copy_shape:
+ */
+ __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim # <<<<<<<<<<<<<<
+ * if copy_shape:
+ * # Allocate new buffer for strides and shape info.
+ */
+ __pyx_v_info->ndim = __pyx_v_ndim;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":223
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim
+ * if copy_shape: # <<<<<<<<<<<<<<
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ */
+ __pyx_t_1 = (__pyx_v_copy_shape != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2) # <<<<<<<<<<<<<<
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":227
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+ __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":228
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ */
+ __pyx_t_4 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<<
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ */
+ (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+ (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+ }
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self) # <<<<<<<<<<<<<<
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self) # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ */
+ __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+ }
+ __pyx_L11:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":234
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<<
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ *
+ */
+ __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<<
+ *
+ * cdef int t
+ */
+ __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *
+ * cdef int t
+ * cdef char* f = NULL # <<<<<<<<<<<<<<
+ * cdef dtype descr = self.descr
+ * cdef list stack
+ */
+ __pyx_v_f = NULL;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":240
+ * cdef int t
+ * cdef char* f = NULL
+ * cdef dtype descr = self.descr # <<<<<<<<<<<<<<
+ * cdef list stack
+ * cdef int offset
+ */
+ __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":244
+ * cdef int offset
+ *
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<<
+ *
+ * if not hasfields and not copy_shape:
+ */
+ __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":246
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ *
+ * if not hasfields and not copy_shape: # <<<<<<<<<<<<<<
+ * # do not call releasebuffer
+ * info.obj = None
+ */
+ __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":248
+ * if not hasfields and not copy_shape:
+ * # do not call releasebuffer
+ * info.obj = None # <<<<<<<<<<<<<<
+ * else:
+ * # need to call releasebuffer
+ */
+ __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = Py_None;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":251
+ * else:
+ * # need to call releasebuffer
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * if not hasfields:
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+ }
+ __pyx_L14:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":253
+ * info.obj = self
+ *
+ * if not hasfields: # <<<<<<<<<<<<<<
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":254
+ *
+ * if not hasfields:
+ * t = descr.type_num # <<<<<<<<<<<<<<
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ */
+ __pyx_t_4 = __pyx_v_descr->type_num;
+ __pyx_v_t = __pyx_t_4;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":255
+ * if not hasfields:
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+ if (!__pyx_t_2) {
+ goto __pyx_L20_next_or;
+ } else {
+ }
+ __pyx_t_2 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_L20_next_or:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L19_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ switch (__pyx_v_t) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ */
+ case NPY_BYTE:
+ __pyx_v_f = __pyx_k_b;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ */
+ case NPY_UBYTE:
+ __pyx_v_f = __pyx_k_B;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ */
+ case NPY_SHORT:
+ __pyx_v_f = __pyx_k_h;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ */
+ case NPY_USHORT:
+ __pyx_v_f = __pyx_k_H;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ */
+ case NPY_INT:
+ __pyx_v_f = __pyx_k_i;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ */
+ case NPY_UINT:
+ __pyx_v_f = __pyx_k_I;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ */
+ case NPY_LONG:
+ __pyx_v_f = __pyx_k_l;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ */
+ case NPY_ULONG:
+ __pyx_v_f = __pyx_k_L;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ */
+ case NPY_LONGLONG:
+ __pyx_v_f = __pyx_k_q;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ */
+ case NPY_ULONGLONG:
+ __pyx_v_f = __pyx_k_Q;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ */
+ case NPY_FLOAT:
+ __pyx_v_f = __pyx_k_f;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ */
+ case NPY_DOUBLE:
+ __pyx_v_f = __pyx_k_d;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ */
+ case NPY_LONGDOUBLE:
+ __pyx_v_f = __pyx_k_g;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+ case NPY_CFLOAT:
+ __pyx_v_f = __pyx_k_Zf;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O"
+ */
+ case NPY_CDOUBLE:
+ __pyx_v_f = __pyx_k_Zd;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ */
+ case NPY_CLONGDOUBLE:
+ __pyx_v_f = __pyx_k_Zg;
+ break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ case NPY_OBJECT:
+ __pyx_v_f = __pyx_k_O;
+ break;
+ default:
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * info.format = f
+ * return
+ */
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ break;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f # <<<<<<<<<<<<<<
+ * return
+ * else:
+ */
+ __pyx_v_info->format = __pyx_v_f;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":278
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f
+ * return # <<<<<<<<<<<<<<
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ * return
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<<
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ */
+ __pyx_v_info->format = ((char *)malloc(255));
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":281
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<<
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1,
+ */
+ (__pyx_v_info->format[0]) = '^';
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":282
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0 # <<<<<<<<<<<<<<
+ * f = _util_dtypestring(descr, info.format + 1,
+ * info.format + _buffer_format_string_len,
+ */
+ __pyx_v_offset = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<<
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ */
+ __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_7;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":286
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<<
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+ (__pyx_v_f[0]) = '\x00';
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+ __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":289
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<<
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":290
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format) # <<<<<<<<<<<<<<
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides)
+ */
+ free(__pyx_v_info->format);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * stdlib.free(info.strides)
+ * # info.shape was stored after info.strides in the same block
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides) # <<<<<<<<<<<<<<
+ * # info.shape was stored after info.strides in the same block
+ *
+ */
+ free(__pyx_v_info->strides);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":769
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ * return PyArray_MultiIterNew(1, <void*>a) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":772
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":775
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":778
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":781
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e) # <<<<<<<<<<<<<<
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+ PyArray_Descr *__pyx_v_child = 0;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ PyObject *__pyx_v_fields = 0;
+ PyObject *__pyx_v_childname = NULL;
+ PyObject *__pyx_v_new_offset = NULL;
+ PyObject *__pyx_v_t = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":790
+ * cdef int delta_offset
+ * cdef tuple i
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * cdef tuple fields
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":791
+ * cdef tuple i
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ * cdef tuple fields
+ *
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ if (unlikely(__pyx_v_descr->names == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+ for (;;) {
+ if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":795
+ *
+ * for childname in descr.names:
+ * fields = descr.fields[childname] # <<<<<<<<<<<<<<
+ * child, new_offset = fields
+ *
+ */
+ __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":796
+ * for childname in descr.names:
+ * fields = descr.fields[childname]
+ * child, new_offset = fields # <<<<<<<<<<<<<<
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+ if (likely(__pyx_v_fields != Py_None)) {
+ PyObject* sequence = __pyx_v_fields;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ #else
+ __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ #endif
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+ __pyx_t_3 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ * child, new_offset = fields
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+ if (!__pyx_t_7) {
+ goto __pyx_L8_next_or;
+ } else {
+ }
+ __pyx_t_7 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_L8_next_or:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * # One could encode it in the format string and have Cython
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":813
+ *
+ * # Output padding bytes
+ * while offset[0] < new_offset: # <<<<<<<<<<<<<<
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ */
+ while (1) {
+ __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (!__pyx_t_6) break;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":814
+ * # Output padding bytes
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<<
+ * f += 1
+ * offset[0] += 1
+ */
+ (__pyx_v_f[0]) = 120;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":815
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte
+ * f += 1 # <<<<<<<<<<<<<<
+ * offset[0] += 1
+ *
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ * offset[0] += 1 # <<<<<<<<<<<<<<
+ *
+ * offset[0] += child.itemsize
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ * offset[0] += 1
+ *
+ * offset[0] += child.itemsize # <<<<<<<<<<<<<<
+ *
+ * if not PyDataType_HASFIELDS(child):
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":820
+ * offset[0] += child.itemsize
+ *
+ * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<<
+ * t = child.type_num
+ * if end - f < 5:
+ */
+ __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ *
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num # <<<<<<<<<<<<<<
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.")
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":822
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num
+ * if end - f < 5: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short.")
+ *
+ */
+ __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 98;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":827
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 66;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":828
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 104;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 72;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 105;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 73;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 108;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 76;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 113;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 81;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 102;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 100;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 103;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 102;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 100;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 103;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 79;
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * f += 1
+ * else:
+ */
+ __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L15:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * f += 1 # <<<<<<<<<<<<<<
+ * else:
+ * # Cython ignores struct boundary information ("T{...}"),
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":849
+ * # Cython ignores struct boundary information ("T{...}"),
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<<
+ * return f
+ *
+ */
+ __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_9;
+ }
+ __pyx_L13:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":850
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset)
+ * return f # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_f;
+ goto __pyx_L0;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_child);
+ __Pyx_XDECREF(__pyx_v_fields);
+ __Pyx_XDECREF(__pyx_v_childname);
+ __Pyx_XDECREF(__pyx_v_new_offset);
+ __Pyx_XDECREF(__pyx_v_t);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+ PyObject *__pyx_v_baseptr;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("set_array_base", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ * cdef PyObject* baseptr
+ * if base is None: # <<<<<<<<<<<<<<
+ * baseptr = NULL
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_base == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * cdef PyObject* baseptr
+ * if base is None:
+ * baseptr = NULL # <<<<<<<<<<<<<<
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ */
+ __pyx_v_baseptr = NULL;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ * baseptr = NULL
+ * else:
+ * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<<
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ */
+ Py_INCREF(__pyx_v_base);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base # <<<<<<<<<<<<<<
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr
+ */
+ __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":973
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base) # <<<<<<<<<<<<<<
+ * arr.base = baseptr
+ *
+ */
+ Py_XDECREF(__pyx_v_arr->base);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr # <<<<<<<<<<<<<<
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ */
+ __pyx_v_arr->base = __pyx_v_baseptr;
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("get_array_base", 0);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL: # <<<<<<<<<<<<<<
+ * return None
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":978
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL:
+ * return None # <<<<<<<<<<<<<<
+ * else:
+ * return <object>arr.base
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ * return None
+ * else:
+ * return <object>arr.base # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+ __pyx_r = ((PyObject *)__pyx_v_arr->base);
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__19);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__19);
+ __Pyx_GIVEREF(__pyx_slice__19);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__20); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__21);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__21);
+ __Pyx_GIVEREF(__pyx_slice__21);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "vector.to_py":78
+ *
+ * @cname("__pyx_convert_vector_to_py_float")
+ * cdef object __pyx_convert_vector_to_py_float(vector[X]& v): # <<<<<<<<<<<<<<
+ * return [X_to_py(v[i]) for i in range(v.size())]
+ *
+ */
+
+static PyObject *__pyx_convert_vector_to_py_float(const std::vector<float> &__pyx_v_v) {
+ size_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ size_t __pyx_t_2;
+ size_t __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_convert_vector_to_py_float", 0);
+
+ /* "vector.to_py":79
+ * @cname("__pyx_convert_vector_to_py_float")
+ * cdef object __pyx_convert_vector_to_py_float(vector[X]& v):
+ * return [X_to_py(v[i]) for i in range(v.size())] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_v.size();
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyFloat_FromDouble((__pyx_v_v[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "vector.to_py":78
+ *
+ * @cname("__pyx_convert_vector_to_py_float")
+ * cdef object __pyx_convert_vector_to_py_float(vector[X]& v): # <<<<<<<<<<<<<<
+ * return [X_to_py(v[i]) for i in range(v.size())]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("vector.to_py.__pyx_convert_vector_to_py_float", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_convert_vector_to_py_unsigned_int(const std::vector<unsigned int> &__pyx_v_v) {
+ size_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ size_t __pyx_t_2;
+ size_t __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__pyx_convert_vector_to_py_unsigned_int", 0);
+
+ /* "vector.to_py":79
+ * @cname("__pyx_convert_vector_to_py_unsigned_int")
+ * cdef object __pyx_convert_vector_to_py_unsigned_int(vector[X]& v):
+ * return [X_to_py(v[i]) for i in range(v.size())] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_v.size();
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = __Pyx_PyInt_From_unsigned_int((__pyx_v_v[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[4]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "vector.to_py":78
+ *
+ * @cname("__pyx_convert_vector_to_py_unsigned_int")
+ * cdef object __pyx_convert_vector_to_py_unsigned_int(vector[X]& v): # <<<<<<<<<<<<<<
+ * return [X_to_py(v[i]) for i in range(v.size())]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("vector.to_py.__pyx_convert_vector_to_py_unsigned_int", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_tp_new_13marchingcubes_MarchingCubes(PyTypeObject *t, PyObject *a, PyObject *k) {
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ if (unlikely(__pyx_pw_13marchingcubes_13MarchingCubes_1__cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_13marchingcubes_MarchingCubes(PyObject *o) {
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_pw_13marchingcubes_13MarchingCubes_3__dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_13marchingcubes_MarchingCubes(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static PyMethodDef __pyx_methods_13marchingcubes_MarchingCubes[] = {
+ {"process", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_7process, METH_O, __pyx_doc_13marchingcubes_13MarchingCubes_6process},
+ {"process_slice", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_9process_slice, METH_VARARGS|METH_KEYWORDS, __pyx_doc_13marchingcubes_13MarchingCubes_8process_slice},
+ {"finish_process", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_11finish_process, METH_NOARGS, __pyx_doc_13marchingcubes_13MarchingCubes_10finish_process},
+ {"reset", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_13reset, METH_NOARGS, __pyx_doc_13marchingcubes_13MarchingCubes_12reset},
+ {"shape", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_15shape, METH_NOARGS, __pyx_doc_13marchingcubes_13MarchingCubes_14shape},
+ {"sampling", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_17sampling, METH_NOARGS, __pyx_doc_13marchingcubes_13MarchingCubes_16sampling},
+ {"isolevel", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_19isolevel, METH_NOARGS, __pyx_doc_13marchingcubes_13MarchingCubes_18isolevel},
+ {"invert_normals", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_21invert_normals, METH_NOARGS, __pyx_doc_13marchingcubes_13MarchingCubes_20invert_normals},
+ {"get_vertices", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_23get_vertices, METH_NOARGS, __pyx_doc_13marchingcubes_13MarchingCubes_22get_vertices},
+ {"get_normals", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_25get_normals, METH_NOARGS, __pyx_doc_13marchingcubes_13MarchingCubes_24get_normals},
+ {"get_indices", (PyCFunction)__pyx_pw_13marchingcubes_13MarchingCubes_27get_indices, METH_NOARGS, __pyx_doc_13marchingcubes_13MarchingCubes_26get_indices},
+ {0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_MarchingCubes = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_13marchingcubes_MarchingCubes, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_MarchingCubes = {
+ 0, /*mp_length*/
+ __pyx_pw_13marchingcubes_13MarchingCubes_5__getitem__, /*mp_subscript*/
+ 0, /*mp_ass_subscript*/
+};
+
+static PyTypeObject __pyx_type_13marchingcubes_MarchingCubes = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "marchingcubes.MarchingCubes", /*tp_name*/
+ sizeof(struct __pyx_obj_13marchingcubes_MarchingCubes), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_13marchingcubes_MarchingCubes, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_MarchingCubes, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_MarchingCubes, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "Compute isosurface using marching cubes algorithm.\n\n It builds a surface from a 3D scalar dataset as a 3D contour at a\n given value.\n The resulting surface is not topologically correct.\n\n See: http://paulbourke.net/geometry/polygonise/\n\n Lorensen, W. E. and Cline, H. E. Marching cubes: A high resolution 3D\n surface construction algorithm. Computer Graphics, 21, 4 (July 1987).\n ACM, 163-169.\n\n Generated vertex and normal coordinates are in the same order\n as input array, i.e., (dim 0, dim 1, dim 2).\n\n Expected indices in memory of a (2, 2, 2) dataset:\n\n dim 0 (depth)\n |\n |\n 4 +------+ 5\n /| /|\n / | / |\n 6 +------+ 7|\n | | | |\n |0 +---|--+ 1 --- dim 2 (width)\n | / | /\n |/ |/\n 2 +------+ 3\n /\n /\n dim 1 (height)\n\n Example with a 3D data set:\n\n >>> vertices, normals, indices = MarchingCubes(data, isolevel=1.)\n\n Example of code for processing a list of images:\n\n >>> mc = MarchingCubes(isolevel=1.) # Create object with iso-level=1\n >>> previous_image = images[0]\n >>> for image in images[1:]:\n ... mc.process_image(previous_image, image) # Process one slice\n ... previous_image = image\n\n >>> vertices = mc.get_vertices() # Array of vertex positions\n >>> normals = mc.get_normals() # Array of normals\n >>> triangle_indices = mc.get_indices() # Array of indices of vertices\n\n :param data: 3D dataset of float32 or None\n :type data: numpy.ndarray of float32 of dimension 3\n :param float isolevel: The value for which to generate the isosurface\n :param bool invert_normals:\n True (default) for normals oriented in direction of gradient descent\n :param sampling: Sampling along each dimension (depth, height, width)\n ", /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_13marchingcubes_MarchingCubes, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_13marchingcubes_MarchingCubes, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "marchingcubes.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "marchingcubes.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "marchingcubes.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "marchingcubes._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "marchingcubes",
+ __pyx_k_This_module_provides_marching_cu, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_05_09_2016, __pyx_k_05_09_2016, sizeof(__pyx_k_05_09_2016), 0, 0, 1, 0},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Index_out_of_range, __pyx_k_Index_out_of_range, sizeof(__pyx_k_Index_out_of_range), 0, 0, 1, 0},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_T_Vincent, __pyx_k_T_Vincent, sizeof(__pyx_k_T_Vincent), 0, 0, 1, 0},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_n_s_get_indices, __pyx_k_get_indices, sizeof(__pyx_k_get_indices), 0, 0, 1, 1},
+ {&__pyx_n_s_get_normals, __pyx_k_get_normals, sizeof(__pyx_k_get_normals), 0, 0, 1, 1},
+ {&__pyx_n_s_get_vertices, __pyx_k_get_vertices, sizeof(__pyx_k_get_vertices), 0, 0, 1, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_invert_normals, __pyx_k_invert_normals, sizeof(__pyx_k_invert_normals), 0, 0, 1, 1},
+ {&__pyx_n_s_isolevel, __pyx_k_isolevel, sizeof(__pyx_k_isolevel), 0, 0, 1, 1},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+ {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_n_s_process, __pyx_k_process, sizeof(__pyx_k_process), 0, 0, 1, 1},
+ {&__pyx_n_s_property, __pyx_k_property, sizeof(__pyx_k_property), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_ravel, __pyx_k_ravel, sizeof(__pyx_k_ravel), 0, 0, 1, 1},
+ {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+ {&__pyx_n_s_sampling, __pyx_k_sampling, sizeof(__pyx_k_sampling), 0, 0, 1, 1},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_slice0, __pyx_k_slice0, sizeof(__pyx_k_slice0), 0, 0, 1, 1},
+ {&__pyx_n_s_slice1, __pyx_k_slice1, sizeof(__pyx_k_slice1), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_n_s_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 0, 1, 1},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_property = __Pyx_GetBuiltinName(__pyx_n_s_property); if (!__pyx_builtin_property) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "marchingcubes.pyx":116
+ *
+ * def __cinit__(self, data=None, isolevel=None,
+ * invert_normals=True, sampling=(1, 1, 1)): # <<<<<<<<<<<<<<
+ * self.c_mc = new mc.MarchingCubes[float, float](isolevel)
+ * self.c_mc.invert_normals = bool(invert_normals)
+ */
+ __pyx_tuple_ = PyTuple_Pack(3, __pyx_int_1, __pyx_int_1, __pyx_int_1); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "marchingcubes.pyx":141
+ * return self.get_indices()
+ * else:
+ * raise IndexError("Index out of range") # <<<<<<<<<<<<<<
+ *
+ * def process(self, cnumpy.ndarray[cnumpy.float32_t, ndim=3, mode='c'] data):
+ */
+ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_Index_out_of_range); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "marchingcubes.pyx":226
+ * Order is dim0, dim1, dim2 (i.e., z, y, x if dim0 is depth).
+ * """
+ * return numpy.array(self.c_mc.vertices).reshape(-1, 3) # <<<<<<<<<<<<<<
+ *
+ * def get_normals(self):
+ */
+ __pyx_tuple__3 = PyTuple_Pack(2, __pyx_int_neg_1, __pyx_int_3); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "marchingcubes.pyx":233
+ * Order is dim0, dim1, dim2 (i.e., z, y, x if dim0 is depth).
+ * """
+ * return numpy.array(self.c_mc.normals).reshape(-1, 3) # <<<<<<<<<<<<<<
+ *
+ * def get_indices(self):
+ */
+ __pyx_tuple__4 = PyTuple_Pack(2, __pyx_int_neg_1, __pyx_int_3); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "marchingcubes.pyx":239
+ * """
+ * return numpy.array(self.c_mc.indices,
+ * dtype=numpy.uint32).reshape(-1, 3) # <<<<<<<<<<<<<<
+ */
+ __pyx_tuple__5 = PyTuple_Pack(2, __pyx_int_neg_1, __pyx_int_3); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__7);
+ __Pyx_GIVEREF(__pyx_tuple__7);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+
+ /* "../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__12);
+ __Pyx_GIVEREF(__pyx_tuple__12);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__13);
+ __Pyx_GIVEREF(__pyx_tuple__13);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__14);
+ __Pyx_GIVEREF(__pyx_tuple__14);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__19 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__19)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__19);
+ __Pyx_GIVEREF(__pyx_slice__19);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__20 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__20)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__20);
+ __Pyx_GIVEREF(__pyx_slice__20);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__21 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__21)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__21);
+ __Pyx_GIVEREF(__pyx_slice__21);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__22);
+ __Pyx_GIVEREF(__pyx_tuple__22);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__23 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__23)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__23);
+ __Pyx_GIVEREF(__pyx_tuple__23);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__24);
+ __Pyx_GIVEREF(__pyx_tuple__24);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__25);
+ __Pyx_GIVEREF(__pyx_tuple__25);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__26);
+ __Pyx_GIVEREF(__pyx_tuple__26);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__27)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__27);
+ __Pyx_GIVEREF(__pyx_tuple__27);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initmarchingcubes(void); /*proto*/
+PyMODINIT_FUNC initmarchingcubes(void)
+#else
+PyMODINIT_FUNC PyInit_marchingcubes(void); /*proto*/
+PyMODINIT_FUNC PyInit_marchingcubes(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_marchingcubes(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("marchingcubes", __pyx_methods, __pyx_k_This_module_provides_marching_cu, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_marchingcubes) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "marchingcubes")) {
+ if (unlikely(PyDict_SetItemString(modules, "marchingcubes", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type_13marchingcubes_MarchingCubes) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type_13marchingcubes_MarchingCubes.tp_print = 0;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ {
+ PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_13marchingcubes_MarchingCubes, "__getitem__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+ __pyx_wrapperbase_13marchingcubes_13MarchingCubes_4__getitem__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+ __pyx_wrapperbase_13marchingcubes_13MarchingCubes_4__getitem__.doc = __pyx_doc_13marchingcubes_13MarchingCubes_4__getitem__;
+ ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_13marchingcubes_13MarchingCubes_4__getitem__;
+ }
+ }
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "MarchingCubes", (PyObject *)&__pyx_type_13marchingcubes_MarchingCubes) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_13marchingcubes_MarchingCubes = &__pyx_type_13marchingcubes_MarchingCubes;
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type",
+ #if CYTHON_COMPILING_IN_PYPY
+ sizeof(PyTypeObject),
+ #else
+ sizeof(PyHeapTypeObject),
+ #endif
+ 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[5]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "marchingcubes.pyx":31
+ * """
+ *
+ * __authors__ = ["T. Vincent"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "05/09/2016"
+ */
+ __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_T_Vincent);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_T_Vincent);
+ __Pyx_GIVEREF(__pyx_kp_s_T_Vincent);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "marchingcubes.pyx":32
+ *
+ * __authors__ = ["T. Vincent"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "05/09/2016"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "marchingcubes.pyx":33
+ * __authors__ = ["T. Vincent"]
+ * __license__ = "MIT"
+ * __date__ = "05/09/2016" # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_05_09_2016) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 33; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "marchingcubes.pyx":36
+ *
+ *
+ * import numpy # <<<<<<<<<<<<<<
+ * cimport numpy as cnumpy
+ * cimport cython
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "marchingcubes.pyx":51
+ * void import_umath()
+ *
+ * if FALSE: # <<<<<<<<<<<<<<
+ * import_array()
+ * import_umath()
+ */
+ __pyx_t_2 = (0 != 0);
+ if (__pyx_t_2) {
+
+ /* "marchingcubes.pyx":52
+ *
+ * if FALSE:
+ * import_array() # <<<<<<<<<<<<<<
+ * import_umath()
+ *
+ */
+ import_array();
+
+ /* "marchingcubes.pyx":53
+ * if FALSE:
+ * import_array()
+ * import_umath() # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ import_umath();
+ goto __pyx_L2;
+ }
+ __pyx_L2:;
+
+ /* "marchingcubes.pyx":194
+ * @cython.embedsignature(False)
+ * @property
+ * def shape(self): # <<<<<<<<<<<<<<
+ * """The shape of the processed scalar field (depth, height, width)."""
+ * return self.c_mc.depth, self.c_mc.height, self.c_mc.width
+ */
+ __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_13marchingcubes_MarchingCubes, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "marchingcubes.pyx":193
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def shape(self):
+ * """The shape of the processed scalar field (depth, height, width)."""
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (PyDict_SetItem((PyObject *)__pyx_ptype_13marchingcubes_MarchingCubes->tp_dict, __pyx_n_s_shape, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_ptype_13marchingcubes_MarchingCubes);
+
+ /* "marchingcubes.pyx":200
+ * @cython.embedsignature(False)
+ * @property
+ * def sampling(self): # <<<<<<<<<<<<<<
+ * """The sampling over each dimension (depth, height, width).
+ *
+ */
+ __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_13marchingcubes_MarchingCubes, __pyx_n_s_sampling); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "marchingcubes.pyx":199
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def sampling(self):
+ * """The sampling over each dimension (depth, height, width).
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (PyDict_SetItem((PyObject *)__pyx_ptype_13marchingcubes_MarchingCubes->tp_dict, __pyx_n_s_sampling, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_ptype_13marchingcubes_MarchingCubes);
+
+ /* "marchingcubes.pyx":211
+ * @cython.embedsignature(False)
+ * @property
+ * def isolevel(self): # <<<<<<<<<<<<<<
+ * """The iso-level at which to generate the isosurface"""
+ * return self.c_mc.isolevel
+ */
+ __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_13marchingcubes_MarchingCubes, __pyx_n_s_isolevel); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "marchingcubes.pyx":210
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def isolevel(self):
+ * """The iso-level at which to generate the isosurface"""
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (PyDict_SetItem((PyObject *)__pyx_ptype_13marchingcubes_MarchingCubes->tp_dict, __pyx_n_s_isolevel, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_ptype_13marchingcubes_MarchingCubes);
+
+ /* "marchingcubes.pyx":217
+ * @cython.embedsignature(False)
+ * @property
+ * def invert_normals(self): # <<<<<<<<<<<<<<
+ * """True to use gradient descent as normals."""
+ * return self.c_mc.invert_normals
+ */
+ __pyx_t_1 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_13marchingcubes_MarchingCubes, __pyx_n_s_invert_normals); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+
+ /* "marchingcubes.pyx":216
+ *
+ * @cython.embedsignature(False)
+ * @property # <<<<<<<<<<<<<<
+ * def invert_normals(self):
+ * """True to use gradient descent as normals."""
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (PyDict_SetItem((PyObject *)__pyx_ptype_13marchingcubes_MarchingCubes->tp_dict, __pyx_n_s_invert_normals, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_ptype_13marchingcubes_MarchingCubes);
+
+ /* "marchingcubes.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * # /[inserted by cython to avoid comment start]*##########################################################################
+ * #
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__23, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "vector.to_py":78
+ *
+ * @cname("__pyx_convert_vector_to_py_unsigned_int")
+ * cdef object __pyx_convert_vector_to_py_unsigned_int(vector[X]& v): # <<<<<<<<<<<<<<
+ * return [X_to_py(v[i]) for i in range(v.size())]
+ *
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init marchingcubes", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init marchingcubes");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+ return __Pyx_PyObject_CallMethO(func, NULL);
+ }
+ }
+ return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
+#endif
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+static void __Pyx_RaiseBufferIndexError(int axis) {
+ PyErr_Format(PyExc_IndexError,
+ "Out of bounds on buffer access (axis %d)", axis);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+static PyObject *__Pyx_GetNameInClass(PyObject *nmspace, PyObject *name) {
+ PyObject *result;
+ result = __Pyx_PyObject_GetAttrStr(nmspace, name);
+ if (!result)
+ result = __Pyx_GetModuleGlobalName(name);
+ return result;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *x) {
+ const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(unsigned int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (unsigned int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(unsigned int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(unsigned int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, long, PyLong_AsLong(x))
+ } else if (sizeof(unsigned int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(unsigned int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ unsigned int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (unsigned int) -1;
+ }
+ } else {
+ unsigned int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (unsigned int) -1;
+ val = __Pyx_PyInt_As_unsigned_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to unsigned int");
+ return (unsigned int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to unsigned int");
+ return (unsigned int) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) {
+ const unsigned int neg_one = (unsigned int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(unsigned int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(unsigned int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(unsigned int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(unsigned int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(unsigned int),
+ little, !is_unsigned);
+ }
+}
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return ::std::complex< float >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return x + y*(__pyx_t_float_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ __pyx_t_float_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrtf(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypotf(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ float denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(a, a);
+ case 3:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, a);
+ case 4:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_absf(a);
+ theta = atan2f(a.imag, a.real);
+ }
+ lnr = logf(r);
+ z_r = expf(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cosf(z_theta);
+ z.imag = z_r * sinf(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return ::std::complex< double >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return x + y*(__pyx_t_double_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ __pyx_t_double_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrt(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypot(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ double denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(a, a);
+ case 3:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, a);
+ case 4:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_abs(a);
+ theta = atan2(a.imag, a.real);
+ }
+ lnr = log(r);
+ z_r = exp(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cos(z_theta);
+ z.imag = z_r * sin(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static CYTHON_INLINE size_t __Pyx_PyInt_As_size_t(PyObject *x) {
+ const size_t neg_one = (size_t) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(size_t) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (size_t) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(size_t) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(size_t) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(size_t, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(size_t, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(size_t) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, long, PyLong_AsLong(x))
+ } else if (sizeof(size_t) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(size_t, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ size_t val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (size_t) -1;
+ }
+ } else {
+ size_t val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (size_t) -1;
+ val = __Pyx_PyInt_As_size_t(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to size_t");
+ return (size_t) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to size_t");
+ return (size_t) -1;
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_ds_float(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_STRIDED) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
+ PyBUF_RECORDS, 1,
+ &__Pyx_TypeInfo_float, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+ PyObject *py_name = 0;
+ PyObject *py_module = 0;
+ py_name = __Pyx_PyIdentifier_FromString(name);
+ if (!py_name)
+ goto bad;
+ py_module = PyImport_Import(py_name);
+ Py_DECREF(py_name);
+ return py_module;
+bad:
+ Py_XDECREF(py_name);
+ return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+ size_t size, int strict)
+{
+ PyObject *py_module = 0;
+ PyObject *result = 0;
+ PyObject *py_name = 0;
+ char warning[200];
+ Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+ PyObject *py_basicsize;
+#endif
+ py_module = __Pyx_ImportModule(module_name);
+ if (!py_module)
+ goto bad;
+ py_name = __Pyx_PyIdentifier_FromString(class_name);
+ if (!py_name)
+ goto bad;
+ result = PyObject_GetAttr(py_module, py_name);
+ Py_DECREF(py_name);
+ py_name = 0;
+ Py_DECREF(py_module);
+ py_module = 0;
+ if (!result)
+ goto bad;
+ if (!PyType_Check(result)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.%.200s is not a type object",
+ module_name, class_name);
+ goto bad;
+ }
+#ifndef Py_LIMITED_API
+ basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+ py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+ if (!py_basicsize)
+ goto bad;
+ basicsize = PyLong_AsSsize_t(py_basicsize);
+ Py_DECREF(py_basicsize);
+ py_basicsize = 0;
+ if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+ goto bad;
+#endif
+ if (!strict && (size_t)basicsize > size) {
+ PyOS_snprintf(warning, sizeof(warning),
+ "%s.%s size changed, may indicate binary incompatibility",
+ module_name, class_name);
+ if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+ }
+ else if ((size_t)basicsize != size) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s.%.200s has the wrong size, try recompiling",
+ module_name, class_name);
+ goto bad;
+ }
+ return (PyTypeObject *)result;
+bad:
+ Py_XDECREF(py_module);
+ Py_XDECREF(result);
+ return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/math/marchingcubes/marchingcubes.pyx b/silx/math/marchingcubes/marchingcubes.pyx
new file mode 100644
index 0000000..8113db5
--- /dev/null
+++ b/silx/math/marchingcubes/marchingcubes.pyx
@@ -0,0 +1,239 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides marching cubes implementation.
+
+It provides a :class:`MarchingCubes` class allowing to build an isosurface
+from data provided as a 3D data set or slice by slice.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/09/2016"
+
+
+import numpy
+cimport numpy as cnumpy
+cimport cython
+
+cimport mc
+
+
+# From numpy_common.pxi to avoid warnings while compiling C code
+# See this thread:
+# https://mail.python.org/pipermail//cython-devel/2012-March/002137.html
+cdef extern from *:
+ bint FALSE "0"
+ void import_array()
+ void import_umath()
+
+if FALSE:
+ import_array()
+ import_umath()
+
+
+cdef class MarchingCubes:
+ """Compute isosurface using marching cubes algorithm.
+
+ It builds a surface from a 3D scalar dataset as a 3D contour at a
+ given value.
+ The resulting surface is not topologically correct.
+
+ See: http://paulbourke.net/geometry/polygonise/
+
+ Lorensen, W. E. and Cline, H. E. Marching cubes: A high resolution 3D
+ surface construction algorithm. Computer Graphics, 21, 4 (July 1987).
+ ACM, 163-169.
+
+ Generated vertex and normal coordinates are in the same order
+ as input array, i.e., (dim 0, dim 1, dim 2).
+
+ Expected indices in memory of a (2, 2, 2) dataset:
+
+ dim 0 (depth)
+ |
+ |
+ 4 +------+ 5
+ /| /|
+ / | / |
+ 6 +------+ 7|
+ | | | |
+ |0 +---|--+ 1 --- dim 2 (width)
+ | / | /
+ |/ |/
+ 2 +------+ 3
+ /
+ /
+ dim 1 (height)
+
+ Example with a 3D data set:
+
+ >>> vertices, normals, indices = MarchingCubes(data, isolevel=1.)
+
+ Example of code for processing a list of images:
+
+ >>> mc = MarchingCubes(isolevel=1.) # Create object with iso-level=1
+ >>> previous_image = images[0]
+ >>> for image in images[1:]:
+ ... mc.process_image(previous_image, image) # Process one slice
+ ... previous_image = image
+
+ >>> vertices = mc.get_vertices() # Array of vertex positions
+ >>> normals = mc.get_normals() # Array of normals
+ >>> triangle_indices = mc.get_indices() # Array of indices of vertices
+
+ :param data: 3D dataset of float32 or None
+ :type data: numpy.ndarray of float32 of dimension 3
+ :param float isolevel: The value for which to generate the isosurface
+ :param bool invert_normals:
+ True (default) for normals oriented in direction of gradient descent
+ :param sampling: Sampling along each dimension (depth, height, width)
+ """
+ cdef mc.MarchingCubes[float, float] * c_mc # Pointer to the C++ instance
+
+ def __cinit__(self, data=None, isolevel=None,
+ invert_normals=True, sampling=(1, 1, 1)):
+ self.c_mc = new mc.MarchingCubes[float, float](isolevel)
+ self.c_mc.invert_normals = bool(invert_normals)
+ self.c_mc.sampling[0] = sampling[0]
+ self.c_mc.sampling[1] = sampling[1]
+ self.c_mc.sampling[2] = sampling[2]
+
+ if data is not None:
+ self.process(data)
+
+ def __dealloc__(self):
+ del self.c_mc
+
+ def __getitem__(self, key):
+ """Allows to unpack object as a single liner:
+
+ vertices, normals, indices = MarchingCubes(...)
+ """
+ if key == 0:
+ return self.get_vertices()
+ elif key == 1:
+ return self.get_normals()
+ elif key == 2:
+ return self.get_indices()
+ else:
+ raise IndexError("Index out of range")
+
+ def process(self, cnumpy.ndarray[cnumpy.float32_t, ndim=3, mode='c'] data):
+ """Compute an isosurface from a 3D scalar field.
+
+ This builds vertices, normals and indices arrays.
+ Vertices and normals coordinates are in the same order as input array,
+ i.e., (dim 0, dim 1, dim 2).
+
+ :param numpy.ndarray data: 3D scalar field
+ """
+ cdef float[:] c_data = numpy.ravel(data)
+ cdef unsigned int depth, height, width
+
+ depth = data.shape[0]
+ height = data.shape[1]
+ width = data.shape[2]
+
+ self.c_mc.process(&c_data[0], depth, height, width)
+
+ def process_slice(self,
+ cnumpy.ndarray[cnumpy.float32_t, ndim=2, mode='c'] slice0,
+ cnumpy.ndarray[cnumpy.float32_t, ndim=2, mode='c'] slice1):
+ """Process a new slice to build the isosurface.
+
+ :param numpy.ndarray slice0: Slice previously provided as slice1.
+ :param numpy.ndarray slice1: Slice to process.
+ """
+ assert slice0.shape[0] == slice1.shape[0]
+ assert slice0.shape[1] == slice1.shape[1]
+
+ cdef float[:] c_slice0 = numpy.ravel(slice0)
+ cdef float[:] c_slice1 = numpy.ravel(slice1)
+
+ if self.c_mc.depth == 0:
+ # Starts a new isosurface, bootstrap with slice size
+ self.c_mc.set_slice_size(slice1.shape[0], slice1.shape[1])
+
+ assert slice1.shape[0] == self.c_mc.height
+ assert slice1.shape[1] == self.c_mc.width
+
+ self.c_mc.process_slice(&c_slice0[0], &c_slice1[0])
+
+ def finish_process(self):
+ """Clear internal cache after processing slice by slice."""
+ self.c_mc.finish_process()
+
+ def reset(self):
+ """Reset internal resources including computed isosurface info."""
+ self.c_mc.reset()
+
+ @cython.embedsignature(False)
+ @property
+ def shape(self):
+ """The shape of the processed scalar field (depth, height, width)."""
+ return self.c_mc.depth, self.c_mc.height, self.c_mc.width
+
+ @cython.embedsignature(False)
+ @property
+ def sampling(self):
+ """The sampling over each dimension (depth, height, width).
+
+ Default: 1, 1, 1
+ """
+ return (self.c_mc.sampling[0],
+ self.c_mc.sampling[1],
+ self.c_mc.sampling[2])
+
+ @cython.embedsignature(False)
+ @property
+ def isolevel(self):
+ """The iso-level at which to generate the isosurface"""
+ return self.c_mc.isolevel
+
+ @cython.embedsignature(False)
+ @property
+ def invert_normals(self):
+ """True to use gradient descent as normals."""
+ return self.c_mc.invert_normals
+
+ def get_vertices(self):
+ """Vertices currently computed (ndarray of dim NbVertices x 3)
+
+ Order is dim0, dim1, dim2 (i.e., z, y, x if dim0 is depth).
+ """
+ return numpy.array(self.c_mc.vertices).reshape(-1, 3)
+
+ def get_normals(self):
+ """Normals currently computed (ndarray of dim NbVertices x 3)
+
+ Order is dim0, dim1, dim2 (i.e., z, y, x if dim0 is depth).
+ """
+ return numpy.array(self.c_mc.normals).reshape(-1, 3)
+
+ def get_indices(self):
+ """Triangle indices currently computed (ndarray of dim NbTriangles x 3)
+ """
+ return numpy.array(self.c_mc.indices,
+ dtype=numpy.uint32).reshape(-1, 3)
diff --git a/silx/math/marchingcubes/mc.hpp b/silx/math/marchingcubes/mc.hpp
new file mode 100644
index 0000000..82eced9
--- /dev/null
+++ b/silx/math/marchingcubes/mc.hpp
@@ -0,0 +1,724 @@
+/*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+#ifndef __mc_HPP__
+#define __mc_HPP__
+
+#include <iostream>
+#include <cmath>
+#include <map>
+#include <stdexcept>
+#include <vector>
+#include <assert.h>
+
+
+extern const int MCTriangleTable[256][16];
+extern const unsigned int MCEdgeIndexToCoordOffsets[12][4];
+
+#define DEPTH_IDX 0
+#define HEIGHT_IDX 1
+#define WIDTH_IDX 2
+
+/** Class Marching cubes
+ *
+ * Implements the marching cube algorithm and provides an API to process
+ * data image by image.
+ *
+ * Dimension convention used is (dim0, dim1, dim2) denoted as
+ * (depth, height, width) with dim2 (= width) being contiguous in memory.
+ *
+ * If data is provided as (depth, height, width), resulting vertices
+ * and normals will be stored as (z, y, x)
+ *
+ * Indices in memory for a single cube:
+ *
+ * dim 0 (depth)
+ * |
+ * |
+ * 4 +------+ 5
+ * /| /|
+ * / | / |
+ * 6 +------+ 7|
+ * | | | |
+ * |0 +---|--+ 1 --- dim 2 (width)
+ * | / | /
+ * |/ |/
+ * 2 +------+ 3
+ * /
+ * /
+ * dim 1 (height)
+ */
+template <typename FloatIn, typename FloatOut>
+class MarchingCubes {
+public:
+ /** Create a marching cube object.
+ *
+ * @param level Level at which to build the isosurface
+ */
+ MarchingCubes(const FloatIn level);
+
+ ~MarchingCubes();
+
+ /** Process a 3D scalar field
+ *
+ * @param data Pointer to the data set
+ * @param depth The 1st dimension of the data set
+ * @param height The 2nd dimension of the data set
+ * @param width The 3rd dimension of the data set
+ * (tightly packed in memory)
+ */
+ void process(const FloatIn * data,
+ const unsigned int depth,
+ const unsigned int height,
+ const unsigned int width);
+
+ /** Init dimension of slices
+ *
+ * @param height Height in pixels of the slices
+ * @param width Width in pixels of the slices
+ */
+ void set_slice_size(const unsigned int height,
+ const unsigned int width);
+
+ /** Process a slice (i.e., an image)
+ *
+ * The size of the images MUST match height and width provided to
+ * set_slice_size.
+ *
+ * The marching cube process 2 consecutive images at a time.
+ * A slice provided as next parameter MUST be provided as current
+ * parameter for the next call.
+ * Example with 3 images:
+ *
+ * float * img1;
+ * float * img2;
+ * float * img3;
+ * ...
+ * mc = MarchingCubes<float>(100.);
+ * mc.set_slice_size(10, 10);
+ * mc.process_slice(img1, img2);
+ * mc.process_slice(img2, img3);
+ * mc.finish_process();
+ *
+ * @param slice0 Pointer to the nth slice data
+ * @param slice1 Pointer to the (n+1)th slice of data
+ */
+ void process_slice(const FloatIn * slice0,
+ const FloatIn * slice1);
+
+ /** Clear marching cube processing internal cache. */
+ void finish_process();
+
+ /** Reset all internal data and counters. */
+ void reset();
+
+ /** Vertices of the isosurface (x, y, z) */
+ std::vector<FloatOut> vertices;
+
+ /** Approximation of normals at the vertices (nx, ny, nz)
+ *
+ * Current implementation provides coarse (but fast) normals computation
+ */
+ std::vector<FloatOut> normals;
+
+ /** Triangle indices */
+ std::vector<unsigned int> indices;
+
+ unsigned int depth; /**< Number of images currently processed */
+ unsigned int height; /**< Images height in pixels */
+ unsigned int width; /**< Images width in pixels */
+
+ /** Sampling of the data (depth, height, width)
+ *
+ * Default: 1, 1, 1
+ */
+ unsigned int sampling[3];
+
+ FloatIn isolevel; /**< Iso level to use */
+ bool invert_normals; /**< True to inverse gradient as normals */
+
+private:
+
+ /** Start to build isosurface starting with first slice
+ *
+ * Bootstrap cache edge_indices
+ *
+ * @param slice The first slice of the data
+ * @param next The second slice
+ */
+ void first_slice(const FloatIn * slice,
+ const FloatIn * next);
+
+ /** Process an edge
+ *
+ * @param value0 Data at 'begining' of edge
+ * @param value Data at 'end' of edge
+ * @param depth Depth coordinate of the edge position
+ * @param row Row coordinate of the edge
+ * @param col Column coordinate of the edge
+ * @param direction Direction of the edge: 0 for x, 1 for y and 2 for z
+ * @param previous
+ * @param current
+ * @param next
+ */
+ void process_edge(const FloatIn value0,
+ const FloatIn value,
+ const unsigned int depth,
+ const unsigned int row,
+ const unsigned int col,
+ const unsigned int direction,
+ const FloatIn * previous,
+ const FloatIn * current,
+ const FloatIn * next);
+
+ /** Return the bit mask of cube corners <= the iso-value.
+ *
+ * @param slice1 1st slice of the cube to consider
+ * @param slice2 2nd slice of the cube to consider
+ * @param row Row of the cube to consider
+ * @param col Column of the cube to consider
+ * @return The bit mask of cube corners <= the iso-value
+ */
+ unsigned char get_cell_code(const FloatIn * slice1,
+ const FloatIn * slice2,
+ const unsigned int row,
+ const unsigned int col);
+
+ /** Compute an edge index from position and edge direction.
+ *
+ * @param depth Depth of the origin of the edge
+ * @param row Row of the origin of the edge
+ * @param col Column of the origin of the edge
+ * @param direction 0 for x, 1 for y, 2 for z
+ * @return The (4D) index of the edge
+ */
+ unsigned int edge_index(const unsigned int depth,
+ const unsigned int row,
+ const unsigned int col,
+ const unsigned int direction);
+
+ /** For each dimension, a map from edge index to vertex index
+ *
+ * This caches indices for previously processed slice.
+ *
+ * Edge index is the linearized position of the edge using size + 1
+ * in all dimensions as coordinates plus the direction as 4th coord.
+ * WARNING: direction 0 for x, 1 for y and 2 for z
+ */
+ std::map<unsigned int, unsigned int> * edge_indices;
+};
+
+
+/* Implementation */
+
+template <typename FloatIn, typename FloatOut>
+MarchingCubes<FloatIn, FloatOut>::MarchingCubes(const FloatIn level)
+{
+ this->edge_indices = 0;
+ this->reset();
+ this->height = 0;
+ this->width = 0;
+ this->isolevel = level;
+ this->invert_normals = true;
+ this->sampling[0] = 1;
+ this->sampling[1] = 1;
+ this->sampling[2] = 1;
+}
+
+template <typename FloatIn, typename FloatOut>
+MarchingCubes<FloatIn, FloatOut>::~MarchingCubes()
+{
+}
+
+template <typename FloatIn, typename FloatOut>
+void
+MarchingCubes<FloatIn, FloatOut>::reset()
+{
+ this->depth = 0;
+ this->vertices.clear();
+ this->normals.clear();
+ this->indices.clear();
+ if (this->edge_indices != 0) {
+ delete this->edge_indices;
+ this->edge_indices = 0;
+ }
+}
+
+template <typename FloatIn, typename FloatOut>
+void
+MarchingCubes<FloatIn, FloatOut>::finish_process()
+{
+ if (this->edge_indices != 0) {
+ delete this->edge_indices;
+ this->edge_indices = 0;
+ }
+}
+
+
+template <typename FloatIn, typename FloatOut>
+void
+MarchingCubes<FloatIn, FloatOut>::process(const FloatIn * data,
+ const unsigned int depth,
+ const unsigned int height,
+ const unsigned int width)
+{
+ assert(data != NULL);
+ unsigned int size = height * width * this->sampling[DEPTH_IDX];
+
+ /* number of slices minus - 1 to process */
+ const unsigned int nb_slices = (depth - 1) / this->sampling[DEPTH_IDX];
+
+ this->reset();
+ this->set_slice_size(height, width);
+
+ for (unsigned int index=0; index < nb_slices; index++) {
+ const FloatIn * slice0 = data + (index * size);
+ const FloatIn * slice1 = slice0 + size;
+
+ this->process_slice(slice0, slice1);
+ }
+ this->finish_process();
+
+ this->depth = depth; /* Forced as it might be < depth otherwise */
+}
+
+
+template <typename FloatIn, typename FloatOut>
+void
+MarchingCubes<FloatIn, FloatOut>::set_slice_size(const unsigned int height,
+ const unsigned int width)
+{
+ this->reset();
+ this->height = height;
+ this->width = width;
+}
+
+
+template <typename FloatIn, typename FloatOut>
+void
+MarchingCubes<FloatIn, FloatOut>::process_slice(const FloatIn * slice0,
+ const FloatIn * slice1)
+{
+ assert(slice0 != NULL);
+ assert(slice1 != NULL);
+ unsigned int row, col;
+
+ if (this->edge_indices == 0) {
+ /* No previously processed slice, bootstrap */
+ this->first_slice(slice0, slice1);
+ }
+
+ /* Keep reference to cache from previous slice */
+ std::map<unsigned int, unsigned int> * previous_edge_indices =
+ this->edge_indices;
+
+ /* Init cache for this slice */
+ this->edge_indices = new std::map<unsigned int, unsigned int>();
+
+ /* Loop over slice to add vertices */
+ for (row=0; row < this->height; row += this->sampling[HEIGHT_IDX]) {
+ unsigned int line_index = row * this->width;
+
+ for (col=0; col < this->width; col += this->sampling[WIDTH_IDX]) {
+ unsigned int item_index = line_index + col;
+
+ FloatIn value0 = slice1[item_index];
+
+ /* Test forward edges and add vertices in the current slice plane */
+ if (col < (width - this->sampling[WIDTH_IDX])) {
+ FloatIn value = slice1[item_index + this->sampling[WIDTH_IDX]];
+
+ this->process_edge(value0, value, this->depth, row, col, 0,
+ slice0, slice1, 0);
+ }
+
+ if (row < (height - this->sampling[HEIGHT_IDX])) {
+ /* Value from next line*/
+ FloatIn value = slice1[item_index + this->width * this->sampling[HEIGHT_IDX]];
+
+ this->process_edge(value0, value, this->depth, row, col, 1,
+ slice0, slice1, 0);
+ }
+
+ /* Test backward edges and add vertices in z direction */
+ {
+ FloatIn value = slice0[item_index];
+
+ /* Expect forward edge, so pass: previous, current */
+ this->process_edge(value, value0,
+ this->depth - this->sampling[DEPTH_IDX],
+ row, col, 2,
+ 0, slice0, slice1);
+ }
+
+ }
+ }
+
+ /* Loop over cubes to add triangle indices */
+ for (row=0; row < this->height - this->sampling[HEIGHT_IDX]; row += this->sampling[HEIGHT_IDX]) {
+ for (col=0; col < this->width - this->sampling[WIDTH_IDX]; col += this->sampling[WIDTH_IDX]) {
+ unsigned char code = this->get_cell_code(slice0, slice1,
+ row, col);
+
+ if (code == 0) {
+ continue;
+ }
+
+ const int * edgeIndexPtr = &MCTriangleTable[code][0];
+ for (; *edgeIndexPtr >= 0; edgeIndexPtr++) {
+ const unsigned int * offsets = \
+ MCEdgeIndexToCoordOffsets[*edgeIndexPtr];
+
+ unsigned int edge_index = this->edge_index(
+ this->depth - this->sampling[DEPTH_IDX] + offsets[DEPTH_IDX] * this->sampling[DEPTH_IDX],
+ row + offsets[HEIGHT_IDX] * this->sampling[HEIGHT_IDX],
+ col + offsets[WIDTH_IDX] * this->sampling[WIDTH_IDX],
+ offsets[3]);
+
+ /* Add vertex index to the list of indices */
+ std::map<unsigned int, unsigned int>::iterator it, end;
+ if (offsets[DEPTH_IDX] == 0 && offsets[3] != 2) {
+ it = previous_edge_indices->find(edge_index);
+ end = previous_edge_indices->end();
+ } else {
+ it = this->edge_indices->find(edge_index);
+ end = this->edge_indices->end();
+ }
+ if (it == end) {
+ throw std::runtime_error(
+ "Internal error: cannot build triangle indices.");
+ }
+ else {
+ this->indices.push_back(it->second);
+ }
+ }
+
+ }
+ }
+
+ /* Clean-up previous slice cache */
+ delete previous_edge_indices;
+
+ this->depth += this->sampling[DEPTH_IDX];
+}
+
+
+template <typename FloatIn, typename FloatOut>
+void
+MarchingCubes<FloatIn, FloatOut>::first_slice(const FloatIn * slice,
+ const FloatIn * next)
+{
+ assert(slice != NULL);
+ assert(next != NULL);
+ /* Init cache for this slice */
+ this->edge_indices = new std::map<unsigned int, unsigned int>();
+
+ unsigned int row, col;
+
+ /* Loop over slice, and add isosurface vertices in the slice plane */
+ for (row=0; row < this->height; row += this->sampling[HEIGHT_IDX]) {
+ unsigned int line_index = row * this->width;
+
+ for (col=0; col < this->width; col += this->sampling[WIDTH_IDX]) {
+ unsigned int item_index = line_index + col;
+
+ /* For each point test forward edges */
+ FloatIn value0 = slice[item_index];
+
+ if (col < (width - this->sampling[WIDTH_IDX])) {
+ FloatIn value = slice[item_index + this->sampling[WIDTH_IDX]];
+
+ this->process_edge(value0, value, this->depth, row, col, 0,
+ 0, slice, next);
+ }
+
+ if (row < (height - this->sampling[HEIGHT_IDX])) {
+ /* Value from next line */
+ FloatIn value = slice[item_index + this->width * this->sampling[HEIGHT_IDX]];
+
+ this->process_edge(value0, value, this->depth, row, col, 1,
+ 0, slice, next);
+ }
+ }
+ }
+
+ this->depth += this->sampling[DEPTH_IDX];
+}
+
+
+template <typename FloatIn, typename FloatOut>
+inline unsigned int
+MarchingCubes<FloatIn, FloatOut>::edge_index(const unsigned int depth,
+ const unsigned int row,
+ const unsigned int col,
+ const unsigned int direction)
+{
+ return ((depth * (this->height + 1) + row) *
+ (this->width + 1) + col) * 3 + direction;
+}
+
+
+template <typename FloatIn, typename FloatOut>
+inline void
+MarchingCubes<FloatIn, FloatOut>::process_edge(const FloatIn value0,
+ const FloatIn value,
+ const unsigned int depth,
+ const unsigned int row,
+ const unsigned int col,
+ const unsigned int direction,
+ const FloatIn * previous,
+ const FloatIn * current,
+ const FloatIn * next)
+{
+ assert(current != NULL);
+
+ if ((value0 <= this->isolevel) ^ (value <= this->isolevel)) {
+
+ /* Crossing iso-surface, store it */
+ FloatIn offset = (this->isolevel - value0) / (value - value0);
+
+ /* Store edge to vertex index correspondance */
+ unsigned int edge_index = this->edge_index(depth, row, col, direction);
+ (*this->edge_indices)[edge_index] = this->vertices.size() / 3;
+
+ /* Store vertex as (z, y, x) */
+ if (direction == 0) {
+ this->vertices.push_back((FloatOut) depth);
+ this->vertices.push_back((FloatOut) row);
+ this->vertices.push_back(
+ (FloatOut) col + offset * this->sampling[WIDTH_IDX]);
+ }
+ else if (direction == 1) {
+ this->vertices.push_back((FloatOut) depth);
+ this->vertices.push_back(
+ (FloatOut) row + offset * this->sampling[HEIGHT_IDX]);
+ this->vertices.push_back((FloatOut) col);
+ }
+ else if (direction == 2) {
+ this->vertices.push_back(
+ (FloatOut) depth + offset * this->sampling[DEPTH_IDX]);
+ this->vertices.push_back((FloatOut) row);
+ this->vertices.push_back((FloatOut) col);
+ } else {
+ throw std::runtime_error(
+ "Internal error: dimension > 3, never event.");
+ }
+
+ /* Store normal as (nz, ny, nx) */
+ FloatOut nz, ny, nx;
+ const FloatIn * slice0 = (previous != 0) ? previous : current;
+ const FloatIn * slice1 = (previous != 0) ? current : next;
+
+ unsigned int row_offset = this->width * this->sampling[HEIGHT_IDX];
+
+ if (direction == 0) {
+ { /* nz */
+ unsigned int item, item_next_col;
+
+ item = row * this->width + col;
+ if (col >= this->width - this->sampling[WIDTH_IDX]) {
+ /* For last column, use previous column */
+ item -= this->sampling[WIDTH_IDX];
+ }
+ item_next_col = item + this->sampling[WIDTH_IDX];
+
+ nz = ((1. - offset) * (slice1[item] - slice0[item]) +
+ offset * (slice1[item_next_col] - slice0[item_next_col]));
+ }
+
+ { /* ny */
+ unsigned int item, item_next_col;
+
+ item = row * this->width + col;
+ if (row >= this->height - this->sampling[HEIGHT_IDX]) {
+ /* For last row, use previous row */
+ item -= row_offset;
+ }
+ if (col >= this->width - this->sampling[WIDTH_IDX]) {
+ /* For last column, use previous column */
+ item -= this->sampling[WIDTH_IDX];
+ }
+ item_next_col = item + this->sampling[WIDTH_IDX];
+
+ ny = ((1. - offset) * (current[item + row_offset] -
+ current[item]) +
+ offset * (current[item_next_col + row_offset] -
+ current[item_next_col]));
+ }
+
+ nx = value - value0;
+
+ } else if (direction == 1) {
+ { /* nz */
+ unsigned int item, item_next_row;
+
+ item = row * this->width + col;
+ if (row >= this->height - this->sampling[HEIGHT_IDX]) {
+ /* For last row, use previous row */
+ item -= row_offset;
+ }
+ item_next_row = item + row_offset;
+
+ nz = ((1. - offset) * (slice1[item] - slice0[item]) +
+ offset * (slice1[item_next_row] - slice0[item_next_row]));
+ }
+
+ ny = value - value0;
+
+ { /* nx */
+ unsigned int item, item_next_row;
+
+ item = row * this->width + col;
+ if (row >= this->height - this->sampling[HEIGHT_IDX]) {
+ /* For last row, use previous row */
+ item -= row_offset;
+ }
+ if (col >= this->width - this->sampling[WIDTH_IDX]) {
+ /* For last column, use previous column */
+ item -= this->sampling[WIDTH_IDX];
+ }
+
+ item_next_row = item + row_offset;
+
+ nx = ((1. - offset) * (current[item + this->sampling[WIDTH_IDX]] - current[item]) +
+ offset * (current[item_next_row + this->sampling[WIDTH_IDX]] - current[item_next_row]));
+ }
+
+ } else { /* direction == 2 */
+ assert(direction == 2);
+ /* Previous should always be 0, only here in case this changes */
+ const FloatIn * other_slice = (previous != 0) ? previous : next;
+
+ nz = value - value0;
+
+ { /* ny */
+ unsigned int item, item_next_row;
+
+ item = row * this->width + col;
+ if (row >= this->height - this->sampling[HEIGHT_IDX]) {
+ /* For last row, use previous row */
+ item -= row_offset;
+ }
+ item_next_row = item + row_offset;
+
+ ny = ((1. - offset) * (current[item_next_row] - current[item]) +
+ offset * (other_slice[item_next_row] - other_slice[item]));
+ }
+
+ { /* nx */
+ unsigned int item;
+
+ item = row * this->width + col;
+ if (col >= this->width - this->sampling[WIDTH_IDX]) {
+ /* For last column, use previous column */
+ item -= this->sampling[WIDTH_IDX];
+ }
+ const unsigned int item_next_col = item + this->sampling[WIDTH_IDX];
+
+ nx = ((1. - offset) * (current[item_next_col] - current[item]) +
+ offset * (other_slice[item_next_col] - other_slice[item]));
+ }
+ }
+
+ /* apply sampling scaling */
+ nz /= (FloatOut) this->sampling[0];
+ ny /= (FloatOut) this->sampling[1];
+ nx /= (FloatOut) this->sampling[2];
+
+ /* normalisation */
+ FloatOut norm = sqrt(nz * nz + ny * ny + nx * nx);
+ if (this->invert_normals) { /* Normal inversion */
+ norm *= -1.;
+ }
+
+ if (norm != 0) {
+ nz /= norm;
+ ny /= norm;
+ nx /= norm;
+ }
+ this->normals.push_back(nz);
+ this->normals.push_back(ny);
+ this->normals.push_back(nx);
+ }
+}
+
+
+template <typename FloatIn, typename FloatOut>
+inline unsigned char
+MarchingCubes<FloatIn, FloatOut>::get_cell_code(const FloatIn * slice1,
+ const FloatIn * slice2,
+ const unsigned int row,
+ const unsigned int col)
+{
+ assert(slice1 != NULL);
+ assert(slice2 != NULL);
+ unsigned int item = row * this->width + col;
+ unsigned int item_next_row = item + this->width * this->sampling[HEIGHT_IDX];
+ unsigned char code = 0;
+
+ /* Cube convention for cell code:
+ * WARNING: This differ from layout in memory
+ *
+ * 4 +------+ 5
+ * /| /|
+ * / | / |
+ * 7 +------+ 6|
+ * | | | |
+ * |0 +---|--+ 1
+ * | / | /
+ * |/ |/
+ * 3 +------+ 2
+ *
+ */
+ /* First slice */
+ if (slice1[item] <= this->isolevel) {
+ code |= 1 << 0;
+ }
+ if (slice1[item + this->sampling[WIDTH_IDX]] <= this->isolevel) {
+ code |= 1 << 1;
+ }
+ if (slice1[item_next_row + this->sampling[WIDTH_IDX]] <= this->isolevel) {
+ code |= 1 << 2;
+ }
+ if (slice1[item_next_row] <= this->isolevel) {
+ code |= 1 << 3;
+ }
+
+ /* Second slice */
+ if (slice2[item] <= this->isolevel) {
+ code |= 1 << 4;
+ }
+ if (slice2[item + this->sampling[WIDTH_IDX]] <= this->isolevel) {
+ code |= 1 << 5;
+ }
+ if (slice2[item_next_row + this->sampling[WIDTH_IDX]] <= this->isolevel) {
+ code |= 1 << 6;
+ }
+ if (slice2[item_next_row] <= this->isolevel) {
+ code |= 1 << 7;
+ }
+
+ return code;
+}
+
+#endif /*__mc_HPP__*/
diff --git a/silx/math/marchingcubes/mc.pxd b/silx/math/marchingcubes/mc.pxd
new file mode 100644
index 0000000..b1c81e7
--- /dev/null
+++ b/silx/math/marchingcubes/mc.pxd
@@ -0,0 +1,51 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+
+from libcpp.vector cimport vector as std_vector
+from libcpp cimport bool
+
+cdef extern from "mc.hpp":
+ cdef cppclass MarchingCubes[FloatIn, FloatOut]:
+ MarchingCubes(FloatIn level) except +
+ void process(FloatIn * data,
+ unsigned int depth,
+ unsigned int height,
+ unsigned int width) except +
+ void set_slice_size(unsigned int height,
+ unsigned int width)
+ void process_slice(FloatIn * slice0,
+ FloatIn * slice1) except +
+ void finish_process()
+ void reset()
+
+ unsigned int depth
+ unsigned int height
+ unsigned int width
+ unsigned int sampling[3]
+ FloatIn isolevel
+ bool invert_normals
+ std_vector[FloatOut] vertices
+ std_vector[FloatOut] normals
+ std_vector[unsigned int] indices
diff --git a/silx/math/marchingcubes/mc_lut.cpp b/silx/math/marchingcubes/mc_lut.cpp
new file mode 100644
index 0000000..7998f1b
--- /dev/null
+++ b/silx/math/marchingcubes/mc_lut.cpp
@@ -0,0 +1,316 @@
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+
+#include "mc.hpp"
+
+
+/** Gives edge index of triangles vertices for each of the 256 possible cubes.
+ *
+ * Table taken from http://paulbourke.net/geometry/polygonise/
+ * Author: Cory Bloyd
+ * Originially this code is public domain,
+ * relicensed here as MIT to provide a license.
+ *
+ * The cube index is a bit mask of cube corners <= isoValue.
+ * See vertexOffset for the place of each corner in the bit mask.
+ */
+const int MCTriangleTable[256][16] = {
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+ {3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+ {3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+ {3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+ {9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
+ {9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+ {2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+ {8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+ {9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+ {4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
+ {3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
+ {1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
+ {4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+ {4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+ {5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+ {2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
+ {9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+ {0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+ {2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
+ {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
+ {4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
+ {5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+ {5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+ {9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+ {0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+ {1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
+ {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
+ {8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
+ {2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+ {7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+ {2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
+ {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
+ {5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
+ {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
+ {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+ {1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
+ {9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+ {5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
+ {2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+ {5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
+ {6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+ {3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
+ {6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+ {5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
+ {1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+ {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+ {6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
+ {8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
+ {7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
+ {3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+ {5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+ {0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
+ {9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
+ {8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+ {5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
+ {0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
+ {6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
+ {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
+ {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+ {8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+ {1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
+ {0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+ {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
+ {3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+ {6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
+ {9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
+ {8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
+ {3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+ {6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+ {0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
+ {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
+ {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+ {2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
+ {7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+ {7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+ {2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
+ {1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
+ {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
+ {8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
+ {0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
+ {7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+ {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+ {2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+ {6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
+ {7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+ {2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
+ {1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
+ {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+ {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
+ {0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
+ {7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+ {6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+ {8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
+ {6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
+ {4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
+ {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
+ {8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+ {0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
+ {1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+ {8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
+ {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+ {4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
+ {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+ {5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+ {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
+ {9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+ {6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
+ {7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
+ {3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
+ {7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
+ {9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
+ {3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
+ {6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
+ {9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
+ {1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
+ {4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
+ {7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
+ {6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+ {3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
+ {0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
+ {6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
+ {0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
+ {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
+ {6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
+ {5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
+ {9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+ {1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
+ {1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
+ {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
+ {0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
+ {5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
+ {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
+ {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
+ {9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
+ {7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
+ {2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+ {8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
+ {9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
+ {9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
+ {1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+ {9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+ {9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+ {5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
+ {0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
+ {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
+ {2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
+ {0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
+ {0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
+ {9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
+ {5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+ {3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
+ {5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
+ {8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
+ {9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+ {0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
+ {1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
+ {3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
+ {4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
+ {9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
+ {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+ {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
+ {2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
+ {9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
+ {3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
+ {1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+ {4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
+ {4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+ {0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+ {3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+ {3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
+ {0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+ {9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
+ {1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
+};
+
+
+/** List edge origin and direction for each edge index in [0-12).
+ *
+ * For each edge, gives the first vertices as 3 coordinates from the origin
+ * of the cube and the direction of the edge as the 4th value.
+ */
+const unsigned int MCEdgeIndexToCoordOffsets[12][4] = {
+ {0, 0, 0, 0},
+ {0, 0, 1, 1},
+ {0, 1, 0, 0},
+ {0, 0, 0, 1},
+ {1, 0, 0, 0},
+ {1, 0, 1, 1},
+ {1, 1, 0, 0},
+ {1, 0, 0, 1},
+ {0, 0, 0, 2},
+ {0, 0, 1, 2},
+ {0, 1, 1, 2},
+ {0, 1, 0, 2}
+};
diff --git a/silx/math/medianfilter/__init__.py b/silx/math/medianfilter/__init__.py
new file mode 100644
index 0000000..fd5c90c
--- /dev/null
+++ b/silx/math/medianfilter/__init__.py
@@ -0,0 +1,30 @@
+# 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.
+#
+# ############################################################################*/
+
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "02/05/2017"
+
+
+from .medianfilter import *
diff --git a/silx/math/medianfilter/include/median_filter.hpp b/silx/math/medianfilter/include/median_filter.hpp
new file mode 100644
index 0000000..da1f9fe
--- /dev/null
+++ b/silx/math/medianfilter/include/median_filter.hpp
@@ -0,0 +1,139 @@
+/*##########################################################################
+#
+# Copyright (c) 2017 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.
+#
+# ###########################################################################*/
+// __authors__ = ["H. Payno"]
+// __license__ = "MIT"
+// __date__ = "10/02/2017"
+
+#ifndef MEDIAN_FILTER
+#define MEDIAN_FILTER
+
+#include <vector>
+#include <assert.h>
+#include <algorithm>
+#include <signal.h>
+
+// Simple function browsing a deque and registring the min and max values
+// and if those values are unique or not
+template<typename T>
+void getMinMax(std::vector<const T*>& v, T& min, T&max){
+ // init min and max values
+ typename std::vector<const T*>::const_iterator it = v.begin();
+ if (v.size() == 0){
+ raise(SIGINT);
+ }else{
+ min = max = *(*it);
+ }
+ it++;
+
+ // Browse all the deque
+ while(it!=v.end()){
+ // check if repeated (should always be before min/max setting)
+ if(*(*it) > max) max = *(*it);
+ if(*(*it) < min) min = *(*it);
+
+ it++;
+ }
+}
+
+template<typename T>
+bool cmp(const T* a, const T* b){
+ return *a < *b;
+}
+
+template<typename T>
+const T* median(std::vector<const T*>& v) {
+ std::nth_element(v.begin(), v.begin() + v.size()/2, v.end(), cmp<T>);
+ return v[v.size()/2];
+}
+
+// Browse the column of pixel_x
+template<typename T>
+void median_filter(
+ const T* input,
+ T* output,
+ int* kernel_dim, // two values : 0:width, 1:height
+ int* image_dim, // two values : 0:width, 1:height
+ int x_pixel, // the x pixel to process
+ int y_pixel_range_min,
+ int y_pixel_range_max,
+ bool conditional){
+
+ assert(kernel_dim[0] > 0);
+ assert(kernel_dim[1] > 0);
+ assert(x_pixel >= 0);
+ assert(image_dim[0] > 0);
+ assert(image_dim[1] > 0);
+ assert(x_pixel >= 0);
+ assert(x_pixel < image_dim[0]);
+ assert(y_pixel_range_max < image_dim[1]);
+ assert(y_pixel_range_min <= y_pixel_range_max);
+ // # kernel odd
+ assert((kernel_dim[0] - 1)%2 == 0);
+ assert((kernel_dim[1] - 1)%2 == 0);
+
+ // # this should be move up to avoid calculation each time
+ int halfKernel_x = (kernel_dim[1] - 1) / 2;
+ int halfKernel_y = (kernel_dim[0] - 1) / 2;
+
+ // init buffer
+ // fill the buffer for the first iteration
+ // we are treating
+ std::vector<const T*> window_values(kernel_dim[0]*kernel_dim[1]);
+
+ for(int pixel_y=y_pixel_range_min; pixel_y <= y_pixel_range_max; pixel_y ++ ){
+ typename std::vector<const T*>::iterator it = window_values.begin();
+ // fill the vector
+ for(int win_y=pixel_y-halfKernel_y; win_y<= pixel_y+halfKernel_y; win_y++)
+ {
+ for(int win_x = x_pixel-halfKernel_x; win_x <= x_pixel+halfKernel_x; win_x++)
+ {
+ int index_x = std::min(std::max(win_x, 0), image_dim[0] - 1);
+ int index_y = std::min(std::max(win_y, 0), image_dim[1] - 1);
+ *it = (&input[index_y*image_dim[0] + index_x]);
+ ++it;
+ }
+ }
+
+ const T* currentPixelValue = &input[image_dim[0]*pixel_y + x_pixel];
+ // change value for the median, only if we don't intend to use the
+ // conditional or if the value of the pixel is one of the extrema
+ // of the pixel value
+ if (conditional == true){
+ T min = 0;
+ T max = 0;
+ getMinMax(window_values, min, max);
+ // In conditional point we are only setting the value to the pixel
+ // if the value is the min or max and unique
+ if ((*currentPixelValue == max) || (*currentPixelValue == min)){
+ output[image_dim[0]*pixel_y + x_pixel] = *(median<T>(window_values));
+ }else{
+ output[image_dim[0]*pixel_y + x_pixel] = *currentPixelValue;
+ }
+ }else{
+ output[image_dim[0]*pixel_y + x_pixel] = *(median<T>(window_values));
+ }
+ }
+}
+
+#endif // MEDIAN_FILTER
diff --git a/silx/math/medianfilter/median_filter.pxd b/silx/math/medianfilter/median_filter.pxd
new file mode 100644
index 0000000..b9d3fd2
--- /dev/null
+++ b/silx/math/medianfilter/median_filter.pxd
@@ -0,0 +1,38 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+
+from libcpp cimport bool
+
+# pyx
+cdef extern from "median_filter.hpp":
+ cdef extern void median_filter[T](const T* image,
+ T* output,
+ int* kernel_dim,
+ int* image_dim,
+ int x_pixel_range_min,
+ int x_pixel_range_max,
+ int y_pixel_range_min,
+ int y_pixel_range_max,
+ bool conditional) nogil;
diff --git a/silx/math/medianfilter/medianfilter.cpp b/silx/math/medianfilter/medianfilter.cpp
new file mode 100644
index 0000000..7ea2899
--- /dev/null
+++ b/silx/math/medianfilter/medianfilter.cpp
@@ -0,0 +1,23404 @@
+/* Generated by Cython 0.21.1 */
+
+#define PY_SSIZE_T_CLEAN
+#ifndef CYTHON_USE_PYLONG_INTERNALS
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#else
+#include "pyconfig.h"
+#ifdef PYLONG_BITS_IN_DIGIT
+#define CYTHON_USE_PYLONG_INTERNALS 1
+#else
+#define CYTHON_USE_PYLONG_INTERNALS 0
+#endif
+#endif
+#endif
+#include "Python.h"
+#ifndef Py_PYTHON_H
+ #error Python headers needed to compile C extensions, please install development version of Python.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+ #error Cython requires Python 2.6+ or Python 3.2+.
+#else
+#define CYTHON_ABI "0_21_1"
+#include <stddef.h>
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+#if !defined(WIN32) && !defined(MS_WINDOWS)
+ #ifndef __stdcall
+ #define __stdcall
+ #endif
+ #ifndef __cdecl
+ #define __cdecl
+ #endif
+ #ifndef __fastcall
+ #define __fastcall
+ #endif
+#endif
+#ifndef DL_IMPORT
+ #define DL_IMPORT(t) t
+#endif
+#ifndef DL_EXPORT
+ #define DL_EXPORT(t) t
+#endif
+#ifndef PY_LONG_LONG
+ #define PY_LONG_LONG LONG_LONG
+#endif
+#ifndef Py_HUGE_VAL
+ #define Py_HUGE_VAL HUGE_VAL
+#endif
+#ifdef PYPY_VERSION
+#define CYTHON_COMPILING_IN_PYPY 1
+#define CYTHON_COMPILING_IN_CPYTHON 0
+#else
+#define CYTHON_COMPILING_IN_PYPY 0
+#define CYTHON_COMPILING_IN_CPYTHON 1
+#endif
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600
+#define Py_OptimizeFlag 0
+#endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyClass_Type
+#else
+ #define __Pyx_BUILTIN_MODULE_NAME "builtins"
+ #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+ PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+ #define __Pyx_DefaultClassType PyType_Type
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define Py_TPFLAGS_CHECKTYPES 0
+ #define Py_TPFLAGS_HAVE_INDEX 0
+ #define Py_TPFLAGS_HAVE_NEWBUFFER 0
+#endif
+#if PY_VERSION_HEX < 0x030400a1 && !defined(Py_TPFLAGS_HAVE_FINALIZE)
+ #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
+#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
+ #define CYTHON_PEP393_ENABLED 1
+ #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ? \
+ 0 : _PyUnicode_Ready((PyObject *)(op)))
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+ #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u)
+ #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u)
+ #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i)
+#else
+ #define CYTHON_PEP393_ENABLED 0
+ #define __Pyx_PyUnicode_READY(op) (0)
+ #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
+ #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
+ #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE))
+ #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u))
+ #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+ #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b)
+ #define __Pyx_PyFrozenSet_Size(s) PyObject_Size(s)
+#else
+ #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b)
+ #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ? \
+ PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+ #define __Pyx_PyFrozenSet_Size(s) PySet_Size(s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b)
+#else
+ #define __Pyx_PyString_Format(a, b) PyString_Format(a, b)
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBaseString_Type PyUnicode_Type
+ #define PyStringObject PyUnicodeObject
+ #define PyString_Type PyUnicode_Type
+ #define PyString_Check PyUnicode_Check
+ #define PyString_CheckExact PyUnicode_CheckExact
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+ #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+ #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+ #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
+#endif
+#ifndef PySet_CheckExact
+ #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type)
+#endif
+#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)
+#if PY_MAJOR_VERSION >= 3
+ #define PyIntObject PyLongObject
+ #define PyInt_Type PyLong_Type
+ #define PyInt_Check(op) PyLong_Check(op)
+ #define PyInt_CheckExact(op) PyLong_CheckExact(op)
+ #define PyInt_FromString PyLong_FromString
+ #define PyInt_FromUnicode PyLong_FromUnicode
+ #define PyInt_FromLong PyLong_FromLong
+ #define PyInt_FromSize_t PyLong_FromSize_t
+ #define PyInt_FromSsize_t PyLong_FromSsize_t
+ #define PyInt_AsLong PyLong_AsLong
+ #define PyInt_AS_LONG PyLong_AS_LONG
+ #define PyInt_AsSsize_t PyLong_AsSsize_t
+ #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
+ #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+ #define PyNumber_Int PyNumber_Long
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define PyBoolObject PyLongObject
+#endif
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+ #ifndef PyUnicode_InternFromString
+ #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+ #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
+ typedef long Py_hash_t;
+ #define __Pyx_PyInt_FromHash_t PyInt_FromLong
+ #define __Pyx_PyInt_AsHash_t PyInt_AsLong
+#else
+ #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
+ #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
+#endif
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+ #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
+#endif
+#ifndef CYTHON_INLINE
+ #if defined(__GNUC__)
+ #define CYTHON_INLINE __inline__
+ #elif defined(_MSC_VER)
+ #define CYTHON_INLINE __inline
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_INLINE inline
+ #else
+ #define CYTHON_INLINE
+ #endif
+#endif
+#ifndef CYTHON_RESTRICT
+ #if defined(__GNUC__)
+ #define CYTHON_RESTRICT __restrict__
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
+ #define CYTHON_RESTRICT __restrict
+ #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+ #define CYTHON_RESTRICT restrict
+ #else
+ #define CYTHON_RESTRICT
+ #endif
+#endif
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
+#else
+static CYTHON_INLINE float __PYX_NAN() {
+ /* Initialize NaN. The sign is irrelevant, an exponent with all bits 1 and
+ a nonzero mantissa means NaN. If the first bit in the mantissa is 1, it is
+ a quiet NaN. */
+ float value;
+ memset(&value, 0xFF, sizeof(value));
+ return value;
+}
+#endif
+#ifdef __cplusplus
+template<typename T>
+void __Pyx_call_destructor(T* x) {
+ x->~T();
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
+#else
+ #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)
+ #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)
+#endif
+
+#ifndef __PYX_EXTERN_C
+ #ifdef __cplusplus
+ #define __PYX_EXTERN_C extern "C"
+ #else
+ #define __PYX_EXTERN_C extern
+ #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+#define _USE_MATH_DEFINES
+#endif
+#include <math.h>
+#define __PYX_HAVE__silx__math__medianfilter__medianfilter
+#define __PYX_HAVE_API__silx__math__medianfilter__medianfilter
+#include "median_filter.hpp"
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "numpy/arrayobject.h"
+#include "numpy/ufuncobject.h"
+#include "pythread.h"
+#include "pystate.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif /* _OPENMP */
+
+#ifdef PYREX_WITHOUT_ASSERTIONS
+#define CYTHON_WITHOUT_ASSERTIONS
+#endif
+
+#ifndef CYTHON_UNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER))
+# define CYTHON_UNUSED __attribute__ ((__unused__))
+# else
+# define CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+ const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed) ( \
+ (sizeof(type) < sizeof(Py_ssize_t)) || \
+ (sizeof(type) > sizeof(Py_ssize_t) && \
+ likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX) && \
+ (!is_signed || likely(v > (type)PY_SSIZE_T_MIN || \
+ v == (type)PY_SSIZE_T_MIN))) || \
+ (sizeof(type) == sizeof(Py_ssize_t) && \
+ (is_signed || likely(v < (type)PY_SSIZE_T_MAX || \
+ v == (type)PY_SSIZE_T_MAX))) )
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+ #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString
+ #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromUString(s) __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromUString(s) __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromUString(s) __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromUString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+ const Py_UNICODE *u_end = u;
+ while (*u_end++) ;
+ return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
+#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
+#if CYTHON_COMPILING_IN_CPYTHON
+#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
+#else
+#define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
+#endif
+#define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ PyObject* ascii_chars_u = NULL;
+ PyObject* ascii_chars_b = NULL;
+ const char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ if (strcmp(default_encoding_c, "ascii") == 0) {
+ __Pyx_sys_getdefaultencoding_not_ascii = 0;
+ } else {
+ char ascii_chars[128];
+ int c;
+ for (c = 0; c < 128; c++) {
+ ascii_chars[c] = c;
+ }
+ __Pyx_sys_getdefaultencoding_not_ascii = 1;
+ ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+ if (!ascii_chars_u) goto bad;
+ ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+ if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+ default_encoding_c);
+ goto bad;
+ }
+ Py_DECREF(ascii_chars_u);
+ Py_DECREF(ascii_chars_b);
+ }
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ Py_XDECREF(ascii_chars_u);
+ Py_XDECREF(ascii_chars_b);
+ return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+ PyObject* sys;
+ PyObject* default_encoding = NULL;
+ char* default_encoding_c;
+ sys = PyImport_ImportModule("sys");
+ if (!sys) goto bad;
+ default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+ Py_DECREF(sys);
+ if (!default_encoding) goto bad;
+ default_encoding_c = PyBytes_AsString(default_encoding);
+ if (!default_encoding_c) goto bad;
+ __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+ if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+ strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+ Py_DECREF(default_encoding);
+ return 0;
+bad:
+ Py_XDECREF(default_encoding);
+ return -1;
+}
+#endif
+#endif
+
+
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+#endif /* __GNUC__ */
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_d;
+static PyObject *__pyx_b;
+static PyObject *__pyx_empty_tuple;
+static PyObject *__pyx_empty_bytes;
+static int __pyx_lineno;
+static int __pyx_clineno = 0;
+static const char * __pyx_cfilenm= __FILE__;
+static const char *__pyx_filename;
+
+#if !defined(CYTHON_CCOMPLEX)
+ #if defined(__cplusplus)
+ #define CYTHON_CCOMPLEX 1
+ #elif defined(_Complex_I)
+ #define CYTHON_CCOMPLEX 1
+ #else
+ #define CYTHON_CCOMPLEX 0
+ #endif
+#endif
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #include <complex>
+ #else
+ #include <complex.h>
+ #endif
+#endif
+#if CYTHON_CCOMPLEX && !defined(__cplusplus) && defined(__sun__) && defined(__GNUC__)
+ #undef _Complex_I
+ #define _Complex_I 1.0fj
+#endif
+
+
+static const char *__pyx_f[] = {
+ "silx/math/medianfilter/medianfilter.pyx",
+ "__init__.pxd",
+ "stringsource",
+ "type.pxd",
+};
+struct __pyx_memoryview_obj;
+typedef struct {
+ struct __pyx_memoryview_obj *memview;
+ char *data;
+ Py_ssize_t shape[8];
+ Py_ssize_t strides[8];
+ Py_ssize_t suboffsets[8];
+} __Pyx_memviewslice;
+
+#define IS_UNSIGNED(type) (((type) -1) > 0)
+struct __Pyx_StructField_;
+#define __PYX_BUF_FLAGS_PACKED_STRUCT (1 << 0)
+typedef struct {
+ const char* name;
+ struct __Pyx_StructField_* fields;
+ size_t size;
+ size_t arraysize[8];
+ int ndim;
+ char typegroup;
+ char is_unsigned;
+ int flags;
+} __Pyx_TypeInfo;
+typedef struct __Pyx_StructField_ {
+ __Pyx_TypeInfo* type;
+ const char* name;
+ size_t offset;
+} __Pyx_StructField;
+typedef struct {
+ __Pyx_StructField* field;
+ size_t parent_offset;
+} __Pyx_BufFmt_StackElem;
+typedef struct {
+ __Pyx_StructField root;
+ __Pyx_BufFmt_StackElem* head;
+ size_t fmt_offset;
+ size_t new_count, enc_count;
+ size_t struct_alignment;
+ int is_complex;
+ char enc_type;
+ char new_packmode;
+ char enc_packmode;
+ char is_valid_array;
+} __Pyx_BufFmt_Context;
+
+#include <pythread.h>
+#ifndef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 1
+#endif
+#define __pyx_atomic_int_type int
+#if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
+ (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
+ !defined(__i386__)
+ #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
+ #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using GNU atomics"
+ #endif
+#elif CYTHON_ATOMICS && MSC_VER
+ #include <Windows.h>
+ #define __pyx_atomic_int_type LONG
+ #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using MSVC atomics"
+ #endif
+#elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
+ #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
+ #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Using Intel atomics"
+ #endif
+#else
+ #undef CYTHON_ATOMICS
+ #define CYTHON_ATOMICS 0
+ #ifdef __PYX_DEBUG_ATOMICS
+ #warning "Not using atomics"
+ #endif
+#endif
+typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
+#if CYTHON_ATOMICS
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
+#else
+ #define __pyx_add_acquisition_count(memview) \
+ __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+ #define __pyx_sub_acquisition_count(memview) \
+ __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
+#endif
+
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":723
+ * # in Cython to enable them only on the right systems.
+ *
+ * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ */
+typedef npy_int8 __pyx_t_5numpy_int8_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":724
+ *
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t
+ */
+typedef npy_int16 __pyx_t_5numpy_int16_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":725
+ * ctypedef npy_int8 int8_t
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_int64 int64_t
+ * #ctypedef npy_int96 int96_t
+ */
+typedef npy_int32 __pyx_t_5numpy_int32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
+ * ctypedef npy_int16 int16_t
+ * ctypedef npy_int32 int32_t
+ * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_int96 int96_t
+ * #ctypedef npy_int128 int128_t
+ */
+typedef npy_int64 __pyx_t_5numpy_int64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":730
+ * #ctypedef npy_int128 int128_t
+ *
+ * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ */
+typedef npy_uint8 __pyx_t_5numpy_uint8_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":731
+ *
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t
+ */
+typedef npy_uint16 __pyx_t_5numpy_uint16_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":732
+ * ctypedef npy_uint8 uint8_t
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uint64 uint64_t
+ * #ctypedef npy_uint96 uint96_t
+ */
+typedef npy_uint32 __pyx_t_5numpy_uint32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
+ * ctypedef npy_uint16 uint16_t
+ * ctypedef npy_uint32 uint32_t
+ * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_uint96 uint96_t
+ * #ctypedef npy_uint128 uint128_t
+ */
+typedef npy_uint64 __pyx_t_5numpy_uint64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":737
+ * #ctypedef npy_uint128 uint128_t
+ *
+ * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<<
+ * ctypedef npy_float64 float64_t
+ * #ctypedef npy_float80 float80_t
+ */
+typedef npy_float32 __pyx_t_5numpy_float32_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":738
+ *
+ * ctypedef npy_float32 float32_t
+ * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<<
+ * #ctypedef npy_float80 float80_t
+ * #ctypedef npy_float128 float128_t
+ */
+typedef npy_float64 __pyx_t_5numpy_float64_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":747
+ * # The int types are mapped a bit surprising --
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t
+ */
+typedef npy_long __pyx_t_5numpy_int_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":748
+ * # numpy.int corresponds to 'l' and numpy.long to 'q'
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longlong longlong_t
+ *
+ */
+typedef npy_longlong __pyx_t_5numpy_long_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":749
+ * ctypedef npy_long int_t
+ * ctypedef npy_longlong long_t
+ * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_ulong uint_t
+ */
+typedef npy_longlong __pyx_t_5numpy_longlong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
+ * ctypedef npy_longlong longlong_t
+ *
+ * ctypedef npy_ulong uint_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t
+ */
+typedef npy_ulong __pyx_t_5numpy_uint_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":752
+ *
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t # <<<<<<<<<<<<<<
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":753
+ * ctypedef npy_ulong uint_t
+ * ctypedef npy_ulonglong ulong_t
+ * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_intp intp_t
+ */
+typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
+ * ctypedef npy_ulonglong ulonglong_t
+ *
+ * ctypedef npy_intp intp_t # <<<<<<<<<<<<<<
+ * ctypedef npy_uintp uintp_t
+ *
+ */
+typedef npy_intp __pyx_t_5numpy_intp_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":756
+ *
+ * ctypedef npy_intp intp_t
+ * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_double float_t
+ */
+typedef npy_uintp __pyx_t_5numpy_uintp_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
+ * ctypedef npy_uintp uintp_t
+ *
+ * ctypedef npy_double float_t # <<<<<<<<<<<<<<
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t
+ */
+typedef npy_double __pyx_t_5numpy_float_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":759
+ *
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t # <<<<<<<<<<<<<<
+ * ctypedef npy_longdouble longdouble_t
+ *
+ */
+typedef npy_double __pyx_t_5numpy_double_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":760
+ * ctypedef npy_double float_t
+ * ctypedef npy_double double_t
+ * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cfloat cfloat_t
+ */
+typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
+
+/* "silx/math/medianfilter/medianfilter.pyx":41
+ * from libcpp cimport bool
+ *
+ * ctypedef unsigned long uint64 # <<<<<<<<<<<<<<
+ * ctypedef unsigned int uint32
+ * ctypedef unsigned short uint16
+ */
+typedef unsigned long __pyx_t_4silx_4math_12medianfilter_12medianfilter_uint64;
+
+/* "silx/math/medianfilter/medianfilter.pyx":42
+ *
+ * ctypedef unsigned long uint64
+ * ctypedef unsigned int uint32 # <<<<<<<<<<<<<<
+ * ctypedef unsigned short uint16
+ *
+ */
+typedef unsigned int __pyx_t_4silx_4math_12medianfilter_12medianfilter_uint32;
+
+/* "silx/math/medianfilter/medianfilter.pyx":43
+ * ctypedef unsigned long uint64
+ * ctypedef unsigned int uint32
+ * ctypedef unsigned short uint16 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+typedef unsigned short __pyx_t_4silx_4math_12medianfilter_12medianfilter_uint16;
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< float > __pyx_t_float_complex;
+ #else
+ typedef float _Complex __pyx_t_float_complex;
+ #endif
+#else
+ typedef struct { float real, imag; } __pyx_t_float_complex;
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ typedef ::std::complex< double > __pyx_t_double_complex;
+ #else
+ typedef double _Complex __pyx_t_double_complex;
+ #endif
+#else
+ typedef struct { double real, imag; } __pyx_t_double_complex;
+#endif
+
+
+/*--- Type declarations ---*/
+struct __pyx_array_obj;
+struct __pyx_MemviewEnum_obj;
+struct __pyx_memoryview_obj;
+struct __pyx_memoryviewslice_obj;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
+ * ctypedef npy_longdouble longdouble_t
+ *
+ * ctypedef npy_cfloat cfloat_t # <<<<<<<<<<<<<<
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t
+ */
+typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":763
+ *
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t # <<<<<<<<<<<<<<
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ */
+typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":764
+ * ctypedef npy_cfloat cfloat_t
+ * ctypedef npy_cdouble cdouble_t
+ * ctypedef npy_clongdouble clongdouble_t # <<<<<<<<<<<<<<
+ *
+ * ctypedef npy_cdouble complex_t
+ */
+typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
+ * ctypedef npy_clongdouble clongdouble_t
+ *
+ * ctypedef npy_cdouble complex_t # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ */
+typedef npy_cdouble __pyx_t_5numpy_complex_t;
+
+/* "View.MemoryView":99
+ *
+ * @cname("__pyx_array")
+ * cdef class array: # <<<<<<<<<<<<<<
+ *
+ * cdef:
+ */
+struct __pyx_array_obj {
+ PyObject_HEAD
+ char *data;
+ Py_ssize_t len;
+ char *format;
+ int ndim;
+ Py_ssize_t *_shape;
+ Py_ssize_t *_strides;
+ Py_ssize_t itemsize;
+ PyObject *mode;
+ PyObject *_format;
+ void (*callback_free_data)(void *);
+ int free_data;
+ int dtype_is_object;
+};
+
+
+/* "View.MemoryView":269
+ *
+ * @cname('__pyx_MemviewEnum')
+ * cdef class Enum(object): # <<<<<<<<<<<<<<
+ * cdef object name
+ * def __init__(self, name):
+ */
+struct __pyx_MemviewEnum_obj {
+ PyObject_HEAD
+ PyObject *name;
+};
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+struct __pyx_memoryview_obj {
+ PyObject_HEAD
+ struct __pyx_vtabstruct_memoryview *__pyx_vtab;
+ PyObject *obj;
+ PyObject *_size;
+ PyObject *_array_interface;
+ PyThread_type_lock lock;
+ __pyx_atomic_int acquisition_count[2];
+ __pyx_atomic_int *acquisition_count_aligned_p;
+ Py_buffer view;
+ int flags;
+ int dtype_is_object;
+ __Pyx_TypeInfo *typeinfo;
+};
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+struct __pyx_memoryviewslice_obj {
+ struct __pyx_memoryview_obj __pyx_base;
+ __Pyx_memviewslice from_slice;
+ PyObject *from_object;
+ PyObject *(*to_object_func)(char *);
+ int (*to_dtype_func)(char *, PyObject *);
+};
+
+
+
+/* "View.MemoryView":302
+ *
+ * @cname('__pyx_memoryview')
+ * cdef class memoryview(object): # <<<<<<<<<<<<<<
+ *
+ * cdef object obj
+ */
+
+struct __pyx_vtabstruct_memoryview {
+ char *(*get_item_pointer)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*is_slice)(struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_slice_assignment)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*setitem_slice_assign_scalar)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *);
+ PyObject *(*setitem_indexed)(struct __pyx_memoryview_obj *, PyObject *, PyObject *);
+ PyObject *(*convert_item_to_object)(struct __pyx_memoryview_obj *, char *);
+ PyObject *(*assign_item_from_object)(struct __pyx_memoryview_obj *, char *, PyObject *);
+};
+static struct __pyx_vtabstruct_memoryview *__pyx_vtabptr_memoryview;
+
+
+/* "View.MemoryView":922
+ *
+ * @cname('__pyx_memoryviewslice')
+ * cdef class _memoryviewslice(memoryview): # <<<<<<<<<<<<<<
+ * "Internal class for passing memoryview slices to Python"
+ *
+ */
+
+struct __pyx_vtabstruct__memoryviewslice {
+ struct __pyx_vtabstruct_memoryview __pyx_base;
+};
+static struct __pyx_vtabstruct__memoryviewslice *__pyx_vtabptr__memoryviewslice;
+#ifndef CYTHON_REFNANNY
+ #define CYTHON_REFNANNY 0
+#endif
+#if CYTHON_REFNANNY
+ typedef struct {
+ void (*INCREF)(void*, PyObject*, int);
+ void (*DECREF)(void*, PyObject*, int);
+ void (*GOTREF)(void*, PyObject*, int);
+ void (*GIVEREF)(void*, PyObject*, int);
+ void* (*SetupContext)(const char*, int, const char*);
+ void (*FinishContext)(void**);
+ } __Pyx_RefNannyAPIStruct;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
+ static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
+ #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
+#ifdef WITH_THREAD
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ if (acquire_gil) { \
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ PyGILState_Release(__pyx_gilstate_save); \
+ } else { \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+ }
+#else
+ #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+ __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
+#endif
+ #define __Pyx_RefNannyFinishContext() \
+ __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
+ #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
+ #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
+ #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
+ #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
+ #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
+#else
+ #define __Pyx_RefNannyDeclarations
+ #define __Pyx_RefNannySetupContext(name, acquire_gil)
+ #define __Pyx_RefNannyFinishContext()
+ #define __Pyx_INCREF(r) Py_INCREF(r)
+ #define __Pyx_DECREF(r) Py_DECREF(r)
+ #define __Pyx_GOTREF(r)
+ #define __Pyx_GIVEREF(r)
+ #define __Pyx_XINCREF(r) Py_XINCREF(r)
+ #define __Pyx_XDECREF(r) Py_XDECREF(r)
+ #define __Pyx_XGOTREF(r)
+ #define __Pyx_XGIVEREF(r)
+#endif
+#define __Pyx_XDECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_XDECREF(tmp); \
+ } while (0)
+#define __Pyx_DECREF_SET(r, v) do { \
+ PyObject *tmp = (PyObject *) r; \
+ r = v; __Pyx_DECREF(tmp); \
+ } while (0)
+#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
+#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+ PyTypeObject* tp = Py_TYPE(obj);
+ if (likely(tp->tp_getattro))
+ return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+ if (likely(tp->tp_getattr))
+ return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+ return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
+ PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
+ const char* function_name);
+
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+ Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) : \
+ (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) : \
+ __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
+ (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
+ __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
+ (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj,
+ __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack);
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
+
+#define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
+#define __Pyx_MEMVIEW_DIRECT 1
+#define __Pyx_MEMVIEW_PTR 2
+#define __Pyx_MEMVIEW_FULL 4
+#define __Pyx_MEMVIEW_CONTIG 8
+#define __Pyx_MEMVIEW_STRIDED 16
+#define __Pyx_MEMVIEW_FOLLOW 32
+#define __Pyx_IS_C_CONTIG 1
+#define __Pyx_IS_F_CONTIG 2
+static int __Pyx_init_memviewslice(
+ struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference);
+static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
+ __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
+#define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
+#define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
+#define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
+#define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
+static CYTHON_INLINE void __Pyx_INC_MEMVIEW(__Pyx_memviewslice *, int, int);
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *, int, int);
+
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact);
+
+#define __Pyx_BufPtrCContig2d(type, buf, i0, s0, i1, s1) ((type)((char*)buf + i0 * s0) + i1)
+#define __Pyx_BufPtrCContig1d(type, buf, i0, s0) ((type)buf + i0)
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t, Py_ssize_t); /* proto */
+
+#ifndef __PYX_FORCE_INIT_THREADS
+ #define __PYX_FORCE_INIT_THREADS 0
+#endif
+
+#define UNARY_NEG_WOULD_OVERFLOW(x) (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len)) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
+#endif
+
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject* none = _PyList_Extend((PyListObject*)L, v);
+ if (unlikely(!none))
+ return -1;
+ Py_DECREF(none);
+ return 0;
+#else
+ return PyList_SetSlice(L, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, v);
+#endif
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+ PyListObject* L = (PyListObject*) list;
+ Py_ssize_t len = Py_SIZE(list);
+ if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+ Py_INCREF(x);
+ PyList_SET_ITEM(list, len, x);
+ Py_SIZE(list) = len+1;
+ return 0;
+ }
+ return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static void __Pyx_WriteUnraisable(const char *name, int clineno,
+ int lineno, const char *filename,
+ int full_traceback);
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+typedef struct {
+ int code_line;
+ PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+ int count;
+ int max_count;
+ __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename);
+
+typedef struct {
+ Py_ssize_t shape, strides, suboffsets;
+} __Pyx_Buf_DimInfo;
+typedef struct {
+ size_t refcount;
+ Py_buffer pybuffer;
+} __Pyx_Buffer;
+typedef struct {
+ __Pyx_Buffer *rcbuffer;
+ char *data;
+ __Pyx_Buf_DimInfo diminfo[8];
+} __Pyx_LocalBuf_ND;
+
+#if PY_MAJOR_VERSION < 3
+ static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
+ static void __Pyx_ReleaseBuffer(Py_buffer *view);
+#else
+ #define __Pyx_GetBuffer PyObject_GetBuffer
+ #define __Pyx_ReleaseBuffer PyBuffer_Release
+#endif
+
+
+static Py_ssize_t __Pyx_zeros[] = {0, 0, 0, 0, 0, 0, 0, 0};
+static Py_ssize_t __Pyx_minusones[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static int __pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b);
+
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_float(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_int32_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_double(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int64_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_uint64_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int32_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_uint32_t(PyObject *);
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int16_t(PyObject *);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ #define __Pyx_CREAL(z) ((z).real())
+ #define __Pyx_CIMAG(z) ((z).imag())
+ #else
+ #define __Pyx_CREAL(z) (__real__(z))
+ #define __Pyx_CIMAG(z) (__imag__(z))
+ #endif
+#else
+ #define __Pyx_CREAL(z) ((z).real)
+ #define __Pyx_CIMAG(z) ((z).imag)
+#endif
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
+ #define __Pyx_SET_CREAL(z,x) ((z).real(x))
+ #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
+#else
+ #define __Pyx_SET_CREAL(z,x) __Pyx_CREAL(z) = (x)
+ #define __Pyx_SET_CIMAG(z,y) __Pyx_CIMAG(z) = (y)
+#endif
+
+static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float, float);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eqf(a, b) ((a)==(b))
+ #define __Pyx_c_sumf(a, b) ((a)+(b))
+ #define __Pyx_c_difff(a, b) ((a)-(b))
+ #define __Pyx_c_prodf(a, b) ((a)*(b))
+ #define __Pyx_c_quotf(a, b) ((a)/(b))
+ #define __Pyx_c_negf(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zerof(z) ((z)==(float)0)
+ #define __Pyx_c_conjf(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_absf(z) (::std::abs(z))
+ #define __Pyx_c_powf(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zerof(z) ((z)==0)
+ #define __Pyx_c_conjf(z) (conjf(z))
+ #if 1
+ #define __Pyx_c_absf(z) (cabsf(z))
+ #define __Pyx_c_powf(a, b) (cpowf(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex, __pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex);
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex);
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex, __pyx_t_float_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double, double);
+
+#if CYTHON_CCOMPLEX
+ #define __Pyx_c_eq(a, b) ((a)==(b))
+ #define __Pyx_c_sum(a, b) ((a)+(b))
+ #define __Pyx_c_diff(a, b) ((a)-(b))
+ #define __Pyx_c_prod(a, b) ((a)*(b))
+ #define __Pyx_c_quot(a, b) ((a)/(b))
+ #define __Pyx_c_neg(a) (-(a))
+ #ifdef __cplusplus
+ #define __Pyx_c_is_zero(z) ((z)==(double)0)
+ #define __Pyx_c_conj(z) (::std::conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (::std::abs(z))
+ #define __Pyx_c_pow(a, b) (::std::pow(a, b))
+ #endif
+ #else
+ #define __Pyx_c_is_zero(z) ((z)==0)
+ #define __Pyx_c_conj(z) (conj(z))
+ #if 1
+ #define __Pyx_c_abs(z) (cabs(z))
+ #define __Pyx_c_pow(a, b) (cpow(a, b))
+ #endif
+ #endif
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex, __pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex);
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex);
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex);
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex, __pyx_t_double_complex);
+ #endif
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
+
+static int __pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim);
+
+static int __pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize);
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object);
+
+static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *);
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
+
+static int __Pyx_check_binary_version(void);
+
+#if !defined(__Pyx_PyIdentifier_FromString)
+#if PY_MAJOR_VERSION < 3
+ #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
+#else
+ #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
+#endif
+#endif
+
+static PyObject *__Pyx_ImportModule(const char *name);
+
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto*/
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src); /* proto*/
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp); /* proto*/
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value); /* proto*/
+
+/* Module declarations from 'cython.view' */
+
+/* Module declarations from 'cython' */
+
+/* Module declarations from 'libcpp' */
+
+/* Module declarations from 'silx.math.medianfilter.median_filter' */
+
+/* Module declarations from 'cpython.buffer' */
+
+/* Module declarations from 'cpython.ref' */
+
+/* Module declarations from 'libc.string' */
+
+/* Module declarations from 'libc.stdio' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from '__builtin__' */
+
+/* Module declarations from 'cpython.type' */
+static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
+
+/* Module declarations from 'libc.stdlib' */
+
+/* Module declarations from 'numpy' */
+
+/* Module declarations from 'numpy' */
+static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
+static PyTypeObject *__pyx_ptype_5numpy_flatiter = 0;
+static PyTypeObject *__pyx_ptype_5numpy_broadcast = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
+static PyTypeObject *__pyx_ptype_5numpy_ufunc = 0;
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, char *, char *, int *); /*proto*/
+
+/* Module declarations from 'silx.math.medianfilter.medianfilter' */
+static PyTypeObject *__pyx_array_type = 0;
+static PyTypeObject *__pyx_MemviewEnum_type = 0;
+static PyTypeObject *__pyx_memoryview_type = 0;
+static PyTypeObject *__pyx_memoryviewslice_type = 0;
+static Py_ssize_t __pyx_v_4silx_4math_12medianfilter_12medianfilter_size;
+static PyObject *generic = 0;
+static PyObject *strided = 0;
+static PyObject *indirect = 0;
+static PyObject *contiguous = 0;
+static PyObject *indirect_contiguous = 0;
+static struct __pyx_array_obj *__pyx_array_new(PyObject *, Py_ssize_t, char *, char *, char *); /*proto*/
+static void *__pyx_align_pointer(void *, size_t); /*proto*/
+static PyObject *__pyx_memoryview_new(PyObject *, int, int, __Pyx_TypeInfo *); /*proto*/
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *); /*proto*/
+static PyObject *_unellipsify(PyObject *, int); /*proto*/
+static PyObject *assert_direct_dimensions(Py_ssize_t *, int); /*proto*/
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *, PyObject *); /*proto*/
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int *, Py_ssize_t, Py_ssize_t, Py_ssize_t, int, int, int, int); /*proto*/
+static char *__pyx_pybuffer_index(Py_buffer *, char *, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memslice_transpose(__Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice, int, PyObject *(*)(char *), int (*)(char *, PyObject *), int); /*proto*/
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *); /*proto*/
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *, __Pyx_memviewslice *); /*proto*/
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t); /*proto*/
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *, int); /*proto*/
+static void _copy_strided_to_strided(char *, Py_ssize_t *, char *, Py_ssize_t *, Py_ssize_t *, Py_ssize_t *, int, size_t); /*proto*/
+static void copy_strided_to_strided(__Pyx_memviewslice *, __Pyx_memviewslice *, int, size_t); /*proto*/
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *, int); /*proto*/
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *, Py_ssize_t *, Py_ssize_t, int, char); /*proto*/
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *, __Pyx_memviewslice *, char, int); /*proto*/
+static int __pyx_memoryview_err_extents(int, Py_ssize_t, Py_ssize_t); /*proto*/
+static int __pyx_memoryview_err_dim(PyObject *, char *, int); /*proto*/
+static int __pyx_memoryview_err(PyObject *, char *); /*proto*/
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice, __Pyx_memviewslice, int, int, int); /*proto*/
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *, int, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_refcount_objects_in_slice(char *, Py_ssize_t *, Py_ssize_t *, int, int); /*proto*/
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *, int, size_t, void *, int); /*proto*/
+static void __pyx_memoryview__slice_assign_scalar(char *, Py_ssize_t *, Py_ssize_t *, int, size_t, void *); /*proto*/
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint16_t = { "uint16_t", NULL, sizeof(__pyx_t_5numpy_uint16_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint16_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint16_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t = { "int32_t", NULL, sizeof(__pyx_t_5numpy_int32_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int32_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int32_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_float = { "float", NULL, sizeof(float), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_double = { "double", NULL, sizeof(double), { 0 }, 0, 'R', 0, 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t = { "int64_t", NULL, sizeof(__pyx_t_5numpy_int64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int64_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t = { "uint64_t", NULL, sizeof(__pyx_t_5numpy_uint64_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint64_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint64_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t = { "uint32_t", NULL, sizeof(__pyx_t_5numpy_uint32_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_uint32_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_uint32_t), 0 };
+static __Pyx_TypeInfo __Pyx_TypeInfo_nn___pyx_t_5numpy_int16_t = { "int16_t", NULL, sizeof(__pyx_t_5numpy_int16_t), { 0 }, 0, IS_UNSIGNED(__pyx_t_5numpy_int16_t) ? 'U' : 'I', IS_UNSIGNED(__pyx_t_5numpy_int16_t), 0 };
+#define __Pyx_MODULE_NAME "silx.math.medianfilter.medianfilter"
+int __pyx_module_is_main_silx__math__medianfilter__medianfilter = 0;
+
+/* Implementation of 'silx.math.medianfilter.medianfilter' */
+static PyObject *__pyx_builtin_ValueError;
+static PyObject *__pyx_builtin_range;
+static PyObject *__pyx_builtin_RuntimeError;
+static PyObject *__pyx_builtin_MemoryError;
+static PyObject *__pyx_builtin_enumerate;
+static PyObject *__pyx_builtin_Ellipsis;
+static PyObject *__pyx_builtin_TypeError;
+static PyObject *__pyx_builtin_xrange;
+static PyObject *__pyx_builtin_id;
+static PyObject *__pyx_builtin_IndexError;
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_medfilt1d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_2medfilt2d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_image, PyObject *__pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_4medfilt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_6check(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_input_buffer, PyObject *__pyx_v_output_buffer); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_8_median_filter_float32(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_10_median_filter_float64(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_12_median_filter_int64(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_14_median_filter_uint64(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_16_median_filter_int32(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_18_median_filter_uint32(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_20_median_filter_int16(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_22_median_filter_uint16(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_input_buffer, PyArrayObject *__pyx_v_output_buffer, PyArrayObject *__pyx_v_kernel_size, bool __pyx_v_conditional); /* proto */
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer); /* proto */
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr); /* proto */
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item); /* proto */
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /* proto */
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name); /* proto */
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object); /* proto */
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index); /* proto */
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /* proto */
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self); /* proto */
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self); /* proto */
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
+static char __pyx_k_B[] = "B";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_c[] = "c";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_x[] = "x";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k_id[] = "id";
+static char __pyx_k_MIT[] = "MIT";
+static char __pyx_k_obj[] = "obj";
+static char __pyx_k_base[] = "base";
+static char __pyx_k_data[] = "data";
+static char __pyx_k_date[] = "__date__";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_mode[] = "mode";
+static char __pyx_k_name[] = "name";
+static char __pyx_k_ndim[] = "ndim";
+static char __pyx_k_pack[] = "pack";
+static char __pyx_k_size[] = "size";
+static char __pyx_k_step[] = "step";
+static char __pyx_k_stop[] = "stop";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_check[] = "check";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_error[] = "error";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_image[] = "image";
+static char __pyx_k_int16[] = "int16";
+static char __pyx_k_int32[] = "int32";
+static char __pyx_k_int64[] = "int64";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_start[] = "start";
+static char __pyx_k_format[] = "format";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_name_2[] = "__name__";
+static char __pyx_k_struct[] = "struct";
+static char __pyx_k_uint16[] = "uint16";
+static char __pyx_k_uint32[] = "uint32";
+static char __pyx_k_uint64[] = "uint64";
+static char __pyx_k_unpack[] = "unpack";
+static char __pyx_k_xrange[] = "xrange";
+static char __pyx_k_H_Payno[] = "H. Payno";
+static char __pyx_k_authors[] = "__authors__";
+static char __pyx_k_float32[] = "float32";
+static char __pyx_k_float64[] = "float64";
+static char __pyx_k_fortran[] = "fortran";
+static char __pyx_k_ker_dim[] = "ker_dim";
+static char __pyx_k_license[] = "__license__";
+static char __pyx_k_medfilt[] = "medfilt";
+static char __pyx_k_memview[] = "memview";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_Ellipsis[] = "Ellipsis";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_reshaped[] = "reshaped";
+static char __pyx_k_J_Kieffer[] = "J. Kieffer";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_enumerate[] = "enumerate";
+static char __pyx_k_image_dim[] = "image_dim";
+static char __pyx_k_medfilt1d[] = "medfilt1d";
+static char __pyx_k_medfilt2d[] = "medfilt2d";
+static char __pyx_k_02_05_2017[] = "02/05/2017";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_zeros_like[] = "zeros_like";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_conditional[] = "conditional";
+static char __pyx_k_kernel_size[] = "kernel_size";
+static char __pyx_k_medfilterfc[] = "medfilterfc";
+static char __pyx_k_C_CONTIGUOUS[] = "C_CONTIGUOUS";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_buffer_shape[] = "buffer_shape";
+static char __pyx_k_input_buffer[] = "input_buffer";
+static char __pyx_k_output_buffer[] = "output_buffer";
+static char __pyx_k_pyx_getbuffer[] = "__pyx_getbuffer";
+static char __pyx_k_allocate_buffer[] = "allocate_buffer";
+static char __pyx_k_dtype_is_object[] = "dtype_is_object";
+static char __pyx_k_strided_and_direct[] = "<strided and direct>";
+static char __pyx_k_median_filter_int16[] = "_median_filter_int16";
+static char __pyx_k_median_filter_int32[] = "_median_filter_int32";
+static char __pyx_k_median_filter_int64[] = "_median_filter_int64";
+static char __pyx_k_median_filter_uint16[] = "_median_filter_uint16";
+static char __pyx_k_median_filter_uint32[] = "_median_filter_uint32";
+static char __pyx_k_median_filter_uint64[] = "_median_filter_uint64";
+static char __pyx_k_strided_and_indirect[] = "<strided and indirect>";
+static char __pyx_k_contiguous_and_direct[] = "<contiguous and direct>";
+static char __pyx_k_median_filter_float32[] = "_median_filter_float32";
+static char __pyx_k_median_filter_float64[] = "_median_filter_float64";
+static char __pyx_k_MemoryView_of_r_object[] = "<MemoryView of %r object>";
+static char __pyx_k_MemoryView_of_r_at_0x_x[] = "<MemoryView of %r at 0x%x>";
+static char __pyx_k_contiguous_and_indirect[] = "<contiguous and indirect>";
+static char __pyx_k_Cannot_index_with_type_s[] = "Cannot index with type '%s'";
+static char __pyx_k_getbuffer_obj_view_flags[] = "getbuffer(obj, view, flags)";
+static char __pyx_k_Dimension_d_is_not_direct[] = "Dimension %d is not direct";
+static char __pyx_k_Invalid_shape_in_axis_d_d[] = "Invalid shape in axis %d: %d.";
+static char __pyx_k_Index_out_of_bounds_axis_d[] = "Index out of bounds (axis %d)";
+static char __pyx_k_Step_may_not_be_zero_axis_d[] = "Step may not be zero (axis %d)";
+static char __pyx_k_itemsize_0_for_cython_array[] = "itemsize <= 0 for cython.array";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_unable_to_allocate_array_data[] = "unable to allocate array data.";
+static char __pyx_k_input_buffer_dimension_must_mo[] = "<input_buffer> dimension must mo higher than 2.";
+static char __pyx_k_strided_and_direct_or_indirect[] = "<strided and direct or indirect>";
+static char __pyx_k_users_payno_Documents_dev_esrf[] = "/users/payno/Documents/dev/esrf/silx/paynoSilx/silx/silx/math/medianfilter/medianfilter.pyx";
+static char __pyx_k_Invalid_data_shape_Dimemsion_of[] = "Invalid data shape. Dimemsion of the arary should be 1 or 2";
+static char __pyx_k_input_buffer_must_be_a_C_CONTIG[] = "<input_buffer> must be a C_CONTIGUOUS numpy array.";
+static char __pyx_k_output_buffer_dimension_must_mo[] = "<output_buffer> dimension must mo higher than 2.";
+static char __pyx_k_output_buffer_must_be_a_C_CONTI[] = "<output_buffer> must be a C_CONTIGUOUS numpy array.";
+static char __pyx_k_s_type_is_not_managed_by_the_me[] = "%s type is not managed by the median filter";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_All_dimensions_preceding_dimensi[] = "All dimensions preceding dimension %d must be indexed and not sliced";
+static char __pyx_k_Buffer_view_does_not_expose_stri[] = "Buffer view does not expose strides";
+static char __pyx_k_Can_only_create_a_buffer_that_is[] = "Can only create a buffer that is contiguous in memory.";
+static char __pyx_k_Cannot_transpose_memoryview_with[] = "Cannot transpose memoryview with indirect dimensions";
+static char __pyx_k_Empty_shape_tuple_for_cython_arr[] = "Empty shape tuple for cython.array";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Indirect_dimensions_not_supporte[] = "Indirect dimensions not supported";
+static char __pyx_k_Invalid_mode_expected_c_or_fortr[] = "Invalid mode, expected 'c' or 'fortran', got %s";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_Out_of_bounds_on_buffer_access_a[] = "Out of bounds on buffer access (axis %d)";
+static char __pyx_k_This_module_provides_median_filt[] = "This module provides median filter function for 1D and 2D arrays.\n";
+static char __pyx_k_Unable_to_convert_item_to_object[] = "Unable to convert item to object";
+static char __pyx_k_got_differing_extents_in_dimensi[] = "got differing extents in dimension %d (got %d and %d)";
+static char __pyx_k_input_buffer_and_output_buffer_m[] = "input buffer and output_buffer must be of the same type";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_silx_math_medianfilter_medianfil[] = "silx.math.medianfilter.medianfilter";
+static char __pyx_k_unable_to_allocate_shape_and_str[] = "unable to allocate shape and strides.";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static char __pyx_k_input_buffer_and_output_buffer_m_2[] = "input buffer and output_buffer must be of the same dimension and same dimension";
+static PyObject *__pyx_kp_s_02_05_2017;
+static PyObject *__pyx_kp_s_Buffer_view_does_not_expose_stri;
+static PyObject *__pyx_n_s_C_CONTIGUOUS;
+static PyObject *__pyx_kp_s_Can_only_create_a_buffer_that_is;
+static PyObject *__pyx_kp_s_Cannot_index_with_type_s;
+static PyObject *__pyx_n_s_Ellipsis;
+static PyObject *__pyx_kp_s_Empty_shape_tuple_for_cython_arr;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_kp_s_H_Payno;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Indirect_dimensions_not_supporte;
+static PyObject *__pyx_kp_s_Invalid_data_shape_Dimemsion_of;
+static PyObject *__pyx_kp_s_Invalid_mode_expected_c_or_fortr;
+static PyObject *__pyx_kp_s_Invalid_shape_in_axis_d_d;
+static PyObject *__pyx_kp_s_J_Kieffer;
+static PyObject *__pyx_n_s_MIT;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_kp_s_MemoryView_of_r_at_0x_x;
+static PyObject *__pyx_kp_s_MemoryView_of_r_object;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_b_O;
+static PyObject *__pyx_kp_s_Out_of_bounds_on_buffer_access_a;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_kp_s_Unable_to_convert_item_to_object;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_n_s_allocate_buffer;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_authors;
+static PyObject *__pyx_n_s_base;
+static PyObject *__pyx_n_s_buffer_shape;
+static PyObject *__pyx_n_s_c;
+static PyObject *__pyx_n_u_c;
+static PyObject *__pyx_n_s_check;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_n_s_conditional;
+static PyObject *__pyx_kp_s_contiguous_and_direct;
+static PyObject *__pyx_kp_s_contiguous_and_indirect;
+static PyObject *__pyx_n_s_data;
+static PyObject *__pyx_n_s_date;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_dtype_is_object;
+static PyObject *__pyx_n_s_enumerate;
+static PyObject *__pyx_n_s_error;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float32;
+static PyObject *__pyx_n_s_float64;
+static PyObject *__pyx_n_s_format;
+static PyObject *__pyx_n_s_fortran;
+static PyObject *__pyx_n_u_fortran;
+static PyObject *__pyx_kp_s_got_differing_extents_in_dimensi;
+static PyObject *__pyx_n_s_id;
+static PyObject *__pyx_n_s_image;
+static PyObject *__pyx_n_s_image_dim;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_input_buffer;
+static PyObject *__pyx_kp_s_input_buffer_and_output_buffer_m;
+static PyObject *__pyx_kp_s_input_buffer_and_output_buffer_m_2;
+static PyObject *__pyx_kp_s_input_buffer_dimension_must_mo;
+static PyObject *__pyx_kp_s_input_buffer_must_be_a_C_CONTIG;
+static PyObject *__pyx_n_s_int16;
+static PyObject *__pyx_n_s_int32;
+static PyObject *__pyx_n_s_int64;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_kp_s_itemsize_0_for_cython_array;
+static PyObject *__pyx_n_s_ker_dim;
+static PyObject *__pyx_n_s_kernel_size;
+static PyObject *__pyx_n_s_license;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_medfilt;
+static PyObject *__pyx_n_s_medfilt1d;
+static PyObject *__pyx_n_s_medfilt2d;
+static PyObject *__pyx_n_s_medfilterfc;
+static PyObject *__pyx_n_s_median_filter_float32;
+static PyObject *__pyx_n_s_median_filter_float64;
+static PyObject *__pyx_n_s_median_filter_int16;
+static PyObject *__pyx_n_s_median_filter_int32;
+static PyObject *__pyx_n_s_median_filter_int64;
+static PyObject *__pyx_n_s_median_filter_uint16;
+static PyObject *__pyx_n_s_median_filter_uint32;
+static PyObject *__pyx_n_s_median_filter_uint64;
+static PyObject *__pyx_n_s_memview;
+static PyObject *__pyx_n_s_mode;
+static PyObject *__pyx_n_s_name;
+static PyObject *__pyx_n_s_name_2;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_ndim;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_obj;
+static PyObject *__pyx_n_s_output_buffer;
+static PyObject *__pyx_kp_s_output_buffer_dimension_must_mo;
+static PyObject *__pyx_kp_s_output_buffer_must_be_a_C_CONTI;
+static PyObject *__pyx_n_s_pack;
+static PyObject *__pyx_n_s_pyx_getbuffer;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_reshaped;
+static PyObject *__pyx_kp_s_s_type_is_not_managed_by_the_me;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_silx_math_medianfilter_medianfil;
+static PyObject *__pyx_n_s_size;
+static PyObject *__pyx_n_s_start;
+static PyObject *__pyx_n_s_step;
+static PyObject *__pyx_n_s_stop;
+static PyObject *__pyx_kp_s_strided_and_direct;
+static PyObject *__pyx_kp_s_strided_and_direct_or_indirect;
+static PyObject *__pyx_kp_s_strided_and_indirect;
+static PyObject *__pyx_n_s_struct;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_n_s_uint16;
+static PyObject *__pyx_n_s_uint32;
+static PyObject *__pyx_n_s_uint64;
+static PyObject *__pyx_kp_s_unable_to_allocate_array_data;
+static PyObject *__pyx_kp_s_unable_to_allocate_shape_and_str;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_n_s_unpack;
+static PyObject *__pyx_kp_s_users_payno_Documents_dev_esrf;
+static PyObject *__pyx_n_s_x;
+static PyObject *__pyx_n_s_xrange;
+static PyObject *__pyx_n_s_zeros_like;
+static PyObject *__pyx_int_0;
+static PyObject *__pyx_int_1;
+static PyObject *__pyx_int_3;
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_tuple__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__21;
+static PyObject *__pyx_slice__22;
+static PyObject *__pyx_slice__23;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__17;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__27;
+static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__31;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_tuple__35;
+static PyObject *__pyx_tuple__37;
+static PyObject *__pyx_tuple__39;
+static PyObject *__pyx_tuple__41;
+static PyObject *__pyx_tuple__43;
+static PyObject *__pyx_tuple__45;
+static PyObject *__pyx_tuple__47;
+static PyObject *__pyx_tuple__49;
+static PyObject *__pyx_tuple__50;
+static PyObject *__pyx_tuple__51;
+static PyObject *__pyx_tuple__52;
+static PyObject *__pyx_tuple__53;
+static PyObject *__pyx_codeobj__26;
+static PyObject *__pyx_codeobj__28;
+static PyObject *__pyx_codeobj__30;
+static PyObject *__pyx_codeobj__32;
+static PyObject *__pyx_codeobj__34;
+static PyObject *__pyx_codeobj__36;
+static PyObject *__pyx_codeobj__38;
+static PyObject *__pyx_codeobj__40;
+static PyObject *__pyx_codeobj__42;
+static PyObject *__pyx_codeobj__44;
+static PyObject *__pyx_codeobj__46;
+static PyObject *__pyx_codeobj__48;
+
+/* "silx/math/medianfilter/medianfilter.pyx":46
+ *
+ *
+ * def medfilt1d(data, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_1medfilt1d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_medfilt1d[] = "medfilt1d(data, kernel_size=3, bool conditional=False)\nFunction computing the median filter of the given input.\n Behavior at boundaries: the algorithm is reducing the size of the\n window/kernel for pixels at boundaries (there is no mirroring).\n\n :param numpy.ndarray data: the array for which we want to apply\n the median filter. Should be 1d.\n :param kernel_size: the dimension of the kernel.\n :type kernel_size: int\n :param bool conditional: True if we want to apply a conditional median\n filtering.\n\n :returns: the array with the median value for each pixel.\n ";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_1medfilt1d = {"medfilt1d", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_1medfilt1d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_medfilt1d};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_1medfilt1d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ PyObject *__pyx_v_kernel_size = 0;
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("medfilt1d (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[3] = {0,0,0};
+ values[1] = ((PyObject *)__pyx_int_3);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "medfilt1d") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = values[0];
+ __pyx_v_kernel_size = values[1];
+ if (values[2]) {
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_conditional = ((bool)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("medfilt1d", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter.medfilt1d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_medfilt1d(__pyx_self, __pyx_v_data, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_medfilt1d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_kernel_size, bool __pyx_v_conditional) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("medfilt1d", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":60
+ * :returns: the array with the median value for each pixel.
+ * """
+ * return medfilt(data, kernel_size, conditional) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_medfilt); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_conditional); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ __pyx_t_5 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_5 = 1;
+ }
+ }
+ __pyx_t_6 = PyTuple_New(3+__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __Pyx_INCREF(__pyx_v_kernel_size);
+ PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_kernel_size);
+ __Pyx_GIVEREF(__pyx_v_kernel_size);
+ PyTuple_SET_ITEM(__pyx_t_6, 2+__pyx_t_5, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":46
+ *
+ *
+ * def medfilt1d(data, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter.medfilt1d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":63
+ *
+ *
+ * def medfilt2d(image, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_3medfilt2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_2medfilt2d[] = "medfilt2d(image, kernel_size=3, bool conditional=False)\nFunction computing the median filter of the given input.\n Behavior at boundaries: the algorithm is reducing the size of the\n window/kernel for pixels at boundaries (there is no mirroring).\n\n :param numpy.ndarray data: the array for which we want to apply\n the median filter. Should be 2d.\n :param kernel_size: the dimension of the kernel.\n :type kernel_size: For 1D should be an int for 2D should be a tuple or\n a list of (kernel_height, kernel_width)\n :param bool conditional: True if we want to apply a conditional median\n filtering.\n\n :returns: the array with the median value for each pixel.\n ";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_3medfilt2d = {"medfilt2d", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_3medfilt2d, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_2medfilt2d};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_3medfilt2d(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_image = 0;
+ PyObject *__pyx_v_kernel_size = 0;
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("medfilt2d (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_image,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[3] = {0,0,0};
+ values[1] = ((PyObject *)__pyx_int_3);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_image)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "medfilt2d") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_image = values[0];
+ __pyx_v_kernel_size = values[1];
+ if (values[2]) {
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_conditional = ((bool)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("medfilt2d", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter.medfilt2d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_2medfilt2d(__pyx_self, __pyx_v_image, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_2medfilt2d(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_image, PyObject *__pyx_v_kernel_size, bool __pyx_v_conditional) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("medfilt2d", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":78
+ * :returns: the array with the median value for each pixel.
+ * """
+ * return medfilt(image, kernel_size, conditional) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_medfilt); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_conditional); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = NULL;
+ __pyx_t_5 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_2))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_2, function);
+ __pyx_t_5 = 1;
+ }
+ }
+ __pyx_t_6 = PyTuple_New(3+__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ if (__pyx_t_4) {
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_image);
+ PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_v_image);
+ __Pyx_GIVEREF(__pyx_v_image);
+ __Pyx_INCREF(__pyx_v_kernel_size);
+ PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_kernel_size);
+ __Pyx_GIVEREF(__pyx_v_kernel_size);
+ PyTuple_SET_ITEM(__pyx_t_6, 2+__pyx_t_5, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":63
+ *
+ *
+ * def medfilt2d(image, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter.medfilt2d", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":81
+ *
+ *
+ * def medfilt(data, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_5medfilt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_4medfilt[] = "medfilt(data, kernel_size=3, bool conditional=False)\nFunction computing the median filter of the given input.\n Behavior at boundaries: the algorithm is reducing the size of the\n window/kernel for pixels at boundaries (there is no mirroring).\n\n :param numpy.ndarray data: the array for which we want to apply \n the median filter. Should be 1d or 2d.\n :param kernel_size: the dimension of the kernel.\n :type kernel_size: For 1D should be an int for 2D should be a tuple or \n a list of (kernel_height, kernel_width)\n :param bool conditional: True if we want to apply a conditional median\n filtering.\n\n :returns: the array with the median value for each pixel.\n ";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_5medfilt = {"medfilt", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_5medfilt, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_4medfilt};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_5medfilt(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_data = 0;
+ PyObject *__pyx_v_kernel_size = 0;
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("medfilt (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_data,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[3] = {0,0,0};
+ values[1] = ((PyObject *)__pyx_int_3);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_data)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size);
+ if (value) { values[1] = value; kw_args--; }
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "medfilt") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_data = values[0];
+ __pyx_v_kernel_size = values[1];
+ if (values[2]) {
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_conditional = ((bool)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("medfilt", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter.medfilt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_4medfilt(__pyx_self, __pyx_v_data, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_4medfilt(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_data, PyObject *__pyx_v_kernel_size, bool __pyx_v_conditional) {
+ int __pyx_v_reshaped;
+ PyObject *__pyx_v_output_buffer = NULL;
+ PyObject *__pyx_v_ker_dim = NULL;
+ PyObject *__pyx_v_medfilterfc = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("medfilt", 0);
+ __Pyx_INCREF(__pyx_v_data);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":96
+ * :returns: the array with the median value for each pixel.
+ * """
+ * reshaped = False # <<<<<<<<<<<<<<
+ * if len(data.shape) == 1:
+ * data = data.reshape(data.shape[0], 1)
+ */
+ __pyx_v_reshaped = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":97
+ * """
+ * reshaped = False
+ * if len(data.shape) == 1: # <<<<<<<<<<<<<<
+ * data = data.reshape(data.shape[0], 1)
+ * reshaped = True
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = ((__pyx_t_2 == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":98
+ * reshaped = False
+ * if len(data.shape) == 1:
+ * data = data.reshape(data.shape[0], 1) # <<<<<<<<<<<<<<
+ * reshaped = True
+ * elif len(data.shape) > 2:
+ */
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_reshape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_GetItemInt(__pyx_t_5, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = NULL;
+ __pyx_t_2 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ __pyx_t_2 = 1;
+ }
+ }
+ __pyx_t_7 = PyTuple_New(2+__pyx_t_2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_2, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_int_1);
+ PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_2, __pyx_int_1);
+ __Pyx_GIVEREF(__pyx_int_1);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF_SET(__pyx_v_data, __pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":99
+ * if len(data.shape) == 1:
+ * data = data.reshape(data.shape[0], 1)
+ * reshaped = True # <<<<<<<<<<<<<<
+ * elif len(data.shape) > 2:
+ * raise ValueError("Invalid data shape. Dimemsion of the arary should be 1 or 2")
+ */
+ __pyx_v_reshaped = 1;
+ goto __pyx_L3;
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":100
+ * data = data.reshape(data.shape[0], 1)
+ * reshaped = True
+ * elif len(data.shape) > 2: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid data shape. Dimemsion of the arary should be 1 or 2")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = ((__pyx_t_2 > 2) != 0);
+ if (__pyx_t_3) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":101
+ * reshaped = True
+ * elif len(data.shape) > 2:
+ * raise ValueError("Invalid data shape. Dimemsion of the arary should be 1 or 2") # <<<<<<<<<<<<<<
+ *
+ * # simple median filter apply into a 2D buffer
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L3:;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":104
+ *
+ * # simple median filter apply into a 2D buffer
+ * output_buffer = numpy.zeros_like(data) # <<<<<<<<<<<<<<
+ * check(data, output_buffer)
+ *
+ */
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_zeros_like); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_v_data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_6, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_output_buffer = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":105
+ * # simple median filter apply into a 2D buffer
+ * output_buffer = numpy.zeros_like(data)
+ * check(data, output_buffer) # <<<<<<<<<<<<<<
+ *
+ * if type(kernel_size) in (tuple, list):
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_check); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = NULL;
+ __pyx_t_2 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ __pyx_t_2 = 1;
+ }
+ }
+ __pyx_t_4 = PyTuple_New(2+__pyx_t_2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (__pyx_t_6) {
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ }
+ __Pyx_INCREF(__pyx_v_data);
+ PyTuple_SET_ITEM(__pyx_t_4, 0+__pyx_t_2, __pyx_v_data);
+ __Pyx_GIVEREF(__pyx_v_data);
+ __Pyx_INCREF(__pyx_v_output_buffer);
+ PyTuple_SET_ITEM(__pyx_t_4, 1+__pyx_t_2, __pyx_v_output_buffer);
+ __Pyx_GIVEREF(__pyx_v_output_buffer);
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":107
+ * check(data, output_buffer)
+ *
+ * if type(kernel_size) in (tuple, list): # <<<<<<<<<<<<<<
+ * if(len(kernel_size) == 1):
+ * ker_dim = numpy.array(1, [kernel_size[0]], dtype=numpy.int32)
+ */
+ __Pyx_INCREF(((PyObject *)Py_TYPE(__pyx_v_kernel_size)));
+ __pyx_t_1 = ((PyObject *)Py_TYPE(__pyx_v_kernel_size));
+ __pyx_t_7 = PyObject_RichCompare(((PyObject *)__pyx_t_1), ((PyObject *)((PyObject*)(&PyTuple_Type))), Py_EQ); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (!__pyx_t_8) {
+ } else {
+ __pyx_t_3 = __pyx_t_8;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_7 = PyObject_RichCompare(((PyObject *)__pyx_t_1), ((PyObject *)((PyObject*)(&PyList_Type))), Py_EQ); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_3 = __pyx_t_8;
+ __pyx_L5_bool_binop_done:;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_8 = (__pyx_t_3 != 0);
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":108
+ *
+ * if type(kernel_size) in (tuple, list):
+ * if(len(kernel_size) == 1): # <<<<<<<<<<<<<<
+ * ker_dim = numpy.array(1, [kernel_size[0]], dtype=numpy.int32)
+ * else:
+ */
+ __pyx_t_2 = PyObject_Length(__pyx_v_kernel_size); if (unlikely(__pyx_t_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_8 = ((__pyx_t_2 == 1) != 0);
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":109
+ * if type(kernel_size) in (tuple, list):
+ * if(len(kernel_size) == 1):
+ * ker_dim = numpy.array(1, [kernel_size[0]], dtype=numpy.int32) # <<<<<<<<<<<<<<
+ * else:
+ * ker_dim = numpy.array(kernel_size, dtype=numpy.int32)
+ */
+ __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_array); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_kernel_size, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = PyList_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyList_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_int_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_int_1);
+ __Pyx_GIVEREF(__pyx_int_1);
+ PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_dtype, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_v_ker_dim = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":111
+ * ker_dim = numpy.array(1, [kernel_size[0]], dtype=numpy.int32)
+ * else:
+ * ker_dim = numpy.array(kernel_size, dtype=numpy.int32) # <<<<<<<<<<<<<<
+ * else:
+ * ker_dim = numpy.array([kernel_size, kernel_size], dtype=numpy.int32)
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_array); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_kernel_size);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_kernel_size);
+ __Pyx_GIVEREF(__pyx_v_kernel_size);
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_int32); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_dtype, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_v_ker_dim = __pyx_t_6;
+ __pyx_t_6 = 0;
+ }
+ __pyx_L7:;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":113
+ * ker_dim = numpy.array(kernel_size, dtype=numpy.int32)
+ * else:
+ * ker_dim = numpy.array([kernel_size, kernel_size], dtype=numpy.int32) # <<<<<<<<<<<<<<
+ *
+ * if data.dtype == numpy.float64:
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_array); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_kernel_size);
+ PyList_SET_ITEM(__pyx_t_6, 0, __pyx_v_kernel_size);
+ __Pyx_GIVEREF(__pyx_v_kernel_size);
+ __Pyx_INCREF(__pyx_v_kernel_size);
+ PyList_SET_ITEM(__pyx_t_6, 1, __pyx_v_kernel_size);
+ __Pyx_GIVEREF(__pyx_v_kernel_size);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_int32); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_t_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_ker_dim = __pyx_t_7;
+ __pyx_t_7 = 0;
+ }
+ __pyx_L4:;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":115
+ * ker_dim = numpy.array([kernel_size, kernel_size], dtype=numpy.int32)
+ *
+ * if data.dtype == numpy.float64: # <<<<<<<<<<<<<<
+ * medfilterfc = _median_filter_float64
+ * elif data.dtype == numpy.float32:
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtype); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_float64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_7, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":116
+ *
+ * if data.dtype == numpy.float64:
+ * medfilterfc = _median_filter_float64 # <<<<<<<<<<<<<<
+ * elif data.dtype == numpy.float32:
+ * medfilterfc = _median_filter_float32
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_median_filter_float64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_v_medfilterfc = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L8;
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":117
+ * if data.dtype == numpy.float64:
+ * medfilterfc = _median_filter_float64
+ * elif data.dtype == numpy.float32: # <<<<<<<<<<<<<<
+ * medfilterfc = _median_filter_float32
+ * elif data.dtype == numpy.int64:
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtype); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_float32); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_6, __pyx_t_7, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":118
+ * medfilterfc = _median_filter_float64
+ * elif data.dtype == numpy.float32:
+ * medfilterfc = _median_filter_float32 # <<<<<<<<<<<<<<
+ * elif data.dtype == numpy.int64:
+ * medfilterfc = _median_filter_int64
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_median_filter_float32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_v_medfilterfc = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L8;
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":119
+ * elif data.dtype == numpy.float32:
+ * medfilterfc = _median_filter_float32
+ * elif data.dtype == numpy.int64: # <<<<<<<<<<<<<<
+ * medfilterfc = _median_filter_int64
+ * elif data.dtype == numpy.uint64:
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtype); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_int64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyObject_RichCompare(__pyx_t_5, __pyx_t_6, Py_EQ); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":120
+ * medfilterfc = _median_filter_float32
+ * elif data.dtype == numpy.int64:
+ * medfilterfc = _median_filter_int64 # <<<<<<<<<<<<<<
+ * elif data.dtype == numpy.uint64:
+ * medfilterfc = _median_filter_uint64
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_median_filter_int64); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_medfilterfc = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L8;
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":121
+ * elif data.dtype == numpy.int64:
+ * medfilterfc = _median_filter_int64
+ * elif data.dtype == numpy.uint64: # <<<<<<<<<<<<<<
+ * medfilterfc = _median_filter_uint64
+ * elif data.dtype == numpy.int32:
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtype); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_uint64); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_7, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":122
+ * medfilterfc = _median_filter_int64
+ * elif data.dtype == numpy.uint64:
+ * medfilterfc = _median_filter_uint64 # <<<<<<<<<<<<<<
+ * elif data.dtype == numpy.int32:
+ * medfilterfc = _median_filter_int32
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_median_filter_uint64); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_v_medfilterfc = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L8;
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":123
+ * elif data.dtype == numpy.uint64:
+ * medfilterfc = _median_filter_uint64
+ * elif data.dtype == numpy.int32: # <<<<<<<<<<<<<<
+ * medfilterfc = _median_filter_int32
+ * elif data.dtype == numpy.uint32:
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtype); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_int32); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_6, __pyx_t_7, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":124
+ * medfilterfc = _median_filter_uint64
+ * elif data.dtype == numpy.int32:
+ * medfilterfc = _median_filter_int32 # <<<<<<<<<<<<<<
+ * elif data.dtype == numpy.uint32:
+ * medfilterfc = _median_filter_uint32
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_median_filter_int32); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_v_medfilterfc = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L8;
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":125
+ * elif data.dtype == numpy.int32:
+ * medfilterfc = _median_filter_int32
+ * elif data.dtype == numpy.uint32: # <<<<<<<<<<<<<<
+ * medfilterfc = _median_filter_uint32
+ * elif data.dtype == numpy.int16:
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtype); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_n_s_uint32); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_7 = PyObject_RichCompare(__pyx_t_5, __pyx_t_6, Py_EQ); __Pyx_XGOTREF(__pyx_t_7); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_7); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":126
+ * medfilterfc = _median_filter_int32
+ * elif data.dtype == numpy.uint32:
+ * medfilterfc = _median_filter_uint32 # <<<<<<<<<<<<<<
+ * elif data.dtype == numpy.int16:
+ * medfilterfc = _median_filter_int16
+ */
+ __pyx_t_7 = __Pyx_GetModuleGlobalName(__pyx_n_s_median_filter_uint32); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_v_medfilterfc = __pyx_t_7;
+ __pyx_t_7 = 0;
+ goto __pyx_L8;
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":127
+ * elif data.dtype == numpy.uint32:
+ * medfilterfc = _median_filter_uint32
+ * elif data.dtype == numpy.int16: # <<<<<<<<<<<<<<
+ * medfilterfc = _median_filter_int16
+ * elif data.dtype == numpy.uint16:
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtype); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_int16); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_7, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":128
+ * medfilterfc = _median_filter_uint32
+ * elif data.dtype == numpy.int16:
+ * medfilterfc = _median_filter_int16 # <<<<<<<<<<<<<<
+ * elif data.dtype == numpy.uint16:
+ * medfilterfc = _median_filter_uint16
+ */
+ __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_median_filter_int16); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_v_medfilterfc = __pyx_t_6;
+ __pyx_t_6 = 0;
+ goto __pyx_L8;
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":129
+ * elif data.dtype == numpy.int16:
+ * medfilterfc = _median_filter_int16
+ * elif data.dtype == numpy.uint16: # <<<<<<<<<<<<<<
+ * medfilterfc = _median_filter_uint16
+ * else:
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtype); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_numpy); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_uint16); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyObject_RichCompare(__pyx_t_6, __pyx_t_7, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":130
+ * medfilterfc = _median_filter_int16
+ * elif data.dtype == numpy.uint16:
+ * medfilterfc = _median_filter_uint16 # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("%s type is not managed by the median filter" % data.dtype)
+ */
+ __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_median_filter_uint16); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_v_medfilterfc = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":132
+ * medfilterfc = _median_filter_uint16
+ * else:
+ * raise ValueError("%s type is not managed by the median filter" % data.dtype) # <<<<<<<<<<<<<<
+ *
+ * medfilterfc(input_buffer=data,
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_dtype); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_s_type_is_not_managed_by_the_me, __pyx_t_5); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_5, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L8:;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":134
+ * raise ValueError("%s type is not managed by the median filter" % data.dtype)
+ *
+ * medfilterfc(input_buffer=data, # <<<<<<<<<<<<<<
+ * output_buffer=output_buffer,
+ * kernel_size=ker_dim,
+ */
+ __pyx_t_7 = PyDict_New(); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_input_buffer, __pyx_v_data) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":135
+ *
+ * medfilterfc(input_buffer=data,
+ * output_buffer=output_buffer, # <<<<<<<<<<<<<<
+ * kernel_size=ker_dim,
+ * conditional=conditional)
+ */
+ if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_output_buffer, __pyx_v_output_buffer) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":136
+ * medfilterfc(input_buffer=data,
+ * output_buffer=output_buffer,
+ * kernel_size=ker_dim, # <<<<<<<<<<<<<<
+ * conditional=conditional)
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_kernel_size, __pyx_v_ker_dim) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":137
+ * output_buffer=output_buffer,
+ * kernel_size=ker_dim,
+ * conditional=conditional) # <<<<<<<<<<<<<<
+ *
+ * if reshaped:
+ */
+ __pyx_t_5 = __Pyx_PyBool_FromLong(__pyx_v_conditional); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_conditional, __pyx_t_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":134
+ * raise ValueError("%s type is not managed by the median filter" % data.dtype)
+ *
+ * medfilterfc(input_buffer=data, # <<<<<<<<<<<<<<
+ * output_buffer=output_buffer,
+ * kernel_size=ker_dim,
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_v_medfilterfc, __pyx_empty_tuple, __pyx_t_7); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":139
+ * conditional=conditional)
+ *
+ * if reshaped: # <<<<<<<<<<<<<<
+ * data = data.reshape(data.shape[0])
+ * output_buffer = output_buffer.reshape(data.shape[0])
+ */
+ __pyx_t_8 = (__pyx_v_reshaped != 0);
+ if (__pyx_t_8) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":140
+ *
+ * if reshaped:
+ * data = data.reshape(data.shape[0]) # <<<<<<<<<<<<<<
+ * output_buffer = output_buffer.reshape(data.shape[0])
+ *
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_reshape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_6, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_6 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_6)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_6);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ }
+ }
+ if (!__pyx_t_6) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_4 = PyTuple_New(1+1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6); __Pyx_GIVEREF(__pyx_t_6); __pyx_t_6 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_4, 0+1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF_SET(__pyx_v_data, __pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":141
+ * if reshaped:
+ * data = data.reshape(data.shape[0])
+ * output_buffer = output_buffer.reshape(data.shape[0]) # <<<<<<<<<<<<<<
+ *
+ * return output_buffer
+ */
+ __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_buffer, __pyx_n_s_reshape); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_data, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_t_4, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_7))) {
+ __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_7);
+ if (likely(__pyx_t_4)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_7);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_7, function);
+ }
+ }
+ if (!__pyx_t_4) {
+ __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_7, __pyx_t_1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_GOTREF(__pyx_t_5);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __Pyx_GIVEREF(__pyx_t_4); __pyx_t_4 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 141; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF_SET(__pyx_v_output_buffer, __pyx_t_5);
+ __pyx_t_5 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":143
+ * output_buffer = output_buffer.reshape(data.shape[0])
+ *
+ * return output_buffer # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_output_buffer);
+ __pyx_r = __pyx_v_output_buffer;
+ goto __pyx_L0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":81
+ *
+ *
+ * def medfilt(data, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter.medfilt", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_output_buffer);
+ __Pyx_XDECREF(__pyx_v_ker_dim);
+ __Pyx_XDECREF(__pyx_v_medfilterfc);
+ __Pyx_XDECREF(__pyx_v_data);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":146
+ *
+ *
+ * def check(input_buffer, output_buffer): # <<<<<<<<<<<<<<
+ * """Simple check on the two buffers to make sure we can apply the median filter
+ * """
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_7check(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_6check[] = "check(input_buffer, output_buffer)\nSimple check on the two buffers to make sure we can apply the median filter\n ";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_7check = {"check", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_7check, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_6check};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_7check(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_input_buffer = 0;
+ PyObject *__pyx_v_output_buffer = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("check (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_buffer,&__pyx_n_s_output_buffer,0};
+ PyObject* values[2] = {0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_buffer)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_buffer)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("check", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "check") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ }
+ __pyx_v_input_buffer = values[0];
+ __pyx_v_output_buffer = values[1];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("check", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter.check", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_6check(__pyx_self, __pyx_v_input_buffer, __pyx_v_output_buffer);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_6check(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_input_buffer, PyObject *__pyx_v_output_buffer) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("check", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":149
+ * """Simple check on the two buffers to make sure we can apply the median filter
+ * """
+ * if (input_buffer.flags['C_CONTIGUOUS'] is False): # <<<<<<<<<<<<<<
+ * raise ValueError('<input_buffer> must be a C_CONTIGUOUS numpy array.')
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_buffer, __pyx_n_s_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_n_s_C_CONTIGUOUS); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_2 == Py_False);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = (__pyx_t_3 != 0);
+ if (__pyx_t_4) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":150
+ * """
+ * if (input_buffer.flags['C_CONTIGUOUS'] is False):
+ * raise ValueError('<input_buffer> must be a C_CONTIGUOUS numpy array.') # <<<<<<<<<<<<<<
+ *
+ * if (output_buffer.flags['C_CONTIGUOUS'] is False):
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":152
+ * raise ValueError('<input_buffer> must be a C_CONTIGUOUS numpy array.')
+ *
+ * if (output_buffer.flags['C_CONTIGUOUS'] is False): # <<<<<<<<<<<<<<
+ * raise ValueError('<output_buffer> must be a C_CONTIGUOUS numpy array.')
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_buffer, __pyx_n_s_flags); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyObject_GetItem(__pyx_t_2, __pyx_n_s_C_CONTIGUOUS); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = (__pyx_t_1 == Py_False);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = (__pyx_t_4 != 0);
+ if (__pyx_t_3) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":153
+ *
+ * if (output_buffer.flags['C_CONTIGUOUS'] is False):
+ * raise ValueError('<output_buffer> must be a C_CONTIGUOUS numpy array.') # <<<<<<<<<<<<<<
+ *
+ * if not (len(input_buffer.shape) <= 2):
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":155
+ * raise ValueError('<output_buffer> must be a C_CONTIGUOUS numpy array.')
+ *
+ * if not (len(input_buffer.shape) <= 2): # <<<<<<<<<<<<<<
+ * raise ValueError('<input_buffer> dimension must mo higher than 2.')
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_buffer, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = ((!((__pyx_t_5 <= 2) != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":156
+ *
+ * if not (len(input_buffer.shape) <= 2):
+ * raise ValueError('<input_buffer> dimension must mo higher than 2.') # <<<<<<<<<<<<<<
+ *
+ * if not (len(output_buffer.shape) <= 2):
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":158
+ * raise ValueError('<input_buffer> dimension must mo higher than 2.')
+ *
+ * if not (len(output_buffer.shape) <= 2): # <<<<<<<<<<<<<<
+ * raise ValueError('<output_buffer> dimension must mo higher than 2.')
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_buffer, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = ((!((__pyx_t_5 <= 2) != 0)) != 0);
+ if (__pyx_t_3) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":159
+ *
+ * if not (len(output_buffer.shape) <= 2):
+ * raise ValueError('<output_buffer> dimension must mo higher than 2.') # <<<<<<<<<<<<<<
+ *
+ * if not(input_buffer.dtype == output_buffer.dtype):
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":161
+ * raise ValueError('<output_buffer> dimension must mo higher than 2.')
+ *
+ * if not(input_buffer.dtype == output_buffer.dtype): # <<<<<<<<<<<<<<
+ * raise ValueError('input buffer and output_buffer must be of the same type')
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_buffer, __pyx_n_s_dtype); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_buffer, __pyx_n_s_dtype); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_t_4 = ((!__pyx_t_3) != 0);
+ if (__pyx_t_4) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":162
+ *
+ * if not(input_buffer.dtype == output_buffer.dtype):
+ * raise ValueError('input buffer and output_buffer must be of the same type') # <<<<<<<<<<<<<<
+ *
+ * if not (input_buffer.shape == output_buffer.shape):
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__6, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":164
+ * raise ValueError('input buffer and output_buffer must be of the same type')
+ *
+ * if not (input_buffer.shape == output_buffer.shape): # <<<<<<<<<<<<<<
+ * raise ValueError('input buffer and output_buffer must be of the same dimension and same dimension')
+ *
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_buffer, __pyx_n_s_shape); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_buffer, __pyx_n_s_shape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_1 = PyObject_RichCompare(__pyx_t_6, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_3 = ((!__pyx_t_4) != 0);
+ if (__pyx_t_3) {
+
+ /* "silx/math/medianfilter/medianfilter.pyx":165
+ *
+ * if not (input_buffer.shape == output_buffer.shape):
+ * raise ValueError('input buffer and output_buffer must be of the same dimension and same dimension') # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__7, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":146
+ *
+ *
+ * def check(input_buffer, output_buffer): # <<<<<<<<<<<<<<
+ * """Simple check on the two buffers to make sure we can apply the median filter
+ * """
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter.check", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":173
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_float32(float[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * float[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_9_median_filter_float32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_8_median_filter_float32[] = "_median_filter_float32(__Pyx_memviewslice input_buffer, __Pyx_memviewslice output_buffer, __Pyx_memviewslice kernel_size, bool conditional)";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_9_median_filter_float32 = {"_median_filter_float32", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_9_median_filter_float32, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_8_median_filter_float32};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_9_median_filter_float32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_input_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_output_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_kernel_size = { 0, 0, { 0 }, { 0 }, { 0 } };
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_median_filter_float32 (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_buffer,&__pyx_n_s_output_buffer,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_buffer)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_buffer)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_float32", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_float32", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_float32", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_median_filter_float32") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_input_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_float(values[0]); if (unlikely(!__pyx_v_input_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_output_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_float(values[1]); if (unlikely(!__pyx_v_output_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_kernel_size = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_int32_t(values[2]); if (unlikely(!__pyx_v_kernel_size.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_median_filter_float32", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter._median_filter_float32", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(((PyObject *)__pyx_v_input_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "input_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_output_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "output_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_kernel_size.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "kernel_size"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_8_median_filter_float32(__pyx_self, __pyx_v_input_buffer, __pyx_v_output_buffer, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_8_median_filter_float32(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional) {
+ int __pyx_v_x;
+ int __pyx_v_image_dim;
+ int __pyx_v_buffer_shape[2];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ __Pyx_RefNannySetupContext("_median_filter_float32", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":179
+ *
+ * cdef:
+ * int x = 0 # <<<<<<<<<<<<<<
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ */
+ __pyx_v_x = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":180
+ * cdef:
+ * int x = 0
+ * int image_dim = input_buffer.shape[1] - 1 # <<<<<<<<<<<<<<
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ */
+ __pyx_v_image_dim = ((__pyx_v_input_buffer.shape[1]) - 1);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":182
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0] # <<<<<<<<<<<<<<
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ */
+ (__pyx_v_buffer_shape[0]) = (__pyx_v_input_buffer.shape[0]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":183
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ * buffer_shape[1] = input_buffer.shape[1] # <<<<<<<<<<<<<<
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ */
+ (__pyx_v_buffer_shape[1]) = (__pyx_v_input_buffer.shape[1]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":185
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[float](<float*> & input_buffer[0,0],
+ * <float*> & output_buffer[0,0],
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+ __pyx_t_1 = (__pyx_v_input_buffer.shape[0]);
+ if (1 == 0) abort();
+ {
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+ #endif
+ __pyx_t_3 = (__pyx_t_1 - 0) / 1;
+ if (__pyx_t_3 > 0)
+ {
+ #ifdef _OPENMP
+ #pragma omp parallel private(__pyx_t_4, __pyx_t_7, __pyx_t_8, __pyx_t_5, __pyx_t_6)
+ #endif /* _OPENMP */
+ {
+ #ifdef _OPENMP
+ #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x)
+ #endif /* _OPENMP */
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
+ {
+ __pyx_v_x = 0 + 1 * __pyx_t_2;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":186
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[float](<float*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <float*> & output_buffer[0,0],
+ * <int*>& kernel_size[0],
+ */
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":187
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[float](<float*> & input_buffer[0,0],
+ * <float*> & output_buffer[0,0], # <<<<<<<<<<<<<<
+ * <int*>& kernel_size[0],
+ * <int*>buffer_shape,
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":188
+ * median_filter.median_filter[float](<float*> & input_buffer[0,0],
+ * <float*> & output_buffer[0,0],
+ * <int*>& kernel_size[0], # <<<<<<<<<<<<<<
+ * <int*>buffer_shape,
+ * x,
+ */
+ __pyx_t_8 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":186
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[float](<float*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <float*> & output_buffer[0,0],
+ * <int*>& kernel_size[0],
+ */
+ median_filter<float>(((float *)(&(*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_input_buffer.data + __pyx_t_4 * __pyx_v_input_buffer.strides[0]) )) + __pyx_t_5)) ))))), ((float *)(&(*((float *) ( /* dim=1 */ ((char *) (((float *) ( /* dim=0 */ (__pyx_v_output_buffer.data + __pyx_t_6 * __pyx_v_output_buffer.strides[0]) )) + __pyx_t_7)) ))))), ((int *)(&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_int32_t *) __pyx_v_kernel_size.data) + __pyx_t_8)) ))))), ((int *)__pyx_v_buffer_shape), __pyx_v_x, 0, __pyx_v_image_dim, __pyx_v_conditional);
+ }
+ }
+ }
+ }
+ }
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+ #endif
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":185
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[float](<float*> & input_buffer[0,0],
+ * <float*> & output_buffer[0,0],
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":173
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_float32(float[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * float[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_input_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_output_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_size, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":200
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_float64(double[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * double[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_11_median_filter_float64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_10_median_filter_float64[] = "_median_filter_float64(__Pyx_memviewslice input_buffer, __Pyx_memviewslice output_buffer, __Pyx_memviewslice kernel_size, bool conditional)";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_11_median_filter_float64 = {"_median_filter_float64", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_11_median_filter_float64, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_10_median_filter_float64};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_11_median_filter_float64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_input_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_output_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_kernel_size = { 0, 0, { 0 }, { 0 }, { 0 } };
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_median_filter_float64 (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_buffer,&__pyx_n_s_output_buffer,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_buffer)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_buffer)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_float64", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_float64", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_float64", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_median_filter_float64") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_input_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_double(values[0]); if (unlikely(!__pyx_v_input_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_output_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_double(values[1]); if (unlikely(!__pyx_v_output_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_kernel_size = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_int32_t(values[2]); if (unlikely(!__pyx_v_kernel_size.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_median_filter_float64", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter._median_filter_float64", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(((PyObject *)__pyx_v_input_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "input_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_output_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "output_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_kernel_size.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "kernel_size"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_10_median_filter_float64(__pyx_self, __pyx_v_input_buffer, __pyx_v_output_buffer, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_10_median_filter_float64(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional) {
+ int __pyx_v_x;
+ int __pyx_v_image_dim;
+ int __pyx_v_buffer_shape[2];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ __Pyx_RefNannySetupContext("_median_filter_float64", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":206
+ *
+ * cdef:
+ * int x = 0 # <<<<<<<<<<<<<<
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ */
+ __pyx_v_x = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":207
+ * cdef:
+ * int x = 0
+ * int image_dim = input_buffer.shape[1] - 1 # <<<<<<<<<<<<<<
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ */
+ __pyx_v_image_dim = ((__pyx_v_input_buffer.shape[1]) - 1);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":209
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0] # <<<<<<<<<<<<<<
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ */
+ (__pyx_v_buffer_shape[0]) = (__pyx_v_input_buffer.shape[0]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":210
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ * buffer_shape[1] = input_buffer.shape[1] # <<<<<<<<<<<<<<
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ */
+ (__pyx_v_buffer_shape[1]) = (__pyx_v_input_buffer.shape[1]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":212
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[double](<double*> & input_buffer[0, 0],
+ * <double*> & output_buffer[0, 0],
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+ __pyx_t_1 = (__pyx_v_input_buffer.shape[0]);
+ if (1 == 0) abort();
+ {
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+ #endif
+ __pyx_t_3 = (__pyx_t_1 - 0) / 1;
+ if (__pyx_t_3 > 0)
+ {
+ #ifdef _OPENMP
+ #pragma omp parallel private(__pyx_t_4, __pyx_t_7, __pyx_t_8, __pyx_t_5, __pyx_t_6)
+ #endif /* _OPENMP */
+ {
+ #ifdef _OPENMP
+ #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x)
+ #endif /* _OPENMP */
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
+ {
+ __pyx_v_x = 0 + 1 * __pyx_t_2;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":213
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[double](<double*> & input_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <double*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":214
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[double](<double*> & input_buffer[0, 0],
+ * <double*> & output_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <int*>&kernel_size[0],
+ * <int*>buffer_shape,
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":215
+ * median_filter.median_filter[double](<double*> & input_buffer[0, 0],
+ * <double*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0], # <<<<<<<<<<<<<<
+ * <int*>buffer_shape,
+ * x,
+ */
+ __pyx_t_8 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":213
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[double](<double*> & input_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <double*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ median_filter<double>(((double *)(&(*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_input_buffer.data + __pyx_t_4 * __pyx_v_input_buffer.strides[0]) )) + __pyx_t_5)) ))))), ((double *)(&(*((double *) ( /* dim=1 */ ((char *) (((double *) ( /* dim=0 */ (__pyx_v_output_buffer.data + __pyx_t_6 * __pyx_v_output_buffer.strides[0]) )) + __pyx_t_7)) ))))), ((int *)(&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_int32_t *) __pyx_v_kernel_size.data) + __pyx_t_8)) ))))), ((int *)__pyx_v_buffer_shape), __pyx_v_x, 0, __pyx_v_image_dim, __pyx_v_conditional);
+ }
+ }
+ }
+ }
+ }
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+ #endif
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":212
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[double](<double*> & input_buffer[0, 0],
+ * <double*> & output_buffer[0, 0],
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":200
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_float64(double[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * double[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_input_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_output_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_size, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":227
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int64(cnumpy.int64_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int64_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_13_median_filter_int64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_12_median_filter_int64[] = "_median_filter_int64(__Pyx_memviewslice input_buffer, __Pyx_memviewslice output_buffer, __Pyx_memviewslice kernel_size, bool conditional)";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_13_median_filter_int64 = {"_median_filter_int64", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_13_median_filter_int64, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_12_median_filter_int64};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_13_median_filter_int64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_input_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_output_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_kernel_size = { 0, 0, { 0 }, { 0 }, { 0 } };
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_median_filter_int64 (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_buffer,&__pyx_n_s_output_buffer,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_buffer)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_buffer)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int64", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int64", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int64", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_median_filter_int64") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_input_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int64_t(values[0]); if (unlikely(!__pyx_v_input_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_output_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int64_t(values[1]); if (unlikely(!__pyx_v_output_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_kernel_size = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_int32_t(values[2]); if (unlikely(!__pyx_v_kernel_size.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int64", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter._median_filter_int64", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(((PyObject *)__pyx_v_input_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "input_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_output_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "output_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_kernel_size.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "kernel_size"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_12_median_filter_int64(__pyx_self, __pyx_v_input_buffer, __pyx_v_output_buffer, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_12_median_filter_int64(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional) {
+ int __pyx_v_x;
+ int __pyx_v_image_dim;
+ int __pyx_v_buffer_shape[2];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ __Pyx_RefNannySetupContext("_median_filter_int64", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":233
+ *
+ * cdef:
+ * int x = 0 # <<<<<<<<<<<<<<
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ */
+ __pyx_v_x = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":234
+ * cdef:
+ * int x = 0
+ * int image_dim = input_buffer.shape[1] - 1 # <<<<<<<<<<<<<<
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ */
+ __pyx_v_image_dim = ((__pyx_v_input_buffer.shape[1]) - 1);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":236
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0] # <<<<<<<<<<<<<<
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ */
+ (__pyx_v_buffer_shape[0]) = (__pyx_v_input_buffer.shape[0]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":237
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ * buffer_shape[1] = input_buffer.shape[1] # <<<<<<<<<<<<<<
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ */
+ (__pyx_v_buffer_shape[1]) = (__pyx_v_input_buffer.shape[1]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":239
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[long](<long*> & input_buffer[0,0],
+ * <long*> & output_buffer[0, 0],
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+ __pyx_t_1 = (__pyx_v_input_buffer.shape[0]);
+ if (1 == 0) abort();
+ {
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+ #endif
+ __pyx_t_3 = (__pyx_t_1 - 0) / 1;
+ if (__pyx_t_3 > 0)
+ {
+ #ifdef _OPENMP
+ #pragma omp parallel private(__pyx_t_4, __pyx_t_7, __pyx_t_8, __pyx_t_5, __pyx_t_6)
+ #endif /* _OPENMP */
+ {
+ #ifdef _OPENMP
+ #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x)
+ #endif /* _OPENMP */
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
+ {
+ __pyx_v_x = 0 + 1 * __pyx_t_2;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":240
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[long](<long*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <long*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":241
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[long](<long*> & input_buffer[0,0],
+ * <long*> & output_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <int*>&kernel_size[0],
+ * <int*>buffer_shape,
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":242
+ * median_filter.median_filter[long](<long*> & input_buffer[0,0],
+ * <long*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0], # <<<<<<<<<<<<<<
+ * <int*>buffer_shape,
+ * x,
+ */
+ __pyx_t_8 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":240
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[long](<long*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <long*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ median_filter<long>(((long *)(&(*((__pyx_t_5numpy_int64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_input_buffer.data + __pyx_t_4 * __pyx_v_input_buffer.strides[0]) )) + __pyx_t_5)) ))))), ((long *)(&(*((__pyx_t_5numpy_int64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_int64_t *) ( /* dim=0 */ (__pyx_v_output_buffer.data + __pyx_t_6 * __pyx_v_output_buffer.strides[0]) )) + __pyx_t_7)) ))))), ((int *)(&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_int32_t *) __pyx_v_kernel_size.data) + __pyx_t_8)) ))))), ((int *)__pyx_v_buffer_shape), __pyx_v_x, 0, __pyx_v_image_dim, __pyx_v_conditional);
+ }
+ }
+ }
+ }
+ }
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+ #endif
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":239
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[long](<long*> & input_buffer[0,0],
+ * <long*> & output_buffer[0, 0],
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":227
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int64(cnumpy.int64_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int64_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_input_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_output_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_size, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":253
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint64( # <<<<<<<<<<<<<<
+ * cnumpy.uint64_t[:, ::1] input_buffer not None,
+ * cnumpy.uint64_t[:, ::1] output_buffer not None,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_15_median_filter_uint64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_14_median_filter_uint64[] = "_median_filter_uint64(__Pyx_memviewslice input_buffer, __Pyx_memviewslice output_buffer, __Pyx_memviewslice kernel_size, bool conditional)";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_15_median_filter_uint64 = {"_median_filter_uint64", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_15_median_filter_uint64, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_14_median_filter_uint64};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_15_median_filter_uint64(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_input_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_output_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_kernel_size = { 0, 0, { 0 }, { 0 }, { 0 } };
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_median_filter_uint64 (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_buffer,&__pyx_n_s_output_buffer,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_buffer)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_buffer)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint64", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint64", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint64", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_median_filter_uint64") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_input_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_uint64_t(values[0]); if (unlikely(!__pyx_v_input_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_output_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_uint64_t(values[1]); if (unlikely(!__pyx_v_output_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_kernel_size = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_int32_t(values[2]); if (unlikely(!__pyx_v_kernel_size.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint64", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter._median_filter_uint64", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(((PyObject *)__pyx_v_input_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "input_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_output_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "output_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 255; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_kernel_size.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "kernel_size"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_14_median_filter_uint64(__pyx_self, __pyx_v_input_buffer, __pyx_v_output_buffer, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_14_median_filter_uint64(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional) {
+ int __pyx_v_x;
+ int __pyx_v_image_dim;
+ int __pyx_v_buffer_shape[2];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ __Pyx_RefNannySetupContext("_median_filter_uint64", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":260
+ *
+ * cdef:
+ * int x = 0 # <<<<<<<<<<<<<<
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ */
+ __pyx_v_x = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":261
+ * cdef:
+ * int x = 0
+ * int image_dim = input_buffer.shape[1] - 1 # <<<<<<<<<<<<<<
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ */
+ __pyx_v_image_dim = ((__pyx_v_input_buffer.shape[1]) - 1);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":263
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0] # <<<<<<<<<<<<<<
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ */
+ (__pyx_v_buffer_shape[0]) = (__pyx_v_input_buffer.shape[0]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":264
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ * buffer_shape[1] = input_buffer.shape[1] # <<<<<<<<<<<<<<
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ */
+ (__pyx_v_buffer_shape[1]) = (__pyx_v_input_buffer.shape[1]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":266
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[uint64](<uint64*> & input_buffer[0,0],
+ * <uint64*> & output_buffer[0, 0],
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+ __pyx_t_1 = (__pyx_v_input_buffer.shape[0]);
+ if (1 == 0) abort();
+ {
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+ #endif
+ __pyx_t_3 = (__pyx_t_1 - 0) / 1;
+ if (__pyx_t_3 > 0)
+ {
+ #ifdef _OPENMP
+ #pragma omp parallel private(__pyx_t_4, __pyx_t_7, __pyx_t_8, __pyx_t_5, __pyx_t_6)
+ #endif /* _OPENMP */
+ {
+ #ifdef _OPENMP
+ #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x)
+ #endif /* _OPENMP */
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
+ {
+ __pyx_v_x = 0 + 1 * __pyx_t_2;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":267
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[uint64](<uint64*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <uint64*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":268
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[uint64](<uint64*> & input_buffer[0,0],
+ * <uint64*> & output_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <int*>&kernel_size[0],
+ * <int*>buffer_shape,
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":269
+ * median_filter.median_filter[uint64](<uint64*> & input_buffer[0,0],
+ * <uint64*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0], # <<<<<<<<<<<<<<
+ * <int*>buffer_shape,
+ * x,
+ */
+ __pyx_t_8 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":267
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[uint64](<uint64*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <uint64*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ median_filter<__pyx_t_4silx_4math_12medianfilter_12medianfilter_uint64>(((__pyx_t_4silx_4math_12medianfilter_12medianfilter_uint64 *)(&(*((__pyx_t_5numpy_uint64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_uint64_t *) ( /* dim=0 */ (__pyx_v_input_buffer.data + __pyx_t_4 * __pyx_v_input_buffer.strides[0]) )) + __pyx_t_5)) ))))), ((__pyx_t_4silx_4math_12medianfilter_12medianfilter_uint64 *)(&(*((__pyx_t_5numpy_uint64_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_uint64_t *) ( /* dim=0 */ (__pyx_v_output_buffer.data + __pyx_t_6 * __pyx_v_output_buffer.strides[0]) )) + __pyx_t_7)) ))))), ((int *)(&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_int32_t *) __pyx_v_kernel_size.data) + __pyx_t_8)) ))))), ((int *)__pyx_v_buffer_shape), __pyx_v_x, 0, __pyx_v_image_dim, __pyx_v_conditional);
+ }
+ }
+ }
+ }
+ }
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+ #endif
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":266
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[uint64](<uint64*> & input_buffer[0,0],
+ * <uint64*> & output_buffer[0, 0],
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":253
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint64( # <<<<<<<<<<<<<<
+ * cnumpy.uint64_t[:, ::1] input_buffer not None,
+ * cnumpy.uint64_t[:, ::1] output_buffer not None,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_input_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_output_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_size, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":281
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int32(cnumpy.int32_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int32_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_17_median_filter_int32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_16_median_filter_int32[] = "_median_filter_int32(__Pyx_memviewslice input_buffer, __Pyx_memviewslice output_buffer, __Pyx_memviewslice kernel_size, bool conditional)";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_17_median_filter_int32 = {"_median_filter_int32", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_17_median_filter_int32, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_16_median_filter_int32};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_17_median_filter_int32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_input_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_output_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_kernel_size = { 0, 0, { 0 }, { 0 }, { 0 } };
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_median_filter_int32 (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_buffer,&__pyx_n_s_output_buffer,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_buffer)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_buffer)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int32", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int32", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int32", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_median_filter_int32") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_input_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int32_t(values[0]); if (unlikely(!__pyx_v_input_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_output_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int32_t(values[1]); if (unlikely(!__pyx_v_output_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_kernel_size = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_int32_t(values[2]); if (unlikely(!__pyx_v_kernel_size.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 284; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int32", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter._median_filter_int32", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(((PyObject *)__pyx_v_input_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "input_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_output_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "output_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_kernel_size.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "kernel_size"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_16_median_filter_int32(__pyx_self, __pyx_v_input_buffer, __pyx_v_output_buffer, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_16_median_filter_int32(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional) {
+ int __pyx_v_x;
+ int __pyx_v_image_dim;
+ int __pyx_v_buffer_shape[2];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ __Pyx_RefNannySetupContext("_median_filter_int32", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":287
+ *
+ * cdef:
+ * int x = 0 # <<<<<<<<<<<<<<
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ */
+ __pyx_v_x = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":288
+ * cdef:
+ * int x = 0
+ * int image_dim = input_buffer.shape[1] - 1 # <<<<<<<<<<<<<<
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ */
+ __pyx_v_image_dim = ((__pyx_v_input_buffer.shape[1]) - 1);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":290
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0] # <<<<<<<<<<<<<<
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ */
+ (__pyx_v_buffer_shape[0]) = (__pyx_v_input_buffer.shape[0]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":291
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ * buffer_shape[1] = input_buffer.shape[1] # <<<<<<<<<<<<<<
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ */
+ (__pyx_v_buffer_shape[1]) = (__pyx_v_input_buffer.shape[1]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":293
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[int](<int*> & input_buffer[0,0],
+ * <int*> & output_buffer[0, 0],
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+ __pyx_t_1 = (__pyx_v_input_buffer.shape[0]);
+ if (1 == 0) abort();
+ {
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+ #endif
+ __pyx_t_3 = (__pyx_t_1 - 0) / 1;
+ if (__pyx_t_3 > 0)
+ {
+ #ifdef _OPENMP
+ #pragma omp parallel private(__pyx_t_4, __pyx_t_7, __pyx_t_8, __pyx_t_5, __pyx_t_6)
+ #endif /* _OPENMP */
+ {
+ #ifdef _OPENMP
+ #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x)
+ #endif /* _OPENMP */
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
+ {
+ __pyx_v_x = 0 + 1 * __pyx_t_2;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":294
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[int](<int*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <int*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":295
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[int](<int*> & input_buffer[0,0],
+ * <int*> & output_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <int*>&kernel_size[0],
+ * <int*>buffer_shape,
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":296
+ * median_filter.median_filter[int](<int*> & input_buffer[0,0],
+ * <int*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0], # <<<<<<<<<<<<<<
+ * <int*>buffer_shape,
+ * x,
+ */
+ __pyx_t_8 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":294
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[int](<int*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <int*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ median_filter<int>(((int *)(&(*((__pyx_t_5numpy_int32_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_input_buffer.data + __pyx_t_4 * __pyx_v_input_buffer.strides[0]) )) + __pyx_t_5)) ))))), ((int *)(&(*((__pyx_t_5numpy_int32_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ (__pyx_v_output_buffer.data + __pyx_t_6 * __pyx_v_output_buffer.strides[0]) )) + __pyx_t_7)) ))))), ((int *)(&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_int32_t *) __pyx_v_kernel_size.data) + __pyx_t_8)) ))))), ((int *)__pyx_v_buffer_shape), __pyx_v_x, 0, __pyx_v_image_dim, __pyx_v_conditional);
+ }
+ }
+ }
+ }
+ }
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+ #endif
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":293
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[int](<int*> & input_buffer[0,0],
+ * <int*> & output_buffer[0, 0],
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":281
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int32(cnumpy.int32_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int32_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_input_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_output_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_size, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":308
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint32(cnumpy.uint32_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.uint32_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_19_median_filter_uint32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_18_median_filter_uint32[] = "_median_filter_uint32(__Pyx_memviewslice input_buffer, __Pyx_memviewslice output_buffer, __Pyx_memviewslice kernel_size, bool conditional)";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_19_median_filter_uint32 = {"_median_filter_uint32", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_19_median_filter_uint32, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_18_median_filter_uint32};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_19_median_filter_uint32(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_input_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_output_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_kernel_size = { 0, 0, { 0 }, { 0 }, { 0 } };
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_median_filter_uint32 (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_buffer,&__pyx_n_s_output_buffer,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_buffer)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_buffer)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint32", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint32", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint32", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_median_filter_uint32") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_input_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_uint32_t(values[0]); if (unlikely(!__pyx_v_input_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_output_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_uint32_t(values[1]); if (unlikely(!__pyx_v_output_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_kernel_size = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_int32_t(values[2]); if (unlikely(!__pyx_v_kernel_size.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint32", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter._median_filter_uint32", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(((PyObject *)__pyx_v_input_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "input_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_output_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "output_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_kernel_size.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "kernel_size"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_18_median_filter_uint32(__pyx_self, __pyx_v_input_buffer, __pyx_v_output_buffer, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_18_median_filter_uint32(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional) {
+ int __pyx_v_x;
+ int __pyx_v_image_dim;
+ int __pyx_v_buffer_shape[2];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ __Pyx_RefNannySetupContext("_median_filter_uint32", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":314
+ *
+ * cdef:
+ * int x = 0 # <<<<<<<<<<<<<<
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ */
+ __pyx_v_x = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":315
+ * cdef:
+ * int x = 0
+ * int image_dim = input_buffer.shape[1] - 1 # <<<<<<<<<<<<<<
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ */
+ __pyx_v_image_dim = ((__pyx_v_input_buffer.shape[1]) - 1);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":317
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0] # <<<<<<<<<<<<<<
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ */
+ (__pyx_v_buffer_shape[0]) = (__pyx_v_input_buffer.shape[0]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":318
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ * buffer_shape[1] = input_buffer.shape[1] # <<<<<<<<<<<<<<
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ */
+ (__pyx_v_buffer_shape[1]) = (__pyx_v_input_buffer.shape[1]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":320
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[uint32](<uint32*> & input_buffer[0,0],
+ * <uint32*> & output_buffer[0, 0],
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+ __pyx_t_1 = (__pyx_v_input_buffer.shape[0]);
+ if (1 == 0) abort();
+ {
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+ #endif
+ __pyx_t_3 = (__pyx_t_1 - 0) / 1;
+ if (__pyx_t_3 > 0)
+ {
+ #ifdef _OPENMP
+ #pragma omp parallel private(__pyx_t_4, __pyx_t_7, __pyx_t_8, __pyx_t_5, __pyx_t_6)
+ #endif /* _OPENMP */
+ {
+ #ifdef _OPENMP
+ #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x)
+ #endif /* _OPENMP */
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
+ {
+ __pyx_v_x = 0 + 1 * __pyx_t_2;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":321
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[uint32](<uint32*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <uint32*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":322
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[uint32](<uint32*> & input_buffer[0,0],
+ * <uint32*> & output_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <int*>&kernel_size[0],
+ * <int*>buffer_shape,
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":323
+ * median_filter.median_filter[uint32](<uint32*> & input_buffer[0,0],
+ * <uint32*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0], # <<<<<<<<<<<<<<
+ * <int*>buffer_shape,
+ * x,
+ */
+ __pyx_t_8 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":321
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[uint32](<uint32*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <uint32*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ median_filter<__pyx_t_4silx_4math_12medianfilter_12medianfilter_uint32>(((__pyx_t_4silx_4math_12medianfilter_12medianfilter_uint32 *)(&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_input_buffer.data + __pyx_t_4 * __pyx_v_input_buffer.strides[0]) )) + __pyx_t_5)) ))))), ((__pyx_t_4silx_4math_12medianfilter_12medianfilter_uint32 *)(&(*((__pyx_t_5numpy_uint32_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_uint32_t *) ( /* dim=0 */ (__pyx_v_output_buffer.data + __pyx_t_6 * __pyx_v_output_buffer.strides[0]) )) + __pyx_t_7)) ))))), ((int *)(&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_int32_t *) __pyx_v_kernel_size.data) + __pyx_t_8)) ))))), ((int *)__pyx_v_buffer_shape), __pyx_v_x, 0, __pyx_v_image_dim, __pyx_v_conditional);
+ }
+ }
+ }
+ }
+ }
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+ #endif
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":320
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[uint32](<uint32*> & input_buffer[0,0],
+ * <uint32*> & output_buffer[0, 0],
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":308
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint32(cnumpy.uint32_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.uint32_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_input_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_output_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_size, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":335
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int16(cnumpy.int16_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int16_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_21_median_filter_int16(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_20_median_filter_int16[] = "_median_filter_int16(__Pyx_memviewslice input_buffer, __Pyx_memviewslice output_buffer, __Pyx_memviewslice kernel_size, bool conditional)";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_21_median_filter_int16 = {"_median_filter_int16", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_21_median_filter_int16, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_20_median_filter_int16};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_21_median_filter_int16(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ __Pyx_memviewslice __pyx_v_input_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_output_buffer = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_memviewslice __pyx_v_kernel_size = { 0, 0, { 0 }, { 0 }, { 0 } };
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_median_filter_int16 (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_buffer,&__pyx_n_s_output_buffer,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_buffer)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_buffer)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int16", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int16", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int16", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_median_filter_int16") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_input_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int16_t(values[0]); if (unlikely(!__pyx_v_input_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_output_buffer = __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int16_t(values[1]); if (unlikely(!__pyx_v_output_buffer.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_kernel_size = __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_int32_t(values[2]); if (unlikely(!__pyx_v_kernel_size.memview)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 337; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 338; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_median_filter_int16", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter._median_filter_int16", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(((PyObject *)__pyx_v_input_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "input_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_output_buffer.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "output_buffer"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (unlikely(((PyObject *)__pyx_v_kernel_size.memview) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "kernel_size"); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 337; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_20_median_filter_int16(__pyx_self, __pyx_v_input_buffer, __pyx_v_output_buffer, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_20_median_filter_int16(CYTHON_UNUSED PyObject *__pyx_self, __Pyx_memviewslice __pyx_v_input_buffer, __Pyx_memviewslice __pyx_v_output_buffer, __Pyx_memviewslice __pyx_v_kernel_size, bool __pyx_v_conditional) {
+ int __pyx_v_x;
+ int __pyx_v_image_dim;
+ int __pyx_v_buffer_shape[2];
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ Py_ssize_t __pyx_t_8;
+ __Pyx_RefNannySetupContext("_median_filter_int16", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":341
+ *
+ * cdef:
+ * int x = 0 # <<<<<<<<<<<<<<
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ */
+ __pyx_v_x = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":342
+ * cdef:
+ * int x = 0
+ * int image_dim = input_buffer.shape[1] - 1 # <<<<<<<<<<<<<<
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ */
+ __pyx_v_image_dim = ((__pyx_v_input_buffer.shape[1]) - 1);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":344
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0] # <<<<<<<<<<<<<<
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ */
+ (__pyx_v_buffer_shape[0]) = (__pyx_v_input_buffer.shape[0]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":345
+ * int[2] buffer_shape
+ * buffer_shape[0] = input_buffer.shape[0]
+ * buffer_shape[1] = input_buffer.shape[1] # <<<<<<<<<<<<<<
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ */
+ (__pyx_v_buffer_shape[1]) = (__pyx_v_input_buffer.shape[1]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":347
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[short](<short*> & input_buffer[0,0],
+ * <short*> & output_buffer[0, 0],
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+ __pyx_t_1 = (__pyx_v_input_buffer.shape[0]);
+ if (1 == 0) abort();
+ {
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+ #endif
+ __pyx_t_3 = (__pyx_t_1 - 0) / 1;
+ if (__pyx_t_3 > 0)
+ {
+ #ifdef _OPENMP
+ #pragma omp parallel private(__pyx_t_4, __pyx_t_7, __pyx_t_8, __pyx_t_5, __pyx_t_6)
+ #endif /* _OPENMP */
+ {
+ #ifdef _OPENMP
+ #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x)
+ #endif /* _OPENMP */
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
+ {
+ __pyx_v_x = 0 + 1 * __pyx_t_2;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":348
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[short](<short*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <short*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":349
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[short](<short*> & input_buffer[0,0],
+ * <short*> & output_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <int*>&kernel_size[0],
+ * <int*>buffer_shape,
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":350
+ * median_filter.median_filter[short](<short*> & input_buffer[0,0],
+ * <short*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0], # <<<<<<<<<<<<<<
+ * <int*>buffer_shape,
+ * x,
+ */
+ __pyx_t_8 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":348
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[short](<short*> & input_buffer[0,0], # <<<<<<<<<<<<<<
+ * <short*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ median_filter<short>(((short *)(&(*((__pyx_t_5numpy_int16_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_input_buffer.data + __pyx_t_4 * __pyx_v_input_buffer.strides[0]) )) + __pyx_t_5)) ))))), ((short *)(&(*((__pyx_t_5numpy_int16_t *) ( /* dim=1 */ ((char *) (((__pyx_t_5numpy_int16_t *) ( /* dim=0 */ (__pyx_v_output_buffer.data + __pyx_t_6 * __pyx_v_output_buffer.strides[0]) )) + __pyx_t_7)) ))))), ((int *)(&(*((__pyx_t_5numpy_int32_t *) ( /* dim=0 */ ((char *) (((__pyx_t_5numpy_int32_t *) __pyx_v_kernel_size.data) + __pyx_t_8)) ))))), ((int *)__pyx_v_buffer_shape), __pyx_v_x, 0, __pyx_v_image_dim, __pyx_v_conditional);
+ }
+ }
+ }
+ }
+ }
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+ #endif
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":347
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[short](<short*> & input_buffer[0,0],
+ * <short*> & output_buffer[0, 0],
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":335
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int16(cnumpy.int16_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int16_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_input_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_output_buffer, 1);
+ __PYX_XDEC_MEMVIEW(&__pyx_v_kernel_size, 1);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "silx/math/medianfilter/medianfilter.pyx":362
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint16( # <<<<<<<<<<<<<<
+ * cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] input_buffer not None,
+ * cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] output_buffer not None,
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_23_median_filter_uint16(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_4silx_4math_12medianfilter_12medianfilter_22_median_filter_uint16[] = "_median_filter_uint16(ndarray input_buffer, ndarray output_buffer, ndarray kernel_size, bool conditional)";
+static PyMethodDef __pyx_mdef_4silx_4math_12medianfilter_12medianfilter_23_median_filter_uint16 = {"_median_filter_uint16", (PyCFunction)__pyx_pw_4silx_4math_12medianfilter_12medianfilter_23_median_filter_uint16, METH_VARARGS|METH_KEYWORDS, __pyx_doc_4silx_4math_12medianfilter_12medianfilter_22_median_filter_uint16};
+static PyObject *__pyx_pw_4silx_4math_12medianfilter_12medianfilter_23_median_filter_uint16(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyArrayObject *__pyx_v_input_buffer = 0;
+ PyArrayObject *__pyx_v_output_buffer = 0;
+ PyArrayObject *__pyx_v_kernel_size = 0;
+ bool __pyx_v_conditional;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("_median_filter_uint16 (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_buffer,&__pyx_n_s_output_buffer,&__pyx_n_s_kernel_size,&__pyx_n_s_conditional,0};
+ PyObject* values[4] = {0,0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_buffer)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_buffer)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint16", 1, 4, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_kernel_size)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint16", 1, 4, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (likely((values[3] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_conditional)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint16", 1, 4, 4, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_median_filter_uint16") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ }
+ __pyx_v_input_buffer = ((PyArrayObject *)values[0]);
+ __pyx_v_output_buffer = ((PyArrayObject *)values[1]);
+ __pyx_v_kernel_size = ((PyArrayObject *)values[2]);
+ __pyx_v_conditional = __Pyx_PyObject_IsTrue(values[3]); if (unlikely((__pyx_v_conditional == (bool)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("_median_filter_uint16", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter._median_filter_uint16", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return NULL;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_input_buffer), __pyx_ptype_5numpy_ndarray, 0, "input_buffer", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_output_buffer), __pyx_ptype_5numpy_ndarray, 0, "output_buffer", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_kernel_size), __pyx_ptype_5numpy_ndarray, 0, "kernel_size", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 365; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = __pyx_pf_4silx_4math_12medianfilter_12medianfilter_22_median_filter_uint16(__pyx_self, __pyx_v_input_buffer, __pyx_v_output_buffer, __pyx_v_kernel_size, __pyx_v_conditional);
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_pf_4silx_4math_12medianfilter_12medianfilter_22_median_filter_uint16(CYTHON_UNUSED PyObject *__pyx_self, PyArrayObject *__pyx_v_input_buffer, PyArrayObject *__pyx_v_output_buffer, PyArrayObject *__pyx_v_kernel_size, bool __pyx_v_conditional) {
+ int __pyx_v_x;
+ int __pyx_v_image_dim;
+ int __pyx_v_buffer_shape[2];
+ __Pyx_LocalBuf_ND __pyx_pybuffernd_input_buffer;
+ __Pyx_Buffer __pyx_pybuffer_input_buffer;
+ __Pyx_LocalBuf_ND __pyx_pybuffernd_kernel_size;
+ __Pyx_Buffer __pyx_pybuffer_kernel_size;
+ __Pyx_LocalBuf_ND __pyx_pybuffernd_output_buffer;
+ __Pyx_Buffer __pyx_pybuffer_output_buffer;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ npy_intp __pyx_t_1;
+ npy_intp __pyx_t_2;
+ npy_intp __pyx_t_3;
+ long __pyx_t_4;
+ long __pyx_t_5;
+ long __pyx_t_6;
+ long __pyx_t_7;
+ long __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_median_filter_uint16", 0);
+ __pyx_pybuffer_input_buffer.pybuffer.buf = NULL;
+ __pyx_pybuffer_input_buffer.refcount = 0;
+ __pyx_pybuffernd_input_buffer.data = NULL;
+ __pyx_pybuffernd_input_buffer.rcbuffer = &__pyx_pybuffer_input_buffer;
+ __pyx_pybuffer_output_buffer.pybuffer.buf = NULL;
+ __pyx_pybuffer_output_buffer.refcount = 0;
+ __pyx_pybuffernd_output_buffer.data = NULL;
+ __pyx_pybuffernd_output_buffer.rcbuffer = &__pyx_pybuffer_output_buffer;
+ __pyx_pybuffer_kernel_size.pybuffer.buf = NULL;
+ __pyx_pybuffer_kernel_size.refcount = 0;
+ __pyx_pybuffernd_kernel_size.data = NULL;
+ __pyx_pybuffernd_kernel_size.rcbuffer = &__pyx_pybuffer_kernel_size;
+ {
+ __Pyx_BufFmt_StackElem __pyx_stack[1];
+ if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_input_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_input_buffer, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint16_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_pybuffernd_input_buffer.diminfo[0].strides = __pyx_pybuffernd_input_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_input_buffer.diminfo[0].shape = __pyx_pybuffernd_input_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_input_buffer.diminfo[1].strides = __pyx_pybuffernd_input_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_input_buffer.diminfo[1].shape = __pyx_pybuffernd_input_buffer.rcbuffer->pybuffer.shape[1];
+ {
+ __Pyx_BufFmt_StackElem __pyx_stack[1];
+ if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_output_buffer.rcbuffer->pybuffer, (PyObject*)__pyx_v_output_buffer, &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint16_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 2, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_pybuffernd_output_buffer.diminfo[0].strides = __pyx_pybuffernd_output_buffer.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_output_buffer.diminfo[0].shape = __pyx_pybuffernd_output_buffer.rcbuffer->pybuffer.shape[0]; __pyx_pybuffernd_output_buffer.diminfo[1].strides = __pyx_pybuffernd_output_buffer.rcbuffer->pybuffer.strides[1]; __pyx_pybuffernd_output_buffer.diminfo[1].shape = __pyx_pybuffernd_output_buffer.rcbuffer->pybuffer.shape[1];
+ {
+ __Pyx_BufFmt_StackElem __pyx_stack[1];
+ if (unlikely(__Pyx_GetBufferAndValidate(&__pyx_pybuffernd_kernel_size.rcbuffer->pybuffer, (PyObject*)__pyx_v_kernel_size, &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, PyBUF_FORMAT| PyBUF_C_CONTIGUOUS, 1, 0, __pyx_stack) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_pybuffernd_kernel_size.diminfo[0].strides = __pyx_pybuffernd_kernel_size.rcbuffer->pybuffer.strides[0]; __pyx_pybuffernd_kernel_size.diminfo[0].shape = __pyx_pybuffernd_kernel_size.rcbuffer->pybuffer.shape[0];
+
+ /* "silx/math/medianfilter/medianfilter.pyx":369
+ *
+ * cdef:
+ * int x = 0 # <<<<<<<<<<<<<<
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape,
+ */
+ __pyx_v_x = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":370
+ * cdef:
+ * int x = 0
+ * int image_dim = input_buffer.shape[1] - 1 # <<<<<<<<<<<<<<
+ * int[2] buffer_shape,
+ * buffer_shape[0] = input_buffer.shape[0]
+ */
+ __pyx_v_image_dim = ((__pyx_v_input_buffer->dimensions[1]) - 1);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":372
+ * int image_dim = input_buffer.shape[1] - 1
+ * int[2] buffer_shape,
+ * buffer_shape[0] = input_buffer.shape[0] # <<<<<<<<<<<<<<
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ */
+ (__pyx_v_buffer_shape[0]) = (__pyx_v_input_buffer->dimensions[0]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":373
+ * int[2] buffer_shape,
+ * buffer_shape[0] = input_buffer.shape[0]
+ * buffer_shape[1] = input_buffer.shape[1] # <<<<<<<<<<<<<<
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ */
+ (__pyx_v_buffer_shape[1]) = (__pyx_v_input_buffer->dimensions[1]);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":375
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[uint16](<uint16*> & input_buffer[0, 0],
+ * <uint16*> & output_buffer[0, 0],
+ */
+ {
+ #ifdef WITH_THREAD
+ PyThreadState *_save;
+ Py_UNBLOCK_THREADS
+ #endif
+ /*try:*/ {
+ __pyx_t_1 = (__pyx_v_input_buffer->dimensions[0]);
+ if (1 == 0) abort();
+ {
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) (x)
+ #define unlikely(x) (x)
+ #endif
+ __pyx_t_3 = (__pyx_t_1 - 0) / 1;
+ if (__pyx_t_3 > 0)
+ {
+ #ifdef _OPENMP
+ #pragma omp parallel private(__pyx_t_8, __pyx_t_5, __pyx_t_6, __pyx_t_4, __pyx_t_7)
+ #endif /* _OPENMP */
+ {
+ #ifdef _OPENMP
+ #pragma omp for firstprivate(__pyx_v_x) lastprivate(__pyx_v_x)
+ #endif /* _OPENMP */
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_3; __pyx_t_2++){
+ {
+ __pyx_v_x = 0 + 1 * __pyx_t_2;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":376
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[uint16](<uint16*> & input_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <uint16*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":377
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[uint16](<uint16*> & input_buffer[0, 0],
+ * <uint16*> & output_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <int*>&kernel_size[0],
+ * <int*>buffer_shape,
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":378
+ * median_filter.median_filter[uint16](<uint16*> & input_buffer[0, 0],
+ * <uint16*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0], # <<<<<<<<<<<<<<
+ * <int*>buffer_shape,
+ * x,
+ */
+ __pyx_t_8 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":376
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True):
+ * median_filter.median_filter[uint16](<uint16*> & input_buffer[0, 0], # <<<<<<<<<<<<<<
+ * <uint16*> & output_buffer[0, 0],
+ * <int*>&kernel_size[0],
+ */
+ median_filter<__pyx_t_4silx_4math_12medianfilter_12medianfilter_uint16>(((__pyx_t_4silx_4math_12medianfilter_12medianfilter_uint16 *)(&(*__Pyx_BufPtrCContig2d(__pyx_t_5numpy_uint16_t *, __pyx_pybuffernd_input_buffer.rcbuffer->pybuffer.buf, __pyx_t_4, __pyx_pybuffernd_input_buffer.diminfo[0].strides, __pyx_t_5, __pyx_pybuffernd_input_buffer.diminfo[1].strides)))), ((__pyx_t_4silx_4math_12medianfilter_12medianfilter_uint16 *)(&(*__Pyx_BufPtrCContig2d(__pyx_t_5numpy_uint16_t *, __pyx_pybuffernd_output_buffer.rcbuffer->pybuffer.buf, __pyx_t_6, __pyx_pybuffernd_output_buffer.diminfo[0].strides, __pyx_t_7, __pyx_pybuffernd_output_buffer.diminfo[1].strides)))), ((int *)(&(*__Pyx_BufPtrCContig1d(__pyx_t_5numpy_int32_t *, __pyx_pybuffernd_kernel_size.rcbuffer->pybuffer.buf, __pyx_t_8, __pyx_pybuffernd_kernel_size.diminfo[0].strides)))), ((int *)__pyx_v_buffer_shape), __pyx_v_x, 0, __pyx_v_image_dim, __pyx_v_conditional);
+ }
+ }
+ }
+ }
+ }
+ #if ((defined(__APPLE__) || defined(__OSX__)) && (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))))
+ #undef likely
+ #undef unlikely
+ #define likely(x) __builtin_expect(!!(x), 1)
+ #define unlikely(x) __builtin_expect(!!(x), 0)
+ #endif
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":375
+ * buffer_shape[1] = input_buffer.shape[1]
+ *
+ * for x in prange(input_buffer.shape[0], nogil=True): # <<<<<<<<<<<<<<
+ * median_filter.median_filter[uint16](<uint16*> & input_buffer[0, 0],
+ * <uint16*> & output_buffer[0, 0],
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ #ifdef WITH_THREAD
+ Py_BLOCK_THREADS
+ #endif
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+ }
+
+ /* "silx/math/medianfilter/medianfilter.pyx":362
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint16( # <<<<<<<<<<<<<<
+ * cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] input_buffer not None,
+ * cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] output_buffer not None,
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
+ __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_input_buffer.rcbuffer->pybuffer);
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_kernel_size.rcbuffer->pybuffer);
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_output_buffer.rcbuffer->pybuffer);
+ __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
+ __Pyx_AddTraceback("silx.math.medianfilter.medianfilter._median_filter_uint16", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ goto __pyx_L2;
+ __pyx_L0:;
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_input_buffer.rcbuffer->pybuffer);
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_kernel_size.rcbuffer->pybuffer);
+ __Pyx_SafeReleaseBuffer(&__pyx_pybuffernd_output_buffer.rcbuffer->pybuffer);
+ __pyx_L2:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_copy_shape;
+ int __pyx_v_i;
+ int __pyx_v_ndim;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ int __pyx_v_t;
+ char *__pyx_v_f;
+ PyArray_Descr *__pyx_v_descr = 0;
+ int __pyx_v_offset;
+ int __pyx_v_hasfields;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":200
+ * # of flags
+ *
+ * if info == NULL: return # <<<<<<<<<<<<<<
+ *
+ * cdef int copy_shape, i, ndim
+ */
+ __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+ if (__pyx_t_1) {
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":204
+ * cdef int copy_shape, i, ndim
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ *
+ * ndim = PyArray_NDIM(self)
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *
+ * ndim = PyArray_NDIM(self) # <<<<<<<<<<<<<<
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":208
+ * ndim = PyArray_NDIM(self)
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * copy_shape = 1
+ * else:
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * copy_shape = 1 # <<<<<<<<<<<<<<
+ * else:
+ * copy_shape = 0
+ */
+ __pyx_v_copy_shape = 1;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ * copy_shape = 1
+ * else:
+ * copy_shape = 0 # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+ __pyx_v_copy_shape = 0;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":213
+ * copy_shape = 0
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L6_bool_binop_done;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * raise ValueError(u"ndarray is not C contiguous")
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS) # <<<<<<<<<<<<<<
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+ __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L9_bool_binop_done;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ */
+ __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * raise ValueError(u"ndarray is not Fortran contiguous")
+ *
+ * info.buf = PyArray_DATA(self) # <<<<<<<<<<<<<<
+ * info.ndim = ndim
+ * if copy_shape:
+ */
+ __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim # <<<<<<<<<<<<<<
+ * if copy_shape:
+ * # Allocate new buffer for strides and shape info.
+ */
+ __pyx_v_info->ndim = __pyx_v_ndim;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":223
+ * info.buf = PyArray_DATA(self)
+ * info.ndim = ndim
+ * if copy_shape: # <<<<<<<<<<<<<<
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ */
+ __pyx_t_1 = (__pyx_v_copy_shape != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ * # Allocate new buffer for strides and shape info.
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2) # <<<<<<<<<<<<<<
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":227
+ * # This is allocated as one block, strides first.
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+ __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":228
+ * info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ * info.shape = info.strides + ndim
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ */
+ __pyx_t_4 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ * info.shape = info.strides + ndim
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i] # <<<<<<<<<<<<<<
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ */
+ (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ * for i in range(ndim):
+ * info.strides[i] = PyArray_STRIDES(self)[i]
+ * info.shape[i] = PyArray_DIMS(self)[i] # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+ (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+ }
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ * info.shape[i] = PyArray_DIMS(self)[i]
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self) # <<<<<<<<<<<<<<
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ */
+ __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ * else:
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self) # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ */
+ __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+ }
+ __pyx_L11:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":234
+ * info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ * info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self) # <<<<<<<<<<<<<<
+ * info.readonly = not PyArray_ISWRITEABLE(self)
+ *
+ */
+ __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ * info.suboffsets = NULL
+ * info.itemsize = PyArray_ITEMSIZE(self)
+ * info.readonly = not PyArray_ISWRITEABLE(self) # <<<<<<<<<<<<<<
+ *
+ * cdef int t
+ */
+ __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *
+ * cdef int t
+ * cdef char* f = NULL # <<<<<<<<<<<<<<
+ * cdef dtype descr = self.descr
+ * cdef list stack
+ */
+ __pyx_v_f = NULL;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":240
+ * cdef int t
+ * cdef char* f = NULL
+ * cdef dtype descr = self.descr # <<<<<<<<<<<<<<
+ * cdef list stack
+ * cdef int offset
+ */
+ __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":244
+ * cdef int offset
+ *
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr) # <<<<<<<<<<<<<<
+ *
+ * if not hasfields and not copy_shape:
+ */
+ __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":246
+ * cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ *
+ * if not hasfields and not copy_shape: # <<<<<<<<<<<<<<
+ * # do not call releasebuffer
+ * info.obj = None
+ */
+ __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L15_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L15_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":248
+ * if not hasfields and not copy_shape:
+ * # do not call releasebuffer
+ * info.obj = None # <<<<<<<<<<<<<<
+ * else:
+ * # need to call releasebuffer
+ */
+ __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = Py_None;
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":251
+ * else:
+ * # need to call releasebuffer
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * if not hasfields:
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+ }
+ __pyx_L14:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":253
+ * info.obj = self
+ *
+ * if not hasfields: # <<<<<<<<<<<<<<
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":254
+ *
+ * if not hasfields:
+ * t = descr.type_num # <<<<<<<<<<<<<<
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ */
+ __pyx_t_4 = __pyx_v_descr->type_num;
+ __pyx_v_t = __pyx_t_4;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":255
+ * if not hasfields:
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+ if (!__pyx_t_2) {
+ goto __pyx_L20_next_or;
+ } else {
+ }
+ __pyx_t_2 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_L20_next_or:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ * t = descr.type_num
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ */
+ __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L19_bool_binop_done;
+ }
+ __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L19_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ switch (__pyx_v_t) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ */
+ case NPY_BYTE:
+ __pyx_v_f = __pyx_k_b;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ * raise ValueError(u"Non-native byte order not supported")
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ */
+ case NPY_UBYTE:
+ __pyx_v_f = __pyx_k_B;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ */
+ case NPY_SHORT:
+ __pyx_v_f = __pyx_k_h;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ * elif t == NPY_UBYTE: f = "B"
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ */
+ case NPY_USHORT:
+ __pyx_v_f = __pyx_k_H;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ * elif t == NPY_SHORT: f = "h"
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ */
+ case NPY_INT:
+ __pyx_v_f = __pyx_k_i;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ * elif t == NPY_USHORT: f = "H"
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ */
+ case NPY_UINT:
+ __pyx_v_f = __pyx_k_I;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ * elif t == NPY_INT: f = "i"
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ */
+ case NPY_LONG:
+ __pyx_v_f = __pyx_k_l;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ * elif t == NPY_UINT: f = "I"
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ */
+ case NPY_ULONG:
+ __pyx_v_f = __pyx_k_L;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ * elif t == NPY_LONG: f = "l"
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ */
+ case NPY_LONGLONG:
+ __pyx_v_f = __pyx_k_q;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ * elif t == NPY_ULONG: f = "L"
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ */
+ case NPY_ULONGLONG:
+ __pyx_v_f = __pyx_k_Q;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ * elif t == NPY_LONGLONG: f = "q"
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ */
+ case NPY_FLOAT:
+ __pyx_v_f = __pyx_k_f;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ * elif t == NPY_ULONGLONG: f = "Q"
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ */
+ case NPY_DOUBLE:
+ __pyx_v_f = __pyx_k_d;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ * elif t == NPY_FLOAT: f = "f"
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ */
+ case NPY_LONGDOUBLE:
+ __pyx_v_f = __pyx_k_g;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ * elif t == NPY_DOUBLE: f = "d"
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf" # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+ case NPY_CFLOAT:
+ __pyx_v_f = __pyx_k_Zf;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ * elif t == NPY_LONGDOUBLE: f = "g"
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd" # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O"
+ */
+ case NPY_CDOUBLE:
+ __pyx_v_f = __pyx_k_Zd;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ * elif t == NPY_CFLOAT: f = "Zf"
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg" # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ */
+ case NPY_CLONGDOUBLE:
+ __pyx_v_f = __pyx_k_Zg;
+ break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ * elif t == NPY_CDOUBLE: f = "Zd"
+ * elif t == NPY_CLONGDOUBLE: f = "Zg"
+ * elif t == NPY_OBJECT: f = "O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ case NPY_OBJECT:
+ __pyx_v_f = __pyx_k_O;
+ break;
+ default:
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ * elif t == NPY_OBJECT: f = "O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * info.format = f
+ * return
+ */
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __pyx_t_6 = 0;
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ break;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":277
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f # <<<<<<<<<<<<<<
+ * return
+ * else:
+ */
+ __pyx_v_info->format = __pyx_v_f;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":278
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * info.format = f
+ * return # <<<<<<<<<<<<<<
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ * return
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len) # <<<<<<<<<<<<<<
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ */
+ __pyx_v_info->format = ((char *)malloc(255));
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":281
+ * else:
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment # <<<<<<<<<<<<<<
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1,
+ */
+ (__pyx_v_info->format[0]) = '^';
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":282
+ * info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0 # <<<<<<<<<<<<<<
+ * f = _util_dtypestring(descr, info.format + 1,
+ * info.format + _buffer_format_string_len,
+ */
+ __pyx_v_offset = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ * info.format[0] = c'^' # Native data types, manual alignment
+ * offset = 0
+ * f = _util_dtypestring(descr, info.format + 1, # <<<<<<<<<<<<<<
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ */
+ __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_7;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":286
+ * info.format + _buffer_format_string_len,
+ * &offset)
+ * f[0] = c'\0' # Terminate format string # <<<<<<<<<<<<<<
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+ (__pyx_v_f[0]) = '\x00';
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":194
+ * # experimental exception made for __getbuffer__ and __releasebuffer__
+ * # -- the details of this may change.
+ * def __getbuffer__(ndarray self, Py_buffer* info, int flags): # <<<<<<<<<<<<<<
+ * # This implementation of getbuffer is geared towards Cython
+ * # requirements, and does not yet fullfill the PEP.
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+ __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":289
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self): # <<<<<<<<<<<<<<
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+ __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":290
+ * def __releasebuffer__(ndarray self, Py_buffer* info):
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format) # <<<<<<<<<<<<<<
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides)
+ */
+ free(__pyx_v_info->format);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t): # <<<<<<<<<<<<<<
+ * stdlib.free(info.strides)
+ * # info.shape was stored after info.strides in the same block
+ */
+ __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ * stdlib.free(info.format)
+ * if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ * stdlib.free(info.strides) # <<<<<<<<<<<<<<
+ * # info.shape was stored after info.strides in the same block
+ *
+ */
+ free(__pyx_v_info->strides);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ * f[0] = c'\0' # Terminate format string
+ *
+ * def __releasebuffer__(ndarray self, Py_buffer* info): # <<<<<<<<<<<<<<
+ * if PyArray_HASFIELDS(self):
+ * stdlib.free(info.format)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":769
+ *
+ * cdef inline object PyArray_MultiIterNew1(a):
+ * return PyArray_MultiIterNew(1, <void*>a) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
+ * ctypedef npy_cdouble complex_t
+ *
+ * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":772
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * return PyArray_MultiIterNew(1, <void*>a)
+ *
+ * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":775
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *
+ * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":778
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d) # <<<<<<<<<<<<<<
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":781
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e) # <<<<<<<<<<<<<<
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<<
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+ PyArray_Descr *__pyx_v_child = 0;
+ int __pyx_v_endian_detector;
+ int __pyx_v_little_endian;
+ PyObject *__pyx_v_fields = 0;
+ PyObject *__pyx_v_childname = NULL;
+ PyObject *__pyx_v_new_offset = NULL;
+ PyObject *__pyx_v_t = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ Py_ssize_t __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ long __pyx_t_8;
+ char *__pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":790
+ * cdef int delta_offset
+ * cdef tuple i
+ * cdef int endian_detector = 1 # <<<<<<<<<<<<<<
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * cdef tuple fields
+ */
+ __pyx_v_endian_detector = 1;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":791
+ * cdef tuple i
+ * cdef int endian_detector = 1
+ * cdef bint little_endian = ((<char*>&endian_detector)[0] != 0) # <<<<<<<<<<<<<<
+ * cdef tuple fields
+ *
+ */
+ __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ if (unlikely(__pyx_v_descr->names == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+ for (;;) {
+ if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":795
+ *
+ * for childname in descr.names:
+ * fields = descr.fields[childname] # <<<<<<<<<<<<<<
+ * child, new_offset = fields
+ *
+ */
+ __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+ __pyx_t_3 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":796
+ * for childname in descr.names:
+ * fields = descr.fields[childname]
+ * child, new_offset = fields # <<<<<<<<<<<<<<
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+ if (likely(__pyx_v_fields != Py_None)) {
+ PyObject* sequence = __pyx_v_fields;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_4);
+ #else
+ __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ #endif
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+ __pyx_t_3 = 0;
+ __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ * child, new_offset = fields
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *
+ * if ((child.byteorder == c'>' and little_endian) or # <<<<<<<<<<<<<<
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported")
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+ if (!__pyx_t_7) {
+ goto __pyx_L8_next_or;
+ } else {
+ }
+ __pyx_t_7 = (__pyx_v_little_endian != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_L8_next_or:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)): # <<<<<<<<<<<<<<
+ * raise ValueError(u"Non-native byte order not supported")
+ * # One could encode it in the format string and have Cython
+ */
+ __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+ if (__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L7_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":813
+ *
+ * # Output padding bytes
+ * while offset[0] < new_offset: # <<<<<<<<<<<<<<
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ */
+ while (1) {
+ __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (!__pyx_t_6) break;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":814
+ * # Output padding bytes
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte # <<<<<<<<<<<<<<
+ * f += 1
+ * offset[0] += 1
+ */
+ (__pyx_v_f[0]) = 120;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":815
+ * while offset[0] < new_offset:
+ * f[0] = 120 # "x"; pad byte
+ * f += 1 # <<<<<<<<<<<<<<
+ * offset[0] += 1
+ *
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ * f[0] = 120 # "x"; pad byte
+ * f += 1
+ * offset[0] += 1 # <<<<<<<<<<<<<<
+ *
+ * offset[0] += child.itemsize
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ * offset[0] += 1
+ *
+ * offset[0] += child.itemsize # <<<<<<<<<<<<<<
+ *
+ * if not PyDataType_HASFIELDS(child):
+ */
+ __pyx_t_8 = 0;
+ (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":820
+ * offset[0] += child.itemsize
+ *
+ * if not PyDataType_HASFIELDS(child): # <<<<<<<<<<<<<<
+ * t = child.type_num
+ * if end - f < 5:
+ */
+ __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ *
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num # <<<<<<<<<<<<<<
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.")
+ */
+ __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+ __pyx_t_4 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":822
+ * if not PyDataType_HASFIELDS(child):
+ * t = child.type_num
+ * if end - f < 5: # <<<<<<<<<<<<<<
+ * raise RuntimeError(u"Format string allocated too short.")
+ *
+ */
+ __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+ if (__pyx_t_6) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b" # <<<<<<<<<<<<<<
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 98;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":827
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B" # <<<<<<<<<<<<<<
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 66;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":828
+ * if t == NPY_BYTE: f[0] = 98 #"b"
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h" # <<<<<<<<<<<<<<
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 104;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ * elif t == NPY_UBYTE: f[0] = 66 #"B"
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H" # <<<<<<<<<<<<<<
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 72;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ * elif t == NPY_SHORT: f[0] = 104 #"h"
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i" # <<<<<<<<<<<<<<
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 105;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ * elif t == NPY_USHORT: f[0] = 72 #"H"
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 73;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ * elif t == NPY_INT: f[0] = 105 #"i"
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 108;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ * elif t == NPY_UINT: f[0] = 73 #"I"
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 76;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ * elif t == NPY_LONG: f[0] = 108 #"l"
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q" # <<<<<<<<<<<<<<
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 113;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ * elif t == NPY_ULONG: f[0] = 76 #"L"
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q" # <<<<<<<<<<<<<<
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 81;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ * elif t == NPY_LONGLONG: f[0] = 113 #"q"
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f" # <<<<<<<<<<<<<<
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 102;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ * elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d" # <<<<<<<<<<<<<<
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 100;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ * elif t == NPY_FLOAT: f[0] = 102 #"f"
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" # <<<<<<<<<<<<<<
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 103;
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ * elif t == NPY_DOUBLE: f[0] = 100 #"d"
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf # <<<<<<<<<<<<<<
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 102;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ * elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd # <<<<<<<<<<<<<<
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 100;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ * elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg # <<<<<<<<<<<<<<
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ */
+ __pyx_t_3 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 90;
+ (__pyx_v_f[1]) = 103;
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L15;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ * elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd
+ * elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ * elif t == NPY_OBJECT: f[0] = 79 #"O" # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+ __pyx_t_4 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ if (__pyx_t_6) {
+ (__pyx_v_f[0]) = 79;
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ * elif t == NPY_OBJECT: f[0] = 79 #"O"
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t) # <<<<<<<<<<<<<<
+ * f += 1
+ * else:
+ */
+ __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[1]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L15:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ * else:
+ * raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ * f += 1 # <<<<<<<<<<<<<<
+ * else:
+ * # Cython ignores struct boundary information ("T{...}"),
+ */
+ __pyx_v_f = (__pyx_v_f + 1);
+ goto __pyx_L13;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":849
+ * # Cython ignores struct boundary information ("T{...}"),
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset) # <<<<<<<<<<<<<<
+ * return f
+ *
+ */
+ __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_f = __pyx_t_9;
+ }
+ __pyx_L13:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ * cdef tuple fields
+ *
+ * for childname in descr.names: # <<<<<<<<<<<<<<
+ * fields = descr.fields[childname]
+ * child, new_offset = fields
+ */
+ }
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":850
+ * # so don't output it
+ * f = _util_dtypestring(child, f, end, offset)
+ * return f # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_f;
+ goto __pyx_L0;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: # <<<<<<<<<<<<<<
+ * # Recursive utility function used in __getbuffer__ to get format
+ * # string. The new location in the format string is returned.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_child);
+ __Pyx_XDECREF(__pyx_v_fields);
+ __Pyx_XDECREF(__pyx_v_childname);
+ __Pyx_XDECREF(__pyx_v_new_offset);
+ __Pyx_XDECREF(__pyx_v_t);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+ PyObject *__pyx_v_baseptr;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("set_array_base", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ * cdef PyObject* baseptr
+ * if base is None: # <<<<<<<<<<<<<<
+ * baseptr = NULL
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_base == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ * cdef PyObject* baseptr
+ * if base is None:
+ * baseptr = NULL # <<<<<<<<<<<<<<
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ */
+ __pyx_v_baseptr = NULL;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ * baseptr = NULL
+ * else:
+ * Py_INCREF(base) # important to do this before decref below! # <<<<<<<<<<<<<<
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ */
+ Py_INCREF(__pyx_v_base);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ * else:
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base # <<<<<<<<<<<<<<
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr
+ */
+ __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+ }
+ __pyx_L3:;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":973
+ * Py_INCREF(base) # important to do this before decref below!
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base) # <<<<<<<<<<<<<<
+ * arr.base = baseptr
+ *
+ */
+ Py_XDECREF(__pyx_v_arr->base);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ * baseptr = <PyObject*>base
+ * Py_XDECREF(arr.base)
+ * arr.base = baseptr # <<<<<<<<<<<<<<
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ */
+ __pyx_v_arr->base = __pyx_v_baseptr;
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ *
+ *
+ * cdef inline void set_array_base(ndarray arr, object base): # <<<<<<<<<<<<<<
+ * cdef PyObject* baseptr
+ * if base is None:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("get_array_base", 0);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ *
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL: # <<<<<<<<<<<<<<
+ * return None
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":978
+ * cdef inline object get_array_base(ndarray arr):
+ * if arr.base is NULL:
+ * return None # <<<<<<<<<<<<<<
+ * else:
+ * return <object>arr.base
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ * return None
+ * else:
+ * return <object>arr.base # <<<<<<<<<<<<<<
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+ __pyx_r = ((PyObject *)__pyx_v_arr->base);
+ goto __pyx_L0;
+ }
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ * arr.base = baseptr
+ *
+ * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<<
+ * if arr.base is NULL:
+ * return None
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_array___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_shape = 0;
+ Py_ssize_t __pyx_v_itemsize;
+ PyObject *__pyx_v_format = 0;
+ PyObject *__pyx_v_mode = 0;
+ int __pyx_v_allocate_buffer;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_itemsize,&__pyx_n_s_format,&__pyx_n_s_mode,&__pyx_n_s_allocate_buffer,0};
+ PyObject* values[5] = {0,0,0,0,0};
+ values[3] = ((PyObject *)__pyx_n_s_c);
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_itemsize)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (likely((values[2] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_format)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 3:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_mode);
+ if (value) { values[3] = value; kw_args--; }
+ }
+ case 4:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_allocate_buffer);
+ if (value) { values[4] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+ case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_shape = ((PyObject*)values[0]);
+ __pyx_v_itemsize = __Pyx_PyIndex_AsSsize_t(values[1]); if (unlikely((__pyx_v_itemsize == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_v_format = values[2];
+ __pyx_v_mode = values[3];
+ if (values[4]) {
+ __pyx_v_allocate_buffer = __Pyx_PyObject_IsTrue(values[4]); if (unlikely((__pyx_v_allocate_buffer == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+
+ /* "View.MemoryView":117
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
+ * mode="c", bint allocate_buffer=True): # <<<<<<<<<<<<<<
+ *
+ * cdef int idx
+ */
+ __pyx_v_allocate_buffer = ((int)1);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_shape), (&PyTuple_Type), 1, "shape", 1))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (unlikely(((PyObject *)__pyx_v_format) == Py_None)) {
+ PyErr_Format(PyExc_TypeError, "Argument '%.200s' must not be None", "format"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_r = __pyx_array_MemoryView_5array___cinit__(((struct __pyx_array_obj *)__pyx_v_self), __pyx_v_shape, __pyx_v_itemsize, __pyx_v_format, __pyx_v_mode, __pyx_v_allocate_buffer);
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array___cinit__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, PyObject *__pyx_v_format, PyObject *__pyx_v_mode, int __pyx_v_allocate_buffer) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_dim;
+ PyObject **__pyx_v_p;
+ char __pyx_v_order;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+ __Pyx_INCREF(__pyx_v_format);
+
+ /* "View.MemoryView":123
+ * cdef PyObject **p
+ *
+ * self.ndim = <int> len(shape) # <<<<<<<<<<<<<<
+ * self.itemsize = itemsize
+ *
+ */
+ if (unlikely(__pyx_v_shape == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "object of type 'NoneType' has no len()");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = PyTuple_GET_SIZE(__pyx_v_shape); if (unlikely(__pyx_t_1 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 123; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->ndim = ((int)__pyx_t_1);
+
+ /* "View.MemoryView":124
+ *
+ * self.ndim = <int> len(shape)
+ * self.itemsize = itemsize # <<<<<<<<<<<<<<
+ *
+ * if not self.ndim:
+ */
+ __pyx_v_self->itemsize = __pyx_v_itemsize;
+
+ /* "View.MemoryView":126
+ * self.itemsize = itemsize
+ *
+ * if not self.ndim: # <<<<<<<<<<<<<<
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_self->ndim != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":129
+ * raise ValueError("Empty shape tuple for cython.array")
+ *
+ * if itemsize <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_itemsize <= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":132
+ * raise ValueError("itemsize <= 0 for cython.array")
+ *
+ * if isinstance(format, unicode): # <<<<<<<<<<<<<<
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ */
+ __pyx_t_2 = PyUnicode_Check(__pyx_v_format);
+ __pyx_t_4 = (__pyx_t_2 != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":133
+ *
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII') # <<<<<<<<<<<<<<
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format
+ */
+ if (unlikely(__pyx_v_format == Py_None)) {
+ PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", "encode");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_3 = PyUnicode_AsASCIIString(((PyObject*)__pyx_v_format)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_format, __pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":134
+ * if isinstance(format, unicode):
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string # <<<<<<<<<<<<<<
+ * self.format = self._format
+ *
+ */
+ if (!(likely(PyBytes_CheckExact(__pyx_v_format))||((__pyx_v_format) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_v_format)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = __pyx_v_format;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __Pyx_GOTREF(__pyx_v_self->_format);
+ __Pyx_DECREF(__pyx_v_self->_format);
+ __pyx_v_self->_format = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":135
+ * format = (<unicode>format).encode('ASCII')
+ * self._format = format # keep a reference to the byte string
+ * self.format = self._format # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __Pyx_PyObject_AsString(__pyx_v_self->_format); if (unlikely((!__pyx_t_5) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_self->format = __pyx_t_5;
+
+ /* "View.MemoryView":138
+ *
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2) # <<<<<<<<<<<<<<
+ * self._strides = self._shape + self.ndim
+ *
+ */
+ __pyx_v_self->_shape = ((Py_ssize_t *)PyMem_Malloc((((sizeof(Py_ssize_t)) * __pyx_v_self->ndim) * 2)));
+
+ /* "View.MemoryView":139
+ *
+ * self._shape = <Py_ssize_t *> PyMem_Malloc(sizeof(Py_ssize_t)*self.ndim*2)
+ * self._strides = self._shape + self.ndim # <<<<<<<<<<<<<<
+ *
+ * if not self._shape:
+ */
+ __pyx_v_self->_strides = (__pyx_v_self->_shape + __pyx_v_self->ndim);
+
+ /* "View.MemoryView":141
+ * self._strides = self._shape + self.ndim
+ *
+ * if not self._shape: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate shape and strides.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->_shape != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ __pyx_t_6 = 0;
+ __pyx_t_3 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_3); __pyx_t_1 = 0;
+ for (;;) {
+ if (__pyx_t_1 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_1); __Pyx_INCREF(__pyx_t_7); __pyx_t_1++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_3, __pyx_t_1); __pyx_t_1++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_t_8 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_8 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __pyx_v_dim = __pyx_t_8;
+ __pyx_v_idx = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":146
+ *
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim
+ */
+ __pyx_t_4 = ((__pyx_v_dim <= 0) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":147
+ * for idx, dim in enumerate(shape):
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim)) # <<<<<<<<<<<<<<
+ * self._shape[idx] = dim
+ *
+ */
+ __pyx_t_7 = __Pyx_PyInt_From_int(__pyx_v_idx); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_9 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_7 = 0;
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_t_10); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_10);
+ PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9);
+ __Pyx_GIVEREF(__pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+ __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":148
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ * self._shape[idx] = dim # <<<<<<<<<<<<<<
+ *
+ * cdef char order
+ */
+ (__pyx_v_self->_shape[__pyx_v_idx]) = __pyx_v_dim;
+
+ /* "View.MemoryView":145
+ *
+ *
+ * for idx, dim in enumerate(shape): # <<<<<<<<<<<<<<
+ * if dim <= 0:
+ * raise ValueError("Invalid shape in axis %d: %d." % (idx, dim))
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":151
+ *
+ * cdef char order
+ * if mode == 'fortran': # <<<<<<<<<<<<<<
+ * order = b'F'
+ * self.mode = u'fortran'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_fortran, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":152
+ * cdef char order
+ * if mode == 'fortran':
+ * order = b'F' # <<<<<<<<<<<<<<
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ */
+ __pyx_v_order = 'F';
+
+ /* "View.MemoryView":153
+ * if mode == 'fortran':
+ * order = b'F'
+ * self.mode = u'fortran' # <<<<<<<<<<<<<<
+ * elif mode == 'c':
+ * order = b'C'
+ */
+ __Pyx_INCREF(__pyx_n_u_fortran);
+ __Pyx_GIVEREF(__pyx_n_u_fortran);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_fortran;
+ goto __pyx_L10;
+ }
+
+ /* "View.MemoryView":154
+ * order = b'F'
+ * self.mode = u'fortran'
+ * elif mode == 'c': # <<<<<<<<<<<<<<
+ * order = b'C'
+ * self.mode = u'c'
+ */
+ __pyx_t_4 = (__Pyx_PyString_Equals(__pyx_v_mode, __pyx_n_s_c, Py_EQ)); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":155
+ * self.mode = u'fortran'
+ * elif mode == 'c':
+ * order = b'C' # <<<<<<<<<<<<<<
+ * self.mode = u'c'
+ * else:
+ */
+ __pyx_v_order = 'C';
+
+ /* "View.MemoryView":156
+ * elif mode == 'c':
+ * order = b'C'
+ * self.mode = u'c' # <<<<<<<<<<<<<<
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ */
+ __Pyx_INCREF(__pyx_n_u_c);
+ __Pyx_GIVEREF(__pyx_n_u_c);
+ __Pyx_GOTREF(__pyx_v_self->mode);
+ __Pyx_DECREF(__pyx_v_self->mode);
+ __pyx_v_self->mode = __pyx_n_u_c;
+ goto __pyx_L10;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":158
+ * self.mode = u'c'
+ * else:
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode) # <<<<<<<<<<<<<<
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides,
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_v_mode); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_9, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":160
+ * raise ValueError("Invalid mode, expected 'c' or 'fortran', got %s" % mode)
+ *
+ * self.len = fill_contig_strides_array(self._shape, self._strides, # <<<<<<<<<<<<<<
+ * itemsize, self.ndim, order)
+ *
+ */
+ __pyx_v_self->len = __pyx_fill_contig_strides_array(__pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_itemsize, __pyx_v_self->ndim, __pyx_v_order);
+
+ /* "View.MemoryView":163
+ * itemsize, self.ndim, order)
+ *
+ * self.free_data = allocate_buffer # <<<<<<<<<<<<<<
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer:
+ */
+ __pyx_v_self->free_data = __pyx_v_allocate_buffer;
+
+ /* "View.MemoryView":164
+ *
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O' # <<<<<<<<<<<<<<
+ * if allocate_buffer:
+ *
+ */
+ __pyx_t_3 = PyObject_RichCompare(__pyx_v_format, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely((__pyx_t_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_4;
+
+ /* "View.MemoryView":165
+ * self.free_data = allocate_buffer
+ * self.dtype_is_object = format == b'O'
+ * if allocate_buffer: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = (__pyx_v_allocate_buffer != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":168
+ *
+ *
+ * self.data = <char *>malloc(self.len) # <<<<<<<<<<<<<<
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.")
+ */
+ __pyx_v_self->data = ((char *)malloc(__pyx_v_self->len));
+
+ /* "View.MemoryView":169
+ *
+ * self.data = <char *>malloc(self.len)
+ * if not self.data: # <<<<<<<<<<<<<<
+ * raise MemoryError("unable to allocate array data.")
+ *
+ */
+ __pyx_t_4 = ((!(__pyx_v_self->data != 0)) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_MemoryError, __pyx_tuple__17, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":172
+ * raise MemoryError("unable to allocate array data.")
+ *
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ */
+ __pyx_t_4 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":173
+ *
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data # <<<<<<<<<<<<<<
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ */
+ __pyx_v_p = ((PyObject **)__pyx_v_self->data);
+
+ /* "View.MemoryView":174
+ * if self.dtype_is_object:
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize): # <<<<<<<<<<<<<<
+ * p[i] = Py_None
+ * Py_INCREF(Py_None)
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_self->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_t_1 = __Pyx_div_Py_ssize_t(__pyx_v_self->len, __pyx_v_itemsize);
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_1; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":175
+ * p = <PyObject **> self.data
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ (__pyx_v_p[__pyx_v_i]) = Py_None;
+
+ /* "View.MemoryView":176
+ * for i in range(self.len / itemsize):
+ * p[i] = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ Py_INCREF(Py_None);
+ }
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":116
+ * cdef bint dtype_is_object
+ *
+ * def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, # <<<<<<<<<<<<<<
+ * mode="c", bint allocate_buffer=True):
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_XDECREF(__pyx_t_10);
+ __Pyx_AddTraceback("View.MemoryView.array.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_format);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_array_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(((struct __pyx_array_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_getbuffer_MemoryView_5array_2__getbuffer__(struct __pyx_array_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_v_bufmode;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ char *__pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":180
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1 # <<<<<<<<<<<<<<
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = -1;
+
+ /* "View.MemoryView":181
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * cdef int bufmode = -1
+ * if self.mode == u"c": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ */
+ __pyx_t_1 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_c, Py_EQ)); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":182
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ */
+ __pyx_v_bufmode = (PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":183
+ * if self.mode == u"c":
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran": # <<<<<<<<<<<<<<
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ */
+ __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_self->mode, __pyx_n_u_fortran, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":184
+ * bufmode = PyBUF_C_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS # <<<<<<<<<<<<<<
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ */
+ __pyx_v_bufmode = (PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":185
+ * elif self.mode == u"fortran":
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode): # <<<<<<<<<<<<<<
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ */
+ __pyx_t_1 = ((!((__pyx_v_flags & __pyx_v_bufmode) != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__18, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":187
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data # <<<<<<<<<<<<<<
+ * info.len = self.len
+ * info.ndim = self.ndim
+ */
+ __pyx_t_4 = __pyx_v_self->data;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":188
+ * raise ValueError("Can only create a buffer that is contiguous in memory.")
+ * info.buf = self.data
+ * info.len = self.len # <<<<<<<<<<<<<<
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ */
+ __pyx_t_5 = __pyx_v_self->len;
+ __pyx_v_info->len = __pyx_t_5;
+
+ /* "View.MemoryView":189
+ * info.buf = self.data
+ * info.len = self.len
+ * info.ndim = self.ndim # <<<<<<<<<<<<<<
+ * info.shape = self._shape
+ * info.strides = self._strides
+ */
+ __pyx_t_6 = __pyx_v_self->ndim;
+ __pyx_v_info->ndim = __pyx_t_6;
+
+ /* "View.MemoryView":190
+ * info.len = self.len
+ * info.ndim = self.ndim
+ * info.shape = self._shape # <<<<<<<<<<<<<<
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ */
+ __pyx_t_7 = __pyx_v_self->_shape;
+ __pyx_v_info->shape = __pyx_t_7;
+
+ /* "View.MemoryView":191
+ * info.ndim = self.ndim
+ * info.shape = self._shape
+ * info.strides = self._strides # <<<<<<<<<<<<<<
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ */
+ __pyx_t_7 = __pyx_v_self->_strides;
+ __pyx_v_info->strides = __pyx_t_7;
+
+ /* "View.MemoryView":192
+ * info.shape = self._shape
+ * info.strides = self._strides
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ * info.itemsize = self.itemsize
+ * info.readonly = 0
+ */
+ __pyx_v_info->suboffsets = NULL;
+
+ /* "View.MemoryView":193
+ * info.strides = self._strides
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ *
+ */
+ __pyx_t_5 = __pyx_v_self->itemsize;
+ __pyx_v_info->itemsize = __pyx_t_5;
+
+ /* "View.MemoryView":194
+ * info.suboffsets = NULL
+ * info.itemsize = self.itemsize
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":196
+ * info.readonly = 0
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":197
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_4 = __pyx_v_self->format;
+ __pyx_v_info->format = __pyx_t_4;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":199
+ * info.format = self.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.obj = self
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":201
+ * info.format = NULL
+ *
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":179
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * cdef int bufmode = -1
+ * if self.mode == u"c":
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+ }
+ goto __pyx_L2;
+ __pyx_L0:;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __pyx_L2:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+/* Python wrapper */
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_array___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_array_MemoryView_5array_4__dealloc__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_array_MemoryView_5array_4__dealloc__(struct __pyx_array_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":206
+ *
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL: # <<<<<<<<<<<<<<
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ */
+ __pyx_t_1 = ((__pyx_v_self->callback_free_data != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":207
+ * def __dealloc__(array self):
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data) # <<<<<<<<<<<<<<
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ */
+ __pyx_v_self->callback_free_data(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":208
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ * elif self.free_data: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape,
+ */
+ __pyx_t_1 = (__pyx_v_self->free_data != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":209
+ * self.callback_free_data(self.data)
+ * elif self.free_data:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":210
+ * elif self.free_data:
+ * if self.dtype_is_object:
+ * refcount_objects_in_slice(self.data, self._shape, # <<<<<<<<<<<<<<
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_self->data, __pyx_v_self->_shape, __pyx_v_self->_strides, __pyx_v_self->ndim, 0);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":212
+ * refcount_objects_in_slice(self.data, self._shape,
+ * self._strides, self.ndim, False)
+ * free(self.data) # <<<<<<<<<<<<<<
+ * PyMem_Free(self._shape)
+ *
+ */
+ free(__pyx_v_self->data);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":213
+ * self._strides, self.ndim, False)
+ * free(self.data)
+ * PyMem_Free(self._shape) # <<<<<<<<<<<<<<
+ *
+ * property memview:
+ */
+ PyMem_Free(__pyx_v_self->_shape);
+
+ /* "View.MemoryView":205
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)")
+ *
+ * def __dealloc__(array self): # <<<<<<<<<<<<<<
+ * if self.callback_free_data != NULL:
+ * self.callback_free_data(self.data)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+/* Python wrapper */
+static PyObject *get_memview(PyObject *__pyx_v_self); /*proto*/
+static PyObject *get_memview(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = get_memview_MemoryView_5array_7memview___get__(((struct __pyx_array_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *get_memview_MemoryView_5array_7memview___get__(struct __pyx_array_obj *__pyx_v_self) {
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":219
+ * def __get__(self):
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE # <<<<<<<<<<<<<<
+ * return memoryview(self, flags, self.dtype_is_object)
+ *
+ */
+ __pyx_v_flags = ((PyBUF_ANY_CONTIGUOUS | PyBUF_FORMAT) | PyBUF_WRITABLE);
+
+ /* "View.MemoryView":220
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ * return memoryview(self, flags, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":217
+ * property memview:
+ * @cname('get_memview')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ *
+ * flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT|PyBUF_WRITABLE
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.array.memview.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr); /*proto*/
+static PyObject *__pyx_array___getattr__(PyObject *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getattr__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_6__getattr__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_attr));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_6__getattr__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_attr) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getattr__", 0);
+
+ /* "View.MemoryView":224
+ *
+ * def __getattr__(self, attr):
+ * return getattr(self.memview, attr) # <<<<<<<<<<<<<<
+ *
+ * def __getitem__(self, item):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_GetAttr(__pyx_t_1, __pyx_v_attr); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":223
+ *
+ *
+ * def __getattr__(self, attr): # <<<<<<<<<<<<<<
+ * return getattr(self.memview, attr)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getattr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item); /*proto*/
+static PyObject *__pyx_array___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_8__getitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_array_MemoryView_5array_8__getitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":227
+ *
+ * def __getitem__(self, item):
+ * return self.memview[item] # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(self, item, value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyObject_GetItem(__pyx_t_1, __pyx_v_item); if (unlikely(__pyx_t_2 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":226
+ * return getattr(self.memview, attr)
+ *
+ * def __getitem__(self, item): # <<<<<<<<<<<<<<
+ * return self.memview[item]
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.array.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_array___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_array_MemoryView_5array_10__setitem__(((struct __pyx_array_obj *)__pyx_v_self), ((PyObject *)__pyx_v_item), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_array_MemoryView_5array_10__setitem__(struct __pyx_array_obj *__pyx_v_self, PyObject *__pyx_v_item, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+
+ /* "View.MemoryView":230
+ *
+ * def __setitem__(self, item, value):
+ * self.memview[item] = value # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_memview); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (unlikely(PyObject_SetItem(__pyx_t_1, __pyx_v_item, __pyx_v_value) < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 230; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":229
+ * return self.memview[item]
+ *
+ * def __setitem__(self, item, value): # <<<<<<<<<<<<<<
+ * self.memview[item] = value
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.array.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+static struct __pyx_array_obj *__pyx_array_new(PyObject *__pyx_v_shape, Py_ssize_t __pyx_v_itemsize, char *__pyx_v_format, char *__pyx_v_mode, char *__pyx_v_buf) {
+ struct __pyx_array_obj *__pyx_v_result = 0;
+ struct __pyx_array_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("array_cwrapper", 0);
+
+ /* "View.MemoryView":238
+ * cdef array result
+ *
+ * if buf == NULL: # <<<<<<<<<<<<<<
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_buf == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":239
+ *
+ * if buf == NULL:
+ * result = array(shape, itemsize, format, mode.decode('ASCII')) # <<<<<<<<<<<<<<
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ */
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_5, 3, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_5, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_mode, 0, strlen(__pyx_v_mode), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_2 = PyTuple_New(4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
+ __Pyx_GIVEREF(__pyx_v_shape);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_2, 2, __pyx_t_5);
+ __Pyx_GIVEREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_2, 3, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_4 = 0;
+ __pyx_t_5 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":242
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False) # <<<<<<<<<<<<<<
+ * result.data = buf
+ *
+ */
+ if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_allocate_buffer, Py_False) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":241
+ * result = array(shape, itemsize, format, mode.decode('ASCII'))
+ * else:
+ * result = array(shape, itemsize, format, mode.decode('ASCII'), # <<<<<<<<<<<<<<
+ * allocate_buffer=False)
+ * result.data = buf
+ */
+ __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_array_type)), __pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_array_obj *)__pyx_t_5);
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":243
+ * result = array(shape, itemsize, format, mode.decode('ASCII'),
+ * allocate_buffer=False)
+ * result.data = buf # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->data = __pyx_v_buf;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":245
+ * result.data = buf
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":234
+ *
+ * @cname("__pyx_array_new")
+ * cdef array array_cwrapper(tuple shape, Py_ssize_t itemsize, char *format, # <<<<<<<<<<<<<<
+ * char *mode, char *buf):
+ * cdef array result
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.array_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+/* Python wrapper */
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_MemviewEnum___init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_name = 0;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_name,0};
+ PyObject* values[1] = {0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_name)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else if (PyTuple_GET_SIZE(__pyx_args) != 1) {
+ goto __pyx_L5_argtuple_error;
+ } else {
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ }
+ __pyx_v_name = values[0];
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__init__", 1, 1, 1, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.Enum.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum___init__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self), __pyx_v_name);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_MemviewEnum_MemoryView_4Enum___init__(struct __pyx_MemviewEnum_obj *__pyx_v_self, PyObject *__pyx_v_name) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__init__", 0);
+
+ /* "View.MemoryView":272
+ * cdef object name
+ * def __init__(self, name):
+ * self.name = name # <<<<<<<<<<<<<<
+ * def __repr__(self):
+ * return self.name
+ */
+ __Pyx_INCREF(__pyx_v_name);
+ __Pyx_GIVEREF(__pyx_v_name);
+ __Pyx_GOTREF(__pyx_v_self->name);
+ __Pyx_DECREF(__pyx_v_self->name);
+ __pyx_v_self->name = __pyx_v_name;
+
+ /* "View.MemoryView":271
+ * cdef class Enum(object):
+ * cdef object name
+ * def __init__(self, name): # <<<<<<<<<<<<<<
+ * self.name = name
+ * def __repr__(self):
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_MemviewEnum___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_MemviewEnum_MemoryView_4Enum_2__repr__(((struct __pyx_MemviewEnum_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_MemviewEnum_MemoryView_4Enum_2__repr__(struct __pyx_MemviewEnum_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":274
+ * self.name = name
+ * def __repr__(self):
+ * return self.name # <<<<<<<<<<<<<<
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->name);
+ __pyx_r = __pyx_v_self->name;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":273
+ * def __init__(self, name):
+ * self.name = name
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return self.name
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+static void *__pyx_align_pointer(void *__pyx_v_memory, size_t __pyx_v_alignment) {
+ Py_intptr_t __pyx_v_aligned_p;
+ size_t __pyx_v_offset;
+ void *__pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":290
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil:
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory # <<<<<<<<<<<<<<
+ * cdef size_t offset
+ *
+ */
+ __pyx_v_aligned_p = ((Py_intptr_t)__pyx_v_memory);
+
+ /* "View.MemoryView":294
+ *
+ * with cython.cdivision(True):
+ * offset = aligned_p % alignment # <<<<<<<<<<<<<<
+ *
+ * if offset > 0:
+ */
+ __pyx_v_offset = (__pyx_v_aligned_p % __pyx_v_alignment);
+
+ /* "View.MemoryView":296
+ * offset = aligned_p % alignment
+ *
+ * if offset > 0: # <<<<<<<<<<<<<<
+ * aligned_p += alignment - offset
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_offset > 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":297
+ *
+ * if offset > 0:
+ * aligned_p += alignment - offset # <<<<<<<<<<<<<<
+ *
+ * return <void *> aligned_p
+ */
+ __pyx_v_aligned_p = (__pyx_v_aligned_p + (__pyx_v_alignment - __pyx_v_offset));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":299
+ * aligned_p += alignment - offset
+ *
+ * return <void *> aligned_p # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview')
+ */
+ __pyx_r = ((void *)__pyx_v_aligned_p);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":288
+ *
+ * @cname('__pyx_align_pointer')
+ * cdef void *align_pointer(void *memory, size_t alignment) nogil: # <<<<<<<<<<<<<<
+ * "Align pointer memory on a given boundary"
+ * cdef Py_intptr_t aligned_p = <Py_intptr_t> memory
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_memoryview___cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+ PyObject *__pyx_v_obj = 0;
+ int __pyx_v_flags;
+ int __pyx_v_dtype_is_object;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+ {
+ static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_obj,&__pyx_n_s_flags,&__pyx_n_s_dtype_is_object,0};
+ PyObject* values[3] = {0,0,0};
+ if (unlikely(__pyx_kwds)) {
+ Py_ssize_t kw_args;
+ const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+ switch (pos_args) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ case 0: break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ kw_args = PyDict_Size(__pyx_kwds);
+ switch (pos_args) {
+ case 0:
+ if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_obj)) != 0)) kw_args--;
+ else goto __pyx_L5_argtuple_error;
+ case 1:
+ if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags)) != 0)) kw_args--;
+ else {
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, 1); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ case 2:
+ if (kw_args > 0) {
+ PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype_is_object);
+ if (value) { values[2] = value; kw_args--; }
+ }
+ }
+ if (unlikely(kw_args > 0)) {
+ if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ }
+ } else {
+ switch (PyTuple_GET_SIZE(__pyx_args)) {
+ case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+ case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+ values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+ break;
+ default: goto __pyx_L5_argtuple_error;
+ }
+ }
+ __pyx_v_obj = values[0];
+ __pyx_v_flags = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_flags == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ if (values[2]) {
+ __pyx_v_dtype_is_object = __Pyx_PyObject_IsTrue(values[2]); if (unlikely((__pyx_v_dtype_is_object == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ } else {
+ __pyx_v_dtype_is_object = ((int)0);
+ }
+ }
+ goto __pyx_L4_argument_unpacking_done;
+ __pyx_L5_argtuple_error:;
+ __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __pyx_L3_error:;
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __Pyx_RefNannyFinishContext();
+ return -1;
+ __pyx_L4_argument_unpacking_done:;
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview___cinit__(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_obj, __pyx_v_flags, __pyx_v_dtype_is_object);
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview___cinit__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj, int __pyx_v_flags, int __pyx_v_dtype_is_object) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__cinit__", 0);
+
+ /* "View.MemoryView":318
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj # <<<<<<<<<<<<<<
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ */
+ __Pyx_INCREF(__pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ __Pyx_GOTREF(__pyx_v_self->obj);
+ __Pyx_DECREF(__pyx_v_self->obj);
+ __pyx_v_self->obj = __pyx_v_obj;
+
+ /* "View.MemoryView":319
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False):
+ * self.obj = obj
+ * self.flags = flags # <<<<<<<<<<<<<<
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ */
+ __pyx_v_self->flags = __pyx_v_flags;
+
+ /* "View.MemoryView":320
+ * self.obj = obj
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ */
+ __pyx_t_2 = (((PyObject *)Py_TYPE(((PyObject *)__pyx_v_self))) == ((PyObject *)((PyObject *)__pyx_memoryview_type)));
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (!__pyx_t_3) {
+ } else {
+ __pyx_t_1 = __pyx_t_3;
+ goto __pyx_L4_bool_binop_done;
+ }
+ __pyx_t_3 = (__pyx_v_obj != Py_None);
+ __pyx_t_2 = (__pyx_t_3 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L4_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":321
+ * self.flags = flags
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags) # <<<<<<<<<<<<<<
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ */
+ __pyx_t_4 = __Pyx_GetBuffer(__pyx_v_obj, (&__pyx_v_self->view), __pyx_v_flags); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":322
+ * if type(self) is memoryview or obj is not None:
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL: # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_self->view.obj) == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":323
+ * __Pyx_GetBuffer(obj, &self.view, flags)
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_self->view))->obj = Py_None;
+
+ /* "View.MemoryView":324
+ * if <PyObject *> self.view.obj == NULL:
+ * (<__pyx_buffer *> &self.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * self.lock = PyThread_allocate_lock()
+ */
+ Py_INCREF(Py_None);
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":326
+ * Py_INCREF(Py_None)
+ *
+ * self.lock = PyThread_allocate_lock() # <<<<<<<<<<<<<<
+ * if self.lock == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_self->lock = PyThread_allocate_lock();
+
+ /* "View.MemoryView":327
+ *
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->lock == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":328
+ * self.lock = PyThread_allocate_lock()
+ * if self.lock == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":330
+ * raise MemoryError
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":331
+ *
+ * if flags & PyBUF_FORMAT:
+ * self.dtype_is_object = self.view.format == b'O' # <<<<<<<<<<<<<<
+ * else:
+ * self.dtype_is_object = dtype_is_object
+ */
+ __pyx_t_5 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = PyObject_RichCompare(__pyx_t_5, __pyx_n_b_O, Py_EQ); __Pyx_XGOTREF(__pyx_t_6); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_6); if (unlikely((__pyx_t_1 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __pyx_v_self->dtype_is_object = __pyx_t_1;
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":333
+ * self.dtype_is_object = self.view.format == b'O'
+ * else:
+ * self.dtype_is_object = dtype_is_object # <<<<<<<<<<<<<<
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ */
+ __pyx_v_self->dtype_is_object = __pyx_v_dtype_is_object;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":335
+ * self.dtype_is_object = dtype_is_object
+ *
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer( # <<<<<<<<<<<<<<
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL
+ */
+ __pyx_v_self->acquisition_count_aligned_p = ((__pyx_atomic_int *)__pyx_align_pointer(((void *)(&(__pyx_v_self->acquisition_count[0]))), (sizeof(__pyx_atomic_int))));
+
+ /* "View.MemoryView":337
+ * self.acquisition_count_aligned_p = <__pyx_atomic_int *> align_pointer(
+ * <void *> &self.acquisition_count[0], sizeof(__pyx_atomic_int))
+ * self.typeinfo = NULL # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(memoryview self):
+ */
+ __pyx_v_self->typeinfo = NULL;
+
+ /* "View.MemoryView":317
+ * cdef __Pyx_TypeInfo *typeinfo
+ *
+ * def __cinit__(memoryview self, object obj, int flags, bint dtype_is_object=False): # <<<<<<<<<<<<<<
+ * self.obj = obj
+ * self.flags = flags
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+/* Python wrapper */
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryview___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryview_MemoryView_10memoryview_2__dealloc__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":340
+ *
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None: # <<<<<<<<<<<<<<
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->obj != Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":341
+ * def __dealloc__(memoryview self):
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view) # <<<<<<<<<<<<<<
+ *
+ * if self.lock != NULL:
+ */
+ __Pyx_ReleaseBuffer((&__pyx_v_self->view));
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":343
+ * __Pyx_ReleaseBuffer(&self.view)
+ *
+ * if self.lock != NULL: # <<<<<<<<<<<<<<
+ * PyThread_free_lock(self.lock)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_self->lock != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":344
+ *
+ * if self.lock != NULL:
+ * PyThread_free_lock(self.lock) # <<<<<<<<<<<<<<
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ */
+ PyThread_free_lock(__pyx_v_self->lock);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":339
+ * self.typeinfo = NULL
+ *
+ * def __dealloc__(memoryview self): # <<<<<<<<<<<<<<
+ * if self.obj is not None:
+ * __Pyx_ReleaseBuffer(&self.view)
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+static char *__pyx_memoryview_get_item_pointer(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ Py_ssize_t __pyx_v_dim;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_v_idx = NULL;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ Py_ssize_t __pyx_t_3;
+ PyObject *(*__pyx_t_4)(PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ Py_ssize_t __pyx_t_6;
+ char *__pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_item_pointer", 0);
+
+ /* "View.MemoryView":348
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL:
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim, idx in enumerate(index):
+ */
+ __pyx_v_itemp = ((char *)__pyx_v_self->view.buf);
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ __pyx_t_1 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_index)) || PyTuple_CheckExact(__pyx_v_index)) {
+ __pyx_t_2 = __pyx_v_index; __Pyx_INCREF(__pyx_t_2); __pyx_t_3 = 0;
+ __pyx_t_4 = NULL;
+ } else {
+ __pyx_t_3 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_index); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_4 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_4)) {
+ if (likely(PyList_CheckExact(__pyx_t_2))) {
+ if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_5 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_3); __Pyx_INCREF(__pyx_t_5); __pyx_t_3++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_5 = PySequence_ITEM(__pyx_t_2, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_5 = __pyx_t_4(__pyx_t_2);
+ if (unlikely(!__pyx_t_5)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_5);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_5);
+ __pyx_t_5 = 0;
+ __pyx_v_dim = __pyx_t_1;
+ __pyx_t_1 = (__pyx_t_1 + 1);
+
+ /* "View.MemoryView":351
+ *
+ * for dim, idx in enumerate(index):
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim) # <<<<<<<<<<<<<<
+ *
+ * return itemp
+ */
+ __pyx_t_6 = __Pyx_PyIndex_AsSsize_t(__pyx_v_idx); if (unlikely((__pyx_t_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = __pyx_pybuffer_index((&__pyx_v_self->view), __pyx_v_itemp, __pyx_t_6, __pyx_v_dim); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_7;
+
+ /* "View.MemoryView":350
+ * cdef char *itemp = <char *> self.view.buf
+ *
+ * for dim, idx in enumerate(index): # <<<<<<<<<<<<<<
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":353
+ * itemp = pybuffer_index(&self.view, itemp, idx, dim)
+ *
+ * return itemp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_itemp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":346
+ * PyThread_free_lock(self.lock)
+ *
+ * cdef char *get_item_pointer(memoryview self, object index) except NULL: # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dim
+ * cdef char *itemp = <char *> self.view.buf
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.get_item_pointer", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index); /*proto*/
+static PyObject *__pyx_memoryview___getitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_4__getitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_4__getitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_indices = NULL;
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ char *__pyx_t_6;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__getitem__", 0);
+
+ /* "View.MemoryView":357
+ *
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis: # <<<<<<<<<<<<<<
+ * return self
+ *
+ */
+ __pyx_t_1 = (__pyx_v_index == __pyx_builtin_Ellipsis);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":358
+ * def __getitem__(memoryview self, object index):
+ * if index is Ellipsis:
+ * return self # <<<<<<<<<<<<<<
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __pyx_r = ((PyObject *)__pyx_v_self);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":360
+ * return self
+ *
+ * have_slices, indices = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef char *itemp
+ */
+ __pyx_t_3 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(__pyx_t_3 != Py_None)) {
+ PyObject* sequence = __pyx_t_3;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_4 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ #else
+ __pyx_t_4 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ #endif
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_v_indices = __pyx_t_5;
+ __pyx_t_5 = 0;
+
+ /* "View.MemoryView":363
+ *
+ * cdef char *itemp
+ * if have_slices: # <<<<<<<<<<<<<<
+ * return memview_slice(self, indices)
+ * else:
+ */
+ __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":364
+ * cdef char *itemp
+ * if have_slices:
+ * return memview_slice(self, indices) # <<<<<<<<<<<<<<
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((PyObject *)__pyx_memview_slice(__pyx_v_self, __pyx_v_indices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":366
+ * return memview_slice(self, indices)
+ * else:
+ * itemp = self.get_item_pointer(indices) # <<<<<<<<<<<<<<
+ * return self.convert_item_to_object(itemp)
+ *
+ */
+ __pyx_t_6 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_indices); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 366; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_6;
+
+ /* "View.MemoryView":367
+ * else:
+ * itemp = self.get_item_pointer(indices)
+ * return self.convert_item_to_object(itemp) # <<<<<<<<<<<<<<
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->convert_item_to_object(__pyx_v_self, __pyx_v_itemp); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 367; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":356
+ *
+ *
+ * def __getitem__(memoryview self, object index): # <<<<<<<<<<<<<<
+ * if index is Ellipsis:
+ * return self
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__getitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_indices);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+/* Python wrapper */
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value); /*proto*/
+static int __pyx_memoryview___setitem__(PyObject *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__setitem__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_6__setitem__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((PyObject *)__pyx_v_index), ((PyObject *)__pyx_v_value));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_MemoryView_10memoryview_6__setitem__(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_have_slices = NULL;
+ PyObject *__pyx_v_obj = NULL;
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__setitem__", 0);
+ __Pyx_INCREF(__pyx_v_index);
+
+ /* "View.MemoryView":370
+ *
+ * def __setitem__(memoryview self, object index, object value):
+ * have_slices, index = _unellipsify(index, self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * if have_slices:
+ */
+ __pyx_t_1 = _unellipsify(__pyx_v_index, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (likely(__pyx_t_1 != Py_None)) {
+ PyObject* sequence = __pyx_t_1;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ Py_ssize_t size = Py_SIZE(sequence);
+ #else
+ Py_ssize_t size = PySequence_Size(sequence);
+ #endif
+ if (unlikely(size != 2)) {
+ if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+ else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0);
+ __pyx_t_3 = PyTuple_GET_ITEM(sequence, 1);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(__pyx_t_3);
+ #else
+ __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ #endif
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ } else {
+ __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_have_slices = __pyx_t_2;
+ __pyx_t_2 = 0;
+ __Pyx_DECREF_SET(__pyx_v_index, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":372
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ * if have_slices: # <<<<<<<<<<<<<<
+ * obj = self.is_slice(value)
+ * if obj:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_have_slices); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":373
+ *
+ * if have_slices:
+ * obj = self.is_slice(value) # <<<<<<<<<<<<<<
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj)
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->is_slice(__pyx_v_self, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_obj = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":374
+ * if have_slices:
+ * obj = self.is_slice(value)
+ * if obj: # <<<<<<<<<<<<<<
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ */
+ __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_v_obj); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":375
+ * obj = self.is_slice(value)
+ * if obj:
+ * self.setitem_slice_assignment(self[index], obj) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value)
+ */
+ __pyx_t_1 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assignment(__pyx_v_self, __pyx_t_1, __pyx_v_obj); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 375; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":377
+ * self.setitem_slice_assignment(self[index], obj)
+ * else:
+ * self.setitem_slice_assign_scalar(self[index], value) # <<<<<<<<<<<<<<
+ * else:
+ * self.setitem_indexed(index, value)
+ */
+ __pyx_t_3 = PyObject_GetItem(((PyObject *)__pyx_v_self), __pyx_v_index); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_slice_assign_scalar(__pyx_v_self, ((struct __pyx_memoryview_obj *)__pyx_t_3), __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 377; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":379
+ * self.setitem_slice_assign_scalar(self[index], value)
+ * else:
+ * self.setitem_indexed(index, value) # <<<<<<<<<<<<<<
+ *
+ * cdef is_slice(self, obj):
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->setitem_indexed(__pyx_v_self, __pyx_v_index, __pyx_v_value); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":369
+ * return self.convert_item_to_object(itemp)
+ *
+ * def __setitem__(memoryview self, object index, object value): # <<<<<<<<<<<<<<
+ * have_slices, index = _unellipsify(index, self.view.ndim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__setitem__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_have_slices);
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+static PyObject *__pyx_memoryview_is_slice(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_obj) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ int __pyx_t_9;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_slice", 0);
+ __Pyx_INCREF(__pyx_v_obj);
+
+ /* "View.MemoryView":382
+ *
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview): # <<<<<<<<<<<<<<
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_obj, ((PyObject *)__pyx_memoryview_type));
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":383
+ * cdef is_slice(self, obj):
+ * if not isinstance(obj, memoryview):
+ * try: # <<<<<<<<<<<<<<
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_3, &__pyx_t_4, &__pyx_t_5);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_5);
+ /*try:*/ {
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_6 = __Pyx_PyInt_From_int((__pyx_v_self->flags | PyBUF_ANY_CONTIGUOUS)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":385
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object) # <<<<<<<<<<<<<<
+ * except TypeError:
+ * return None
+ */
+ __pyx_t_7 = __Pyx_PyBool_FromLong(__pyx_v_self->dtype_is_object); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 385; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+
+ /* "View.MemoryView":384
+ * if not isinstance(obj, memoryview):
+ * try:
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS, # <<<<<<<<<<<<<<
+ * self.dtype_is_object)
+ * except TypeError:
+ */
+ __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_INCREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_v_obj);
+ __Pyx_GIVEREF(__pyx_v_obj);
+ PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_6 = 0;
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_8, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF_SET(__pyx_v_obj, __pyx_t_7);
+ __pyx_t_7 = 0;
+ }
+ __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ goto __pyx_L11_try_end;
+ __pyx_L4_error:;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":386
+ * obj = memoryview(obj, self.flags|PyBUF_ANY_CONTIGUOUS,
+ * self.dtype_is_object)
+ * except TypeError: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_9 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+ if (__pyx_t_9) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_6) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_GOTREF(__pyx_t_8);
+ __Pyx_GOTREF(__pyx_t_6);
+
+ /* "View.MemoryView":387
+ * self.dtype_is_object)
+ * except TypeError:
+ * return None # <<<<<<<<<<<<<<
+ *
+ * return obj
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ goto __pyx_L7_except_return;
+ }
+ goto __pyx_L6_except_error;
+ __pyx_L6_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L1_error;
+ __pyx_L7_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_XGIVEREF(__pyx_t_5);
+ __Pyx_ExceptionReset(__pyx_t_3, __pyx_t_4, __pyx_t_5);
+ goto __pyx_L0;
+ __pyx_L11_try_end:;
+ }
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":389
+ * return None
+ *
+ * return obj # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assignment(self, dst, src):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_obj);
+ __pyx_r = __pyx_v_obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":381
+ * self.setitem_indexed(index, value)
+ *
+ * cdef is_slice(self, obj): # <<<<<<<<<<<<<<
+ * if not isinstance(obj, memoryview):
+ * try:
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_obj);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assignment(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_dst, PyObject *__pyx_v_src) {
+ __Pyx_memviewslice __pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_src_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assignment", 0);
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ if (!(likely(((__pyx_v_src) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_src, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":396
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0], # <<<<<<<<<<<<<<
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_v_dst) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_dst, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 396; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":397
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0],
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_src, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_2 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_dst, __pyx_n_s_ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":395
+ * cdef __Pyx_memviewslice src_slice
+ *
+ * memoryview_copy_contents(get_slice_from_memview(src, &src_slice)[0], # <<<<<<<<<<<<<<
+ * get_slice_from_memview(dst, &dst_slice)[0],
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ */
+ __pyx_t_4 = __pyx_memoryview_copy_contents((__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_src), (&__pyx_v_src_slice))[0]), (__pyx_memoryview_get_slice_from_memoryview(((struct __pyx_memoryview_obj *)__pyx_v_dst), (&__pyx_v_dst_slice))[0]), __pyx_t_2, __pyx_t_3, __pyx_v_self->dtype_is_object); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 395; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":391
+ * return obj
+ *
+ * cdef setitem_slice_assignment(self, dst, src): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice dst_slice
+ * cdef __Pyx_memviewslice src_slice
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+static PyObject *__pyx_memoryview_setitem_slice_assign_scalar(struct __pyx_memoryview_obj *__pyx_v_self, struct __pyx_memoryview_obj *__pyx_v_dst, PyObject *__pyx_v_value) {
+ int __pyx_v_array[128];
+ void *__pyx_v_tmp;
+ void *__pyx_v_item;
+ __Pyx_memviewslice *__pyx_v_dst_slice;
+ __Pyx_memviewslice __pyx_v_tmp_slice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ char const *__pyx_t_5;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ PyObject *__pyx_t_10 = NULL;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_slice_assign_scalar", 0);
+
+ /* "View.MemoryView":401
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value):
+ * cdef int array[128]
+ * cdef void *tmp = NULL # <<<<<<<<<<<<<<
+ * cdef void *item
+ *
+ */
+ __pyx_v_tmp = NULL;
+
+ /* "View.MemoryView":406
+ * cdef __Pyx_memviewslice *dst_slice
+ * cdef __Pyx_memviewslice tmp_slice
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice) # <<<<<<<<<<<<<<
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ */
+ __pyx_v_dst_slice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_dst, (&__pyx_v_tmp_slice));
+
+ /* "View.MemoryView":408
+ * dst_slice = get_slice_from_memview(dst, &tmp_slice)
+ *
+ * if <size_t>self.view.itemsize > sizeof(array): # <<<<<<<<<<<<<<
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ */
+ __pyx_t_1 = ((((size_t)__pyx_v_self->view.itemsize) > (sizeof(__pyx_v_array))) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":409
+ *
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize) # <<<<<<<<<<<<<<
+ * if tmp == NULL:
+ * raise MemoryError
+ */
+ __pyx_v_tmp = PyMem_Malloc(__pyx_v_self->view.itemsize);
+
+ /* "View.MemoryView":410
+ * if <size_t>self.view.itemsize > sizeof(array):
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL: # <<<<<<<<<<<<<<
+ * raise MemoryError
+ * item = tmp
+ */
+ __pyx_t_1 = ((__pyx_v_tmp == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":411
+ * tmp = PyMem_Malloc(self.view.itemsize)
+ * if tmp == NULL:
+ * raise MemoryError # <<<<<<<<<<<<<<
+ * item = tmp
+ * else:
+ */
+ PyErr_NoMemory(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":412
+ * if tmp == NULL:
+ * raise MemoryError
+ * item = tmp # <<<<<<<<<<<<<<
+ * else:
+ * item = <void *> array
+ */
+ __pyx_v_item = __pyx_v_tmp;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":414
+ * item = tmp
+ * else:
+ * item = <void *> array # <<<<<<<<<<<<<<
+ *
+ * try:
+ */
+ __pyx_v_item = ((void *)__pyx_v_array);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":416
+ * item = <void *> array
+ *
+ * try: # <<<<<<<<<<<<<<
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value
+ */
+ /*try:*/ {
+
+ /* "View.MemoryView":417
+ *
+ * try:
+ * if self.dtype_is_object: # <<<<<<<<<<<<<<
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ */
+ __pyx_t_1 = (__pyx_v_self->dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":418
+ * try:
+ * if self.dtype_is_object:
+ * (<PyObject **> item)[0] = <PyObject *> value # <<<<<<<<<<<<<<
+ * else:
+ * self.assign_item_from_object(<char *> item, value)
+ */
+ (((PyObject **)__pyx_v_item)[0]) = ((PyObject *)__pyx_v_value);
+ goto __pyx_L8;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":420
+ * (<PyObject **> item)[0] = <PyObject *> value
+ * else:
+ * self.assign_item_from_object(<char *> item, value) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, ((char *)__pyx_v_item), __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":424
+ *
+ *
+ * if self.view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":425
+ *
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim) # <<<<<<<<<<<<<<
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize,
+ * item, self.dtype_is_object)
+ */
+ __pyx_t_2 = assert_direct_dimensions(__pyx_v_self->view.suboffsets, __pyx_v_self->view.ndim); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L6_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":426
+ * if self.view.suboffsets != NULL:
+ * assert_direct_dimensions(self.view.suboffsets, self.view.ndim)
+ * slice_assign_scalar(dst_slice, dst.view.ndim, self.view.itemsize, # <<<<<<<<<<<<<<
+ * item, self.dtype_is_object)
+ * finally:
+ */
+ __pyx_memoryview_slice_assign_scalar(__pyx_v_dst_slice, __pyx_v_dst->view.ndim, __pyx_v_self->view.itemsize, __pyx_v_item, __pyx_v_self->dtype_is_object);
+ }
+
+ /* "View.MemoryView":429
+ * item, self.dtype_is_object)
+ * finally:
+ * PyMem_Free(tmp) # <<<<<<<<<<<<<<
+ *
+ * cdef setitem_indexed(self, index, value):
+ */
+ /*finally:*/ {
+ /*normal exit:*/{
+ PyMem_Free(__pyx_v_tmp);
+ goto __pyx_L7;
+ }
+ /*exception exit:*/{
+ __pyx_L6_error:;
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+ if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_9, &__pyx_t_10, &__pyx_t_11);
+ if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8) < 0)) __Pyx_ErrFetch(&__pyx_t_6, &__pyx_t_7, &__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_6);
+ __Pyx_XGOTREF(__pyx_t_7);
+ __Pyx_XGOTREF(__pyx_t_8);
+ __Pyx_XGOTREF(__pyx_t_9);
+ __Pyx_XGOTREF(__pyx_t_10);
+ __Pyx_XGOTREF(__pyx_t_11);
+ __pyx_t_3 = __pyx_lineno; __pyx_t_4 = __pyx_clineno; __pyx_t_5 = __pyx_filename;
+ {
+ PyMem_Free(__pyx_v_tmp);
+ }
+ if (PY_MAJOR_VERSION >= 3) {
+ __Pyx_XGIVEREF(__pyx_t_9);
+ __Pyx_XGIVEREF(__pyx_t_10);
+ __Pyx_XGIVEREF(__pyx_t_11);
+ __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11);
+ }
+ __Pyx_XGIVEREF(__pyx_t_6);
+ __Pyx_XGIVEREF(__pyx_t_7);
+ __Pyx_XGIVEREF(__pyx_t_8);
+ __Pyx_ErrRestore(__pyx_t_6, __pyx_t_7, __pyx_t_8);
+ __pyx_t_6 = 0; __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0;
+ __pyx_lineno = __pyx_t_3; __pyx_clineno = __pyx_t_4; __pyx_filename = __pyx_t_5;
+ goto __pyx_L1_error;
+ }
+ __pyx_L7:;
+ }
+
+ /* "View.MemoryView":399
+ * src.ndim, dst.ndim, self.dtype_is_object)
+ *
+ * cdef setitem_slice_assign_scalar(self, memoryview dst, value): # <<<<<<<<<<<<<<
+ * cdef int array[128]
+ * cdef void *tmp = NULL
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_slice_assign_scalar", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+static PyObject *__pyx_memoryview_setitem_indexed(struct __pyx_memoryview_obj *__pyx_v_self, PyObject *__pyx_v_index, PyObject *__pyx_v_value) {
+ char *__pyx_v_itemp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ char *__pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("setitem_indexed", 0);
+
+ /* "View.MemoryView":432
+ *
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index) # <<<<<<<<<<<<<<
+ * self.assign_item_from_object(itemp, value)
+ *
+ */
+ __pyx_t_1 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->get_item_pointer(__pyx_v_self, __pyx_v_index); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 432; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_itemp = __pyx_t_1;
+
+ /* "View.MemoryView":433
+ * cdef setitem_indexed(self, index, value):
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __pyx_t_2 = ((struct __pyx_vtabstruct_memoryview *)__pyx_v_self->__pyx_vtab)->assign_item_from_object(__pyx_v_self, __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":431
+ * PyMem_Free(tmp)
+ *
+ * cdef setitem_indexed(self, index, value): # <<<<<<<<<<<<<<
+ * cdef char *itemp = self.get_item_pointer(index)
+ * self.assign_item_from_object(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.setitem_indexed", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_convert_item_to_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_v_struct = NULL;
+ PyObject *__pyx_v_bytesitem = 0;
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ PyObject *__pyx_t_9 = NULL;
+ size_t __pyx_t_10;
+ int __pyx_t_11;
+ int __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":438
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef bytes bytesitem
+ *
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":441
+ * cdef bytes bytesitem
+ *
+ * bytesitem = itemp[:self.view.itemsize] # <<<<<<<<<<<<<<
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ */
+ __pyx_t_1 = __Pyx_PyBytes_FromStringAndSize(__pyx_v_itemp + 0, __pyx_v_self->view.itemsize - 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_bytesitem = ((PyObject*)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":442
+ *
+ * bytesitem = itemp[:self.view.itemsize]
+ * try: # <<<<<<<<<<<<<<
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ */
+ {
+ __Pyx_ExceptionSave(&__pyx_t_2, &__pyx_t_3, &__pyx_t_4);
+ __Pyx_XGOTREF(__pyx_t_2);
+ __Pyx_XGOTREF(__pyx_t_3);
+ __Pyx_XGOTREF(__pyx_t_4);
+ /*try:*/ {
+
+ /* "View.MemoryView":443
+ * bytesitem = itemp[:self.view.itemsize]
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem) # <<<<<<<<<<<<<<
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object")
+ */
+ __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_unpack); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_t_6 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_7 = NULL;
+ __pyx_t_8 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_5))) {
+ __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
+ if (likely(__pyx_t_7)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
+ __Pyx_INCREF(__pyx_t_7);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_5, function);
+ __pyx_t_8 = 1;
+ }
+ }
+ __pyx_t_9 = PyTuple_New(2+__pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ if (__pyx_t_7) {
+ PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_7); __Pyx_GIVEREF(__pyx_t_7); __pyx_t_7 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_8, __pyx_t_6);
+ __Pyx_GIVEREF(__pyx_t_6);
+ __Pyx_INCREF(__pyx_v_bytesitem);
+ PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_8, __pyx_v_bytesitem);
+ __Pyx_GIVEREF(__pyx_v_bytesitem);
+ __pyx_t_6 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_9, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 443; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __pyx_v_result = __pyx_t_1;
+ __pyx_t_1 = 0;
+ }
+ /*else:*/ {
+
+ /* "View.MemoryView":447
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ * if len(self.view.format) == 1: # <<<<<<<<<<<<<<
+ * return result[0]
+ * return result
+ */
+ __pyx_t_10 = strlen(__pyx_v_self->view.format);
+ __pyx_t_11 = ((__pyx_t_10 == 1) != 0);
+ if (__pyx_t_11) {
+
+ /* "View.MemoryView":448
+ * else:
+ * if len(self.view.format) == 1:
+ * return result[0] # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;};
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L6_except_return;
+ }
+
+ /* "View.MemoryView":449
+ * if len(self.view.format) == 1:
+ * return result[0]
+ * return result # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_result);
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L6_except_return;
+ }
+ __pyx_L3_error:;
+ __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
+ __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+ __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":444
+ * try:
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error: # <<<<<<<<<<<<<<
+ * raise ValueError("Unable to convert item to object")
+ * else:
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_error); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_12 = PyErr_ExceptionMatches(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ if (__pyx_t_12) {
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_5, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 444; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_GOTREF(__pyx_t_9);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L5_except_error;}
+ }
+ goto __pyx_L5_except_error;
+ __pyx_L5_except_error:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L1_error;
+ __pyx_L6_except_return:;
+ __Pyx_XGIVEREF(__pyx_t_2);
+ __Pyx_XGIVEREF(__pyx_t_3);
+ __Pyx_XGIVEREF(__pyx_t_4);
+ __Pyx_ExceptionReset(__pyx_t_2, __pyx_t_3, __pyx_t_4);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":435
+ * self.assign_item_from_object(itemp, value)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesitem);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+static PyObject *__pyx_memoryview_assign_item_from_object(struct __pyx_memoryview_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_v_struct = NULL;
+ char __pyx_v_c;
+ PyObject *__pyx_v_bytesvalue = 0;
+ Py_ssize_t __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ Py_ssize_t __pyx_t_7;
+ PyObject *__pyx_t_8 = NULL;
+ PyObject *__pyx_t_9 = NULL;
+ char *__pyx_t_10;
+ char *__pyx_t_11;
+ char *__pyx_t_12;
+ char *__pyx_t_13;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":454
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ * import struct # <<<<<<<<<<<<<<
+ * cdef char c
+ * cdef bytes bytesvalue
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_v_struct = __pyx_t_1;
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":459
+ * cdef Py_ssize_t i
+ *
+ * if isinstance(value, tuple): # <<<<<<<<<<<<<<
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ */
+ __pyx_t_2 = PyTuple_Check(__pyx_v_value);
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":460
+ *
+ * if isinstance(value, tuple):
+ * bytesvalue = struct.pack(self.view.format, *value) # <<<<<<<<<<<<<<
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value)
+ */
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_4 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = PySequence_Tuple(__pyx_v_value); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = PyNumber_Add(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_6, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 460; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":462
+ * bytesvalue = struct.pack(self.view.format, *value)
+ * else:
+ * bytesvalue = struct.pack(self.view.format, value) # <<<<<<<<<<<<<<
+ *
+ * for i, c in enumerate(bytesvalue):
+ */
+ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_struct, __pyx_n_s_pack); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ __pyx_t_1 = __Pyx_PyBytes_FromString(__pyx_v_self->view.format); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_5 = NULL;
+ __pyx_t_7 = 0;
+ if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_6))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_6, function);
+ __pyx_t_7 = 1;
+ }
+ }
+ __pyx_t_8 = PyTuple_New(2+__pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_8);
+ if (__pyx_t_5) {
+ PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ }
+ PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_7, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_v_value);
+ PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_7, __pyx_v_value);
+ __Pyx_GIVEREF(__pyx_v_value);
+ __pyx_t_1 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ if (!(likely(PyBytes_CheckExact(__pyx_t_4))||((__pyx_t_4) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "bytes", Py_TYPE(__pyx_t_4)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_bytesvalue = ((PyObject*)__pyx_t_4);
+ __pyx_t_4 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = 0;
+ if (unlikely(__pyx_v_bytesvalue == Py_None)) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' is not iterable");
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_INCREF(__pyx_v_bytesvalue);
+ __pyx_t_9 = __pyx_v_bytesvalue;
+ __pyx_t_11 = PyBytes_AS_STRING(__pyx_t_9);
+ __pyx_t_12 = (__pyx_t_11 + PyBytes_GET_SIZE(__pyx_t_9));
+ for (__pyx_t_13 = __pyx_t_11; __pyx_t_13 < __pyx_t_12; __pyx_t_13++) {
+ __pyx_t_10 = __pyx_t_13;
+ __pyx_v_c = (__pyx_t_10[0]);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ __pyx_v_i = __pyx_t_7;
+
+ /* "View.MemoryView":464
+ * bytesvalue = struct.pack(self.view.format, value)
+ *
+ * for i, c in enumerate(bytesvalue): # <<<<<<<<<<<<<<
+ * itemp[i] = c
+ *
+ */
+ __pyx_t_7 = (__pyx_t_7 + 1);
+
+ /* "View.MemoryView":465
+ *
+ * for i, c in enumerate(bytesvalue):
+ * itemp[i] = c # <<<<<<<<<<<<<<
+ *
+ * @cname('getbuffer')
+ */
+ (__pyx_v_itemp[__pyx_v_i]) = __pyx_v_c;
+ }
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+
+ /* "View.MemoryView":451
+ * return result
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * """Only used if instantiated manually by the user, or if Cython doesn't
+ * know how to convert the type"""
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_XDECREF(__pyx_t_8);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_struct);
+ __Pyx_XDECREF(__pyx_v_bytesvalue);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_memoryview_getbuffer(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(((struct __pyx_memoryview_obj *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static int __pyx_memoryview_getbuffer_MemoryView_10memoryview_8__getbuffer__(struct __pyx_memoryview_obj *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ char *__pyx_t_3;
+ void *__pyx_t_4;
+ int __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ __Pyx_RefNannySetupContext("__getbuffer__", 0);
+ if (__pyx_v_info != NULL) {
+ __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+ __Pyx_GIVEREF(__pyx_v_info->obj);
+ }
+
+ /* "View.MemoryView":469
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.shape = self.view.shape
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":470
+ * def __getbuffer__(self, Py_buffer *info, int flags):
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape # <<<<<<<<<<<<<<
+ * else:
+ * info.shape = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.shape;
+ __pyx_v_info->shape = __pyx_t_2;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":472
+ * info.shape = self.view.shape
+ * else:
+ * info.shape = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_STRIDES:
+ */
+ __pyx_v_info->shape = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":474
+ * info.shape = NULL
+ *
+ * if flags & PyBUF_STRIDES: # <<<<<<<<<<<<<<
+ * info.strides = self.view.strides
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_STRIDES) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":475
+ *
+ * if flags & PyBUF_STRIDES:
+ * info.strides = self.view.strides # <<<<<<<<<<<<<<
+ * else:
+ * info.strides = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.strides;
+ __pyx_v_info->strides = __pyx_t_2;
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":477
+ * info.strides = self.view.strides
+ * else:
+ * info.strides = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_INDIRECT:
+ */
+ __pyx_v_info->strides = NULL;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":479
+ * info.strides = NULL
+ *
+ * if flags & PyBUF_INDIRECT: # <<<<<<<<<<<<<<
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_INDIRECT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":480
+ *
+ * if flags & PyBUF_INDIRECT:
+ * info.suboffsets = self.view.suboffsets # <<<<<<<<<<<<<<
+ * else:
+ * info.suboffsets = NULL
+ */
+ __pyx_t_2 = __pyx_v_self->view.suboffsets;
+ __pyx_v_info->suboffsets = __pyx_t_2;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":482
+ * info.suboffsets = self.view.suboffsets
+ * else:
+ * info.suboffsets = NULL # <<<<<<<<<<<<<<
+ *
+ * if flags & PyBUF_FORMAT:
+ */
+ __pyx_v_info->suboffsets = NULL;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":484
+ * info.suboffsets = NULL
+ *
+ * if flags & PyBUF_FORMAT: # <<<<<<<<<<<<<<
+ * info.format = self.view.format
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_flags & PyBUF_FORMAT) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":485
+ *
+ * if flags & PyBUF_FORMAT:
+ * info.format = self.view.format # <<<<<<<<<<<<<<
+ * else:
+ * info.format = NULL
+ */
+ __pyx_t_3 = __pyx_v_self->view.format;
+ __pyx_v_info->format = __pyx_t_3;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":487
+ * info.format = self.view.format
+ * else:
+ * info.format = NULL # <<<<<<<<<<<<<<
+ *
+ * info.buf = self.view.buf
+ */
+ __pyx_v_info->format = NULL;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":489
+ * info.format = NULL
+ *
+ * info.buf = self.view.buf # <<<<<<<<<<<<<<
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ */
+ __pyx_t_4 = __pyx_v_self->view.buf;
+ __pyx_v_info->buf = __pyx_t_4;
+
+ /* "View.MemoryView":490
+ *
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim # <<<<<<<<<<<<<<
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ */
+ __pyx_t_5 = __pyx_v_self->view.ndim;
+ __pyx_v_info->ndim = __pyx_t_5;
+
+ /* "View.MemoryView":491
+ * info.buf = self.view.buf
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize # <<<<<<<<<<<<<<
+ * info.len = self.view.len
+ * info.readonly = 0
+ */
+ __pyx_t_6 = __pyx_v_self->view.itemsize;
+ __pyx_v_info->itemsize = __pyx_t_6;
+
+ /* "View.MemoryView":492
+ * info.ndim = self.view.ndim
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len # <<<<<<<<<<<<<<
+ * info.readonly = 0
+ * info.obj = self
+ */
+ __pyx_t_6 = __pyx_v_self->view.len;
+ __pyx_v_info->len = __pyx_t_6;
+
+ /* "View.MemoryView":493
+ * info.itemsize = self.view.itemsize
+ * info.len = self.view.len
+ * info.readonly = 0 # <<<<<<<<<<<<<<
+ * info.obj = self
+ *
+ */
+ __pyx_v_info->readonly = 0;
+
+ /* "View.MemoryView":494
+ * info.len = self.view.len
+ * info.readonly = 0
+ * info.obj = self # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __Pyx_GOTREF(__pyx_v_info->obj);
+ __Pyx_DECREF(__pyx_v_info->obj);
+ __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+
+ /* "View.MemoryView":468
+ *
+ * @cname('getbuffer')
+ * def __getbuffer__(self, Py_buffer *info, int flags): # <<<<<<<<<<<<<<
+ * if flags & PyBUF_STRIDES:
+ * info.shape = self.view.shape
+ */
+
+ /* function exit code */
+ __pyx_r = 0;
+ if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+ __Pyx_GOTREF(Py_None);
+ __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+ }
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_transpose(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_transpose_MemoryView_10memoryview_1T___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":502
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self) # <<<<<<<<<<<<<<
+ * transpose_memslice(&result.from_slice)
+ * return result
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_object(__pyx_v_self); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (!(likely(((__pyx_t_1) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_1, __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 502; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":503
+ * def __get__(self):
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice) # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_t_2 = __pyx_memslice_transpose((&__pyx_v_result->from_slice)); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":504
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ * return result # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":501
+ * property T:
+ * @cname('__pyx_memoryview_transpose')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * cdef _memoryviewslice result = memoryview_copy(self)
+ * transpose_memslice(&result.from_slice)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.T.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview__get__base_MemoryView_10memoryview_4base___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":509
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self):
+ * return self.obj # <<<<<<<<<<<<<<
+ *
+ * property shape:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->obj);
+ __pyx_r = __pyx_v_self->obj;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":508
+ * property base:
+ * @cname('__pyx_memoryview__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.obj
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_shape(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_shape_MemoryView_10memoryview_5shape___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":514
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self):
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property strides:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __pyx_v_self->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+ __pyx_t_4 = PyInt_FromSsize_t((__pyx_v_self->view.shape[__pyx_v_i])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_1, (PyObject*)__pyx_t_4))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ }
+ __pyx_t_4 = PyList_AsTuple(((PyObject*)__pyx_t_1)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_r = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":513
+ * property shape:
+ * @cname('__pyx_memoryview_get_shape')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return tuple([self.view.shape[i] for i in xrange(self.view.ndim)])
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.shape.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_strides(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_strides_MemoryView_10memoryview_7strides___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":519
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self):
+ * if self.view.strides == NULL: # <<<<<<<<<<<<<<
+ *
+ * raise ValueError("Buffer view does not expose strides")
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.strides == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__20, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":523
+ * raise ValueError("Buffer view does not expose strides")
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property suboffsets:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.strides[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":518
+ * property strides:
+ * @cname('__pyx_memoryview_get_strides')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.strides == NULL:
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.strides.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_suboffsets(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_suboffsets_MemoryView_10memoryview_10suboffsets___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":528
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self):
+ * if self.view.suboffsets == NULL: # <<<<<<<<<<<<<<
+ * return [-1] * self.view.ndim
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.suboffsets == NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":529
+ * def __get__(self):
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)])
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(1 * ((__pyx_v_self->view.ndim<0) ? 0:__pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_self->view.ndim; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_int_neg_1);
+ PyList_SET_ITEM(__pyx_t_2, __pyx_temp, __pyx_int_neg_1);
+ __Pyx_GIVEREF(__pyx_int_neg_1);
+ }
+ }
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":531
+ * return [-1] * self.view.ndim
+ *
+ * return tuple([self.view.suboffsets[i] for i in xrange(self.view.ndim)]) # <<<<<<<<<<<<<<
+ *
+ * property ndim:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __pyx_v_self->view.ndim;
+ for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+ __pyx_v_i = __pyx_t_4;
+ __pyx_t_5 = PyInt_FromSsize_t((__pyx_v_self->view.suboffsets[__pyx_v_i])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ if (unlikely(__Pyx_ListComp_Append(__pyx_t_2, (PyObject*)__pyx_t_5))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __pyx_t_5 = PyList_AsTuple(((PyObject*)__pyx_t_2)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 531; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":527
+ * property suboffsets:
+ * @cname('__pyx_memoryview_get_suboffsets')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self.view.suboffsets == NULL:
+ * return [-1] * self.view.ndim
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.suboffsets.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_ndim(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_ndim_MemoryView_10memoryview_4ndim___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":536
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self):
+ * return self.view.ndim # <<<<<<<<<<<<<<
+ *
+ * property itemsize:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->view.ndim); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":535
+ * property ndim:
+ * @cname('__pyx_memoryview_get_ndim')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.ndim.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_itemsize(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_itemsize_MemoryView_10memoryview_8itemsize___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":541
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self):
+ * return self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property nbytes:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 541; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":540
+ * property itemsize:
+ * @cname('__pyx_memoryview_get_itemsize')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.itemsize.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_nbytes(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_nbytes_MemoryView_10memoryview_6nbytes___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":546
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self):
+ * return self.size * self.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * property size:
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_size); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_self->view.itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyNumber_Multiply(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 546; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":545
+ * property nbytes:
+ * @cname('__pyx_memoryview_get_nbytes')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.size * self.view.itemsize
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.nbytes.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview_get_size(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_get_size_MemoryView_10memoryview_4size___get__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_v_result = NULL;
+ PyObject *__pyx_v_length = NULL;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":551
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self):
+ * if self._size is None: # <<<<<<<<<<<<<<
+ * result = 1
+ *
+ */
+ __pyx_t_1 = (__pyx_v_self->_size == Py_None);
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":552
+ * def __get__(self):
+ * if self._size is None:
+ * result = 1 # <<<<<<<<<<<<<<
+ *
+ * for length in self.shape:
+ */
+ __Pyx_INCREF(__pyx_int_1);
+ __pyx_v_result = __pyx_int_1;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ __pyx_t_3 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (likely(PyList_CheckExact(__pyx_t_3)) || PyTuple_CheckExact(__pyx_t_3)) {
+ __pyx_t_4 = __pyx_t_3; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_3 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_3)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 554; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_3);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_length, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":555
+ *
+ * for length in self.shape:
+ * result *= length # <<<<<<<<<<<<<<
+ *
+ * self._size = result
+ */
+ __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_result, __pyx_v_length); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 555; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF_SET(__pyx_v_result, __pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":554
+ * result = 1
+ *
+ * for length in self.shape: # <<<<<<<<<<<<<<
+ * result *= length
+ *
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+ /* "View.MemoryView":557
+ * result *= length
+ *
+ * self._size = result # <<<<<<<<<<<<<<
+ *
+ * return self._size
+ */
+ __Pyx_INCREF(__pyx_v_result);
+ __Pyx_GIVEREF(__pyx_v_result);
+ __Pyx_GOTREF(__pyx_v_self->_size);
+ __Pyx_DECREF(__pyx_v_self->_size);
+ __pyx_v_self->_size = __pyx_v_result;
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":559
+ * self._size = result
+ *
+ * return self._size # <<<<<<<<<<<<<<
+ *
+ * def __len__(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->_size);
+ __pyx_r = __pyx_v_self->_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":550
+ * property size:
+ * @cname('__pyx_memoryview_get_size')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * if self._size is None:
+ * result = 1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.size.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_length);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+/* Python wrapper */
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self); /*proto*/
+static Py_ssize_t __pyx_memoryview___len__(PyObject *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__len__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_10__len__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static Py_ssize_t __pyx_memoryview_MemoryView_10memoryview_10__len__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ Py_ssize_t __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("__len__", 0);
+
+ /* "View.MemoryView":562
+ *
+ * def __len__(self):
+ * if self.view.ndim >= 1: # <<<<<<<<<<<<<<
+ * return self.view.shape[0]
+ *
+ */
+ __pyx_t_1 = ((__pyx_v_self->view.ndim >= 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":563
+ * def __len__(self):
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0] # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ __pyx_r = (__pyx_v_self->view.shape[0]);
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":565
+ * return self.view.shape[0]
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * def __repr__(self):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":561
+ * return self._size
+ *
+ * def __len__(self): # <<<<<<<<<<<<<<
+ * if self.view.ndim >= 1:
+ * return self.view.shape[0]
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___repr__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_12__repr__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_12__repr__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__repr__", 0);
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":569
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self)) # <<<<<<<<<<<<<<
+ *
+ * def __str__(self):
+ */
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_INCREF(((PyObject *)__pyx_v_self));
+ PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_v_self));
+ __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_id, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+ /* "View.MemoryView":568
+ *
+ * def __repr__(self):
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__, # <<<<<<<<<<<<<<
+ * id(self))
+ *
+ */
+ __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":567
+ * return 0
+ *
+ * def __repr__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r at 0x%x>" % (self.base.__class__.__name__,
+ * id(self))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryview___str__(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__str__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_14__str__(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_14__str__(struct __pyx_memoryview_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("__str__", 0);
+
+ /* "View.MemoryView":572
+ *
+ * def __str__(self):
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_class); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_name_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+ __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_MemoryView_of_r_object, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 572; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":571
+ * id(self))
+ *
+ * def __str__(self): # <<<<<<<<<<<<<<
+ * return "<MemoryView of %r object>" % (self.base.__class__.__name__,)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.__str__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_c_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_c_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_16is_c_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_16is_c_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_c_contig", 0);
+
+ /* "View.MemoryView":578
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":579
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'C', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def is_f_contig(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'C', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 579; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":575
+ *
+ *
+ * def is_c_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_c_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_is_f_contig(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("is_f_contig (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_18is_f_contig(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_18is_f_contig(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice *__pyx_v_mslice;
+ __Pyx_memviewslice __pyx_v_tmp;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("is_f_contig", 0);
+
+ /* "View.MemoryView":584
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp) # <<<<<<<<<<<<<<
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ */
+ __pyx_v_mslice = __pyx_memoryview_get_slice_from_memoryview(__pyx_v_self, (&__pyx_v_tmp));
+
+ /* "View.MemoryView":585
+ * cdef __Pyx_memviewslice tmp
+ * mslice = get_slice_from_memview(self, &tmp)
+ * return slice_is_contig(mslice, 'F', self.view.ndim) # <<<<<<<<<<<<<<
+ *
+ * def copy(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_memviewslice_is_contig(__pyx_v_mslice, 'F', __pyx_v_self->view.ndim)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 585; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":581
+ * return slice_is_contig(mslice, 'C', self.view.ndim)
+ *
+ * def is_f_contig(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice *mslice
+ * cdef __Pyx_memviewslice tmp
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.is_f_contig", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_20copy(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_20copy(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_mslice;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy", 0);
+
+ /* "View.MemoryView":589
+ * def copy(self):
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &mslice)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_F_CONTIGUOUS));
+
+ /* "View.MemoryView":591
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ *
+ * slice_copy(self, &mslice) # <<<<<<<<<<<<<<
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_mslice));
+
+ /* "View.MemoryView":592
+ *
+ * slice_copy(self, &mslice)
+ * mslice = slice_copy_contig(&mslice, "c", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_C_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_mslice), __pyx_k_c, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_C_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 592; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_mslice = __pyx_t_1;
+
+ /* "View.MemoryView":597
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &mslice) # <<<<<<<<<<<<<<
+ *
+ * def copy_fortran(self):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_mslice)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":587
+ * return slice_is_contig(mslice, 'F', self.view.ndim)
+ *
+ * def copy(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice mslice
+ * cdef int flags = self.flags & ~PyBUF_F_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_memoryview_copy_fortran(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("copy_fortran (wrapper)", 0);
+ __pyx_r = __pyx_memoryview_MemoryView_10memoryview_22copy_fortran(((struct __pyx_memoryview_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryview_MemoryView_10memoryview_22copy_fortran(struct __pyx_memoryview_obj *__pyx_v_self) {
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ int __pyx_v_flags;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_memviewslice __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("copy_fortran", 0);
+
+ /* "View.MemoryView":601
+ * def copy_fortran(self):
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS # <<<<<<<<<<<<<<
+ *
+ * slice_copy(self, &src)
+ */
+ __pyx_v_flags = (__pyx_v_self->flags & (~PyBUF_C_CONTIGUOUS));
+
+ /* "View.MemoryView":603
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ *
+ * slice_copy(self, &src) # <<<<<<<<<<<<<<
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim,
+ * self.view.itemsize,
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_self, (&__pyx_v_src));
+
+ /* "View.MemoryView":604
+ *
+ * slice_copy(self, &src)
+ * dst = slice_copy_contig(&src, "fortran", self.view.ndim, # <<<<<<<<<<<<<<
+ * self.view.itemsize,
+ * flags|PyBUF_F_CONTIGUOUS,
+ */
+ __pyx_t_1 = __pyx_memoryview_copy_new_contig((&__pyx_v_src), __pyx_k_fortran, __pyx_v_self->view.ndim, __pyx_v_self->view.itemsize, (__pyx_v_flags | PyBUF_F_CONTIGUOUS), __pyx_v_self->dtype_is_object); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 604; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_dst = __pyx_t_1;
+
+ /* "View.MemoryView":609
+ * self.dtype_is_object)
+ *
+ * return memoryview_copy_from_slice(self, &dst) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_copy_object_from_slice(__pyx_v_self, (&__pyx_v_dst)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 609; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":599
+ * return memoryview_copy_from_slice(self, &mslice)
+ *
+ * def copy_fortran(self): # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice src, dst
+ * cdef int flags = self.flags & ~PyBUF_C_CONTIGUOUS
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView.memoryview.copy_fortran", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+static PyObject *__pyx_memoryview_new(PyObject *__pyx_v_o, int __pyx_v_flags, int __pyx_v_dtype_is_object, __Pyx_TypeInfo *__pyx_v_typeinfo) {
+ struct __pyx_memoryview_obj *__pyx_v_result = 0;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_cwrapper", 0);
+
+ /* "View.MemoryView":614
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object) # <<<<<<<<<<<<<<
+ * result.typeinfo = typeinfo
+ * return result
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_o);
+ __Pyx_GIVEREF(__pyx_v_o);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryview_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryview_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":615
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo):
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo # <<<<<<<<<<<<<<
+ * return result
+ *
+ */
+ __pyx_v_result->typeinfo = __pyx_v_typeinfo;
+
+ /* "View.MemoryView":616
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_check')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":613
+ *
+ * @cname('__pyx_memoryview_new')
+ * cdef memoryview_cwrapper(object o, int flags, bint dtype_is_object, __Pyx_TypeInfo *typeinfo): # <<<<<<<<<<<<<<
+ * cdef memoryview result = memoryview(o, flags, dtype_is_object)
+ * result.typeinfo = typeinfo
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_cwrapper", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+static CYTHON_INLINE int __pyx_memoryview_check(PyObject *__pyx_v_o) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ __Pyx_RefNannySetupContext("memoryview_check", 0);
+
+ /* "View.MemoryView":620
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o):
+ * return isinstance(o, memoryview) # <<<<<<<<<<<<<<
+ *
+ * cdef tuple _unellipsify(object index, int ndim):
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_o, ((PyObject *)__pyx_memoryview_type));
+ __pyx_r = __pyx_t_1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":619
+ *
+ * @cname('__pyx_memoryview_check')
+ * cdef inline bint memoryview_check(object o): # <<<<<<<<<<<<<<
+ * return isinstance(o, memoryview)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+static PyObject *_unellipsify(PyObject *__pyx_v_index, int __pyx_v_ndim) {
+ PyObject *__pyx_v_tup = NULL;
+ PyObject *__pyx_v_result = NULL;
+ int __pyx_v_have_slices;
+ int __pyx_v_seen_ellipsis;
+ CYTHON_UNUSED PyObject *__pyx_v_idx = NULL;
+ PyObject *__pyx_v_item = NULL;
+ Py_ssize_t __pyx_v_nslices;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ Py_ssize_t __pyx_t_5;
+ PyObject *(*__pyx_t_6)(PyObject *);
+ PyObject *__pyx_t_7 = NULL;
+ Py_ssize_t __pyx_t_8;
+ int __pyx_t_9;
+ int __pyx_t_10;
+ PyObject *__pyx_t_11 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("_unellipsify", 0);
+
+ /* "View.MemoryView":627
+ * full slices.
+ * """
+ * if not isinstance(index, tuple): # <<<<<<<<<<<<<<
+ * tup = (index,)
+ * else:
+ */
+ __pyx_t_1 = PyTuple_Check(__pyx_v_index);
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":628
+ * """
+ * if not isinstance(index, tuple):
+ * tup = (index,) # <<<<<<<<<<<<<<
+ * else:
+ * tup = index
+ */
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_index);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_index);
+ __Pyx_GIVEREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_t_3;
+ __pyx_t_3 = 0;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":630
+ * tup = (index,)
+ * else:
+ * tup = index # <<<<<<<<<<<<<<
+ *
+ * result = []
+ */
+ __Pyx_INCREF(__pyx_v_index);
+ __pyx_v_tup = __pyx_v_index;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":632
+ * tup = index
+ *
+ * result = [] # <<<<<<<<<<<<<<
+ * have_slices = False
+ * seen_ellipsis = False
+ */
+ __pyx_t_3 = PyList_New(0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 632; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_v_result = ((PyObject*)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":633
+ *
+ * result = []
+ * have_slices = False # <<<<<<<<<<<<<<
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ */
+ __pyx_v_have_slices = 0;
+
+ /* "View.MemoryView":634
+ * result = []
+ * have_slices = False
+ * seen_ellipsis = False # <<<<<<<<<<<<<<
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ */
+ __pyx_v_seen_ellipsis = 0;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ __Pyx_INCREF(__pyx_int_0);
+ __pyx_t_3 = __pyx_int_0;
+ if (likely(PyList_CheckExact(__pyx_v_tup)) || PyTuple_CheckExact(__pyx_v_tup)) {
+ __pyx_t_4 = __pyx_v_tup; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0;
+ __pyx_t_6 = NULL;
+ } else {
+ __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_tup); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_6)) {
+ if (likely(PyList_CheckExact(__pyx_t_4))) {
+ if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_7); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_7 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_7 = __pyx_t_6(__pyx_t_4);
+ if (unlikely(!__pyx_t_7)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_7);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_item, __pyx_t_7);
+ __pyx_t_7 = 0;
+ __Pyx_INCREF(__pyx_t_3);
+ __Pyx_XDECREF_SET(__pyx_v_idx, __pyx_t_3);
+ __pyx_t_7 = PyNumber_Add(__pyx_t_3, __pyx_int_1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_3);
+ __pyx_t_3 = __pyx_t_7;
+ __pyx_t_7 = 0;
+
+ /* "View.MemoryView":636
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis: # <<<<<<<<<<<<<<
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ */
+ __pyx_t_2 = (__pyx_v_item == __pyx_builtin_Ellipsis);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":637
+ * for idx, item in enumerate(tup):
+ * if item is Ellipsis:
+ * if not seen_ellipsis: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True
+ */
+ __pyx_t_1 = ((!(__pyx_v_seen_ellipsis != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_t_8 = PyObject_Length(__pyx_v_tup); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_7 = PyList_New(1 * ((((__pyx_v_ndim - __pyx_t_8) + 1)<0) ? 0:((__pyx_v_ndim - __pyx_t_8) + 1))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < ((__pyx_v_ndim - __pyx_t_8) + 1); __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__21);
+ PyList_SET_ITEM(__pyx_t_7, __pyx_temp, __pyx_slice__21);
+ __Pyx_GIVEREF(__pyx_slice__21);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_7); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+ /* "View.MemoryView":639
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1))
+ * seen_ellipsis = True # <<<<<<<<<<<<<<
+ * else:
+ * result.append(slice(None))
+ */
+ __pyx_v_seen_ellipsis = 1;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_slice__22); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+
+ /* "View.MemoryView":642
+ * else:
+ * result.append(slice(None))
+ * have_slices = True # <<<<<<<<<<<<<<
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ */
+ __pyx_v_have_slices = 1;
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":644
+ * have_slices = True
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item): # <<<<<<<<<<<<<<
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ */
+ __pyx_t_2 = PySlice_Check(__pyx_v_item);
+ __pyx_t_10 = ((!(__pyx_t_2 != 0)) != 0);
+ if (__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = ((!(PyIndex_Check(__pyx_v_item) != 0)) != 0);
+ __pyx_t_1 = __pyx_t_10;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":645
+ * else:
+ * if not isinstance(item, slice) and not PyIndex_Check(item):
+ * raise TypeError("Cannot index with type '%s'" % type(item)) # <<<<<<<<<<<<<<
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ */
+ __pyx_t_7 = __Pyx_PyString_Format(__pyx_kp_s_Cannot_index_with_type_s, ((PyObject *)Py_TYPE(__pyx_v_item))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_11);
+ PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_7);
+ __Pyx_GIVEREF(__pyx_t_7);
+ __pyx_t_7 = 0;
+ __pyx_t_7 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+ __Pyx_Raise(__pyx_t_7, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":647
+ * raise TypeError("Cannot index with type '%s'" % type(item))
+ *
+ * have_slices = have_slices or isinstance(item, slice) # <<<<<<<<<<<<<<
+ * result.append(item)
+ *
+ */
+ __pyx_t_10 = (__pyx_v_have_slices != 0);
+ if (!__pyx_t_10) {
+ } else {
+ __pyx_t_1 = __pyx_t_10;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = PySlice_Check(__pyx_v_item);
+ __pyx_t_2 = (__pyx_t_10 != 0);
+ __pyx_t_1 = __pyx_t_2;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_have_slices = __pyx_t_1;
+
+ /* "View.MemoryView":648
+ *
+ * have_slices = have_slices or isinstance(item, slice)
+ * result.append(item) # <<<<<<<<<<<<<<
+ *
+ * nslices = ndim - len(result)
+ */
+ __pyx_t_9 = __Pyx_PyList_Append(__pyx_v_result, __pyx_v_item); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 648; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":635
+ * have_slices = False
+ * seen_ellipsis = False
+ * for idx, item in enumerate(tup): # <<<<<<<<<<<<<<
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ */
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":650
+ * result.append(item)
+ *
+ * nslices = ndim - len(result) # <<<<<<<<<<<<<<
+ * if nslices:
+ * result.extend([slice(None)] * nslices)
+ */
+ __pyx_t_5 = PyList_GET_SIZE(__pyx_v_result); if (unlikely(__pyx_t_5 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 650; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_nslices = (__pyx_v_ndim - __pyx_t_5);
+
+ /* "View.MemoryView":651
+ *
+ * nslices = ndim - len(result)
+ * if nslices: # <<<<<<<<<<<<<<
+ * result.extend([slice(None)] * nslices)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_nslices != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_t_3 = PyList_New(1 * ((__pyx_v_nslices<0) ? 0:__pyx_v_nslices)); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ { Py_ssize_t __pyx_temp;
+ for (__pyx_temp=0; __pyx_temp < __pyx_v_nslices; __pyx_temp++) {
+ __Pyx_INCREF(__pyx_slice__23);
+ PyList_SET_ITEM(__pyx_t_3, __pyx_temp, __pyx_slice__23);
+ __Pyx_GIVEREF(__pyx_slice__23);
+ }
+ }
+ __pyx_t_9 = __Pyx_PyList_Extend(__pyx_v_result, __pyx_t_3); if (unlikely(__pyx_t_9 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+
+ /* "View.MemoryView":654
+ * result.extend([slice(None)] * nslices)
+ *
+ * return have_slices or nslices, tuple(result) # <<<<<<<<<<<<<<
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ if (!__pyx_v_have_slices) {
+ } else {
+ __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_have_slices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ goto __pyx_L14_bool_binop_done;
+ }
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_nslices); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __pyx_t_4;
+ __pyx_t_4 = 0;
+ __pyx_L14_bool_binop_done:;
+ __pyx_t_4 = PyList_AsTuple(__pyx_v_result); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_7);
+ PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_3 = 0;
+ __pyx_t_4 = 0;
+ __pyx_r = ((PyObject*)__pyx_t_7);
+ __pyx_t_7 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":622
+ * return isinstance(o, memoryview)
+ *
+ * cdef tuple _unellipsify(object index, int ndim): # <<<<<<<<<<<<<<
+ * """
+ * Replace all ellipses with full slices and fill incomplete indices with
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_7);
+ __Pyx_XDECREF(__pyx_t_11);
+ __Pyx_AddTraceback("View.MemoryView._unellipsify", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF(__pyx_v_tup);
+ __Pyx_XDECREF(__pyx_v_result);
+ __Pyx_XDECREF(__pyx_v_idx);
+ __Pyx_XDECREF(__pyx_v_item);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+static PyObject *assert_direct_dimensions(Py_ssize_t *__pyx_v_suboffsets, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assert_direct_dimensions", 0);
+
+ /* "View.MemoryView":658
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim):
+ * cdef int i
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported")
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":659
+ * cdef int i
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * raise ValueError("Indirect dimensions not supported")
+ *
+ */
+ __pyx_t_3 = (((__pyx_v_suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+
+ /* "View.MemoryView":656
+ * return have_slices or nslices, tuple(result)
+ *
+ * cdef assert_direct_dimensions(Py_ssize_t *suboffsets, int ndim): # <<<<<<<<<<<<<<
+ * cdef int i
+ * for i in range(ndim):
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.assert_direct_dimensions", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+static struct __pyx_memoryview_obj *__pyx_memview_slice(struct __pyx_memoryview_obj *__pyx_v_memview, PyObject *__pyx_v_indices) {
+ int __pyx_v_new_ndim;
+ int __pyx_v_suboffset_dim;
+ int __pyx_v_dim;
+ __Pyx_memviewslice __pyx_v_src;
+ __Pyx_memviewslice __pyx_v_dst;
+ __Pyx_memviewslice *__pyx_v_p_src;
+ struct __pyx_memoryviewslice_obj *__pyx_v_memviewsliceobj = 0;
+ __Pyx_memviewslice *__pyx_v_p_dst;
+ int *__pyx_v_p_suboffset_dim;
+ Py_ssize_t __pyx_v_start;
+ Py_ssize_t __pyx_v_stop;
+ Py_ssize_t __pyx_v_step;
+ int __pyx_v_have_start;
+ int __pyx_v_have_stop;
+ int __pyx_v_have_step;
+ PyObject *__pyx_v_index = NULL;
+ struct __pyx_memoryview_obj *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ char *__pyx_t_5;
+ int __pyx_t_6;
+ Py_ssize_t __pyx_t_7;
+ PyObject *(*__pyx_t_8)(PyObject *);
+ PyObject *__pyx_t_9 = NULL;
+ Py_ssize_t __pyx_t_10;
+ int __pyx_t_11;
+ Py_ssize_t __pyx_t_12;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memview_slice", 0);
+
+ /* "View.MemoryView":668
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices):
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim # <<<<<<<<<<<<<<
+ * cdef bint negative_step
+ * cdef __Pyx_memviewslice src, dst
+ */
+ __pyx_v_new_ndim = 0;
+ __pyx_v_suboffset_dim = -1;
+
+ /* "View.MemoryView":675
+ *
+ *
+ * memset(&dst, 0, sizeof(dst)) # <<<<<<<<<<<<<<
+ *
+ * cdef _memoryviewslice memviewsliceobj
+ */
+ memset((&__pyx_v_dst), 0, (sizeof(__pyx_v_dst)));
+
+ /* "View.MemoryView":679
+ * cdef _memoryviewslice memviewsliceobj
+ *
+ * assert memview.view.ndim > 0 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ #ifndef CYTHON_WITHOUT_ASSERTIONS
+ if (unlikely(!Py_OptimizeFlag)) {
+ if (unlikely(!((__pyx_v_memview->view.ndim > 0) != 0))) {
+ PyErr_SetNone(PyExc_AssertionError);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 679; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+
+ /* "View.MemoryView":681
+ * assert memview.view.ndim > 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":682
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview # <<<<<<<<<<<<<<
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_memviewsliceobj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":683
+ * if isinstance(memview, _memoryviewslice):
+ * memviewsliceobj = memview
+ * p_src = &memviewsliceobj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, &src)
+ */
+ __pyx_v_p_src = (&__pyx_v_memviewsliceobj->from_slice);
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":685
+ * p_src = &memviewsliceobj.from_slice
+ * else:
+ * slice_copy(memview, &src) # <<<<<<<<<<<<<<
+ * p_src = &src
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_src));
+
+ /* "View.MemoryView":686
+ * else:
+ * slice_copy(memview, &src)
+ * p_src = &src # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_p_src = (&__pyx_v_src);
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":692
+ *
+ *
+ * dst.memview = p_src.memview # <<<<<<<<<<<<<<
+ * dst.data = p_src.data
+ *
+ */
+ __pyx_t_4 = __pyx_v_p_src->memview;
+ __pyx_v_dst.memview = __pyx_t_4;
+
+ /* "View.MemoryView":693
+ *
+ * dst.memview = p_src.memview
+ * dst.data = p_src.data # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_v_p_src->data;
+ __pyx_v_dst.data = __pyx_t_5;
+
+ /* "View.MemoryView":698
+ *
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst # <<<<<<<<<<<<<<
+ * cdef int *p_suboffset_dim = &suboffset_dim
+ * cdef Py_ssize_t start, stop, step
+ */
+ __pyx_v_p_dst = (&__pyx_v_dst);
+
+ /* "View.MemoryView":699
+ *
+ * cdef __Pyx_memviewslice *p_dst = &dst
+ * cdef int *p_suboffset_dim = &suboffset_dim # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t start, stop, step
+ * cdef bint have_start, have_stop, have_step
+ */
+ __pyx_v_p_suboffset_dim = (&__pyx_v_suboffset_dim);
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ __pyx_t_6 = 0;
+ if (likely(PyList_CheckExact(__pyx_v_indices)) || PyTuple_CheckExact(__pyx_v_indices)) {
+ __pyx_t_3 = __pyx_v_indices; __Pyx_INCREF(__pyx_t_3); __pyx_t_7 = 0;
+ __pyx_t_8 = NULL;
+ } else {
+ __pyx_t_7 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_v_indices); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_8 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ for (;;) {
+ if (likely(!__pyx_t_8)) {
+ if (likely(PyList_CheckExact(__pyx_t_3))) {
+ if (__pyx_t_7 >= PyList_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ } else {
+ if (__pyx_t_7 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
+ #if CYTHON_COMPILING_IN_CPYTHON
+ __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_7); __Pyx_INCREF(__pyx_t_9); __pyx_t_7++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_t_9 = PySequence_ITEM(__pyx_t_3, __pyx_t_7); __pyx_t_7++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ }
+ } else {
+ __pyx_t_9 = __pyx_t_8(__pyx_t_3);
+ if (unlikely(!__pyx_t_9)) {
+ PyObject* exc_type = PyErr_Occurred();
+ if (exc_type) {
+ if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+ else {__pyx_filename = __pyx_f[2]; __pyx_lineno = 703; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ break;
+ }
+ __Pyx_GOTREF(__pyx_t_9);
+ }
+ __Pyx_XDECREF_SET(__pyx_v_index, __pyx_t_9);
+ __pyx_t_9 = 0;
+ __pyx_v_dim = __pyx_t_6;
+ __pyx_t_6 = (__pyx_t_6 + 1);
+
+ /* "View.MemoryView":704
+ *
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index): # <<<<<<<<<<<<<<
+ * slice_memviewslice(
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ */
+ __pyx_t_2 = (PyIndex_Check(__pyx_v_index) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":708
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ * index, 0, 0, # start, stop, step # <<<<<<<<<<<<<<
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ */
+ __pyx_t_10 = __Pyx_PyIndex_AsSsize_t(__pyx_v_index); if (unlikely((__pyx_t_10 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":705
+ * for dim, index in enumerate(indices):
+ * if PyIndex_Check(index):
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_t_10, 0, 0, 0, 0, 0, 0); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 705; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L6;
+ }
+
+ /* "View.MemoryView":711
+ * 0, 0, 0, # have_{start,stop,step}
+ * False)
+ * elif index is None: # <<<<<<<<<<<<<<
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ */
+ __pyx_t_2 = (__pyx_v_index == Py_None);
+ __pyx_t_1 = (__pyx_t_2 != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":712
+ * False)
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1 # <<<<<<<<<<<<<<
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ */
+ (__pyx_v_p_dst->shape[__pyx_v_new_ndim]) = 1;
+
+ /* "View.MemoryView":713
+ * elif index is None:
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0 # <<<<<<<<<<<<<<
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1
+ */
+ (__pyx_v_p_dst->strides[__pyx_v_new_ndim]) = 0;
+
+ /* "View.MemoryView":714
+ * p_dst.shape[new_ndim] = 1
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1 # <<<<<<<<<<<<<<
+ * new_ndim += 1
+ * else:
+ */
+ (__pyx_v_p_dst->suboffsets[__pyx_v_new_ndim]) = -1;
+
+ /* "View.MemoryView":715
+ * p_dst.strides[new_ndim] = 0
+ * p_dst.suboffsets[new_ndim] = -1
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = index.start or 0
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":717
+ * new_ndim += 1
+ * else:
+ * start = index.start or 0 # <<<<<<<<<<<<<<
+ * stop = index.stop or 0
+ * step = index.step or 0
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L7_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L7_bool_binop_done:;
+ __pyx_v_start = __pyx_t_10;
+
+ /* "View.MemoryView":718
+ * else:
+ * start = index.start or 0
+ * stop = index.stop or 0 # <<<<<<<<<<<<<<
+ * step = index.step or 0
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L9_bool_binop_done:;
+ __pyx_v_stop = __pyx_t_10;
+
+ /* "View.MemoryView":719
+ * start = index.start or 0
+ * stop = index.stop or 0
+ * step = index.step or 0 # <<<<<<<<<<<<<<
+ *
+ * have_start = index.start is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!__pyx_t_1) {
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ } else {
+ __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_10 = __pyx_t_12;
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ goto __pyx_L11_bool_binop_done;
+ }
+ __pyx_t_10 = 0;
+ __pyx_L11_bool_binop_done:;
+ __pyx_v_step = __pyx_t_10;
+
+ /* "View.MemoryView":721
+ * step = index.step or 0
+ *
+ * have_start = index.start is not None # <<<<<<<<<<<<<<
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_start); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_start = __pyx_t_1;
+
+ /* "View.MemoryView":722
+ *
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None # <<<<<<<<<<<<<<
+ * have_step = index.step is not None
+ *
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_stop); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 722; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_stop = __pyx_t_1;
+
+ /* "View.MemoryView":723
+ * have_start = index.start is not None
+ * have_stop = index.stop is not None
+ * have_step = index.step is not None # <<<<<<<<<<<<<<
+ *
+ * slice_memviewslice(
+ */
+ __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_index, __pyx_n_s_step); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_9);
+ __pyx_t_1 = (__pyx_t_9 != Py_None);
+ __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+ __pyx_v_have_step = __pyx_t_1;
+
+ /* "View.MemoryView":725
+ * have_step = index.step is not None
+ *
+ * slice_memviewslice( # <<<<<<<<<<<<<<
+ * p_dst, p_src.shape[dim], p_src.strides[dim], p_src.suboffsets[dim],
+ * dim, new_ndim, p_suboffset_dim,
+ */
+ __pyx_t_11 = __pyx_memoryview_slice_memviewslice(__pyx_v_p_dst, (__pyx_v_p_src->shape[__pyx_v_dim]), (__pyx_v_p_src->strides[__pyx_v_dim]), (__pyx_v_p_src->suboffsets[__pyx_v_dim]), __pyx_v_dim, __pyx_v_new_ndim, __pyx_v_p_suboffset_dim, __pyx_v_start, __pyx_v_stop, __pyx_v_step, __pyx_v_have_start, __pyx_v_have_stop, __pyx_v_have_step, 1); if (unlikely(__pyx_t_11 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":731
+ * have_start, have_stop, have_step,
+ * True)
+ * new_ndim += 1 # <<<<<<<<<<<<<<
+ *
+ * if isinstance(memview, _memoryviewslice):
+ */
+ __pyx_v_new_ndim = (__pyx_v_new_ndim + 1);
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":703
+ * cdef bint have_start, have_stop, have_step
+ *
+ * for dim, index in enumerate(indices): # <<<<<<<<<<<<<<
+ * if PyIndex_Check(index):
+ * slice_memviewslice(
+ */
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+ /* "View.MemoryView":733
+ * new_ndim += 1
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":735
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 735; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":736
+ * return memoryview_fromslice(dst, new_ndim,
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ * else:
+ */
+ if (unlikely(!__pyx_v_memviewsliceobj)) { __Pyx_RaiseUnboundLocalError("memviewsliceobj"); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;} }
+
+ /* "View.MemoryView":734
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * return memoryview_fromslice(dst, new_ndim, # <<<<<<<<<<<<<<
+ * memviewsliceobj.to_object_func,
+ * memviewsliceobj.to_dtype_func,
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, __pyx_v_memviewsliceobj->to_object_func, __pyx_v_memviewsliceobj->to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ __Pyx_XDECREF(((PyObject *)__pyx_r));
+
+ /* "View.MemoryView":740
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_fromslice(__pyx_v_dst, __pyx_v_new_ndim, NULL, NULL, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+
+ /* "View.MemoryView":739
+ * memview.dtype_is_object)
+ * else:
+ * return memoryview_fromslice(dst, new_ndim, NULL, NULL, # <<<<<<<<<<<<<<
+ * memview.dtype_is_object)
+ *
+ */
+ if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_memoryview_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 739; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_r = ((struct __pyx_memoryview_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":667
+ *
+ * @cname('__pyx_memview_slice')
+ * cdef memoryview memview_slice(memoryview memview, object indices): # <<<<<<<<<<<<<<
+ * cdef int new_ndim = 0, suboffset_dim = -1, dim
+ * cdef bint negative_step
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_9);
+ __Pyx_AddTraceback("View.MemoryView.memview_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_memviewsliceobj);
+ __Pyx_XDECREF(__pyx_v_index);
+ __Pyx_XGIVEREF((PyObject *)__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+static int __pyx_memoryview_slice_memviewslice(__Pyx_memviewslice *__pyx_v_dst, Py_ssize_t __pyx_v_shape, Py_ssize_t __pyx_v_stride, Py_ssize_t __pyx_v_suboffset, int __pyx_v_dim, int __pyx_v_new_ndim, int *__pyx_v_suboffset_dim, Py_ssize_t __pyx_v_start, Py_ssize_t __pyx_v_stop, Py_ssize_t __pyx_v_step, int __pyx_v_have_start, int __pyx_v_have_stop, int __pyx_v_have_step, int __pyx_v_is_slice) {
+ Py_ssize_t __pyx_v_new_shape;
+ int __pyx_v_negative_step;
+ int __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":784
+ * cdef bint negative_step
+ *
+ * if not is_slice: # <<<<<<<<<<<<<<
+ *
+ * if start < 0:
+ */
+ __pyx_t_1 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":786
+ * if not is_slice:
+ *
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if not 0 <= start < shape:
+ */
+ __pyx_t_1 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":787
+ *
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+
+ /* "View.MemoryView":788
+ * if start < 0:
+ * start += shape
+ * if not 0 <= start < shape: # <<<<<<<<<<<<<<
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim)
+ * else:
+ */
+ __pyx_t_1 = (0 <= __pyx_v_start);
+ if (__pyx_t_1) {
+ __pyx_t_1 = (__pyx_v_start < __pyx_v_shape);
+ }
+ __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":789
+ * start += shape
+ * if not 0 <= start < shape:
+ * _err_dim(IndexError, "Index out of bounds (axis %d)", dim) # <<<<<<<<<<<<<<
+ * else:
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_Index_out_of_bounds_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":792
+ * else:
+ *
+ * negative_step = have_step != 0 and step < 0 # <<<<<<<<<<<<<<
+ *
+ * if have_step and step == 0:
+ */
+ __pyx_t_1 = ((__pyx_v_have_step != 0) != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step < 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L6_bool_binop_done:;
+ __pyx_v_negative_step = __pyx_t_2;
+
+ /* "View.MemoryView":794
+ * negative_step = have_step != 0 and step < 0
+ *
+ * if have_step and step == 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim)
+ *
+ */
+ __pyx_t_1 = (__pyx_v_have_step != 0);
+ if (__pyx_t_1) {
+ } else {
+ __pyx_t_2 = __pyx_t_1;
+ goto __pyx_L9_bool_binop_done;
+ }
+ __pyx_t_1 = ((__pyx_v_step == 0) != 0);
+ __pyx_t_2 = __pyx_t_1;
+ __pyx_L9_bool_binop_done:;
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":795
+ *
+ * if have_step and step == 0:
+ * _err_dim(ValueError, "Step may not be zero (axis %d)", dim) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Step_may_not_be_zero_axis_d, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":798
+ *
+ *
+ * if have_start: # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_start != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":799
+ *
+ * if have_start:
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start += shape
+ * if start < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":800
+ * if have_start:
+ * if start < 0:
+ * start += shape # <<<<<<<<<<<<<<
+ * if start < 0:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_start + __pyx_v_shape);
+
+ /* "View.MemoryView":801
+ * if start < 0:
+ * start += shape
+ * if start < 0: # <<<<<<<<<<<<<<
+ * start = 0
+ * elif start >= shape:
+ */
+ __pyx_t_2 = ((__pyx_v_start < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":802
+ * start += shape
+ * if start < 0:
+ * start = 0 # <<<<<<<<<<<<<<
+ * elif start >= shape:
+ * if negative_step:
+ */
+ __pyx_v_start = 0;
+ goto __pyx_L13;
+ }
+ __pyx_L13:;
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":803
+ * if start < 0:
+ * start = 0
+ * elif start >= shape: # <<<<<<<<<<<<<<
+ * if negative_step:
+ * start = shape - 1
+ */
+ __pyx_t_2 = ((__pyx_v_start >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":804
+ * start = 0
+ * elif start >= shape:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":805
+ * elif start >= shape:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = shape
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L14;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":807
+ * start = shape - 1
+ * else:
+ * start = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_start = __pyx_v_shape;
+ }
+ __pyx_L14:;
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+ goto __pyx_L11;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":809
+ * start = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * start = shape - 1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":810
+ * else:
+ * if negative_step:
+ * start = shape - 1 # <<<<<<<<<<<<<<
+ * else:
+ * start = 0
+ */
+ __pyx_v_start = (__pyx_v_shape - 1);
+ goto __pyx_L15;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":812
+ * start = shape - 1
+ * else:
+ * start = 0 # <<<<<<<<<<<<<<
+ *
+ * if have_stop:
+ */
+ __pyx_v_start = 0;
+ }
+ __pyx_L15:;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":814
+ * start = 0
+ *
+ * if have_stop: # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop += shape
+ */
+ __pyx_t_2 = (__pyx_v_have_stop != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":815
+ *
+ * if have_stop:
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop += shape
+ * if stop < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":816
+ * if have_stop:
+ * if stop < 0:
+ * stop += shape # <<<<<<<<<<<<<<
+ * if stop < 0:
+ * stop = 0
+ */
+ __pyx_v_stop = (__pyx_v_stop + __pyx_v_shape);
+
+ /* "View.MemoryView":817
+ * if stop < 0:
+ * stop += shape
+ * if stop < 0: # <<<<<<<<<<<<<<
+ * stop = 0
+ * elif stop > shape:
+ */
+ __pyx_t_2 = ((__pyx_v_stop < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":818
+ * stop += shape
+ * if stop < 0:
+ * stop = 0 # <<<<<<<<<<<<<<
+ * elif stop > shape:
+ * stop = shape
+ */
+ __pyx_v_stop = 0;
+ goto __pyx_L18;
+ }
+ __pyx_L18:;
+ goto __pyx_L17;
+ }
+
+ /* "View.MemoryView":819
+ * if stop < 0:
+ * stop = 0
+ * elif stop > shape: # <<<<<<<<<<<<<<
+ * stop = shape
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_stop > __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":820
+ * stop = 0
+ * elif stop > shape:
+ * stop = shape # <<<<<<<<<<<<<<
+ * else:
+ * if negative_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ goto __pyx_L17;
+ }
+ __pyx_L17:;
+ goto __pyx_L16;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":822
+ * stop = shape
+ * else:
+ * if negative_step: # <<<<<<<<<<<<<<
+ * stop = -1
+ * else:
+ */
+ __pyx_t_2 = (__pyx_v_negative_step != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":823
+ * else:
+ * if negative_step:
+ * stop = -1 # <<<<<<<<<<<<<<
+ * else:
+ * stop = shape
+ */
+ __pyx_v_stop = -1;
+ goto __pyx_L19;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":825
+ * stop = -1
+ * else:
+ * stop = shape # <<<<<<<<<<<<<<
+ *
+ * if not have_step:
+ */
+ __pyx_v_stop = __pyx_v_shape;
+ }
+ __pyx_L19:;
+ }
+ __pyx_L16:;
+
+ /* "View.MemoryView":827
+ * stop = shape
+ *
+ * if not have_step: # <<<<<<<<<<<<<<
+ * step = 1
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_have_step != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":828
+ *
+ * if not have_step:
+ * step = 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_step = 1;
+ goto __pyx_L20;
+ }
+ __pyx_L20:;
+
+ /* "View.MemoryView":832
+ *
+ * with cython.cdivision(True):
+ * new_shape = (stop - start) // step # <<<<<<<<<<<<<<
+ *
+ * if (stop - start) - step * new_shape:
+ */
+ __pyx_v_new_shape = ((__pyx_v_stop - __pyx_v_start) / __pyx_v_step);
+
+ /* "View.MemoryView":834
+ * new_shape = (stop - start) // step
+ *
+ * if (stop - start) - step * new_shape: # <<<<<<<<<<<<<<
+ * new_shape += 1
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_stop - __pyx_v_start) - (__pyx_v_step * __pyx_v_new_shape)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":835
+ *
+ * if (stop - start) - step * new_shape:
+ * new_shape += 1 # <<<<<<<<<<<<<<
+ *
+ * if new_shape < 0:
+ */
+ __pyx_v_new_shape = (__pyx_v_new_shape + 1);
+ goto __pyx_L21;
+ }
+ __pyx_L21:;
+
+ /* "View.MemoryView":837
+ * new_shape += 1
+ *
+ * if new_shape < 0: # <<<<<<<<<<<<<<
+ * new_shape = 0
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_new_shape < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":838
+ *
+ * if new_shape < 0:
+ * new_shape = 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_new_shape = 0;
+ goto __pyx_L22;
+ }
+ __pyx_L22:;
+
+ /* "View.MemoryView":841
+ *
+ *
+ * dst.strides[new_ndim] = stride * step # <<<<<<<<<<<<<<
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset
+ */
+ (__pyx_v_dst->strides[__pyx_v_new_ndim]) = (__pyx_v_stride * __pyx_v_step);
+
+ /* "View.MemoryView":842
+ *
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape # <<<<<<<<<<<<<<
+ * dst.suboffsets[new_ndim] = suboffset
+ *
+ */
+ (__pyx_v_dst->shape[__pyx_v_new_ndim]) = __pyx_v_new_shape;
+
+ /* "View.MemoryView":843
+ * dst.strides[new_ndim] = stride * step
+ * dst.shape[new_ndim] = new_shape
+ * dst.suboffsets[new_ndim] = suboffset # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_new_ndim]) = __pyx_v_suboffset;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":846
+ *
+ *
+ * if suboffset_dim[0] < 0: # <<<<<<<<<<<<<<
+ * dst.data += start * stride
+ * else:
+ */
+ __pyx_t_2 = (((__pyx_v_suboffset_dim[0]) < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":847
+ *
+ * if suboffset_dim[0] < 0:
+ * dst.data += start * stride # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ */
+ __pyx_v_dst->data = (__pyx_v_dst->data + (__pyx_v_start * __pyx_v_stride));
+ goto __pyx_L23;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":849
+ * dst.data += start * stride
+ * else:
+ * dst.suboffsets[suboffset_dim[0]] += start * stride # <<<<<<<<<<<<<<
+ *
+ * if suboffset >= 0:
+ */
+ __pyx_t_3 = (__pyx_v_suboffset_dim[0]);
+ (__pyx_v_dst->suboffsets[__pyx_t_3]) = ((__pyx_v_dst->suboffsets[__pyx_t_3]) + (__pyx_v_start * __pyx_v_stride));
+ }
+ __pyx_L23:;
+
+ /* "View.MemoryView":851
+ * dst.suboffsets[suboffset_dim[0]] += start * stride
+ *
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * if not is_slice:
+ * if new_ndim == 0:
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":852
+ *
+ * if suboffset >= 0:
+ * if not is_slice: # <<<<<<<<<<<<<<
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ */
+ __pyx_t_2 = ((!(__pyx_v_is_slice != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":853
+ * if suboffset >= 0:
+ * if not is_slice:
+ * if new_ndim == 0: # <<<<<<<<<<<<<<
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ */
+ __pyx_t_2 = ((__pyx_v_new_ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":854
+ * if not is_slice:
+ * if new_ndim == 0:
+ * dst.data = (<char **> dst.data)[0] + suboffset # <<<<<<<<<<<<<<
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d "
+ */
+ __pyx_v_dst->data = ((((char **)__pyx_v_dst->data)[0]) + __pyx_v_suboffset);
+ goto __pyx_L26;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":856
+ * dst.data = (<char **> dst.data)[0] + suboffset
+ * else:
+ * _err_dim(IndexError, "All dimensions preceding dimension %d " # <<<<<<<<<<<<<<
+ * "must be indexed and not sliced", dim)
+ * else:
+ */
+ __pyx_t_3 = __pyx_memoryview_err_dim(__pyx_builtin_IndexError, __pyx_k_All_dimensions_preceding_dimensi, __pyx_v_dim); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 856; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L26:;
+ goto __pyx_L25;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":859
+ * "must be indexed and not sliced", dim)
+ * else:
+ * suboffset_dim[0] = new_ndim # <<<<<<<<<<<<<<
+ *
+ * return 0
+ */
+ (__pyx_v_suboffset_dim[0]) = __pyx_v_new_ndim;
+ }
+ __pyx_L25:;
+ goto __pyx_L24;
+ }
+ __pyx_L24:;
+
+ /* "View.MemoryView":861
+ * suboffset_dim[0] = new_ndim
+ *
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":764
+ *
+ * @cname('__pyx_memoryview_slice_memviewslice')
+ * cdef int slice_memviewslice( # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * Py_ssize_t shape, Py_ssize_t stride, Py_ssize_t suboffset,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.slice_memviewslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+static char *__pyx_pybuffer_index(Py_buffer *__pyx_v_view, char *__pyx_v_bufp, Py_ssize_t __pyx_v_index, Py_ssize_t __pyx_v_dim) {
+ Py_ssize_t __pyx_v_shape;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_suboffset;
+ Py_ssize_t __pyx_v_itemsize;
+ char *__pyx_v_resultp;
+ char *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("pybuffer_index", 0);
+
+ /* "View.MemoryView":869
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index,
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t itemsize = view.itemsize
+ * cdef char *resultp
+ */
+ __pyx_v_suboffset = -1;
+
+ /* "View.MemoryView":870
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ * cdef Py_ssize_t itemsize = view.itemsize # <<<<<<<<<<<<<<
+ * cdef char *resultp
+ *
+ */
+ __pyx_t_1 = __pyx_v_view->itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":873
+ * cdef char *resultp
+ *
+ * if view.ndim == 0: # <<<<<<<<<<<<<<
+ * shape = view.len / itemsize
+ * stride = itemsize
+ */
+ __pyx_t_2 = ((__pyx_v_view->ndim == 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":874
+ *
+ * if view.ndim == 0:
+ * shape = view.len / itemsize # <<<<<<<<<<<<<<
+ * stride = itemsize
+ * else:
+ */
+ if (unlikely(__pyx_v_itemsize == 0)) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ else if (sizeof(Py_ssize_t) == sizeof(long) && unlikely(__pyx_v_itemsize == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(__pyx_v_view->len))) {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ PyErr_SetString(PyExc_OverflowError, "value too large to perform division");
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_v_shape = __Pyx_div_Py_ssize_t(__pyx_v_view->len, __pyx_v_itemsize);
+
+ /* "View.MemoryView":875
+ * if view.ndim == 0:
+ * shape = view.len / itemsize
+ * stride = itemsize # <<<<<<<<<<<<<<
+ * else:
+ * shape = view.shape[dim]
+ */
+ __pyx_v_stride = __pyx_v_itemsize;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":877
+ * stride = itemsize
+ * else:
+ * shape = view.shape[dim] # <<<<<<<<<<<<<<
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ */
+ __pyx_v_shape = (__pyx_v_view->shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":878
+ * else:
+ * shape = view.shape[dim]
+ * stride = view.strides[dim] # <<<<<<<<<<<<<<
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim]
+ */
+ __pyx_v_stride = (__pyx_v_view->strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":879
+ * shape = view.shape[dim]
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL: # <<<<<<<<<<<<<<
+ * suboffset = view.suboffsets[dim]
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_view->suboffsets != NULL) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":880
+ * stride = view.strides[dim]
+ * if view.suboffsets != NULL:
+ * suboffset = view.suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * if index < 0:
+ */
+ __pyx_v_suboffset = (__pyx_v_view->suboffsets[__pyx_v_dim]);
+ goto __pyx_L4;
+ }
+ __pyx_L4:;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":882
+ * suboffset = view.suboffsets[dim]
+ *
+ * if index < 0: # <<<<<<<<<<<<<<
+ * index += view.shape[dim]
+ * if index < 0:
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":883
+ *
+ * if index < 0:
+ * index += view.shape[dim] # <<<<<<<<<<<<<<
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ */
+ __pyx_v_index = (__pyx_v_index + (__pyx_v_view->shape[__pyx_v_dim]));
+
+ /* "View.MemoryView":884
+ * if index < 0:
+ * index += view.shape[dim]
+ * if index < 0: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index < 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":885
+ * index += view.shape[dim]
+ * if index < 0:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * if index >= shape:
+ */
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 885; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":887
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * if index >= shape: # <<<<<<<<<<<<<<
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_index >= __pyx_v_shape) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":888
+ *
+ * if index >= shape:
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim) # <<<<<<<<<<<<<<
+ *
+ * resultp = bufp + index * stride
+ */
+ __pyx_t_4 = PyInt_FromSsize_t(__pyx_v_dim); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":890
+ * raise IndexError("Out of bounds on buffer access (axis %d)" % dim)
+ *
+ * resultp = bufp + index * stride # <<<<<<<<<<<<<<
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset
+ */
+ __pyx_v_resultp = (__pyx_v_bufp + (__pyx_v_index * __pyx_v_stride));
+
+ /* "View.MemoryView":891
+ *
+ * resultp = bufp + index * stride
+ * if suboffset >= 0: # <<<<<<<<<<<<<<
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_suboffset >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":892
+ * resultp = bufp + index * stride
+ * if suboffset >= 0:
+ * resultp = (<char **> resultp)[0] + suboffset # <<<<<<<<<<<<<<
+ *
+ * return resultp
+ */
+ __pyx_v_resultp = ((((char **)__pyx_v_resultp)[0]) + __pyx_v_suboffset);
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+
+ /* "View.MemoryView":894
+ * resultp = (<char **> resultp)[0] + suboffset
+ *
+ * return resultp # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_resultp;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":867
+ *
+ * @cname('__pyx_pybuffer_index')
+ * cdef char *pybuffer_index(Py_buffer *view, char *bufp, Py_ssize_t index, # <<<<<<<<<<<<<<
+ * Py_ssize_t dim) except NULL:
+ * cdef Py_ssize_t shape, stride, suboffset = -1
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView.pybuffer_index", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = NULL;
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+static int __pyx_memslice_transpose(__Pyx_memviewslice *__pyx_v_memslice) {
+ int __pyx_v_ndim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ int __pyx_v_i;
+ int __pyx_v_j;
+ int __pyx_r;
+ int __pyx_t_1;
+ Py_ssize_t *__pyx_t_2;
+ long __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+ int __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":901
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0:
+ * cdef int ndim = memslice.memview.view.ndim # <<<<<<<<<<<<<<
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ */
+ __pyx_t_1 = __pyx_v_memslice->memview->view.ndim;
+ __pyx_v_ndim = __pyx_t_1;
+
+ /* "View.MemoryView":903
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ * cdef Py_ssize_t *shape = memslice.shape # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t *strides = memslice.strides
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->shape;
+ __pyx_v_shape = __pyx_t_2;
+
+ /* "View.MemoryView":904
+ *
+ * cdef Py_ssize_t *shape = memslice.shape
+ * cdef Py_ssize_t *strides = memslice.strides # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = __pyx_v_memslice->strides;
+ __pyx_v_strides = __pyx_t_2;
+
+ /* "View.MemoryView":908
+ *
+ * cdef int i, j
+ * for i in range(ndim / 2): # <<<<<<<<<<<<<<
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ */
+ __pyx_t_3 = __Pyx_div_long(__pyx_v_ndim, 2);
+ for (__pyx_t_1 = 0; __pyx_t_1 < __pyx_t_3; __pyx_t_1+=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":909
+ * cdef int i, j
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i # <<<<<<<<<<<<<<
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i]
+ */
+ __pyx_v_j = ((__pyx_v_ndim - 1) - __pyx_v_i);
+
+ /* "View.MemoryView":910
+ * for i in range(ndim / 2):
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i] # <<<<<<<<<<<<<<
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ */
+ __pyx_t_4 = (__pyx_v_strides[__pyx_v_j]);
+ __pyx_t_5 = (__pyx_v_strides[__pyx_v_i]);
+ (__pyx_v_strides[__pyx_v_i]) = __pyx_t_4;
+ (__pyx_v_strides[__pyx_v_j]) = __pyx_t_5;
+
+ /* "View.MemoryView":911
+ * j = ndim - 1 - i
+ * strides[i], strides[j] = strides[j], strides[i]
+ * shape[i], shape[j] = shape[j], shape[i] # <<<<<<<<<<<<<<
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ */
+ __pyx_t_5 = (__pyx_v_shape[__pyx_v_j]);
+ __pyx_t_4 = (__pyx_v_shape[__pyx_v_i]);
+ (__pyx_v_shape[__pyx_v_i]) = __pyx_t_5;
+ (__pyx_v_shape[__pyx_v_j]) = __pyx_t_4;
+
+ /* "View.MemoryView":913
+ * shape[i], shape[j] = shape[j], shape[i]
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0: # <<<<<<<<<<<<<<
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ */
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (!__pyx_t_7) {
+ } else {
+ __pyx_t_6 = __pyx_t_7;
+ goto __pyx_L6_bool_binop_done;
+ }
+ __pyx_t_7 = (((__pyx_v_memslice->suboffsets[__pyx_v_j]) >= 0) != 0);
+ __pyx_t_6 = __pyx_t_7;
+ __pyx_L6_bool_binop_done:;
+ if (__pyx_t_6) {
+
+ /* "View.MemoryView":914
+ *
+ * if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions") # <<<<<<<<<<<<<<
+ *
+ * return 1
+ */
+ __pyx_t_8 = __pyx_memoryview_err(__pyx_builtin_ValueError, __pyx_k_Cannot_transpose_memoryview_with); if (unlikely(__pyx_t_8 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L5;
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":916
+ * _err(ValueError, "Cannot transpose memoryview with indirect dimensions")
+ *
+ * return 1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = 1;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":900
+ *
+ * @cname('__pyx_memslice_transpose')
+ * cdef int transpose_memslice(__Pyx_memviewslice *memslice) nogil except 0: # <<<<<<<<<<<<<<
+ * cdef int ndim = memslice.memview.view.ndim
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.transpose_memslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = 0;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+/* Python wrapper */
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_memoryviewslice___dealloc__(PyObject *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+ __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_memoryviewslice_MemoryView_16_memoryviewslice___dealloc__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__dealloc__", 0);
+
+ /* "View.MemoryView":934
+ *
+ * def __dealloc__(self):
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1) # <<<<<<<<<<<<<<
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ */
+ __PYX_XDEC_MEMVIEW((&__pyx_v_self->from_slice), 1);
+
+ /* "View.MemoryView":933
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * def __dealloc__(self): # <<<<<<<<<<<<<<
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+static PyObject *__pyx_memoryviewslice_convert_item_to_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("convert_item_to_object", 0);
+
+ /* "View.MemoryView":937
+ *
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL: # <<<<<<<<<<<<<<
+ * return self.to_object_func(itemp)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_object_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":938
+ * cdef convert_item_to_object(self, char *itemp):
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp) # <<<<<<<<<<<<<<
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp)
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_v_self->to_object_func(__pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":940
+ * return self.to_object_func(itemp)
+ * else:
+ * return memoryview.convert_item_to_object(self, itemp) # <<<<<<<<<<<<<<
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_2 = __pyx_memoryview_convert_item_to_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_r = __pyx_t_2;
+ __pyx_t_2 = 0;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":936
+ * __PYX_XDEC_MEMVIEW(&self.from_slice, 1)
+ *
+ * cdef convert_item_to_object(self, char *itemp): # <<<<<<<<<<<<<<
+ * if self.to_object_func != NULL:
+ * return self.to_object_func(itemp)
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.convert_item_to_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+static PyObject *__pyx_memoryviewslice_assign_item_from_object(struct __pyx_memoryviewslice_obj *__pyx_v_self, char *__pyx_v_itemp, PyObject *__pyx_v_value) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("assign_item_from_object", 0);
+
+ /* "View.MemoryView":943
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL: # <<<<<<<<<<<<<<
+ * self.to_dtype_func(itemp, value)
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_self->to_dtype_func != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":944
+ * cdef assign_item_from_object(self, char *itemp, object value):
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value) # <<<<<<<<<<<<<<
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value)
+ */
+ __pyx_t_2 = __pyx_v_self->to_dtype_func(__pyx_v_itemp, __pyx_v_value); if (unlikely(__pyx_t_2 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":946
+ * self.to_dtype_func(itemp, value)
+ * else:
+ * memoryview.assign_item_from_object(self, itemp, value) # <<<<<<<<<<<<<<
+ *
+ * property base:
+ */
+ __pyx_t_3 = __pyx_memoryview_assign_item_from_object(((struct __pyx_memoryview_obj *)__pyx_v_self), __pyx_v_itemp, __pyx_v_value); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":942
+ * return memoryview.convert_item_to_object(self, itemp)
+ *
+ * cdef assign_item_from_object(self, char *itemp, object value): # <<<<<<<<<<<<<<
+ * if self.to_dtype_func != NULL:
+ * self.to_dtype_func(itemp, value)
+ */
+
+ /* function exit code */
+ __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView._memoryviewslice.assign_item_from_object", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+/* Python wrapper */
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self); /*proto*/
+static PyObject *__pyx_memoryviewslice__get__base(PyObject *__pyx_v_self) {
+ PyObject *__pyx_r = 0;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__ (wrapper)", 0);
+ __pyx_r = __pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(((struct __pyx_memoryviewslice_obj *)__pyx_v_self));
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+static PyObject *__pyx_memoryviewslice__get__base_MemoryView_16_memoryviewslice_4base___get__(struct __pyx_memoryviewslice_obj *__pyx_v_self) {
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__get__", 0);
+
+ /* "View.MemoryView":951
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self):
+ * return self.from_object # <<<<<<<<<<<<<<
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)")
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(__pyx_v_self->from_object);
+ __pyx_r = __pyx_v_self->from_object;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":950
+ * property base:
+ * @cname('__pyx_memoryviewslice__get__base')
+ * def __get__(self): # <<<<<<<<<<<<<<
+ * return self.from_object
+ *
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+static PyObject *__pyx_memoryview_fromslice(__Pyx_memviewslice __pyx_v_memviewslice, int __pyx_v_ndim, PyObject *(*__pyx_v_to_object_func)(char *), int (*__pyx_v_to_dtype_func)(char *, PyObject *), int __pyx_v_dtype_is_object) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_result = 0;
+ int __pyx_v_i;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ __Pyx_TypeInfo *__pyx_t_4;
+ Py_buffer __pyx_t_5;
+ Py_ssize_t __pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_t_8;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_fromslice", 0);
+
+ /* "View.MemoryView":966
+ * cdef int i
+ *
+ * if <PyObject *> memviewslice.memview == Py_None: # <<<<<<<<<<<<<<
+ * return None
+ *
+ */
+ __pyx_t_1 = ((((PyObject *)__pyx_v_memviewslice.memview) == Py_None) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":967
+ *
+ * if <PyObject *> memviewslice.memview == Py_None:
+ * return None # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(Py_None);
+ __pyx_r = Py_None;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":972
+ *
+ *
+ * result = _memoryviewslice(None, 0, dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ * result.from_slice = memviewslice
+ */
+ __pyx_t_2 = __Pyx_PyBool_FromLong(__pyx_v_dtype_is_object); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(Py_None);
+ PyTuple_SET_ITEM(__pyx_t_3, 0, Py_None);
+ __Pyx_GIVEREF(Py_None);
+ __Pyx_INCREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_int_0);
+ __Pyx_GIVEREF(__pyx_int_0);
+ PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __pyx_t_2 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_memoryviewslice_type)), __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 972; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __pyx_v_result = ((struct __pyx_memoryviewslice_obj *)__pyx_t_2);
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":974
+ * result = _memoryviewslice(None, 0, dtype_is_object)
+ *
+ * result.from_slice = memviewslice # <<<<<<<<<<<<<<
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ */
+ __pyx_v_result->from_slice = __pyx_v_memviewslice;
+
+ /* "View.MemoryView":975
+ *
+ * result.from_slice = memviewslice
+ * __PYX_INC_MEMVIEW(&memviewslice, 1) # <<<<<<<<<<<<<<
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ */
+ __PYX_INC_MEMVIEW((&__pyx_v_memviewslice), 1);
+
+ /* "View.MemoryView":977
+ * __PYX_INC_MEMVIEW(&memviewslice, 1)
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base # <<<<<<<<<<<<<<
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ */
+ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_memviewslice.memview), __pyx_n_s_base); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 977; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ __Pyx_GOTREF(__pyx_v_result->from_object);
+ __Pyx_DECREF(__pyx_v_result->from_object);
+ __pyx_v_result->from_object = __pyx_t_2;
+ __pyx_t_2 = 0;
+
+ /* "View.MemoryView":978
+ *
+ * result.from_object = (<memoryview> memviewslice.memview).base
+ * result.typeinfo = memviewslice.memview.typeinfo # <<<<<<<<<<<<<<
+ *
+ * result.view = memviewslice.memview.view
+ */
+ __pyx_t_4 = __pyx_v_memviewslice.memview->typeinfo;
+ __pyx_v_result->__pyx_base.typeinfo = __pyx_t_4;
+
+ /* "View.MemoryView":980
+ * result.typeinfo = memviewslice.memview.typeinfo
+ *
+ * result.view = memviewslice.memview.view # <<<<<<<<<<<<<<
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ */
+ __pyx_t_5 = __pyx_v_memviewslice.memview->view;
+ __pyx_v_result->__pyx_base.view = __pyx_t_5;
+
+ /* "View.MemoryView":981
+ *
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data # <<<<<<<<<<<<<<
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ */
+ __pyx_v_result->__pyx_base.view.buf = ((void *)__pyx_v_memviewslice.data);
+
+ /* "View.MemoryView":982
+ * result.view = memviewslice.memview.view
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim # <<<<<<<<<<<<<<
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None)
+ */
+ __pyx_v_result->__pyx_base.view.ndim = __pyx_v_ndim;
+
+ /* "View.MemoryView":983
+ * result.view.buf = <void *> memviewslice.data
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None # <<<<<<<<<<<<<<
+ * Py_INCREF(Py_None)
+ *
+ */
+ ((Py_buffer *)(&__pyx_v_result->__pyx_base.view))->obj = Py_None;
+
+ /* "View.MemoryView":984
+ * result.view.ndim = ndim
+ * (<__pyx_buffer *> &result.view).obj = Py_None
+ * Py_INCREF(Py_None) # <<<<<<<<<<<<<<
+ *
+ * result.flags = PyBUF_RECORDS
+ */
+ Py_INCREF(Py_None);
+
+ /* "View.MemoryView":986
+ * Py_INCREF(Py_None)
+ *
+ * result.flags = PyBUF_RECORDS # <<<<<<<<<<<<<<
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ */
+ __pyx_v_result->__pyx_base.flags = PyBUF_RECORDS;
+
+ /* "View.MemoryView":988
+ * result.flags = PyBUF_RECORDS
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape # <<<<<<<<<<<<<<
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ */
+ __pyx_v_result->__pyx_base.view.shape = ((Py_ssize_t *)__pyx_v_result->from_slice.shape);
+
+ /* "View.MemoryView":989
+ *
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides # <<<<<<<<<<<<<<
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ */
+ __pyx_v_result->__pyx_base.view.strides = ((Py_ssize_t *)__pyx_v_result->from_slice.strides);
+
+ /* "View.MemoryView":990
+ * result.view.shape = <Py_ssize_t *> result.from_slice.shape
+ * result.view.strides = <Py_ssize_t *> result.from_slice.strides
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets # <<<<<<<<<<<<<<
+ *
+ * result.view.len = result.view.itemsize
+ */
+ __pyx_v_result->__pyx_base.view.suboffsets = ((Py_ssize_t *)__pyx_v_result->from_slice.suboffsets);
+
+ /* "View.MemoryView":992
+ * result.view.suboffsets = <Py_ssize_t *> result.from_slice.suboffsets
+ *
+ * result.view.len = result.view.itemsize # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i]
+ */
+ __pyx_t_6 = __pyx_v_result->__pyx_base.view.itemsize;
+ __pyx_v_result->__pyx_base.view.len = __pyx_t_6;
+
+ /* "View.MemoryView":993
+ *
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * result.view.len *= result.view.shape[i]
+ *
+ */
+ __pyx_t_7 = __pyx_v_ndim;
+ for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
+ __pyx_v_i = __pyx_t_8;
+
+ /* "View.MemoryView":994
+ * result.view.len = result.view.itemsize
+ * for i in range(ndim):
+ * result.view.len *= result.view.shape[i] # <<<<<<<<<<<<<<
+ *
+ * result.to_object_func = to_object_func
+ */
+ __pyx_v_result->__pyx_base.view.len = (__pyx_v_result->__pyx_base.view.len * (__pyx_v_result->__pyx_base.view.shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":996
+ * result.view.len *= result.view.shape[i]
+ *
+ * result.to_object_func = to_object_func # <<<<<<<<<<<<<<
+ * result.to_dtype_func = to_dtype_func
+ *
+ */
+ __pyx_v_result->to_object_func = __pyx_v_to_object_func;
+
+ /* "View.MemoryView":997
+ *
+ * result.to_object_func = to_object_func
+ * result.to_dtype_func = to_dtype_func # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ __pyx_v_result->to_dtype_func = __pyx_v_to_dtype_func;
+
+ /* "View.MemoryView":999
+ * result.to_dtype_func = to_dtype_func
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __Pyx_INCREF(((PyObject *)__pyx_v_result));
+ __pyx_r = ((PyObject *)__pyx_v_result);
+ goto __pyx_L0;
+
+ /* "View.MemoryView":957
+ *
+ * @cname('__pyx_memoryview_fromslice')
+ * cdef memoryview_fromslice(__Pyx_memviewslice memviewslice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * object (*to_object_func)(char *),
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_fromslice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_result);
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+static __Pyx_memviewslice *__pyx_memoryview_get_slice_from_memoryview(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_mslice) {
+ struct __pyx_memoryviewslice_obj *__pyx_v_obj = 0;
+ __Pyx_memviewslice *__pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *__pyx_t_3 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("get_slice_from_memview", 0);
+
+ /* "View.MemoryView":1005
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * obj = memview
+ * return &obj.from_slice
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1006
+ * cdef _memoryviewslice obj
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview # <<<<<<<<<<<<<<
+ * return &obj.from_slice
+ * else:
+ */
+ if (!(likely(((((PyObject *)__pyx_v_memview)) == Py_None) || likely(__Pyx_TypeTest(((PyObject *)__pyx_v_memview), __pyx_memoryviewslice_type))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_t_3 = ((PyObject *)__pyx_v_memview);
+ __Pyx_INCREF(__pyx_t_3);
+ __pyx_v_obj = ((struct __pyx_memoryviewslice_obj *)__pyx_t_3);
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1007
+ * if isinstance(memview, _memoryviewslice):
+ * obj = memview
+ * return &obj.from_slice # <<<<<<<<<<<<<<
+ * else:
+ * slice_copy(memview, mslice)
+ */
+ __pyx_r = (&__pyx_v_obj->from_slice);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1009
+ * return &obj.from_slice
+ * else:
+ * slice_copy(memview, mslice) # <<<<<<<<<<<<<<
+ * return mslice
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, __pyx_v_mslice);
+
+ /* "View.MemoryView":1010
+ * else:
+ * slice_copy(memview, mslice)
+ * return mslice # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ */
+ __pyx_r = __pyx_v_mslice;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1002
+ *
+ * @cname('__pyx_memoryview_get_slice_from_memoryview')
+ * cdef __Pyx_memviewslice *get_slice_from_memview(memoryview memview, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *mslice):
+ * cdef _memoryviewslice obj
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_WriteUnraisable("View.MemoryView.get_slice_from_memview", __pyx_clineno, __pyx_lineno, __pyx_filename, 0);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XDECREF((PyObject *)__pyx_v_obj);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+static void __pyx_memoryview_slice_copy(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_dst) {
+ int __pyx_v_dim;
+ Py_ssize_t *__pyx_v_shape;
+ Py_ssize_t *__pyx_v_strides;
+ Py_ssize_t *__pyx_v_suboffsets;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t *__pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ __Pyx_RefNannySetupContext("slice_copy", 0);
+
+ /* "View.MemoryView":1017
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ *
+ * shape = memview.view.shape # <<<<<<<<<<<<<<
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets
+ */
+ __pyx_t_1 = __pyx_v_memview->view.shape;
+ __pyx_v_shape = __pyx_t_1;
+
+ /* "View.MemoryView":1018
+ *
+ * shape = memview.view.shape
+ * strides = memview.view.strides # <<<<<<<<<<<<<<
+ * suboffsets = memview.view.suboffsets
+ *
+ */
+ __pyx_t_1 = __pyx_v_memview->view.strides;
+ __pyx_v_strides = __pyx_t_1;
+
+ /* "View.MemoryView":1019
+ * shape = memview.view.shape
+ * strides = memview.view.strides
+ * suboffsets = memview.view.suboffsets # <<<<<<<<<<<<<<
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ */
+ __pyx_t_1 = __pyx_v_memview->view.suboffsets;
+ __pyx_v_suboffsets = __pyx_t_1;
+
+ /* "View.MemoryView":1021
+ * suboffsets = memview.view.suboffsets
+ *
+ * dst.memview = <__pyx_memoryview *> memview # <<<<<<<<<<<<<<
+ * dst.data = <char *> memview.view.buf
+ *
+ */
+ __pyx_v_dst->memview = ((struct __pyx_memoryview_obj *)__pyx_v_memview);
+
+ /* "View.MemoryView":1022
+ *
+ * dst.memview = <__pyx_memoryview *> memview
+ * dst.data = <char *> memview.view.buf # <<<<<<<<<<<<<<
+ *
+ * for dim in range(memview.view.ndim):
+ */
+ __pyx_v_dst->data = ((char *)__pyx_v_memview->view.buf);
+
+ /* "View.MemoryView":1024
+ * dst.data = <char *> memview.view.buf
+ *
+ * for dim in range(memview.view.ndim): # <<<<<<<<<<<<<<
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ */
+ __pyx_t_2 = __pyx_v_memview->view.ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_dim = __pyx_t_3;
+
+ /* "View.MemoryView":1025
+ *
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim] # <<<<<<<<<<<<<<
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ */
+ (__pyx_v_dst->shape[__pyx_v_dim]) = (__pyx_v_shape[__pyx_v_dim]);
+
+ /* "View.MemoryView":1026
+ * for dim in range(memview.view.ndim):
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim] # <<<<<<<<<<<<<<
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1
+ */
+ (__pyx_v_dst->strides[__pyx_v_dim]) = (__pyx_v_strides[__pyx_v_dim]);
+
+ /* "View.MemoryView":1027
+ * dst.shape[dim] = shape[dim]
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL: # <<<<<<<<<<<<<<
+ * dst.suboffsets[dim] = -1
+ * else:
+ */
+ __pyx_t_4 = ((__pyx_v_suboffsets == NULL) != 0);
+ if (__pyx_t_4) {
+
+ /* "View.MemoryView":1028
+ * dst.strides[dim] = strides[dim]
+ * if suboffsets == NULL:
+ * dst.suboffsets[dim] = -1 # <<<<<<<<<<<<<<
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim]
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = -1;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1030
+ * dst.suboffsets[dim] = -1
+ * else:
+ * dst.suboffsets[dim] = suboffsets[dim] # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ */
+ (__pyx_v_dst->suboffsets[__pyx_v_dim]) = (__pyx_v_suboffsets[__pyx_v_dim]);
+ }
+ __pyx_L5:;
+ }
+
+ /* "View.MemoryView":1013
+ *
+ * @cname('__pyx_memoryview_slice_copy')
+ * cdef void slice_copy(memoryview memview, __Pyx_memviewslice *dst): # <<<<<<<<<<<<<<
+ * cdef int dim
+ * cdef (Py_ssize_t*) shape, strides, suboffsets
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+static PyObject *__pyx_memoryview_copy_object(struct __pyx_memoryview_obj *__pyx_v_memview) {
+ __Pyx_memviewslice __pyx_v_memviewslice;
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy", 0);
+
+ /* "View.MemoryView":1036
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice) # <<<<<<<<<<<<<<
+ * return memoryview_copy_from_slice(memview, &memviewslice)
+ *
+ */
+ __pyx_memoryview_slice_copy(__pyx_v_memview, (&__pyx_v_memviewslice));
+
+ /* "View.MemoryView":1037
+ * cdef __Pyx_memviewslice memviewslice
+ * slice_copy(memview, &memviewslice)
+ * return memoryview_copy_from_slice(memview, &memviewslice) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ */
+ __Pyx_XDECREF(__pyx_r);
+ __pyx_t_1 = __pyx_memoryview_copy_object_from_slice(__pyx_v_memview, (&__pyx_v_memviewslice)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_r = __pyx_t_1;
+ __pyx_t_1 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1033
+ *
+ * @cname('__pyx_memoryview_copy_object')
+ * cdef memoryview_copy(memoryview memview): # <<<<<<<<<<<<<<
+ * "Create a new memoryview object"
+ * cdef __Pyx_memviewslice memviewslice
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+static PyObject *__pyx_memoryview_copy_object_from_slice(struct __pyx_memoryview_obj *__pyx_v_memview, __Pyx_memviewslice *__pyx_v_memviewslice) {
+ PyObject *(*__pyx_v_to_object_func)(char *);
+ int (*__pyx_v_to_dtype_func)(char *, PyObject *);
+ PyObject *__pyx_r = NULL;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ int __pyx_t_2;
+ PyObject *(*__pyx_t_3)(char *);
+ int (*__pyx_t_4)(char *, PyObject *);
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannySetupContext("memoryview_copy_from_slice", 0);
+
+ /* "View.MemoryView":1047
+ * cdef int (*to_dtype_func)(char *, object) except 0
+ *
+ * if isinstance(memview, _memoryviewslice): # <<<<<<<<<<<<<<
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ */
+ __pyx_t_1 = __Pyx_TypeCheck(((PyObject *)__pyx_v_memview), ((PyObject *)__pyx_memoryviewslice_type));
+ __pyx_t_2 = (__pyx_t_1 != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1048
+ *
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func # <<<<<<<<<<<<<<
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ */
+ __pyx_t_3 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_object_func;
+ __pyx_v_to_object_func = __pyx_t_3;
+
+ /* "View.MemoryView":1049
+ * if isinstance(memview, _memoryviewslice):
+ * to_object_func = (<_memoryviewslice> memview).to_object_func
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func # <<<<<<<<<<<<<<
+ * else:
+ * to_object_func = NULL
+ */
+ __pyx_t_4 = ((struct __pyx_memoryviewslice_obj *)__pyx_v_memview)->to_dtype_func;
+ __pyx_v_to_dtype_func = __pyx_t_4;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1051
+ * to_dtype_func = (<_memoryviewslice> memview).to_dtype_func
+ * else:
+ * to_object_func = NULL # <<<<<<<<<<<<<<
+ * to_dtype_func = NULL
+ *
+ */
+ __pyx_v_to_object_func = NULL;
+
+ /* "View.MemoryView":1052
+ * else:
+ * to_object_func = NULL
+ * to_dtype_func = NULL # <<<<<<<<<<<<<<
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ */
+ __pyx_v_to_dtype_func = NULL;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1054
+ * to_dtype_func = NULL
+ *
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim, # <<<<<<<<<<<<<<
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object)
+ */
+ __Pyx_XDECREF(__pyx_r);
+
+ /* "View.MemoryView":1056
+ * return memoryview_fromslice(memviewslice[0], memview.view.ndim,
+ * to_object_func, to_dtype_func,
+ * memview.dtype_is_object) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_5 = __pyx_memoryview_fromslice((__pyx_v_memviewslice[0]), __pyx_v_memview->view.ndim, __pyx_v_to_object_func, __pyx_v_to_dtype_func, __pyx_v_memview->dtype_is_object); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1054; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ __pyx_r = __pyx_t_5;
+ __pyx_t_5 = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1040
+ *
+ * @cname('__pyx_memoryview_copy_object_from_slice')
+ * cdef memoryview_copy_from_slice(memoryview memview, __Pyx_memviewslice *memviewslice): # <<<<<<<<<<<<<<
+ * """
+ * Create a new memoryview object from a given memoryview object and slice.
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_from_slice", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = 0;
+ __pyx_L0:;
+ __Pyx_XGIVEREF(__pyx_r);
+ __Pyx_RefNannyFinishContext();
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+static Py_ssize_t abs_py_ssize_t(Py_ssize_t __pyx_v_arg) {
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1063
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0: # <<<<<<<<<<<<<<
+ * return -arg
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_arg < 0) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1064
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil:
+ * if arg < 0:
+ * return -arg # <<<<<<<<<<<<<<
+ * else:
+ * return arg
+ */
+ __pyx_r = (-__pyx_v_arg);
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1066
+ * return -arg
+ * else:
+ * return arg # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_get_best_slice_order')
+ */
+ __pyx_r = __pyx_v_arg;
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1062
+ *
+ *
+ * cdef Py_ssize_t abs_py_ssize_t(Py_ssize_t arg) nogil: # <<<<<<<<<<<<<<
+ * if arg < 0:
+ * return -arg
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+static char __pyx_get_best_slice_order(__Pyx_memviewslice *__pyx_v_mslice, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_c_stride;
+ Py_ssize_t __pyx_v_f_stride;
+ char __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1074
+ * """
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0 # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t f_stride = 0
+ *
+ */
+ __pyx_v_c_stride = 0;
+
+ /* "View.MemoryView":1075
+ * cdef int i
+ * cdef Py_ssize_t c_stride = 0
+ * cdef Py_ssize_t f_stride = 0 # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_f_stride = 0;
+
+ /* "View.MemoryView":1077
+ * cdef Py_ssize_t f_stride = 0
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1078
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * c_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1079
+ * for i in range(ndim - 1, -1, -1):
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_c_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1080
+ * if mslice.shape[i] > 1:
+ * c_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ goto __pyx_L4_break;
+ }
+ }
+ __pyx_L4_break:;
+
+ /* "View.MemoryView":1082
+ * break
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ */
+ __pyx_t_1 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_1; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1083
+ *
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1: # <<<<<<<<<<<<<<
+ * f_stride = mslice.strides[i]
+ * break
+ */
+ __pyx_t_2 = (((__pyx_v_mslice->shape[__pyx_v_i]) > 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1084
+ * for i in range(ndim):
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i] # <<<<<<<<<<<<<<
+ * break
+ *
+ */
+ __pyx_v_f_stride = (__pyx_v_mslice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1085
+ * if mslice.shape[i] > 1:
+ * f_stride = mslice.strides[i]
+ * break # <<<<<<<<<<<<<<
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ */
+ goto __pyx_L7_break;
+ }
+ }
+ __pyx_L7_break:;
+
+ /* "View.MemoryView":1087
+ * break
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride): # <<<<<<<<<<<<<<
+ * return 'C'
+ * else:
+ */
+ __pyx_t_2 = ((abs_py_ssize_t(__pyx_v_c_stride) <= abs_py_ssize_t(__pyx_v_f_stride)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1088
+ *
+ * if abs_py_ssize_t(c_stride) <= abs_py_ssize_t(f_stride):
+ * return 'C' # <<<<<<<<<<<<<<
+ * else:
+ * return 'F'
+ */
+ __pyx_r = 'C';
+ goto __pyx_L0;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1090
+ * return 'C'
+ * else:
+ * return 'F' # <<<<<<<<<<<<<<
+ *
+ * @cython.cdivision(True)
+ */
+ __pyx_r = 'F';
+ goto __pyx_L0;
+ }
+
+ /* "View.MemoryView":1069
+ *
+ * @cname('__pyx_get_best_slice_order')
+ * cdef char get_best_order(__Pyx_memviewslice *mslice, int ndim) nogil: # <<<<<<<<<<<<<<
+ * """
+ * Figure out the best memory access order for a given slice.
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+static void _copy_strided_to_strided(char *__pyx_v_src_data, Py_ssize_t *__pyx_v_src_strides, char *__pyx_v_dst_data, Py_ssize_t *__pyx_v_dst_strides, Py_ssize_t *__pyx_v_src_shape, Py_ssize_t *__pyx_v_dst_shape, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ CYTHON_UNUSED Py_ssize_t __pyx_v_src_extent;
+ Py_ssize_t __pyx_v_dst_extent;
+ Py_ssize_t __pyx_v_src_stride;
+ Py_ssize_t __pyx_v_dst_stride;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ Py_ssize_t __pyx_t_4;
+ Py_ssize_t __pyx_t_5;
+
+ /* "View.MemoryView":1100
+ *
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ */
+ __pyx_v_src_extent = (__pyx_v_src_shape[0]);
+
+ /* "View.MemoryView":1101
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ */
+ __pyx_v_dst_extent = (__pyx_v_dst_shape[0]);
+
+ /* "View.MemoryView":1102
+ * cdef Py_ssize_t src_extent = src_shape[0]
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ */
+ __pyx_v_src_stride = (__pyx_v_src_strides[0]);
+
+ /* "View.MemoryView":1103
+ * cdef Py_ssize_t dst_extent = dst_shape[0]
+ * cdef Py_ssize_t src_stride = src_strides[0]
+ * cdef Py_ssize_t dst_stride = dst_strides[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_dst_stride = (__pyx_v_dst_strides[0]);
+
+ /* "View.MemoryView":1105
+ * cdef Py_ssize_t dst_stride = dst_strides[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1106
+ *
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and # <<<<<<<<<<<<<<
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ */
+ __pyx_t_2 = ((__pyx_v_src_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+ __pyx_t_2 = ((__pyx_v_dst_stride > 0) != 0);
+ if (__pyx_t_2) {
+ } else {
+ __pyx_t_1 = __pyx_t_2;
+ goto __pyx_L5_bool_binop_done;
+ }
+
+ /* "View.MemoryView":1107
+ * if ndim == 1:
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ */
+ __pyx_t_2 = (((size_t)__pyx_v_src_stride) == __pyx_v_itemsize);
+ if (__pyx_t_2) {
+ __pyx_t_2 = (__pyx_v_itemsize == ((size_t)__pyx_v_dst_stride));
+ }
+ __pyx_t_3 = (__pyx_t_2 != 0);
+ __pyx_t_1 = __pyx_t_3;
+ __pyx_L5_bool_binop_done:;
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1108
+ * if (src_stride > 0 and dst_stride > 0 and
+ * <size_t> src_stride == itemsize == <size_t> dst_stride):
+ * memcpy(dst_data, src_data, itemsize * dst_extent) # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, (__pyx_v_itemsize * __pyx_v_dst_extent));
+ goto __pyx_L4;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1110
+ * memcpy(dst_data, src_data, itemsize * dst_extent)
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1111
+ * else:
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize) # <<<<<<<<<<<<<<
+ * src_data += src_stride
+ * dst_data += dst_stride
+ */
+ memcpy(__pyx_v_dst_data, __pyx_v_src_data, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1112
+ * for i in range(dst_extent):
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ * else:
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1113
+ * memcpy(dst_data, src_data, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(dst_extent):
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L4:;
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1115
+ * dst_data += dst_stride
+ * else:
+ * for i in range(dst_extent): # <<<<<<<<<<<<<<
+ * _copy_strided_to_strided(src_data, src_strides + 1,
+ * dst_data, dst_strides + 1,
+ */
+ __pyx_t_4 = __pyx_v_dst_extent;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1116
+ * else:
+ * for i in range(dst_extent):
+ * _copy_strided_to_strided(src_data, src_strides + 1, # <<<<<<<<<<<<<<
+ * dst_data, dst_strides + 1,
+ * src_shape + 1, dst_shape + 1,
+ */
+ _copy_strided_to_strided(__pyx_v_src_data, (__pyx_v_src_strides + 1), __pyx_v_dst_data, (__pyx_v_dst_strides + 1), (__pyx_v_src_shape + 1), (__pyx_v_dst_shape + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize);
+
+ /* "View.MemoryView":1120
+ * src_shape + 1, dst_shape + 1,
+ * ndim - 1, itemsize)
+ * src_data += src_stride # <<<<<<<<<<<<<<
+ * dst_data += dst_stride
+ *
+ */
+ __pyx_v_src_data = (__pyx_v_src_data + __pyx_v_src_stride);
+
+ /* "View.MemoryView":1121
+ * ndim - 1, itemsize)
+ * src_data += src_stride
+ * dst_data += dst_stride # <<<<<<<<<<<<<<
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src,
+ */
+ __pyx_v_dst_data = (__pyx_v_dst_data + __pyx_v_dst_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1093
+ *
+ * @cython.cdivision(True)
+ * cdef void _copy_strided_to_strided(char *src_data, Py_ssize_t *src_strides, # <<<<<<<<<<<<<<
+ * char *dst_data, Py_ssize_t *dst_strides,
+ * Py_ssize_t *src_shape, Py_ssize_t *dst_shape,
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+static void copy_strided_to_strided(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize) {
+
+ /* "View.MemoryView":1126
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ * _copy_strided_to_strided(src.data, src.strides, dst.data, dst.strides, # <<<<<<<<<<<<<<
+ * src.shape, dst.shape, ndim, itemsize)
+ *
+ */
+ _copy_strided_to_strided(__pyx_v_src->data, __pyx_v_src->strides, __pyx_v_dst->data, __pyx_v_dst->strides, __pyx_v_src->shape, __pyx_v_dst->shape, __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1123
+ * dst_data += dst_stride
+ *
+ * cdef void copy_strided_to_strided(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *dst,
+ * int ndim, size_t itemsize) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+static Py_ssize_t __pyx_memoryview_slice_get_size(__Pyx_memviewslice *__pyx_v_src, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ Py_ssize_t __pyx_v_size;
+ Py_ssize_t __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1133
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ * cdef Py_ssize_t size = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_size = __pyx_t_1;
+
+ /* "View.MemoryView":1135
+ * cdef Py_ssize_t size = src.memview.view.itemsize
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * size *= src.shape[i]
+ *
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1136
+ *
+ * for i in range(ndim):
+ * size *= src.shape[i] # <<<<<<<<<<<<<<
+ *
+ * return size
+ */
+ __pyx_v_size = (__pyx_v_size * (__pyx_v_src->shape[__pyx_v_i]));
+ }
+
+ /* "View.MemoryView":1138
+ * size *= src.shape[i]
+ *
+ * return size # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ */
+ __pyx_r = __pyx_v_size;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1130
+ *
+ * @cname('__pyx_memoryview_slice_get_size')
+ * cdef Py_ssize_t slice_get_size(__Pyx_memviewslice *src, int ndim) nogil: # <<<<<<<<<<<<<<
+ * "Return the size of the memory occupied by the slice in number of bytes"
+ * cdef int i
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+static Py_ssize_t __pyx_fill_contig_strides_array(Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, Py_ssize_t __pyx_v_stride, int __pyx_v_ndim, char __pyx_v_order) {
+ int __pyx_v_idx;
+ Py_ssize_t __pyx_r;
+ int __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+
+ /* "View.MemoryView":1150
+ * cdef int idx
+ *
+ * if order == 'F': # <<<<<<<<<<<<<<
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ */
+ __pyx_t_1 = ((__pyx_v_order == 'F') != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1151
+ *
+ * if order == 'F':
+ * for idx in range(ndim): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ __pyx_t_2 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_idx = __pyx_t_3;
+
+ /* "View.MemoryView":1152
+ * if order == 'F':
+ * for idx in range(ndim):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ * else:
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1153
+ * for idx in range(ndim):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1155
+ * stride = stride * shape[idx]
+ * else:
+ * for idx in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * strides[idx] = stride
+ * stride = stride * shape[idx]
+ */
+ for (__pyx_t_2 = (__pyx_v_ndim - 1); __pyx_t_2 > -1; __pyx_t_2-=1) {
+ __pyx_v_idx = __pyx_t_2;
+
+ /* "View.MemoryView":1156
+ * else:
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride # <<<<<<<<<<<<<<
+ * stride = stride * shape[idx]
+ *
+ */
+ (__pyx_v_strides[__pyx_v_idx]) = __pyx_v_stride;
+
+ /* "View.MemoryView":1157
+ * for idx in range(ndim - 1, -1, -1):
+ * strides[idx] = stride
+ * stride = stride * shape[idx] # <<<<<<<<<<<<<<
+ *
+ * return stride
+ */
+ __pyx_v_stride = (__pyx_v_stride * (__pyx_v_shape[__pyx_v_idx]));
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1159
+ * stride = stride * shape[idx]
+ *
+ * return stride # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ */
+ __pyx_r = __pyx_v_stride;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1141
+ *
+ * @cname('__pyx_fill_contig_strides_array')
+ * cdef Py_ssize_t fill_contig_strides_array( # <<<<<<<<<<<<<<
+ * Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t stride,
+ * int ndim, char order) nogil:
+ */
+
+ /* function exit code */
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+static void *__pyx_memoryview_copy_data_to_temp(__Pyx_memviewslice *__pyx_v_src, __Pyx_memviewslice *__pyx_v_tmpslice, char __pyx_v_order, int __pyx_v_ndim) {
+ int __pyx_v_i;
+ void *__pyx_v_result;
+ size_t __pyx_v_itemsize;
+ size_t __pyx_v_size;
+ void *__pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ struct __pyx_memoryview_obj *__pyx_t_4;
+ int __pyx_t_5;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1173
+ * cdef void *result
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ */
+ __pyx_t_1 = __pyx_v_src->memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1174
+ *
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef size_t size = slice_get_size(src, ndim) # <<<<<<<<<<<<<<
+ *
+ * result = malloc(size)
+ */
+ __pyx_v_size = __pyx_memoryview_slice_get_size(__pyx_v_src, __pyx_v_ndim);
+
+ /* "View.MemoryView":1176
+ * cdef size_t size = slice_get_size(src, ndim)
+ *
+ * result = malloc(size) # <<<<<<<<<<<<<<
+ * if not result:
+ * _err(MemoryError, NULL)
+ */
+ __pyx_v_result = malloc(__pyx_v_size);
+
+ /* "View.MemoryView":1177
+ *
+ * result = malloc(size)
+ * if not result: # <<<<<<<<<<<<<<
+ * _err(MemoryError, NULL)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_result != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1178
+ * result = malloc(size)
+ * if not result:
+ * _err(MemoryError, NULL) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_3 = __pyx_memoryview_err(__pyx_builtin_MemoryError, NULL); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1181
+ *
+ *
+ * tmpslice.data = <char *> result # <<<<<<<<<<<<<<
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ */
+ __pyx_v_tmpslice->data = ((char *)__pyx_v_result);
+
+ /* "View.MemoryView":1182
+ *
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview # <<<<<<<<<<<<<<
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ */
+ __pyx_t_4 = __pyx_v_src->memview;
+ __pyx_v_tmpslice->memview = __pyx_t_4;
+
+ /* "View.MemoryView":1183
+ * tmpslice.data = <char *> result
+ * tmpslice.memview = src.memview
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1184
+ * tmpslice.memview = src.memview
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i] # <<<<<<<<<<<<<<
+ * tmpslice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_tmpslice->shape[__pyx_v_i]) = (__pyx_v_src->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1185
+ * for i in range(ndim):
+ * tmpslice.shape[i] = src.shape[i]
+ * tmpslice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize,
+ */
+ (__pyx_v_tmpslice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1187
+ * tmpslice.suboffsets[i] = -1
+ *
+ * fill_contig_strides_array(&tmpslice.shape[0], &tmpslice.strides[0], itemsize, # <<<<<<<<<<<<<<
+ * ndim, order)
+ *
+ */
+ __pyx_fill_contig_strides_array((&(__pyx_v_tmpslice->shape[0])), (&(__pyx_v_tmpslice->strides[0])), __pyx_v_itemsize, __pyx_v_ndim, __pyx_v_order);
+
+ /* "View.MemoryView":1191
+ *
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0
+ */
+ __pyx_t_3 = __pyx_v_ndim;
+ for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_3; __pyx_t_5+=1) {
+ __pyx_v_i = __pyx_t_5;
+
+ /* "View.MemoryView":1192
+ *
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1: # <<<<<<<<<<<<<<
+ * tmpslice.strides[i] = 0
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_tmpslice->shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1193
+ * for i in range(ndim):
+ * if tmpslice.shape[i] == 1:
+ * tmpslice.strides[i] = 0 # <<<<<<<<<<<<<<
+ *
+ * if slice_is_contig(src, order, ndim):
+ */
+ (__pyx_v_tmpslice->strides[__pyx_v_i]) = 0;
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1195
+ * tmpslice.strides[i] = 0
+ *
+ * if slice_is_contig(src, order, ndim): # <<<<<<<<<<<<<<
+ * memcpy(result, src.data, size)
+ * else:
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig(__pyx_v_src, __pyx_v_order, __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1196
+ *
+ * if slice_is_contig(src, order, ndim):
+ * memcpy(result, src.data, size) # <<<<<<<<<<<<<<
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ */
+ memcpy(__pyx_v_result, __pyx_v_src->data, __pyx_v_size);
+ goto __pyx_L9;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1198
+ * memcpy(result, src.data, size)
+ * else:
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize) # <<<<<<<<<<<<<<
+ *
+ * return result
+ */
+ copy_strided_to_strided(__pyx_v_src, __pyx_v_tmpslice, __pyx_v_ndim, __pyx_v_itemsize);
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1200
+ * copy_strided_to_strided(src, tmpslice, ndim, itemsize)
+ *
+ * return result # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_r = __pyx_v_result;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1162
+ *
+ * @cname('__pyx_memoryview_copy_data_to_temp')
+ * cdef void *copy_data_to_temp(__Pyx_memviewslice *src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice *tmpslice,
+ * char order,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.copy_data_to_temp", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = NULL;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+static int __pyx_memoryview_err_extents(int __pyx_v_i, Py_ssize_t __pyx_v_extent1, Py_ssize_t __pyx_v_extent2) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_extents", 0);
+
+ /* "View.MemoryView":1208
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ * (i, extent1, extent2)) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ */
+ __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_i); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __pyx_t_2 = PyInt_FromSsize_t(__pyx_v_extent1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_extent2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyTuple_New(3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+ __Pyx_GIVEREF(__pyx_t_2);
+ PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_1 = 0;
+ __pyx_t_2 = 0;
+ __pyx_t_3 = 0;
+
+ /* "View.MemoryView":1207
+ * cdef int _err_extents(int i, Py_ssize_t extent1,
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" % # <<<<<<<<<<<<<<
+ * (i, extent1, extent2))
+ *
+ */
+ __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1205
+ *
+ * @cname('__pyx_memoryview_err_extents')
+ * cdef int _err_extents(int i, Py_ssize_t extent1, # <<<<<<<<<<<<<<
+ * Py_ssize_t extent2) except -1 with gil:
+ * raise ValueError("got differing extents in dimension %d (got %d and %d)" %
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_AddTraceback("View.MemoryView._err_extents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+static int __pyx_memoryview_err_dim(PyObject *__pyx_v_error, char *__pyx_v_msg, int __pyx_v_dim) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ PyObject *__pyx_t_1 = NULL;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err_dim", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1212
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
+ * raise error(msg.decode('ascii') % dim) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_err')
+ */
+ __pyx_t_2 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_dim); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __pyx_t_4 = PyUnicode_Format(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_4);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_3 = __pyx_v_error; __pyx_t_2 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+ __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+ if (likely(__pyx_t_2)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+ __Pyx_INCREF(__pyx_t_2);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_3, function);
+ }
+ }
+ if (!__pyx_t_2) {
+ __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_GOTREF(__pyx_t_1);
+ } else {
+ __pyx_t_5 = PyTuple_New(1+1); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_5);
+ PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __Pyx_GIVEREF(__pyx_t_2); __pyx_t_2 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_5, 0+1, __pyx_t_4);
+ __Pyx_GIVEREF(__pyx_t_4);
+ __pyx_t_4 = 0;
+ __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1211
+ *
+ * @cname('__pyx_memoryview_err_dim')
+ * cdef int _err_dim(object error, char *msg, int dim) except -1 with gil: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii') % dim)
+ *
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_AddTraceback("View.MemoryView._err_dim", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+static int __pyx_memoryview_err(PyObject *__pyx_v_error, char *__pyx_v_msg) {
+ int __pyx_r;
+ __Pyx_RefNannyDeclarations
+ int __pyx_t_1;
+ PyObject *__pyx_t_2 = NULL;
+ PyObject *__pyx_t_3 = NULL;
+ PyObject *__pyx_t_4 = NULL;
+ PyObject *__pyx_t_5 = NULL;
+ PyObject *__pyx_t_6 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("_err", 0);
+ __Pyx_INCREF(__pyx_v_error);
+
+ /* "View.MemoryView":1216
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL: # <<<<<<<<<<<<<<
+ * raise error(msg.decode('ascii'))
+ * else:
+ */
+ __pyx_t_1 = ((__pyx_v_msg != NULL) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1217
+ * cdef int _err(object error, char *msg) except -1 with gil:
+ * if msg != NULL:
+ * raise error(msg.decode('ascii')) # <<<<<<<<<<<<<<
+ * else:
+ * raise error
+ */
+ __pyx_t_3 = __Pyx_decode_c_string(__pyx_v_msg, 0, strlen(__pyx_v_msg), NULL, NULL, PyUnicode_DecodeASCII); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_3);
+ __Pyx_INCREF(__pyx_v_error);
+ __pyx_t_4 = __pyx_v_error; __pyx_t_5 = NULL;
+ if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+ __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
+ if (likely(__pyx_t_5)) {
+ PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+ __Pyx_INCREF(__pyx_t_5);
+ __Pyx_INCREF(function);
+ __Pyx_DECREF_SET(__pyx_t_4, function);
+ }
+ }
+ if (!__pyx_t_5) {
+ __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+ __Pyx_GOTREF(__pyx_t_2);
+ } else {
+ __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_6);
+ PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __Pyx_GIVEREF(__pyx_t_5); __pyx_t_5 = NULL;
+ PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
+ __Pyx_GIVEREF(__pyx_t_3);
+ __pyx_t_3 = 0;
+ __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_2);
+ __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+ }
+ __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+ __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+ __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1219
+ * raise error(msg.decode('ascii'))
+ * else:
+ * raise error # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ */
+ __Pyx_Raise(__pyx_v_error, 0, 0, 0);
+ {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+
+ /* "View.MemoryView":1215
+ *
+ * @cname('__pyx_memoryview_err')
+ * cdef int _err(object error, char *msg) except -1 with gil: # <<<<<<<<<<<<<<
+ * if msg != NULL:
+ * raise error(msg.decode('ascii'))
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_2);
+ __Pyx_XDECREF(__pyx_t_3);
+ __Pyx_XDECREF(__pyx_t_4);
+ __Pyx_XDECREF(__pyx_t_5);
+ __Pyx_XDECREF(__pyx_t_6);
+ __Pyx_AddTraceback("View.MemoryView._err", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ __pyx_r = -1;
+ __Pyx_XDECREF(__pyx_v_error);
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+static int __pyx_memoryview_copy_contents(__Pyx_memviewslice __pyx_v_src, __Pyx_memviewslice __pyx_v_dst, int __pyx_v_src_ndim, int __pyx_v_dst_ndim, int __pyx_v_dtype_is_object) {
+ void *__pyx_v_tmpdata;
+ size_t __pyx_v_itemsize;
+ int __pyx_v_i;
+ char __pyx_v_order;
+ int __pyx_v_broadcasting;
+ int __pyx_v_direct_copy;
+ __Pyx_memviewslice __pyx_v_tmp;
+ int __pyx_v_ndim;
+ int __pyx_r;
+ Py_ssize_t __pyx_t_1;
+ int __pyx_t_2;
+ int __pyx_t_3;
+ int __pyx_t_4;
+ int __pyx_t_5;
+ void *__pyx_t_6;
+ int __pyx_t_7;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+
+ /* "View.MemoryView":1230
+ * Check for overlapping memory and verify the shapes.
+ * """
+ * cdef void *tmpdata = NULL # <<<<<<<<<<<<<<
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ */
+ __pyx_v_tmpdata = NULL;
+
+ /* "View.MemoryView":1231
+ * """
+ * cdef void *tmpdata = NULL
+ * cdef size_t itemsize = src.memview.view.itemsize # <<<<<<<<<<<<<<
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ */
+ __pyx_t_1 = __pyx_v_src.memview->view.itemsize;
+ __pyx_v_itemsize = __pyx_t_1;
+
+ /* "View.MemoryView":1233
+ * cdef size_t itemsize = src.memview.view.itemsize
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim) # <<<<<<<<<<<<<<
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_src), __pyx_v_src_ndim);
+
+ /* "View.MemoryView":1234
+ * cdef int i
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False # <<<<<<<<<<<<<<
+ * cdef bint direct_copy = False
+ * cdef __Pyx_memviewslice tmp
+ */
+ __pyx_v_broadcasting = 0;
+
+ /* "View.MemoryView":1235
+ * cdef char order = get_best_order(&src, src_ndim)
+ * cdef bint broadcasting = False
+ * cdef bint direct_copy = False # <<<<<<<<<<<<<<
+ * cdef __Pyx_memviewslice tmp
+ *
+ */
+ __pyx_v_direct_copy = 0;
+
+ /* "View.MemoryView":1238
+ * cdef __Pyx_memviewslice tmp
+ *
+ * if src_ndim < dst_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ */
+ __pyx_t_2 = ((__pyx_v_src_ndim < __pyx_v_dst_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1239
+ *
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_src), __pyx_v_src_ndim, __pyx_v_dst_ndim);
+ goto __pyx_L3;
+ }
+
+ /* "View.MemoryView":1240
+ * if src_ndim < dst_ndim:
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim: # <<<<<<<<<<<<<<
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ */
+ __pyx_t_2 = ((__pyx_v_dst_ndim < __pyx_v_src_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1241
+ * broadcast_leading(&src, src_ndim, dst_ndim)
+ * elif dst_ndim < src_ndim:
+ * broadcast_leading(&dst, dst_ndim, src_ndim) # <<<<<<<<<<<<<<
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ */
+ __pyx_memoryview_broadcast_leading((&__pyx_v_dst), __pyx_v_dst_ndim, __pyx_v_src_ndim);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1243
+ * broadcast_leading(&dst, dst_ndim, src_ndim)
+ *
+ * cdef int ndim = max(src_ndim, dst_ndim) # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim):
+ */
+ __pyx_t_3 = __pyx_v_dst_ndim;
+ __pyx_t_4 = __pyx_v_src_ndim;
+ if (((__pyx_t_3 > __pyx_t_4) != 0)) {
+ __pyx_t_5 = __pyx_t_3;
+ } else {
+ __pyx_t_5 = __pyx_t_4;
+ }
+ __pyx_v_ndim = __pyx_t_5;
+
+ /* "View.MemoryView":1245
+ * cdef int ndim = max(src_ndim, dst_ndim)
+ *
+ * for i in range(ndim): # <<<<<<<<<<<<<<
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ */
+ __pyx_t_5 = __pyx_v_ndim;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1246
+ *
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]: # <<<<<<<<<<<<<<
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) != (__pyx_v_dst.shape[__pyx_v_i])) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1247
+ * for i in range(ndim):
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1: # <<<<<<<<<<<<<<
+ * broadcasting = True
+ * src.strides[i] = 0
+ */
+ __pyx_t_2 = (((__pyx_v_src.shape[__pyx_v_i]) == 1) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1248
+ * if src.shape[i] != dst.shape[i]:
+ * if src.shape[i] == 1:
+ * broadcasting = True # <<<<<<<<<<<<<<
+ * src.strides[i] = 0
+ * else:
+ */
+ __pyx_v_broadcasting = 1;
+
+ /* "View.MemoryView":1249
+ * if src.shape[i] == 1:
+ * broadcasting = True
+ * src.strides[i] = 0 # <<<<<<<<<<<<<<
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ */
+ (__pyx_v_src.strides[__pyx_v_i]) = 0;
+ goto __pyx_L7;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1251
+ * src.strides[i] = 0
+ * else:
+ * _err_extents(i, dst.shape[i], src.shape[i]) # <<<<<<<<<<<<<<
+ *
+ * if src.suboffsets[i] >= 0:
+ */
+ __pyx_t_4 = __pyx_memoryview_err_extents(__pyx_v_i, (__pyx_v_dst.shape[__pyx_v_i]), (__pyx_v_src.shape[__pyx_v_i])); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ __pyx_L7:;
+ goto __pyx_L6;
+ }
+ __pyx_L6:;
+
+ /* "View.MemoryView":1253
+ * _err_extents(i, dst.shape[i], src.shape[i])
+ *
+ * if src.suboffsets[i] >= 0: # <<<<<<<<<<<<<<
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ */
+ __pyx_t_2 = (((__pyx_v_src.suboffsets[__pyx_v_i]) >= 0) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1254
+ *
+ * if src.suboffsets[i] >= 0:
+ * _err_dim(ValueError, "Dimension %d is not direct", i) # <<<<<<<<<<<<<<
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ */
+ __pyx_t_4 = __pyx_memoryview_err_dim(__pyx_builtin_ValueError, __pyx_k_Dimension_d_is_not_direct, __pyx_v_i); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L8;
+ }
+ __pyx_L8:;
+ }
+
+ /* "View.MemoryView":1256
+ * _err_dim(ValueError, "Dimension %d is not direct", i)
+ *
+ * if slices_overlap(&src, &dst, ndim, itemsize): # <<<<<<<<<<<<<<
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ */
+ __pyx_t_2 = (__pyx_slices_overlap((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1258
+ * if slices_overlap(&src, &dst, ndim, itemsize):
+ *
+ * if not slice_is_contig(&src, order, ndim): # <<<<<<<<<<<<<<
+ * order = get_best_order(&dst, ndim)
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_memviewslice_is_contig((&__pyx_v_src), __pyx_v_order, __pyx_v_ndim) != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1259
+ *
+ * if not slice_is_contig(&src, order, ndim):
+ * order = get_best_order(&dst, ndim) # <<<<<<<<<<<<<<
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ */
+ __pyx_v_order = __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim);
+ goto __pyx_L10;
+ }
+ __pyx_L10:;
+
+ /* "View.MemoryView":1261
+ * order = get_best_order(&dst, ndim)
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim) # <<<<<<<<<<<<<<
+ * src = tmp
+ *
+ */
+ __pyx_t_6 = __pyx_memoryview_copy_data_to_temp((&__pyx_v_src), (&__pyx_v_tmp), __pyx_v_order, __pyx_v_ndim); if (unlikely(__pyx_t_6 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_v_tmpdata = __pyx_t_6;
+
+ /* "View.MemoryView":1262
+ *
+ * tmpdata = copy_data_to_temp(&src, &tmp, order, ndim)
+ * src = tmp # <<<<<<<<<<<<<<
+ *
+ * if not broadcasting:
+ */
+ __pyx_v_src = __pyx_v_tmp;
+ goto __pyx_L9;
+ }
+ __pyx_L9:;
+
+ /* "View.MemoryView":1264
+ * src = tmp
+ *
+ * if not broadcasting: # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = ((!(__pyx_v_broadcasting != 0)) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1267
+ *
+ *
+ * if slice_is_contig(&src, 'C', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'C', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1268
+ *
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim) # <<<<<<<<<<<<<<
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'C', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+
+ /* "View.MemoryView":1269
+ * if slice_is_contig(&src, 'C', ndim):
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim): # <<<<<<<<<<<<<<
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ */
+ __pyx_t_2 = (__pyx_memviewslice_is_contig((&__pyx_v_src), 'F', __pyx_v_ndim) != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1270
+ * direct_copy = slice_is_contig(&dst, 'C', ndim)
+ * elif slice_is_contig(&src, 'F', ndim):
+ * direct_copy = slice_is_contig(&dst, 'F', ndim) # <<<<<<<<<<<<<<
+ *
+ * if direct_copy:
+ */
+ __pyx_v_direct_copy = __pyx_memviewslice_is_contig((&__pyx_v_dst), 'F', __pyx_v_ndim);
+ goto __pyx_L12;
+ }
+ __pyx_L12:;
+
+ /* "View.MemoryView":1272
+ * direct_copy = slice_is_contig(&dst, 'F', ndim)
+ *
+ * if direct_copy: # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_2 = (__pyx_v_direct_copy != 0);
+ if (__pyx_t_2) {
+
+ /* "View.MemoryView":1274
+ * if direct_copy:
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1275
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim)) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ */
+ memcpy(__pyx_v_dst.data, __pyx_v_src.data, __pyx_memoryview_slice_get_size((&__pyx_v_src), __pyx_v_ndim));
+
+ /* "View.MemoryView":1276
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ * free(tmpdata)
+ * return 0
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1277
+ * memcpy(dst.data, src.data, slice_get_size(&src, ndim))
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1278
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * if order == 'F' == get_best_order(&dst, ndim):
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+ }
+ goto __pyx_L11;
+ }
+ __pyx_L11:;
+
+ /* "View.MemoryView":1280
+ * return 0
+ *
+ * if order == 'F' == get_best_order(&dst, ndim): # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_2 = (__pyx_v_order == 'F');
+ if (__pyx_t_2) {
+ __pyx_t_2 = ('F' == __pyx_get_best_slice_order((&__pyx_v_dst), __pyx_v_ndim));
+ }
+ __pyx_t_7 = (__pyx_t_2 != 0);
+ if (__pyx_t_7) {
+
+ /* "View.MemoryView":1283
+ *
+ *
+ * transpose_memslice(&src) # <<<<<<<<<<<<<<
+ * transpose_memslice(&dst)
+ *
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_src)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":1284
+ *
+ * transpose_memslice(&src)
+ * transpose_memslice(&dst) # <<<<<<<<<<<<<<
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ */
+ __pyx_t_5 = __pyx_memslice_transpose((&__pyx_v_dst)); if (unlikely(__pyx_t_5 == 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ goto __pyx_L14;
+ }
+ __pyx_L14:;
+
+ /* "View.MemoryView":1286
+ * transpose_memslice(&dst)
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1287
+ *
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize) # <<<<<<<<<<<<<<
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ */
+ copy_strided_to_strided((&__pyx_v_src), (&__pyx_v_dst), __pyx_v_ndim, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1288
+ * refcount_copying(&dst, dtype_is_object, ndim, False)
+ * copy_strided_to_strided(&src, &dst, ndim, itemsize)
+ * refcount_copying(&dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ * free(tmpdata)
+ */
+ __pyx_memoryview_refcount_copying((&__pyx_v_dst), __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1290
+ * refcount_copying(&dst, dtype_is_object, ndim, True)
+ *
+ * free(tmpdata) # <<<<<<<<<<<<<<
+ * return 0
+ *
+ */
+ free(__pyx_v_tmpdata);
+
+ /* "View.MemoryView":1291
+ *
+ * free(tmpdata)
+ * return 0 # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ */
+ __pyx_r = 0;
+ goto __pyx_L0;
+
+ /* "View.MemoryView":1222
+ *
+ * @cname('__pyx_memoryview_copy_contents')
+ * cdef int memoryview_copy_contents(__Pyx_memviewslice src, # <<<<<<<<<<<<<<
+ * __Pyx_memviewslice dst,
+ * int src_ndim, int dst_ndim,
+ */
+
+ /* function exit code */
+ __pyx_L1_error:;
+ {
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_AddTraceback("View.MemoryView.memoryview_copy_contents", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+ }
+ __pyx_r = -1;
+ __pyx_L0:;
+ return __pyx_r;
+}
+
+/* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+static void __pyx_memoryview_broadcast_leading(__Pyx_memviewslice *__pyx_v_slice, int __pyx_v_ndim, int __pyx_v_ndim_other) {
+ int __pyx_v_i;
+ int __pyx_v_offset;
+ int __pyx_t_1;
+ int __pyx_t_2;
+
+ /* "View.MemoryView":1298
+ * int ndim_other) nogil:
+ * cdef int i
+ * cdef int offset = ndim_other - ndim # <<<<<<<<<<<<<<
+ *
+ * for i in range(ndim - 1, -1, -1):
+ */
+ __pyx_v_offset = (__pyx_v_ndim_other - __pyx_v_ndim);
+
+ /* "View.MemoryView":1300
+ * cdef int offset = ndim_other - ndim
+ *
+ * for i in range(ndim - 1, -1, -1): # <<<<<<<<<<<<<<
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ */
+ for (__pyx_t_1 = (__pyx_v_ndim - 1); __pyx_t_1 > -1; __pyx_t_1-=1) {
+ __pyx_v_i = __pyx_t_1;
+
+ /* "View.MemoryView":1301
+ *
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i] # <<<<<<<<<<<<<<
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ */
+ (__pyx_v_slice->shape[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->shape[__pyx_v_i]);
+
+ /* "View.MemoryView":1302
+ * for i in range(ndim - 1, -1, -1):
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ */
+ (__pyx_v_slice->strides[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->strides[__pyx_v_i]);
+
+ /* "View.MemoryView":1303
+ * slice.shape[i + offset] = slice.shape[i]
+ * slice.strides[i + offset] = slice.strides[i]
+ * slice.suboffsets[i + offset] = slice.suboffsets[i] # <<<<<<<<<<<<<<
+ *
+ * for i in range(offset):
+ */
+ (__pyx_v_slice->suboffsets[(__pyx_v_i + __pyx_v_offset)]) = (__pyx_v_slice->suboffsets[__pyx_v_i]);
+ }
+
+ /* "View.MemoryView":1305
+ * slice.suboffsets[i + offset] = slice.suboffsets[i]
+ *
+ * for i in range(offset): # <<<<<<<<<<<<<<
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ */
+ __pyx_t_1 = __pyx_v_offset;
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1306
+ *
+ * for i in range(offset):
+ * slice.shape[i] = 1 # <<<<<<<<<<<<<<
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1
+ */
+ (__pyx_v_slice->shape[__pyx_v_i]) = 1;
+
+ /* "View.MemoryView":1307
+ * for i in range(offset):
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0] # <<<<<<<<<<<<<<
+ * slice.suboffsets[i] = -1
+ *
+ */
+ (__pyx_v_slice->strides[__pyx_v_i]) = (__pyx_v_slice->strides[0]);
+
+ /* "View.MemoryView":1308
+ * slice.shape[i] = 1
+ * slice.strides[i] = slice.strides[0]
+ * slice.suboffsets[i] = -1 # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ (__pyx_v_slice->suboffsets[__pyx_v_i]) = -1;
+ }
+
+ /* "View.MemoryView":1294
+ *
+ * @cname('__pyx_memoryview_broadcast_leading')
+ * cdef void broadcast_leading(__Pyx_memviewslice *slice, # <<<<<<<<<<<<<<
+ * int ndim,
+ * int ndim_other) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+static void __pyx_memoryview_refcount_copying(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_dtype_is_object, int __pyx_v_ndim, int __pyx_v_inc) {
+ int __pyx_t_1;
+
+ /* "View.MemoryView":1320
+ *
+ *
+ * if dtype_is_object: # <<<<<<<<<<<<<<
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape,
+ * dst.strides, ndim, inc)
+ */
+ __pyx_t_1 = (__pyx_v_dtype_is_object != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1321
+ *
+ * if dtype_is_object:
+ * refcount_objects_in_slice_with_gil(dst.data, dst.shape, # <<<<<<<<<<<<<<
+ * dst.strides, ndim, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice_with_gil(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_inc);
+ goto __pyx_L3;
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1316
+ *
+ * @cname('__pyx_memoryview_refcount_copying')
+ * cdef void refcount_copying(__Pyx_memviewslice *dst, bint dtype_is_object, # <<<<<<<<<<<<<<
+ * int ndim, bint inc) nogil:
+ *
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice_with_gil(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ __Pyx_RefNannyDeclarations
+ #ifdef WITH_THREAD
+ PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
+ #endif
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice_with_gil", 0);
+
+ /* "View.MemoryView":1328
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ * refcount_objects_in_slice(data, shape, strides, ndim, inc) # <<<<<<<<<<<<<<
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, __pyx_v_shape, __pyx_v_strides, __pyx_v_ndim, __pyx_v_inc);
+
+ /* "View.MemoryView":1325
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice_with_gil')
+ * cdef void refcount_objects_in_slice_with_gil(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * bint inc) with gil:
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+ #ifdef WITH_THREAD
+ PyGILState_Release(__pyx_gilstate_save);
+ #endif
+}
+
+/* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+static void __pyx_memoryview_refcount_objects_in_slice(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, int __pyx_v_inc) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ __Pyx_RefNannyDeclarations
+ Py_ssize_t __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ int __pyx_t_3;
+ __Pyx_RefNannySetupContext("refcount_objects_in_slice", 0);
+
+ /* "View.MemoryView":1335
+ * cdef Py_ssize_t i
+ *
+ * for i in range(shape[0]): # <<<<<<<<<<<<<<
+ * if ndim == 1:
+ * if inc:
+ */
+ __pyx_t_1 = (__pyx_v_shape[0]);
+ for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+ __pyx_v_i = __pyx_t_2;
+
+ /* "View.MemoryView":1336
+ *
+ * for i in range(shape[0]):
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0])
+ */
+ __pyx_t_3 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1337
+ * for i in range(shape[0]):
+ * if ndim == 1:
+ * if inc: # <<<<<<<<<<<<<<
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ */
+ __pyx_t_3 = (__pyx_v_inc != 0);
+ if (__pyx_t_3) {
+
+ /* "View.MemoryView":1338
+ * if ndim == 1:
+ * if inc:
+ * Py_INCREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * Py_DECREF((<PyObject **> data)[0])
+ */
+ Py_INCREF((((PyObject **)__pyx_v_data)[0]));
+ goto __pyx_L6;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1340
+ * Py_INCREF((<PyObject **> data)[0])
+ * else:
+ * Py_DECREF((<PyObject **> data)[0]) # <<<<<<<<<<<<<<
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1,
+ */
+ Py_DECREF((((PyObject **)__pyx_v_data)[0]));
+ }
+ __pyx_L6:;
+ goto __pyx_L5;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1342
+ * Py_DECREF((<PyObject **> data)[0])
+ * else:
+ * refcount_objects_in_slice(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, inc)
+ *
+ */
+ __pyx_memoryview_refcount_objects_in_slice(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_inc);
+ }
+ __pyx_L5:;
+
+ /* "View.MemoryView":1345
+ * ndim - 1, inc)
+ *
+ * data += strides[0] # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + (__pyx_v_strides[0]));
+ }
+
+ /* "View.MemoryView":1331
+ *
+ * @cname('__pyx_memoryview_refcount_objects_in_slice')
+ * cdef void refcount_objects_in_slice(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim, bint inc):
+ * cdef Py_ssize_t i
+ */
+
+ /* function exit code */
+ __Pyx_RefNannyFinishContext();
+}
+
+/* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+static void __pyx_memoryview_slice_assign_scalar(__Pyx_memviewslice *__pyx_v_dst, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item, int __pyx_v_dtype_is_object) {
+
+ /* "View.MemoryView":1354
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False) # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 0);
+
+ /* "View.MemoryView":1355
+ * bint dtype_is_object) nogil:
+ * refcount_copying(dst, dtype_is_object, ndim, False)
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim, # <<<<<<<<<<<<<<
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True)
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_dst->data, __pyx_v_dst->shape, __pyx_v_dst->strides, __pyx_v_ndim, __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1357
+ * _slice_assign_scalar(dst.data, dst.shape, dst.strides, ndim,
+ * itemsize, item)
+ * refcount_copying(dst, dtype_is_object, ndim, True) # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_memoryview_refcount_copying(__pyx_v_dst, __pyx_v_dtype_is_object, __pyx_v_ndim, 1);
+
+ /* "View.MemoryView":1351
+ *
+ * @cname('__pyx_memoryview_slice_assign_scalar')
+ * cdef void slice_assign_scalar(__Pyx_memviewslice *dst, int ndim, # <<<<<<<<<<<<<<
+ * size_t itemsize, void *item,
+ * bint dtype_is_object) nogil:
+ */
+
+ /* function exit code */
+}
+
+/* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+static void __pyx_memoryview__slice_assign_scalar(char *__pyx_v_data, Py_ssize_t *__pyx_v_shape, Py_ssize_t *__pyx_v_strides, int __pyx_v_ndim, size_t __pyx_v_itemsize, void *__pyx_v_item) {
+ CYTHON_UNUSED Py_ssize_t __pyx_v_i;
+ Py_ssize_t __pyx_v_stride;
+ Py_ssize_t __pyx_v_extent;
+ int __pyx_t_1;
+ Py_ssize_t __pyx_t_2;
+ Py_ssize_t __pyx_t_3;
+
+ /* "View.MemoryView":1365
+ * size_t itemsize, void *item) nogil:
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0] # <<<<<<<<<<<<<<
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ */
+ __pyx_v_stride = (__pyx_v_strides[0]);
+
+ /* "View.MemoryView":1366
+ * cdef Py_ssize_t i
+ * cdef Py_ssize_t stride = strides[0]
+ * cdef Py_ssize_t extent = shape[0] # <<<<<<<<<<<<<<
+ *
+ * if ndim == 1:
+ */
+ __pyx_v_extent = (__pyx_v_shape[0]);
+
+ /* "View.MemoryView":1368
+ * cdef Py_ssize_t extent = shape[0]
+ *
+ * if ndim == 1: # <<<<<<<<<<<<<<
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ */
+ __pyx_t_1 = ((__pyx_v_ndim == 1) != 0);
+ if (__pyx_t_1) {
+
+ /* "View.MemoryView":1369
+ *
+ * if ndim == 1:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * memcpy(data, item, itemsize)
+ * data += stride
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1370
+ * if ndim == 1:
+ * for i in range(extent):
+ * memcpy(data, item, itemsize) # <<<<<<<<<<<<<<
+ * data += stride
+ * else:
+ */
+ memcpy(__pyx_v_data, __pyx_v_item, __pyx_v_itemsize);
+
+ /* "View.MemoryView":1371
+ * for i in range(extent):
+ * memcpy(data, item, itemsize)
+ * data += stride # <<<<<<<<<<<<<<
+ * else:
+ * for i in range(extent):
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ goto __pyx_L3;
+ }
+ /*else*/ {
+
+ /* "View.MemoryView":1373
+ * data += stride
+ * else:
+ * for i in range(extent): # <<<<<<<<<<<<<<
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ */
+ __pyx_t_2 = __pyx_v_extent;
+ for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+ __pyx_v_i = __pyx_t_3;
+
+ /* "View.MemoryView":1374
+ * else:
+ * for i in range(extent):
+ * _slice_assign_scalar(data, shape + 1, strides + 1, # <<<<<<<<<<<<<<
+ * ndim - 1, itemsize, item)
+ * data += stride
+ */
+ __pyx_memoryview__slice_assign_scalar(__pyx_v_data, (__pyx_v_shape + 1), (__pyx_v_strides + 1), (__pyx_v_ndim - 1), __pyx_v_itemsize, __pyx_v_item);
+
+ /* "View.MemoryView":1376
+ * _slice_assign_scalar(data, shape + 1, strides + 1,
+ * ndim - 1, itemsize, item)
+ * data += stride # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_v_data = (__pyx_v_data + __pyx_v_stride);
+ }
+ }
+ __pyx_L3:;
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /* function exit code */
+}
+
+static PyObject *__pyx_tp_new_array(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_array_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_array_obj *)o);
+ p->mode = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ p->_format = ((PyObject*)Py_None); Py_INCREF(Py_None);
+ if (unlikely(__pyx_array___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_array(PyObject *o) {
+ struct __pyx_array_obj *p = (struct __pyx_array_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && (!PyType_IS_GC(Py_TYPE(o)) || !_PyGC_FINALIZED(o))) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_array___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->mode);
+ Py_CLEAR(p->_format);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+static PyObject *__pyx_sq_item_array(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_array(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_array___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_tp_getattro_array(PyObject *o, PyObject *n) {
+ PyObject *v = PyObject_GenericGetAttr(o, n);
+ if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ v = __pyx_array___getattr__(o, n);
+ }
+ return v;
+}
+
+static PyObject *__pyx_getprop___pyx_array_memview(PyObject *o, CYTHON_UNUSED void *x) {
+ return get_memview(o);
+}
+
+static PyMethodDef __pyx_methods_array[] = {
+ {"__getattr__", (PyCFunction)__pyx_array___getattr__, METH_O|METH_COEXIST, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_array[] = {
+ {(char *)"memview", __pyx_getprop___pyx_array_memview, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_array = {
+ 0, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_array, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_array = {
+ 0, /*mp_length*/
+ __pyx_array___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_array, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_array = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_array_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_array = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.math.medianfilter.medianfilter.array", /*tp_name*/
+ sizeof(struct __pyx_array_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_array, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_array, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_array, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ __pyx_tp_getattro_array, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_array, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_array, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_array, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_array, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
+ struct __pyx_MemviewEnum_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_MemviewEnum_obj *)o);
+ p->name = Py_None; Py_INCREF(Py_None);
+ return o;
+}
+
+static void __pyx_tp_dealloc_Enum(PyObject *o) {
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ Py_CLEAR(p->name);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_Enum(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ if (p->name) {
+ e = (*v)(p->name, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_Enum(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_MemviewEnum_obj *p = (struct __pyx_MemviewEnum_obj *)o;
+ tmp = ((PyObject*)p->name);
+ p->name = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ return 0;
+}
+
+static PyMethodDef __pyx_methods_Enum[] = {
+ {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_MemviewEnum = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.math.medianfilter.medianfilter.Enum", /*tp_name*/
+ sizeof(struct __pyx_MemviewEnum_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_Enum, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_MemviewEnum___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_Enum, /*tp_traverse*/
+ __pyx_tp_clear_Enum, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_Enum, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ __pyx_MemviewEnum___init__, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_Enum, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
+
+static PyObject *__pyx_tp_new_memoryview(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryview_obj *p;
+ PyObject *o;
+ if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+ o = (*t->tp_alloc)(t, 0);
+ } else {
+ o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+ }
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryview_obj *)o);
+ p->__pyx_vtab = __pyx_vtabptr_memoryview;
+ p->obj = Py_None; Py_INCREF(Py_None);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ p->view.obj = NULL;
+ if (unlikely(__pyx_memoryview___cinit__(o, a, k) < 0)) {
+ Py_DECREF(o); o = 0;
+ }
+ return o;
+}
+
+static void __pyx_tp_dealloc_memoryview(PyObject *o) {
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryview___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->obj);
+ Py_CLEAR(p->_size);
+ Py_CLEAR(p->_array_interface);
+ (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_memoryview(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ if (p->obj) {
+ e = (*v)(p->obj, a); if (e) return e;
+ }
+ if (p->_size) {
+ e = (*v)(p->_size, a); if (e) return e;
+ }
+ if (p->_array_interface) {
+ e = (*v)(p->_array_interface, a); if (e) return e;
+ }
+ if (p->view.obj) {
+ e = (*v)(p->view.obj, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear_memoryview(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryview_obj *p = (struct __pyx_memoryview_obj *)o;
+ tmp = ((PyObject*)p->obj);
+ p->obj = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_size);
+ p->_size = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ tmp = ((PyObject*)p->_array_interface);
+ p->_array_interface = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ Py_CLEAR(p->view.obj);
+ return 0;
+}
+static PyObject *__pyx_sq_item_memoryview(PyObject *o, Py_ssize_t i) {
+ PyObject *r;
+ PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;
+ r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);
+ Py_DECREF(x);
+ return r;
+}
+
+static int __pyx_mp_ass_subscript_memoryview(PyObject *o, PyObject *i, PyObject *v) {
+ if (v) {
+ return __pyx_memoryview___setitem__(o, i, v);
+ }
+ else {
+ PyErr_Format(PyExc_NotImplementedError,
+ "Subscript deletion not supported by %.200s", Py_TYPE(o)->tp_name);
+ return -1;
+ }
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_T(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_transpose(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview__get__base(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_shape(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_shape(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_strides(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_strides(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_suboffsets(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_suboffsets(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_ndim(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_ndim(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_itemsize(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_itemsize(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_nbytes(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_nbytes(o);
+}
+
+static PyObject *__pyx_getprop___pyx_memoryview_size(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryview_get_size(o);
+}
+
+static PyMethodDef __pyx_methods_memoryview[] = {
+ {"is_c_contig", (PyCFunction)__pyx_memoryview_is_c_contig, METH_NOARGS, 0},
+ {"is_f_contig", (PyCFunction)__pyx_memoryview_is_f_contig, METH_NOARGS, 0},
+ {"copy", (PyCFunction)__pyx_memoryview_copy, METH_NOARGS, 0},
+ {"copy_fortran", (PyCFunction)__pyx_memoryview_copy_fortran, METH_NOARGS, 0},
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets_memoryview[] = {
+ {(char *)"T", __pyx_getprop___pyx_memoryview_T, 0, 0, 0},
+ {(char *)"base", __pyx_getprop___pyx_memoryview_base, 0, 0, 0},
+ {(char *)"shape", __pyx_getprop___pyx_memoryview_shape, 0, 0, 0},
+ {(char *)"strides", __pyx_getprop___pyx_memoryview_strides, 0, 0, 0},
+ {(char *)"suboffsets", __pyx_getprop___pyx_memoryview_suboffsets, 0, 0, 0},
+ {(char *)"ndim", __pyx_getprop___pyx_memoryview_ndim, 0, 0, 0},
+ {(char *)"itemsize", __pyx_getprop___pyx_memoryview_itemsize, 0, 0, 0},
+ {(char *)"nbytes", __pyx_getprop___pyx_memoryview_nbytes, 0, 0, 0},
+ {(char *)"size", __pyx_getprop___pyx_memoryview_size, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_memoryview = {
+ __pyx_memoryview___len__, /*sq_length*/
+ 0, /*sq_concat*/
+ 0, /*sq_repeat*/
+ __pyx_sq_item_memoryview, /*sq_item*/
+ 0, /*sq_slice*/
+ 0, /*sq_ass_item*/
+ 0, /*sq_ass_slice*/
+ 0, /*sq_contains*/
+ 0, /*sq_inplace_concat*/
+ 0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_memoryview = {
+ __pyx_memoryview___len__, /*mp_length*/
+ __pyx_memoryview___getitem__, /*mp_subscript*/
+ __pyx_mp_ass_subscript_memoryview, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_memoryview = {
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getreadbuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getwritebuffer*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getsegcount*/
+ #endif
+ #if PY_MAJOR_VERSION < 3
+ 0, /*bf_getcharbuffer*/
+ #endif
+ __pyx_memoryview_getbuffer, /*bf_getbuffer*/
+ 0, /*bf_releasebuffer*/
+};
+
+static PyTypeObject __pyx_type___pyx_memoryview = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.math.medianfilter.medianfilter.memoryview", /*tp_name*/
+ sizeof(struct __pyx_memoryview_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc_memoryview, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ __pyx_memoryview___repr__, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &__pyx_tp_as_sequence_memoryview, /*tp_as_sequence*/
+ &__pyx_tp_as_mapping_memoryview, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ __pyx_memoryview___str__, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &__pyx_tp_as_buffer_memoryview, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ __pyx_tp_traverse_memoryview, /*tp_traverse*/
+ __pyx_tp_clear_memoryview, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods_memoryview, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets_memoryview, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new_memoryview, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
+
+static PyObject *__pyx_tp_new__memoryviewslice(PyTypeObject *t, PyObject *a, PyObject *k) {
+ struct __pyx_memoryviewslice_obj *p;
+ PyObject *o = __pyx_tp_new_memoryview(t, a, k);
+ if (unlikely(!o)) return 0;
+ p = ((struct __pyx_memoryviewslice_obj *)o);
+ p->__pyx_base.__pyx_vtab = (struct __pyx_vtabstruct_memoryview*)__pyx_vtabptr__memoryviewslice;
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ p->from_slice.memview = NULL;
+ return o;
+}
+
+static void __pyx_tp_dealloc__memoryviewslice(PyObject *o) {
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ #if PY_VERSION_HEX >= 0x030400a1
+ if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+ if (PyObject_CallFinalizerFromDealloc(o)) return;
+ }
+ #endif
+ PyObject_GC_UnTrack(o);
+ {
+ PyObject *etype, *eval, *etb;
+ PyErr_Fetch(&etype, &eval, &etb);
+ ++Py_REFCNT(o);
+ __pyx_memoryviewslice___dealloc__(o);
+ --Py_REFCNT(o);
+ PyErr_Restore(etype, eval, etb);
+ }
+ Py_CLEAR(p->from_object);
+ PyObject_GC_Track(o);
+ __pyx_tp_dealloc_memoryview(o);
+}
+
+static int __pyx_tp_traverse__memoryviewslice(PyObject *o, visitproc v, void *a) {
+ int e;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ e = __pyx_tp_traverse_memoryview(o, v, a); if (e) return e;
+ if (p->from_object) {
+ e = (*v)(p->from_object, a); if (e) return e;
+ }
+ return 0;
+}
+
+static int __pyx_tp_clear__memoryviewslice(PyObject *o) {
+ PyObject* tmp;
+ struct __pyx_memoryviewslice_obj *p = (struct __pyx_memoryviewslice_obj *)o;
+ __pyx_tp_clear_memoryview(o);
+ tmp = ((PyObject*)p->from_object);
+ p->from_object = Py_None; Py_INCREF(Py_None);
+ Py_XDECREF(tmp);
+ __PYX_XDEC_MEMVIEW(&p->from_slice, 1);
+ return 0;
+}
+
+static PyObject *__pyx_getprop___pyx_memoryviewslice_base(PyObject *o, CYTHON_UNUSED void *x) {
+ return __pyx_memoryviewslice__get__base(o);
+}
+
+static PyMethodDef __pyx_methods__memoryviewslice[] = {
+ {0, 0, 0, 0}
+};
+
+static struct PyGetSetDef __pyx_getsets__memoryviewslice[] = {
+ {(char *)"base", __pyx_getprop___pyx_memoryviewslice_base, 0, 0, 0},
+ {0, 0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type___pyx_memoryviewslice = {
+ PyVarObject_HEAD_INIT(0, 0)
+ "silx.math.medianfilter.medianfilter._memoryviewslice", /*tp_name*/
+ sizeof(struct __pyx_memoryviewslice_obj), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ __pyx_tp_dealloc__memoryviewslice, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ #if PY_MAJOR_VERSION < 3
+ 0, /*tp_compare*/
+ #else
+ 0, /*reserved*/
+ #endif
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___repr__, /*tp_repr*/
+ #else
+ 0, /*tp_repr*/
+ #endif
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ #if CYTHON_COMPILING_IN_PYPY
+ __pyx_memoryview___str__, /*tp_str*/
+ #else
+ 0, /*tp_str*/
+ #endif
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ "Internal class for passing memoryview slices to Python", /*tp_doc*/
+ __pyx_tp_traverse__memoryviewslice, /*tp_traverse*/
+ __pyx_tp_clear__memoryviewslice, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ __pyx_methods__memoryviewslice, /*tp_methods*/
+ 0, /*tp_members*/
+ __pyx_getsets__memoryviewslice, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ __pyx_tp_new__memoryviewslice, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ #if PY_VERSION_HEX >= 0x030400a1
+ 0, /*tp_finalize*/
+ #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+ {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+ #if PY_VERSION_HEX < 0x03020000
+ { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+ #else
+ PyModuleDef_HEAD_INIT,
+ #endif
+ "medianfilter",
+ __pyx_k_This_module_provides_median_filt, /* m_doc */
+ -1, /* m_size */
+ __pyx_methods /* m_methods */,
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+ {&__pyx_kp_s_02_05_2017, __pyx_k_02_05_2017, sizeof(__pyx_k_02_05_2017), 0, 0, 1, 0},
+ {&__pyx_kp_s_Buffer_view_does_not_expose_stri, __pyx_k_Buffer_view_does_not_expose_stri, sizeof(__pyx_k_Buffer_view_does_not_expose_stri), 0, 0, 1, 0},
+ {&__pyx_n_s_C_CONTIGUOUS, __pyx_k_C_CONTIGUOUS, sizeof(__pyx_k_C_CONTIGUOUS), 0, 0, 1, 1},
+ {&__pyx_kp_s_Can_only_create_a_buffer_that_is, __pyx_k_Can_only_create_a_buffer_that_is, sizeof(__pyx_k_Can_only_create_a_buffer_that_is), 0, 0, 1, 0},
+ {&__pyx_kp_s_Cannot_index_with_type_s, __pyx_k_Cannot_index_with_type_s, sizeof(__pyx_k_Cannot_index_with_type_s), 0, 0, 1, 0},
+ {&__pyx_n_s_Ellipsis, __pyx_k_Ellipsis, sizeof(__pyx_k_Ellipsis), 0, 0, 1, 1},
+ {&__pyx_kp_s_Empty_shape_tuple_for_cython_arr, __pyx_k_Empty_shape_tuple_for_cython_arr, sizeof(__pyx_k_Empty_shape_tuple_for_cython_arr), 0, 0, 1, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+ {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+ {&__pyx_kp_s_H_Payno, __pyx_k_H_Payno, sizeof(__pyx_k_H_Payno), 0, 0, 1, 0},
+ {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Indirect_dimensions_not_supporte, __pyx_k_Indirect_dimensions_not_supporte, sizeof(__pyx_k_Indirect_dimensions_not_supporte), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_data_shape_Dimemsion_of, __pyx_k_Invalid_data_shape_Dimemsion_of, sizeof(__pyx_k_Invalid_data_shape_Dimemsion_of), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_mode_expected_c_or_fortr, __pyx_k_Invalid_mode_expected_c_or_fortr, sizeof(__pyx_k_Invalid_mode_expected_c_or_fortr), 0, 0, 1, 0},
+ {&__pyx_kp_s_Invalid_shape_in_axis_d_d, __pyx_k_Invalid_shape_in_axis_d_d, sizeof(__pyx_k_Invalid_shape_in_axis_d_d), 0, 0, 1, 0},
+ {&__pyx_kp_s_J_Kieffer, __pyx_k_J_Kieffer, sizeof(__pyx_k_J_Kieffer), 0, 0, 1, 0},
+ {&__pyx_n_s_MIT, __pyx_k_MIT, sizeof(__pyx_k_MIT), 0, 0, 1, 1},
+ {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+ {&__pyx_kp_s_MemoryView_of_r_at_0x_x, __pyx_k_MemoryView_of_r_at_0x_x, sizeof(__pyx_k_MemoryView_of_r_at_0x_x), 0, 0, 1, 0},
+ {&__pyx_kp_s_MemoryView_of_r_object, __pyx_k_MemoryView_of_r_object, sizeof(__pyx_k_MemoryView_of_r_object), 0, 0, 1, 0},
+ {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+ {&__pyx_n_b_O, __pyx_k_O, sizeof(__pyx_k_O), 0, 0, 0, 1},
+ {&__pyx_kp_s_Out_of_bounds_on_buffer_access_a, __pyx_k_Out_of_bounds_on_buffer_access_a, sizeof(__pyx_k_Out_of_bounds_on_buffer_access_a), 0, 0, 1, 0},
+ {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+ {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+ {&__pyx_kp_s_Unable_to_convert_item_to_object, __pyx_k_Unable_to_convert_item_to_object, sizeof(__pyx_k_Unable_to_convert_item_to_object), 0, 0, 1, 0},
+ {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+ {&__pyx_n_s_allocate_buffer, __pyx_k_allocate_buffer, sizeof(__pyx_k_allocate_buffer), 0, 0, 1, 1},
+ {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+ {&__pyx_n_s_authors, __pyx_k_authors, sizeof(__pyx_k_authors), 0, 0, 1, 1},
+ {&__pyx_n_s_base, __pyx_k_base, sizeof(__pyx_k_base), 0, 0, 1, 1},
+ {&__pyx_n_s_buffer_shape, __pyx_k_buffer_shape, sizeof(__pyx_k_buffer_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 0, 1, 1},
+ {&__pyx_n_u_c, __pyx_k_c, sizeof(__pyx_k_c), 0, 1, 0, 1},
+ {&__pyx_n_s_check, __pyx_k_check, sizeof(__pyx_k_check), 0, 0, 1, 1},
+ {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+ {&__pyx_n_s_conditional, __pyx_k_conditional, sizeof(__pyx_k_conditional), 0, 0, 1, 1},
+ {&__pyx_kp_s_contiguous_and_direct, __pyx_k_contiguous_and_direct, sizeof(__pyx_k_contiguous_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_contiguous_and_indirect, __pyx_k_contiguous_and_indirect, sizeof(__pyx_k_contiguous_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1},
+ {&__pyx_n_s_date, __pyx_k_date, sizeof(__pyx_k_date), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+ {&__pyx_n_s_dtype_is_object, __pyx_k_dtype_is_object, sizeof(__pyx_k_dtype_is_object), 0, 0, 1, 1},
+ {&__pyx_n_s_enumerate, __pyx_k_enumerate, sizeof(__pyx_k_enumerate), 0, 0, 1, 1},
+ {&__pyx_n_s_error, __pyx_k_error, sizeof(__pyx_k_error), 0, 0, 1, 1},
+ {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+ {&__pyx_n_s_float32, __pyx_k_float32, sizeof(__pyx_k_float32), 0, 0, 1, 1},
+ {&__pyx_n_s_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 0, 1, 1},
+ {&__pyx_n_s_format, __pyx_k_format, sizeof(__pyx_k_format), 0, 0, 1, 1},
+ {&__pyx_n_s_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 0, 1, 1},
+ {&__pyx_n_u_fortran, __pyx_k_fortran, sizeof(__pyx_k_fortran), 0, 1, 0, 1},
+ {&__pyx_kp_s_got_differing_extents_in_dimensi, __pyx_k_got_differing_extents_in_dimensi, sizeof(__pyx_k_got_differing_extents_in_dimensi), 0, 0, 1, 0},
+ {&__pyx_n_s_id, __pyx_k_id, sizeof(__pyx_k_id), 0, 0, 1, 1},
+ {&__pyx_n_s_image, __pyx_k_image, sizeof(__pyx_k_image), 0, 0, 1, 1},
+ {&__pyx_n_s_image_dim, __pyx_k_image_dim, sizeof(__pyx_k_image_dim), 0, 0, 1, 1},
+ {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+ {&__pyx_n_s_input_buffer, __pyx_k_input_buffer, sizeof(__pyx_k_input_buffer), 0, 0, 1, 1},
+ {&__pyx_kp_s_input_buffer_and_output_buffer_m, __pyx_k_input_buffer_and_output_buffer_m, sizeof(__pyx_k_input_buffer_and_output_buffer_m), 0, 0, 1, 0},
+ {&__pyx_kp_s_input_buffer_and_output_buffer_m_2, __pyx_k_input_buffer_and_output_buffer_m_2, sizeof(__pyx_k_input_buffer_and_output_buffer_m_2), 0, 0, 1, 0},
+ {&__pyx_kp_s_input_buffer_dimension_must_mo, __pyx_k_input_buffer_dimension_must_mo, sizeof(__pyx_k_input_buffer_dimension_must_mo), 0, 0, 1, 0},
+ {&__pyx_kp_s_input_buffer_must_be_a_C_CONTIG, __pyx_k_input_buffer_must_be_a_C_CONTIG, sizeof(__pyx_k_input_buffer_must_be_a_C_CONTIG), 0, 0, 1, 0},
+ {&__pyx_n_s_int16, __pyx_k_int16, sizeof(__pyx_k_int16), 0, 0, 1, 1},
+ {&__pyx_n_s_int32, __pyx_k_int32, sizeof(__pyx_k_int32), 0, 0, 1, 1},
+ {&__pyx_n_s_int64, __pyx_k_int64, sizeof(__pyx_k_int64), 0, 0, 1, 1},
+ {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+ {&__pyx_kp_s_itemsize_0_for_cython_array, __pyx_k_itemsize_0_for_cython_array, sizeof(__pyx_k_itemsize_0_for_cython_array), 0, 0, 1, 0},
+ {&__pyx_n_s_ker_dim, __pyx_k_ker_dim, sizeof(__pyx_k_ker_dim), 0, 0, 1, 1},
+ {&__pyx_n_s_kernel_size, __pyx_k_kernel_size, sizeof(__pyx_k_kernel_size), 0, 0, 1, 1},
+ {&__pyx_n_s_license, __pyx_k_license, sizeof(__pyx_k_license), 0, 0, 1, 1},
+ {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+ {&__pyx_n_s_medfilt, __pyx_k_medfilt, sizeof(__pyx_k_medfilt), 0, 0, 1, 1},
+ {&__pyx_n_s_medfilt1d, __pyx_k_medfilt1d, sizeof(__pyx_k_medfilt1d), 0, 0, 1, 1},
+ {&__pyx_n_s_medfilt2d, __pyx_k_medfilt2d, sizeof(__pyx_k_medfilt2d), 0, 0, 1, 1},
+ {&__pyx_n_s_medfilterfc, __pyx_k_medfilterfc, sizeof(__pyx_k_medfilterfc), 0, 0, 1, 1},
+ {&__pyx_n_s_median_filter_float32, __pyx_k_median_filter_float32, sizeof(__pyx_k_median_filter_float32), 0, 0, 1, 1},
+ {&__pyx_n_s_median_filter_float64, __pyx_k_median_filter_float64, sizeof(__pyx_k_median_filter_float64), 0, 0, 1, 1},
+ {&__pyx_n_s_median_filter_int16, __pyx_k_median_filter_int16, sizeof(__pyx_k_median_filter_int16), 0, 0, 1, 1},
+ {&__pyx_n_s_median_filter_int32, __pyx_k_median_filter_int32, sizeof(__pyx_k_median_filter_int32), 0, 0, 1, 1},
+ {&__pyx_n_s_median_filter_int64, __pyx_k_median_filter_int64, sizeof(__pyx_k_median_filter_int64), 0, 0, 1, 1},
+ {&__pyx_n_s_median_filter_uint16, __pyx_k_median_filter_uint16, sizeof(__pyx_k_median_filter_uint16), 0, 0, 1, 1},
+ {&__pyx_n_s_median_filter_uint32, __pyx_k_median_filter_uint32, sizeof(__pyx_k_median_filter_uint32), 0, 0, 1, 1},
+ {&__pyx_n_s_median_filter_uint64, __pyx_k_median_filter_uint64, sizeof(__pyx_k_median_filter_uint64), 0, 0, 1, 1},
+ {&__pyx_n_s_memview, __pyx_k_memview, sizeof(__pyx_k_memview), 0, 0, 1, 1},
+ {&__pyx_n_s_mode, __pyx_k_mode, sizeof(__pyx_k_mode), 0, 0, 1, 1},
+ {&__pyx_n_s_name, __pyx_k_name, sizeof(__pyx_k_name), 0, 0, 1, 1},
+ {&__pyx_n_s_name_2, __pyx_k_name_2, sizeof(__pyx_k_name_2), 0, 0, 1, 1},
+ {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+ {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+ {&__pyx_n_s_ndim, __pyx_k_ndim, sizeof(__pyx_k_ndim), 0, 0, 1, 1},
+ {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+ {&__pyx_n_s_obj, __pyx_k_obj, sizeof(__pyx_k_obj), 0, 0, 1, 1},
+ {&__pyx_n_s_output_buffer, __pyx_k_output_buffer, sizeof(__pyx_k_output_buffer), 0, 0, 1, 1},
+ {&__pyx_kp_s_output_buffer_dimension_must_mo, __pyx_k_output_buffer_dimension_must_mo, sizeof(__pyx_k_output_buffer_dimension_must_mo), 0, 0, 1, 0},
+ {&__pyx_kp_s_output_buffer_must_be_a_C_CONTI, __pyx_k_output_buffer_must_be_a_C_CONTI, sizeof(__pyx_k_output_buffer_must_be_a_C_CONTI), 0, 0, 1, 0},
+ {&__pyx_n_s_pack, __pyx_k_pack, sizeof(__pyx_k_pack), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_getbuffer, __pyx_k_pyx_getbuffer, sizeof(__pyx_k_pyx_getbuffer), 0, 0, 1, 1},
+ {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+ {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+ {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+ {&__pyx_n_s_reshaped, __pyx_k_reshaped, sizeof(__pyx_k_reshaped), 0, 0, 1, 1},
+ {&__pyx_kp_s_s_type_is_not_managed_by_the_me, __pyx_k_s_type_is_not_managed_by_the_me, sizeof(__pyx_k_s_type_is_not_managed_by_the_me), 0, 0, 1, 0},
+ {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+ {&__pyx_n_s_silx_math_medianfilter_medianfil, __pyx_k_silx_math_medianfilter_medianfil, sizeof(__pyx_k_silx_math_medianfilter_medianfil), 0, 0, 1, 1},
+ {&__pyx_n_s_size, __pyx_k_size, sizeof(__pyx_k_size), 0, 0, 1, 1},
+ {&__pyx_n_s_start, __pyx_k_start, sizeof(__pyx_k_start), 0, 0, 1, 1},
+ {&__pyx_n_s_step, __pyx_k_step, sizeof(__pyx_k_step), 0, 0, 1, 1},
+ {&__pyx_n_s_stop, __pyx_k_stop, sizeof(__pyx_k_stop), 0, 0, 1, 1},
+ {&__pyx_kp_s_strided_and_direct, __pyx_k_strided_and_direct, sizeof(__pyx_k_strided_and_direct), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_direct_or_indirect, __pyx_k_strided_and_direct_or_indirect, sizeof(__pyx_k_strided_and_direct_or_indirect), 0, 0, 1, 0},
+ {&__pyx_kp_s_strided_and_indirect, __pyx_k_strided_and_indirect, sizeof(__pyx_k_strided_and_indirect), 0, 0, 1, 0},
+ {&__pyx_n_s_struct, __pyx_k_struct, sizeof(__pyx_k_struct), 0, 0, 1, 1},
+ {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+ {&__pyx_n_s_uint16, __pyx_k_uint16, sizeof(__pyx_k_uint16), 0, 0, 1, 1},
+ {&__pyx_n_s_uint32, __pyx_k_uint32, sizeof(__pyx_k_uint32), 0, 0, 1, 1},
+ {&__pyx_n_s_uint64, __pyx_k_uint64, sizeof(__pyx_k_uint64), 0, 0, 1, 1},
+ {&__pyx_kp_s_unable_to_allocate_array_data, __pyx_k_unable_to_allocate_array_data, sizeof(__pyx_k_unable_to_allocate_array_data), 0, 0, 1, 0},
+ {&__pyx_kp_s_unable_to_allocate_shape_and_str, __pyx_k_unable_to_allocate_shape_and_str, sizeof(__pyx_k_unable_to_allocate_shape_and_str), 0, 0, 1, 0},
+ {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+ {&__pyx_n_s_unpack, __pyx_k_unpack, sizeof(__pyx_k_unpack), 0, 0, 1, 1},
+ {&__pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_k_users_payno_Documents_dev_esrf, sizeof(__pyx_k_users_payno_Documents_dev_esrf), 0, 0, 1, 0},
+ {&__pyx_n_s_x, __pyx_k_x, sizeof(__pyx_k_x), 0, 0, 1, 1},
+ {&__pyx_n_s_xrange, __pyx_k_xrange, sizeof(__pyx_k_xrange), 0, 0, 1, 1},
+ {&__pyx_n_s_zeros_like, __pyx_k_zeros_like, sizeof(__pyx_k_zeros_like), 0, 0, 1, 1},
+ {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+ __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 228; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_enumerate = __Pyx_GetBuiltinName(__pyx_n_s_enumerate); if (!__pyx_builtin_enumerate) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_Ellipsis = __Pyx_GetBuiltinName(__pyx_n_s_Ellipsis); if (!__pyx_builtin_Ellipsis) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 386; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION >= 3
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #else
+ __pyx_builtin_xrange = __Pyx_GetBuiltinName(__pyx_n_s_xrange); if (!__pyx_builtin_xrange) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ __pyx_builtin_id = __Pyx_GetBuiltinName(__pyx_n_s_id); if (!__pyx_builtin_id) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+ __Pyx_RefNannyDeclarations
+ __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":101
+ * reshaped = True
+ * elif len(data.shape) > 2:
+ * raise ValueError("Invalid data shape. Dimemsion of the arary should be 1 or 2") # <<<<<<<<<<<<<<
+ *
+ * # simple median filter apply into a 2D buffer
+ */
+ __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_Invalid_data_shape_Dimemsion_of); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple_);
+ __Pyx_GIVEREF(__pyx_tuple_);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":150
+ * """
+ * if (input_buffer.flags['C_CONTIGUOUS'] is False):
+ * raise ValueError('<input_buffer> must be a C_CONTIGUOUS numpy array.') # <<<<<<<<<<<<<<
+ *
+ * if (output_buffer.flags['C_CONTIGUOUS'] is False):
+ */
+ __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_input_buffer_must_be_a_C_CONTIG); if (unlikely(!__pyx_tuple__2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__2);
+ __Pyx_GIVEREF(__pyx_tuple__2);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":153
+ *
+ * if (output_buffer.flags['C_CONTIGUOUS'] is False):
+ * raise ValueError('<output_buffer> must be a C_CONTIGUOUS numpy array.') # <<<<<<<<<<<<<<
+ *
+ * if not (len(input_buffer.shape) <= 2):
+ */
+ __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_output_buffer_must_be_a_C_CONTI); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__3);
+ __Pyx_GIVEREF(__pyx_tuple__3);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":156
+ *
+ * if not (len(input_buffer.shape) <= 2):
+ * raise ValueError('<input_buffer> dimension must mo higher than 2.') # <<<<<<<<<<<<<<
+ *
+ * if not (len(output_buffer.shape) <= 2):
+ */
+ __pyx_tuple__4 = PyTuple_Pack(1, __pyx_kp_s_input_buffer_dimension_must_mo); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__4);
+ __Pyx_GIVEREF(__pyx_tuple__4);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":159
+ *
+ * if not (len(output_buffer.shape) <= 2):
+ * raise ValueError('<output_buffer> dimension must mo higher than 2.') # <<<<<<<<<<<<<<
+ *
+ * if not(input_buffer.dtype == output_buffer.dtype):
+ */
+ __pyx_tuple__5 = PyTuple_Pack(1, __pyx_kp_s_output_buffer_dimension_must_mo); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__5);
+ __Pyx_GIVEREF(__pyx_tuple__5);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":162
+ *
+ * if not(input_buffer.dtype == output_buffer.dtype):
+ * raise ValueError('input buffer and output_buffer must be of the same type') # <<<<<<<<<<<<<<
+ *
+ * if not (input_buffer.shape == output_buffer.shape):
+ */
+ __pyx_tuple__6 = PyTuple_Pack(1, __pyx_kp_s_input_buffer_and_output_buffer_m); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__6);
+ __Pyx_GIVEREF(__pyx_tuple__6);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":165
+ *
+ * if not (input_buffer.shape == output_buffer.shape):
+ * raise ValueError('input buffer and output_buffer must be of the same dimension and same dimension') # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__7 = PyTuple_Pack(1, __pyx_kp_s_input_buffer_and_output_buffer_m_2); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__7);
+ __Pyx_GIVEREF(__pyx_tuple__7);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":215
+ * if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not C contiguous") # <<<<<<<<<<<<<<
+ *
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+ __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__8);
+ __Pyx_GIVEREF(__pyx_tuple__8);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":219
+ * if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ * and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ * raise ValueError(u"ndarray is not Fortran contiguous") # <<<<<<<<<<<<<<
+ *
+ * info.buf = PyArray_DATA(self)
+ */
+ __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__9);
+ __Pyx_GIVEREF(__pyx_tuple__9);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ * if ((descr.byteorder == c'>' and little_endian) or
+ * (descr.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * if t == NPY_BYTE: f = "b"
+ * elif t == NPY_UBYTE: f = "B"
+ */
+ __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__10);
+ __Pyx_GIVEREF(__pyx_tuple__10);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ *
+ * if (end - f) - <int>(new_offset - offset[0]) < 15:
+ * raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd") # <<<<<<<<<<<<<<
+ *
+ * if ((child.byteorder == c'>' and little_endian) or
+ */
+ __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__11);
+ __Pyx_GIVEREF(__pyx_tuple__11);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ * if ((child.byteorder == c'>' and little_endian) or
+ * (child.byteorder == c'<' and not little_endian)):
+ * raise ValueError(u"Non-native byte order not supported") # <<<<<<<<<<<<<<
+ * # One could encode it in the format string and have Cython
+ * # complain instead, BUT: < and > in format strings also imply
+ */
+ __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__12);
+ __Pyx_GIVEREF(__pyx_tuple__12);
+
+ /* "../../../../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ * t = child.type_num
+ * if end - f < 5:
+ * raise RuntimeError(u"Format string allocated too short.") # <<<<<<<<<<<<<<
+ *
+ * # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+ __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__13);
+ __Pyx_GIVEREF(__pyx_tuple__13);
+
+ /* "View.MemoryView":127
+ *
+ * if not self.ndim:
+ * raise ValueError("Empty shape tuple for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if itemsize <= 0:
+ */
+ __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_Empty_shape_tuple_for_cython_arr); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__14);
+ __Pyx_GIVEREF(__pyx_tuple__14);
+
+ /* "View.MemoryView":130
+ *
+ * if itemsize <= 0:
+ * raise ValueError("itemsize <= 0 for cython.array") # <<<<<<<<<<<<<<
+ *
+ * if isinstance(format, unicode):
+ */
+ __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_itemsize_0_for_cython_array); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__15);
+ __Pyx_GIVEREF(__pyx_tuple__15);
+
+ /* "View.MemoryView":142
+ *
+ * if not self._shape:
+ * raise MemoryError("unable to allocate shape and strides.") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_shape_and_str); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__16);
+ __Pyx_GIVEREF(__pyx_tuple__16);
+
+ /* "View.MemoryView":170
+ * self.data = <char *>malloc(self.len)
+ * if not self.data:
+ * raise MemoryError("unable to allocate array data.") # <<<<<<<<<<<<<<
+ *
+ * if self.dtype_is_object:
+ */
+ __pyx_tuple__17 = PyTuple_Pack(1, __pyx_kp_s_unable_to_allocate_array_data); if (unlikely(!__pyx_tuple__17)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__17);
+ __Pyx_GIVEREF(__pyx_tuple__17);
+
+ /* "View.MemoryView":186
+ * bufmode = PyBUF_F_CONTIGUOUS | PyBUF_ANY_CONTIGUOUS
+ * if not (flags & bufmode):
+ * raise ValueError("Can only create a buffer that is contiguous in memory.") # <<<<<<<<<<<<<<
+ * info.buf = self.data
+ * info.len = self.len
+ */
+ __pyx_tuple__18 = PyTuple_Pack(1, __pyx_kp_s_Can_only_create_a_buffer_that_is); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__18);
+ __Pyx_GIVEREF(__pyx_tuple__18);
+
+ /* "View.MemoryView":445
+ * result = struct.unpack(self.view.format, bytesitem)
+ * except struct.error:
+ * raise ValueError("Unable to convert item to object") # <<<<<<<<<<<<<<
+ * else:
+ * if len(self.view.format) == 1:
+ */
+ __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_Unable_to_convert_item_to_object); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 445; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__19);
+ __Pyx_GIVEREF(__pyx_tuple__19);
+
+ /* "View.MemoryView":521
+ * if self.view.strides == NULL:
+ *
+ * raise ValueError("Buffer view does not expose strides") # <<<<<<<<<<<<<<
+ *
+ * return tuple([self.view.strides[i] for i in xrange(self.view.ndim)])
+ */
+ __pyx_tuple__20 = PyTuple_Pack(1, __pyx_kp_s_Buffer_view_does_not_expose_stri); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__20);
+ __Pyx_GIVEREF(__pyx_tuple__20);
+
+ /* "View.MemoryView":638
+ * if item is Ellipsis:
+ * if not seen_ellipsis:
+ * result.extend([slice(None)] * (ndim - len(tup) + 1)) # <<<<<<<<<<<<<<
+ * seen_ellipsis = True
+ * else:
+ */
+ __pyx_slice__21 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__21)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 638; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__21);
+ __Pyx_GIVEREF(__pyx_slice__21);
+
+ /* "View.MemoryView":641
+ * seen_ellipsis = True
+ * else:
+ * result.append(slice(None)) # <<<<<<<<<<<<<<
+ * have_slices = True
+ * else:
+ */
+ __pyx_slice__22 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__22)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 641; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__22);
+ __Pyx_GIVEREF(__pyx_slice__22);
+
+ /* "View.MemoryView":652
+ * nslices = ndim - len(result)
+ * if nslices:
+ * result.extend([slice(None)] * nslices) # <<<<<<<<<<<<<<
+ *
+ * return have_slices or nslices, tuple(result)
+ */
+ __pyx_slice__23 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__23)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 652; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_slice__23);
+ __Pyx_GIVEREF(__pyx_slice__23);
+
+ /* "View.MemoryView":660
+ * for i in range(ndim):
+ * if suboffsets[i] >= 0:
+ * raise ValueError("Indirect dimensions not supported") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_Indirect_dimensions_not_supporte); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 660; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__24);
+ __Pyx_GIVEREF(__pyx_tuple__24);
+
+ /* "silx/math/medianfilter/medianfilter.pyx":46
+ *
+ *
+ * def medfilt1d(data, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+ __pyx_tuple__25 = PyTuple_Pack(3, __pyx_n_s_data, __pyx_n_s_kernel_size, __pyx_n_s_conditional); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__25);
+ __Pyx_GIVEREF(__pyx_tuple__25);
+ __pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_medfilt1d, 46, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":63
+ *
+ *
+ * def medfilt2d(image, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+ __pyx_tuple__27 = PyTuple_Pack(3, __pyx_n_s_image, __pyx_n_s_kernel_size, __pyx_n_s_conditional); if (unlikely(!__pyx_tuple__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__27);
+ __Pyx_GIVEREF(__pyx_tuple__27);
+ __pyx_codeobj__28 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_medfilt2d, 63, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":81
+ *
+ *
+ * def medfilt(data, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+ __pyx_tuple__29 = PyTuple_Pack(7, __pyx_n_s_data, __pyx_n_s_kernel_size, __pyx_n_s_conditional, __pyx_n_s_reshaped, __pyx_n_s_output_buffer, __pyx_n_s_ker_dim, __pyx_n_s_medfilterfc); if (unlikely(!__pyx_tuple__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__29);
+ __Pyx_GIVEREF(__pyx_tuple__29);
+ __pyx_codeobj__30 = (PyObject*)__Pyx_PyCode_New(3, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__29, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_medfilt, 81, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__30)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":146
+ *
+ *
+ * def check(input_buffer, output_buffer): # <<<<<<<<<<<<<<
+ * """Simple check on the two buffers to make sure we can apply the median filter
+ * """
+ */
+ __pyx_tuple__31 = PyTuple_Pack(2, __pyx_n_s_input_buffer, __pyx_n_s_output_buffer); if (unlikely(!__pyx_tuple__31)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__31);
+ __Pyx_GIVEREF(__pyx_tuple__31);
+ __pyx_codeobj__32 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__31, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_check, 146, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":173
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_float32(float[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * float[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_tuple__33 = PyTuple_Pack(7, __pyx_n_s_input_buffer, __pyx_n_s_output_buffer, __pyx_n_s_kernel_size, __pyx_n_s_conditional, __pyx_n_s_x, __pyx_n_s_image_dim, __pyx_n_s_buffer_shape); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__33);
+ __Pyx_GIVEREF(__pyx_tuple__33);
+ __pyx_codeobj__34 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__33, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_median_filter_float32, 173, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__34)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":200
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_float64(double[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * double[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_tuple__35 = PyTuple_Pack(7, __pyx_n_s_input_buffer, __pyx_n_s_output_buffer, __pyx_n_s_kernel_size, __pyx_n_s_conditional, __pyx_n_s_x, __pyx_n_s_image_dim, __pyx_n_s_buffer_shape); if (unlikely(!__pyx_tuple__35)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__35);
+ __Pyx_GIVEREF(__pyx_tuple__35);
+ __pyx_codeobj__36 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__35, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_median_filter_float64, 200, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__36)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":227
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int64(cnumpy.int64_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int64_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_tuple__37 = PyTuple_Pack(7, __pyx_n_s_input_buffer, __pyx_n_s_output_buffer, __pyx_n_s_kernel_size, __pyx_n_s_conditional, __pyx_n_s_x, __pyx_n_s_image_dim, __pyx_n_s_buffer_shape); if (unlikely(!__pyx_tuple__37)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__37);
+ __Pyx_GIVEREF(__pyx_tuple__37);
+ __pyx_codeobj__38 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__37, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_median_filter_int64, 227, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__38)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":253
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint64( # <<<<<<<<<<<<<<
+ * cnumpy.uint64_t[:, ::1] input_buffer not None,
+ * cnumpy.uint64_t[:, ::1] output_buffer not None,
+ */
+ __pyx_tuple__39 = PyTuple_Pack(7, __pyx_n_s_input_buffer, __pyx_n_s_output_buffer, __pyx_n_s_kernel_size, __pyx_n_s_conditional, __pyx_n_s_x, __pyx_n_s_image_dim, __pyx_n_s_buffer_shape); if (unlikely(!__pyx_tuple__39)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__39);
+ __Pyx_GIVEREF(__pyx_tuple__39);
+ __pyx_codeobj__40 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__39, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_median_filter_uint64, 253, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__40)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":281
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int32(cnumpy.int32_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int32_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_tuple__41 = PyTuple_Pack(7, __pyx_n_s_input_buffer, __pyx_n_s_output_buffer, __pyx_n_s_kernel_size, __pyx_n_s_conditional, __pyx_n_s_x, __pyx_n_s_image_dim, __pyx_n_s_buffer_shape); if (unlikely(!__pyx_tuple__41)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__41);
+ __Pyx_GIVEREF(__pyx_tuple__41);
+ __pyx_codeobj__42 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__41, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_median_filter_int32, 281, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__42)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":308
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint32(cnumpy.uint32_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.uint32_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_tuple__43 = PyTuple_Pack(7, __pyx_n_s_input_buffer, __pyx_n_s_output_buffer, __pyx_n_s_kernel_size, __pyx_n_s_conditional, __pyx_n_s_x, __pyx_n_s_image_dim, __pyx_n_s_buffer_shape); if (unlikely(!__pyx_tuple__43)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__43);
+ __Pyx_GIVEREF(__pyx_tuple__43);
+ __pyx_codeobj__44 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__43, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_median_filter_uint32, 308, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":335
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int16(cnumpy.int16_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int16_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_tuple__45 = PyTuple_Pack(7, __pyx_n_s_input_buffer, __pyx_n_s_output_buffer, __pyx_n_s_kernel_size, __pyx_n_s_conditional, __pyx_n_s_x, __pyx_n_s_image_dim, __pyx_n_s_buffer_shape); if (unlikely(!__pyx_tuple__45)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__45);
+ __Pyx_GIVEREF(__pyx_tuple__45);
+ __pyx_codeobj__46 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__45, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_median_filter_int16, 335, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":362
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint16( # <<<<<<<<<<<<<<
+ * cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] input_buffer not None,
+ * cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] output_buffer not None,
+ */
+ __pyx_tuple__47 = PyTuple_Pack(7, __pyx_n_s_input_buffer, __pyx_n_s_output_buffer, __pyx_n_s_kernel_size, __pyx_n_s_conditional, __pyx_n_s_x, __pyx_n_s_image_dim, __pyx_n_s_buffer_shape); if (unlikely(!__pyx_tuple__47)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__47);
+ __Pyx_GIVEREF(__pyx_tuple__47);
+ __pyx_codeobj__48 = (PyObject*)__Pyx_PyCode_New(4, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__47, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_users_payno_Documents_dev_esrf, __pyx_n_s_median_filter_uint16, 362, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__48)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_tuple__49 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct_or_indirect); if (unlikely(!__pyx_tuple__49)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__49);
+ __Pyx_GIVEREF(__pyx_tuple__49);
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_tuple__50 = PyTuple_Pack(1, __pyx_kp_s_strided_and_direct); if (unlikely(!__pyx_tuple__50)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__50);
+ __Pyx_GIVEREF(__pyx_tuple__50);
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__51 = PyTuple_Pack(1, __pyx_kp_s_strided_and_indirect); if (unlikely(!__pyx_tuple__51)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__51);
+ __Pyx_GIVEREF(__pyx_tuple__51);
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_tuple__52 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_direct); if (unlikely(!__pyx_tuple__52)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__52);
+ __Pyx_GIVEREF(__pyx_tuple__52);
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_tuple__53 = PyTuple_Pack(1, __pyx_kp_s_contiguous_and_indirect); if (unlikely(!__pyx_tuple__53)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_tuple__53);
+ __Pyx_GIVEREF(__pyx_tuple__53);
+ __Pyx_RefNannyFinishContext();
+ return 0;
+ __pyx_L1_error:;
+ __Pyx_RefNannyFinishContext();
+ return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+ /* InitThreads.init */
+ #ifdef WITH_THREAD
+PyEval_InitThreads();
+#endif
+
+if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ return 0;
+ __pyx_L1_error:;
+ return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initmedianfilter(void); /*proto*/
+PyMODINIT_FUNC initmedianfilter(void)
+#else
+PyMODINIT_FUNC PyInit_medianfilter(void); /*proto*/
+PyMODINIT_FUNC PyInit_medianfilter(void)
+#endif
+{
+ PyObject *__pyx_t_1 = NULL;
+ int __pyx_lineno = 0;
+ const char *__pyx_filename = NULL;
+ int __pyx_clineno = 0;
+ __Pyx_RefNannyDeclarations
+ #if CYTHON_REFNANNY
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+ if (!__Pyx_RefNanny) {
+ PyErr_Clear();
+ __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+ if (!__Pyx_RefNanny)
+ Py_FatalError("failed to import 'refnanny' module");
+ }
+ #endif
+ __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_medianfilter(void)", 0);
+ if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #ifdef __Pyx_CyFunction_USED
+ if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_FusedFunction_USED
+ if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ #ifdef __Pyx_Generator_USED
+ if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ /*--- Library function declarations ---*/
+ /*--- Threads initialization code ---*/
+ #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+ #ifdef WITH_THREAD /* Python build with threading support? */
+ PyEval_InitThreads();
+ #endif
+ #endif
+ /*--- Module creation code ---*/
+ #if PY_MAJOR_VERSION < 3
+ __pyx_m = Py_InitModule4("medianfilter", __pyx_methods, __pyx_k_This_module_provides_median_filt, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+ #else
+ __pyx_m = PyModule_Create(&__pyx_moduledef);
+ #endif
+ if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ Py_INCREF(__pyx_d);
+ __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if CYTHON_COMPILING_IN_PYPY
+ Py_INCREF(__pyx_b);
+ #endif
+ if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ /*--- Initialize various global constants etc. ---*/
+ if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+ if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ #endif
+ if (__pyx_module_is_main_silx__math__medianfilter__medianfilter) {
+ if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+ }
+ #if PY_MAJOR_VERSION >= 3
+ {
+ PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ if (!PyDict_GetItemString(modules, "silx.math.medianfilter.medianfilter")) {
+ if (unlikely(PyDict_SetItemString(modules, "silx.math.medianfilter.medianfilter", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ }
+ }
+ #endif
+ /*--- Builtin init code ---*/
+ if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Constants init code ---*/
+ if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Global init code ---*/
+ generic = Py_None; Py_INCREF(Py_None);
+ strided = Py_None; Py_INCREF(Py_None);
+ indirect = Py_None; Py_INCREF(Py_None);
+ contiguous = Py_None; Py_INCREF(Py_None);
+ indirect_contiguous = Py_None; Py_INCREF(Py_None);
+ /*--- Variable export code ---*/
+ /*--- Function export code ---*/
+ /*--- Type init code ---*/
+ if (PyType_Ready(&__pyx_type___pyx_array) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_array.tp_print = 0;
+ __pyx_array_type = &__pyx_type___pyx_array;
+ if (PyType_Ready(&__pyx_type___pyx_MemviewEnum) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_MemviewEnum.tp_print = 0;
+ __pyx_MemviewEnum_type = &__pyx_type___pyx_MemviewEnum;
+ __pyx_vtabptr_memoryview = &__pyx_vtable_memoryview;
+ __pyx_vtable_memoryview.get_item_pointer = (char *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_get_item_pointer;
+ __pyx_vtable_memoryview.is_slice = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_is_slice;
+ __pyx_vtable_memoryview.setitem_slice_assignment = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_slice_assignment;
+ __pyx_vtable_memoryview.setitem_slice_assign_scalar = (PyObject *(*)(struct __pyx_memoryview_obj *, struct __pyx_memoryview_obj *, PyObject *))__pyx_memoryview_setitem_slice_assign_scalar;
+ __pyx_vtable_memoryview.setitem_indexed = (PyObject *(*)(struct __pyx_memoryview_obj *, PyObject *, PyObject *))__pyx_memoryview_setitem_indexed;
+ __pyx_vtable_memoryview.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryview_convert_item_to_object;
+ __pyx_vtable_memoryview.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryview_assign_item_from_object;
+ if (PyType_Ready(&__pyx_type___pyx_memoryview) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryview.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryview.tp_dict, __pyx_vtabptr_memoryview) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryview_type = &__pyx_type___pyx_memoryview;
+ __pyx_vtabptr__memoryviewslice = &__pyx_vtable__memoryviewslice;
+ __pyx_vtable__memoryviewslice.__pyx_base = *__pyx_vtabptr_memoryview;
+ __pyx_vtable__memoryviewslice.__pyx_base.convert_item_to_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *))__pyx_memoryviewslice_convert_item_to_object;
+ __pyx_vtable__memoryviewslice.__pyx_base.assign_item_from_object = (PyObject *(*)(struct __pyx_memoryview_obj *, char *, PyObject *))__pyx_memoryviewslice_assign_item_from_object;
+ __pyx_type___pyx_memoryviewslice.tp_base = __pyx_memoryview_type;
+ if (PyType_Ready(&__pyx_type___pyx_memoryviewslice) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_type___pyx_memoryviewslice.tp_print = 0;
+ if (__Pyx_SetVtable(__pyx_type___pyx_memoryviewslice.tp_dict, __pyx_vtabptr__memoryviewslice) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_memoryviewslice_type = &__pyx_type___pyx_memoryviewslice;
+ /*--- Type import code ---*/
+ __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type",
+ #if CYTHON_COMPILING_IN_PYPY
+ sizeof(PyTypeObject),
+ #else
+ sizeof(PyHeapTypeObject),
+ #endif
+ 0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ /*--- Variable import code ---*/
+ /*--- Function import code ---*/
+ /*--- Execution code ---*/
+
+ /* "silx/math/medianfilter/medianfilter.pyx":28
+ * """
+ *
+ * __authors__ = ["H. Payno", "J. Kieffer"] # <<<<<<<<<<<<<<
+ * __license__ = "MIT"
+ * __date__ = "02/05/2017"
+ */
+ __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_INCREF(__pyx_kp_s_H_Payno);
+ PyList_SET_ITEM(__pyx_t_1, 0, __pyx_kp_s_H_Payno);
+ __Pyx_GIVEREF(__pyx_kp_s_H_Payno);
+ __Pyx_INCREF(__pyx_kp_s_J_Kieffer);
+ PyList_SET_ITEM(__pyx_t_1, 1, __pyx_kp_s_J_Kieffer);
+ __Pyx_GIVEREF(__pyx_kp_s_J_Kieffer);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_authors, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 28; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":29
+ *
+ * __authors__ = ["H. Payno", "J. Kieffer"]
+ * __license__ = "MIT" # <<<<<<<<<<<<<<
+ * __date__ = "02/05/2017"
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_license, __pyx_n_s_MIT) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 29; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":30
+ * __authors__ = ["H. Payno", "J. Kieffer"]
+ * __license__ = "MIT"
+ * __date__ = "02/05/2017" # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_date, __pyx_kp_s_02_05_2017) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+ /* "silx/math/medianfilter/medianfilter.pyx":36
+ * cimport cython
+ * cimport median_filter
+ * import numpy # <<<<<<<<<<<<<<
+ * cimport numpy as cnumpy
+ * cdef Py_ssize_t size = 10
+ */
+ __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_numpy, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":38
+ * import numpy
+ * cimport numpy as cnumpy
+ * cdef Py_ssize_t size = 10 # <<<<<<<<<<<<<<
+ * from libcpp cimport bool
+ *
+ */
+ __pyx_v_4silx_4math_12medianfilter_12medianfilter_size = 10;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":46
+ *
+ *
+ * def medfilt1d(data, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_1medfilt1d, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_medfilt1d, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":63
+ *
+ *
+ * def medfilt2d(image, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_3medfilt2d, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_medfilt2d, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":81
+ *
+ *
+ * def medfilt(data, kernel_size=3, bool conditional=False): # <<<<<<<<<<<<<<
+ * """Function computing the median filter of the given input.
+ * Behavior at boundaries: the algorithm is reducing the size of the
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_5medfilt, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_medfilt, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":146
+ *
+ *
+ * def check(input_buffer, output_buffer): # <<<<<<<<<<<<<<
+ * """Simple check on the two buffers to make sure we can apply the median filter
+ * """
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_7check, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_check, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":173
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_float32(float[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * float[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_9_median_filter_float32, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_median_filter_float32, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":200
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_float64(double[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * double[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_11_median_filter_float64, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_median_filter_float64, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":227
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int64(cnumpy.int64_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int64_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_13_median_filter_int64, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_median_filter_int64, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":253
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint64( # <<<<<<<<<<<<<<
+ * cnumpy.uint64_t[:, ::1] input_buffer not None,
+ * cnumpy.uint64_t[:, ::1] output_buffer not None,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_15_median_filter_uint64, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_median_filter_uint64, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":281
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int32(cnumpy.int32_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int32_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_17_median_filter_int32, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_median_filter_int32, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":308
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint32(cnumpy.uint32_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.uint32_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_19_median_filter_uint32, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_median_filter_uint32, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":335
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_int16(cnumpy.int16_t[:, ::1] input_buffer not None, # <<<<<<<<<<<<<<
+ * cnumpy.int16_t[:, ::1] output_buffer not None,
+ * cnumpy.int32_t[::1] kernel_size not None,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_21_median_filter_int16, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_median_filter_int16, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":362
+ * @cython.wraparound(False)
+ * @cython.initializedcheck(False)
+ * def _median_filter_uint16( # <<<<<<<<<<<<<<
+ * cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] input_buffer not None,
+ * cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] output_buffer not None,
+ */
+ __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_4silx_4math_12medianfilter_12medianfilter_23_median_filter_uint16, NULL, __pyx_n_s_silx_math_medianfilter_medianfil); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_median_filter_uint16, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 362; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "silx/math/medianfilter/medianfilter.pyx":1
+ * # coding: utf-8 # <<<<<<<<<<<<<<
+ * # /[inserted by cython to avoid comment start]*##########################################################################
+ * #
+ */
+ __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+ /* "View.MemoryView":203
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_array_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ * def __dealloc__(array self):
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_array_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_array_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_array_type);
+
+ /* "View.MemoryView":276
+ * return self.name
+ *
+ * cdef generic = Enum("<strided and direct or indirect>") # <<<<<<<<<<<<<<
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>")
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__49, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(generic);
+ __Pyx_DECREF_SET(generic, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":277
+ *
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default # <<<<<<<<<<<<<<
+ * cdef indirect = Enum("<strided and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__50, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(strided);
+ __Pyx_DECREF_SET(strided, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":278
+ * cdef generic = Enum("<strided and direct or indirect>")
+ * cdef strided = Enum("<strided and direct>") # default
+ * cdef indirect = Enum("<strided and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__51, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect);
+ __Pyx_DECREF_SET(indirect, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":281
+ *
+ *
+ * cdef contiguous = Enum("<contiguous and direct>") # <<<<<<<<<<<<<<
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>")
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__52, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(contiguous);
+ __Pyx_DECREF_SET(contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":282
+ *
+ * cdef contiguous = Enum("<contiguous and direct>")
+ * cdef indirect_contiguous = Enum("<contiguous and indirect>") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)((PyObject *)__pyx_MemviewEnum_type)), __pyx_tuple__53, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ __Pyx_XGOTREF(indirect_contiguous);
+ __Pyx_DECREF_SET(indirect_contiguous, __pyx_t_1);
+ __Pyx_GIVEREF(__pyx_t_1);
+ __pyx_t_1 = 0;
+
+ /* "View.MemoryView":496
+ * info.obj = self
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryview_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryview_type);
+
+ /* "View.MemoryView":953
+ * return self.from_object
+ *
+ * __pyx_getbuffer = capsule(<void *> &__pyx_memoryview_getbuffer, "getbuffer(obj, view, flags)") # <<<<<<<<<<<<<<
+ *
+ *
+ */
+ __pyx_t_1 = __pyx_capsule_create(((void *)(&__pyx_memoryview_getbuffer)), __pyx_k_getbuffer_obj_view_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_GOTREF(__pyx_t_1);
+ if (PyDict_SetItem(__pyx_memoryviewslice_type->tp_dict, __pyx_n_s_pyx_getbuffer, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 953; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+ __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+ PyType_Modified(__pyx_memoryviewslice_type);
+
+ /* "View.MemoryView":1361
+ *
+ * @cname('__pyx_memoryview__slice_assign_scalar')
+ * cdef void _slice_assign_scalar(char *data, Py_ssize_t *shape, # <<<<<<<<<<<<<<
+ * Py_ssize_t *strides, int ndim,
+ * size_t itemsize, void *item) nogil:
+ */
+
+ /*--- Wrapped vars code ---*/
+
+ goto __pyx_L0;
+ __pyx_L1_error:;
+ __Pyx_XDECREF(__pyx_t_1);
+ if (__pyx_m) {
+ if (__pyx_d) {
+ __Pyx_AddTraceback("init silx.math.medianfilter.medianfilter", __pyx_clineno, __pyx_lineno, __pyx_filename);
+ }
+ Py_DECREF(__pyx_m); __pyx_m = 0;
+ } else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ImportError, "init silx.math.medianfilter.medianfilter");
+ }
+ __pyx_L0:;
+ __Pyx_RefNannyFinishContext();
+ #if PY_MAJOR_VERSION < 3
+ return;
+ #else
+ return __pyx_m;
+ #endif
+}
+
+/* Runtime support code */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+ PyObject *m = NULL, *p = NULL;
+ void *r = NULL;
+ m = PyImport_ImportModule((char *)modname);
+ if (!m) goto end;
+ p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+ if (!p) goto end;
+ r = PyLong_AsVoidPtr(p);
+end:
+ Py_XDECREF(p);
+ Py_XDECREF(m);
+ return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+ PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+ if (unlikely(!result)) {
+ PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+ "name '%U' is not defined", name);
+#else
+ "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+ }
+ return result;
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+ const char* func_name,
+ PyObject* kw_name)
+{
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION >= 3
+ "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+ #else
+ "%s() got multiple values for keyword argument '%s'", func_name,
+ PyString_AsString(kw_name));
+ #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+ PyObject *kwds,
+ PyObject **argnames[],
+ PyObject *kwds2,
+ PyObject *values[],
+ Py_ssize_t num_pos_args,
+ const char* function_name)
+{
+ PyObject *key = 0, *value = 0;
+ Py_ssize_t pos = 0;
+ PyObject*** name;
+ PyObject*** first_kw_arg = argnames + num_pos_args;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ name = first_kw_arg;
+ while (*name && (**name != key)) name++;
+ if (*name) {
+ values[name-argnames] = value;
+ continue;
+ }
+ name = first_kw_arg;
+ #if PY_MAJOR_VERSION < 3
+ if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+ while (*name) {
+ if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**name, key)) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ if ((**argname == key) || (
+ (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+ && _PyString_Eq(**argname, key))) {
+ goto arg_passed_twice;
+ }
+ argname++;
+ }
+ }
+ } else
+ #endif
+ if (likely(PyUnicode_Check(key))) {
+ while (*name) {
+ int cmp = (**name == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**name, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) {
+ values[name-argnames] = value;
+ break;
+ }
+ name++;
+ }
+ if (*name) continue;
+ else {
+ PyObject*** argname = argnames;
+ while (argname != first_kw_arg) {
+ int cmp = (**argname == key) ? 0 :
+ #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+ (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+ #endif
+ PyUnicode_Compare(**argname, key);
+ if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+ if (cmp == 0) goto arg_passed_twice;
+ argname++;
+ }
+ }
+ } else
+ goto invalid_keyword_type;
+ if (kwds2) {
+ if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+ } else {
+ goto invalid_keyword;
+ }
+ }
+ return 0;
+arg_passed_twice:
+ __Pyx_RaiseDoubleKeywordsError(function_name, key);
+ goto bad;
+invalid_keyword_type:
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings", function_name);
+ goto bad;
+invalid_keyword:
+ PyErr_Format(PyExc_TypeError,
+ #if PY_MAJOR_VERSION < 3
+ "%.200s() got an unexpected keyword argument '%.200s'",
+ function_name, PyString_AsString(key));
+ #else
+ "%s() got an unexpected keyword argument '%U'",
+ function_name, key);
+ #endif
+bad:
+ return -1;
+}
+
+static void __Pyx_RaiseArgtupleInvalid(
+ const char* func_name,
+ int exact,
+ Py_ssize_t num_min,
+ Py_ssize_t num_max,
+ Py_ssize_t num_found)
+{
+ Py_ssize_t num_expected;
+ const char *more_or_less;
+ if (num_found < num_min) {
+ num_expected = num_min;
+ more_or_less = "at least";
+ } else {
+ num_expected = num_max;
+ more_or_less = "at most";
+ }
+ if (exact) {
+ more_or_less = "exactly";
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+ func_name, more_or_less, num_expected,
+ (num_expected == 1) ? "" : "s", num_found);
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+ PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+ result = PyDict_GetItem(__pyx_d, name);
+ if (likely(result)) {
+ Py_INCREF(result);
+ } else {
+#else
+ result = PyObject_GetItem(__pyx_d, name);
+ if (!result) {
+ PyErr_Clear();
+#endif
+ result = __Pyx_GetBuiltinName(name);
+ }
+ return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+ PyObject *result;
+ ternaryfunc call = func->ob_type->tp_call;
+ if (unlikely(!call))
+ return PyObject_Call(func, arg, kw);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = (*call)(func, arg, kw);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+ PyObject *r;
+ if (!j) return NULL;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+ PyObject *r = PyList_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+ int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, i);
+ Py_INCREF(r);
+ return r;
+ }
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+ return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+ int is_list, int wraparound, int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (is_list || PyList_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+ if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+ PyObject *r = PyList_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ }
+ else if (PyTuple_CheckExact(o)) {
+ Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+ if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+ PyObject *r = PyTuple_GET_ITEM(o, n);
+ Py_INCREF(r);
+ return r;
+ }
+ } else {
+ PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+ if (likely(m && m->sq_item)) {
+ if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+ Py_ssize_t l = m->sq_length(o);
+ if (likely(l >= 0)) {
+ i += l;
+ } else {
+ if (PyErr_ExceptionMatches(PyExc_OverflowError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ }
+ return m->sq_item(o, i);
+ }
+ }
+#else
+ if (is_list || PySequence_Check(o)) {
+ return PySequence_GetItem(o, i);
+ }
+#endif
+ return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->curexc_type;
+ tmp_value = tstate->curexc_value;
+ tmp_tb = tstate->curexc_traceback;
+ tstate->curexc_type = type;
+ tstate->curexc_value = value;
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->curexc_type;
+ *value = tstate->curexc_value;
+ *tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+ CYTHON_UNUSED PyObject *cause) {
+ Py_XINCREF(type);
+ if (!value || value == Py_None)
+ value = NULL;
+ else
+ Py_INCREF(value);
+ if (!tb || tb == Py_None)
+ tb = NULL;
+ else {
+ Py_INCREF(tb);
+ if (!PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ }
+ if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+ if (!value) {
+ Py_INCREF(Py_None);
+ value = Py_None;
+ }
+#endif
+ PyErr_NormalizeException(&type, &value, &tb);
+ } else {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(type);
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ }
+ __Pyx_ErrRestore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+ PyObject* owned_instance = NULL;
+ if (tb == Py_None) {
+ tb = 0;
+ } else if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto bad;
+ }
+ if (value == Py_None)
+ value = 0;
+ if (PyExceptionInstance_Check(type)) {
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto bad;
+ }
+ value = type;
+ type = (PyObject*) Py_TYPE(value);
+ } else if (PyExceptionClass_Check(type)) {
+ PyObject *instance_class = NULL;
+ if (value && PyExceptionInstance_Check(value)) {
+ instance_class = (PyObject*) Py_TYPE(value);
+ if (instance_class != type) {
+ if (PyObject_IsSubclass(instance_class, type)) {
+ type = instance_class;
+ } else {
+ instance_class = NULL;
+ }
+ }
+ }
+ if (!instance_class) {
+ PyObject *args;
+ if (!value)
+ args = PyTuple_New(0);
+ else if (PyTuple_Check(value)) {
+ Py_INCREF(value);
+ args = value;
+ } else
+ args = PyTuple_Pack(1, value);
+ if (!args)
+ goto bad;
+ owned_instance = PyObject_Call(type, args, NULL);
+ Py_DECREF(args);
+ if (!owned_instance)
+ goto bad;
+ value = owned_instance;
+ if (!PyExceptionInstance_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "calling %R should have returned an instance of "
+ "BaseException, not %R",
+ type, Py_TYPE(value));
+ goto bad;
+ }
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto bad;
+ }
+#if PY_VERSION_HEX >= 0x03030000
+ if (cause) {
+#else
+ if (cause && cause != Py_None) {
+#endif
+ PyObject *fixed_cause;
+ if (cause == Py_None) {
+ fixed_cause = NULL;
+ } else if (PyExceptionClass_Check(cause)) {
+ fixed_cause = PyObject_CallObject(cause, NULL);
+ if (fixed_cause == NULL)
+ goto bad;
+ } else if (PyExceptionInstance_Check(cause)) {
+ fixed_cause = cause;
+ Py_INCREF(fixed_cause);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "exception causes must derive from "
+ "BaseException");
+ goto bad;
+ }
+ PyException_SetCause(value, fixed_cause);
+ }
+ PyErr_SetObject(type, value);
+ if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyErr_Fetch(tmp_type, tmp_value, tmp_tb);
+ Py_INCREF(tb);
+ PyErr_Restore(tmp_type, tmp_value, tb);
+ Py_XDECREF(tmp_tb);
+#else
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject* tmp_tb = tstate->curexc_traceback;
+ if (tb != tmp_tb) {
+ Py_INCREF(tb);
+ tstate->curexc_traceback = tb;
+ Py_XDECREF(tmp_tb);
+ }
+#endif
+ }
+bad:
+ Py_XDECREF(owned_instance);
+ return;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+ PyObject *self, *result;
+ PyCFunction cfunc;
+ cfunc = PyCFunction_GET_FUNCTION(func);
+ self = PyCFunction_GET_SELF(func);
+ if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+ return NULL;
+ result = cfunc(self, arg);
+ Py_LeaveRecursiveCall();
+ if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+ PyErr_SetString(
+ PyExc_SystemError,
+ "NULL result without error in PyObject_Call");
+ }
+ return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject *result;
+ PyObject *args = PyTuple_New(1);
+ if (unlikely(!args)) return NULL;
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(args, 0, arg);
+ result = __Pyx_PyObject_Call(func, args, NULL);
+ Py_DECREF(args);
+ return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+ if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+ if (likely(PyCFunction_Check(func))) {
+#endif
+ if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+ return __Pyx_PyObject_CallMethO(func, arg);
+ }
+ }
+ return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+ PyObject* args = PyTuple_Pack(1, arg);
+ return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static CYTHON_INLINE int __Pyx_IsLittleEndian(void) {
+ unsigned int n = 1;
+ return *(unsigned char*)(&n) != 0;
+}
+static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx,
+ __Pyx_BufFmt_StackElem* stack,
+ __Pyx_TypeInfo* type) {
+ stack[0].field = &ctx->root;
+ stack[0].parent_offset = 0;
+ ctx->root.type = type;
+ ctx->root.name = "buffer dtype";
+ ctx->root.offset = 0;
+ ctx->head = stack;
+ ctx->head->field = &ctx->root;
+ ctx->fmt_offset = 0;
+ ctx->head->parent_offset = 0;
+ ctx->new_packmode = '@';
+ ctx->enc_packmode = '@';
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ ctx->is_valid_array = 0;
+ ctx->struct_alignment = 0;
+ while (type->typegroup == 'S') {
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = 0;
+ type = type->fields->type;
+ }
+}
+static int __Pyx_BufFmt_ParseNumber(const char** ts) {
+ int count;
+ const char* t = *ts;
+ if (*t < '0' || *t > '9') {
+ return -1;
+ } else {
+ count = *t++ - '0';
+ while (*t >= '0' && *t < '9') {
+ count *= 10;
+ count += *t++ - '0';
+ }
+ }
+ *ts = t;
+ return count;
+}
+static int __Pyx_BufFmt_ExpectNumber(const char **ts) {
+ int number = __Pyx_BufFmt_ParseNumber(ts);
+ if (number == -1)
+ PyErr_Format(PyExc_ValueError,\
+ "Does not understand character buffer dtype format string ('%c')", **ts);
+ return number;
+}
+static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) {
+ PyErr_Format(PyExc_ValueError,
+ "Unexpected format string character: '%c'", ch);
+}
+static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': return "'char'";
+ case 'b': return "'signed char'";
+ case 'B': return "'unsigned char'";
+ case 'h': return "'short'";
+ case 'H': return "'unsigned short'";
+ case 'i': return "'int'";
+ case 'I': return "'unsigned int'";
+ case 'l': return "'long'";
+ case 'L': return "'unsigned long'";
+ case 'q': return "'long long'";
+ case 'Q': return "'unsigned long long'";
+ case 'f': return (is_complex ? "'complex float'" : "'float'");
+ case 'd': return (is_complex ? "'complex double'" : "'double'");
+ case 'g': return (is_complex ? "'complex long double'" : "'long double'");
+ case 'T': return "a struct";
+ case 'O': return "Python object";
+ case 'P': return "a pointer";
+ case 's': case 'p': return "a string";
+ case 0: return "end";
+ default: return "unparseable format string";
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return 2;
+ case 'i': case 'I': case 'l': case 'L': return 4;
+ case 'q': case 'Q': return 8;
+ case 'f': return (is_complex ? 8 : 4);
+ case 'd': return (is_complex ? 16 : 8);
+ case 'g': {
+ PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g')..");
+ return 0;
+ }
+ case 'O': case 'P': return sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) {
+ switch (ch) {
+ case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(short);
+ case 'i': case 'I': return sizeof(int);
+ case 'l': case 'L': return sizeof(long);
+ #ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(PY_LONG_LONG);
+ #endif
+ case 'f': return sizeof(float) * (is_complex ? 2 : 1);
+ case 'd': return sizeof(double) * (is_complex ? 2 : 1);
+ case 'g': return sizeof(long double) * (is_complex ? 2 : 1);
+ case 'O': case 'P': return sizeof(void*);
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+typedef struct { char c; short x; } __Pyx_st_short;
+typedef struct { char c; int x; } __Pyx_st_int;
+typedef struct { char c; long x; } __Pyx_st_long;
+typedef struct { char c; float x; } __Pyx_st_float;
+typedef struct { char c; double x; } __Pyx_st_double;
+typedef struct { char c; long double x; } __Pyx_st_longdouble;
+typedef struct { char c; void *x; } __Pyx_st_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { char c; PY_LONG_LONG x; } __Pyx_st_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_st_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_st_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_st_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+/* These are for computing the padding at the end of the struct to align
+ on the first member of the struct. This will probably the same as above,
+ but we don't have any guarantees.
+ */
+typedef struct { short x; char c; } __Pyx_pad_short;
+typedef struct { int x; char c; } __Pyx_pad_int;
+typedef struct { long x; char c; } __Pyx_pad_long;
+typedef struct { float x; char c; } __Pyx_pad_float;
+typedef struct { double x; char c; } __Pyx_pad_double;
+typedef struct { long double x; char c; } __Pyx_pad_longdouble;
+typedef struct { void *x; char c; } __Pyx_pad_void_p;
+#ifdef HAVE_LONG_LONG
+typedef struct { PY_LONG_LONG x; char c; } __Pyx_pad_longlong;
+#endif
+static size_t __Pyx_BufFmt_TypeCharToPadding(char ch, CYTHON_UNUSED int is_complex) {
+ switch (ch) {
+ case '?': case 'c': case 'b': case 'B': case 's': case 'p': return 1;
+ case 'h': case 'H': return sizeof(__Pyx_pad_short) - sizeof(short);
+ case 'i': case 'I': return sizeof(__Pyx_pad_int) - sizeof(int);
+ case 'l': case 'L': return sizeof(__Pyx_pad_long) - sizeof(long);
+#ifdef HAVE_LONG_LONG
+ case 'q': case 'Q': return sizeof(__Pyx_pad_longlong) - sizeof(PY_LONG_LONG);
+#endif
+ case 'f': return sizeof(__Pyx_pad_float) - sizeof(float);
+ case 'd': return sizeof(__Pyx_pad_double) - sizeof(double);
+ case 'g': return sizeof(__Pyx_pad_longdouble) - sizeof(long double);
+ case 'P': case 'O': return sizeof(__Pyx_pad_void_p) - sizeof(void*);
+ default:
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+}
+static char __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) {
+ switch (ch) {
+ case 'c':
+ return 'H';
+ case 'b': case 'h': case 'i':
+ case 'l': case 'q': case 's': case 'p':
+ return 'I';
+ case 'B': case 'H': case 'I': case 'L': case 'Q':
+ return 'U';
+ case 'f': case 'd': case 'g':
+ return (is_complex ? 'C' : 'R');
+ case 'O':
+ return 'O';
+ case 'P':
+ return 'P';
+ default: {
+ __Pyx_BufFmt_RaiseUnexpectedChar(ch);
+ return 0;
+ }
+ }
+}
+static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) {
+ if (ctx->head == NULL || ctx->head->field == &ctx->root) {
+ const char* expected;
+ const char* quote;
+ if (ctx->head == NULL) {
+ expected = "end";
+ quote = "";
+ } else {
+ expected = ctx->head->field->type->name;
+ quote = "'";
+ }
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected %s%s%s but got %s",
+ quote, expected, quote,
+ __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex));
+ } else {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_StructField* parent = (ctx->head - 1)->field;
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'",
+ field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex),
+ parent->type->name, field->name);
+ }
+}
+static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) {
+ char group;
+ size_t size, offset, arraysize = 1;
+ if (ctx->enc_type == 0) return 0;
+ if (ctx->head->field->type->arraysize[0]) {
+ int i, ndim = 0;
+ if (ctx->enc_type == 's' || ctx->enc_type == 'p') {
+ ctx->is_valid_array = ctx->head->field->type->ndim == 1;
+ ndim = 1;
+ if (ctx->enc_count != ctx->head->field->type->arraysize[0]) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %zu",
+ ctx->head->field->type->arraysize[0], ctx->enc_count);
+ return -1;
+ }
+ }
+ if (!ctx->is_valid_array) {
+ PyErr_Format(PyExc_ValueError, "Expected %d dimensions, got %d",
+ ctx->head->field->type->ndim, ndim);
+ return -1;
+ }
+ for (i = 0; i < ctx->head->field->type->ndim; i++) {
+ arraysize *= ctx->head->field->type->arraysize[i];
+ }
+ ctx->is_valid_array = 0;
+ ctx->enc_count = 1;
+ }
+ group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex);
+ do {
+ __Pyx_StructField* field = ctx->head->field;
+ __Pyx_TypeInfo* type = field->type;
+ if (ctx->enc_packmode == '@' || ctx->enc_packmode == '^') {
+ size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex);
+ } else {
+ size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex);
+ }
+ if (ctx->enc_packmode == '@') {
+ size_t align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex);
+ size_t align_mod_offset;
+ if (align_at == 0) return -1;
+ align_mod_offset = ctx->fmt_offset % align_at;
+ if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset;
+ if (ctx->struct_alignment == 0)
+ ctx->struct_alignment = __Pyx_BufFmt_TypeCharToPadding(ctx->enc_type,
+ ctx->is_complex);
+ }
+ if (type->size != size || type->typegroup != group) {
+ if (type->typegroup == 'C' && type->fields != NULL) {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ ++ctx->head;
+ ctx->head->field = type->fields;
+ ctx->head->parent_offset = parent_offset;
+ continue;
+ }
+ if ((type->typegroup == 'H' || group == 'H') && type->size == size) {
+ } else {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ }
+ offset = ctx->head->parent_offset + field->offset;
+ if (ctx->fmt_offset != offset) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer dtype mismatch; next field is at offset %" CYTHON_FORMAT_SSIZE_T "d but %" CYTHON_FORMAT_SSIZE_T "d expected",
+ (Py_ssize_t)ctx->fmt_offset, (Py_ssize_t)offset);
+ return -1;
+ }
+ ctx->fmt_offset += size;
+ if (arraysize)
+ ctx->fmt_offset += (arraysize - 1) * size;
+ --ctx->enc_count;
+ while (1) {
+ if (field == &ctx->root) {
+ ctx->head = NULL;
+ if (ctx->enc_count != 0) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return -1;
+ }
+ break;
+ }
+ ctx->head->field = ++field;
+ if (field->type == NULL) {
+ --ctx->head;
+ field = ctx->head->field;
+ continue;
+ } else if (field->type->typegroup == 'S') {
+ size_t parent_offset = ctx->head->parent_offset + field->offset;
+ if (field->type->fields->type == NULL) continue;
+ field = field->type->fields;
+ ++ctx->head;
+ ctx->head->field = field;
+ ctx->head->parent_offset = parent_offset;
+ break;
+ } else {
+ break;
+ }
+ }
+ } while (ctx->enc_count);
+ ctx->enc_type = 0;
+ ctx->is_complex = 0;
+ return 0;
+}
+static CYTHON_INLINE PyObject *
+__pyx_buffmt_parse_array(__Pyx_BufFmt_Context* ctx, const char** tsp)
+{
+ const char *ts = *tsp;
+ int i = 0, number;
+ int ndim = ctx->head->field->type->ndim;
+;
+ ++ts;
+ if (ctx->new_count != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot handle repeated arrays in format string");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ while (*ts && *ts != ')') {
+ switch (*ts) {
+ case ' ': case '\f': case '\r': case '\n': case '\t': case '\v': continue;
+ default: break;
+ }
+ number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ if (i < ndim && (size_t) number != ctx->head->field->type->arraysize[i])
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a dimension of size %zu, got %d",
+ ctx->head->field->type->arraysize[i], number);
+ if (*ts != ',' && *ts != ')')
+ return PyErr_Format(PyExc_ValueError,
+ "Expected a comma in format string, got '%c'", *ts);
+ if (*ts == ',') ts++;
+ i++;
+ }
+ if (i != ndim)
+ return PyErr_Format(PyExc_ValueError, "Expected %d dimension(s), got %d",
+ ctx->head->field->type->ndim, i);
+ if (!*ts) {
+ PyErr_SetString(PyExc_ValueError,
+ "Unexpected end of format string, expected ')'");
+ return NULL;
+ }
+ ctx->is_valid_array = 1;
+ ctx->new_count = 1;
+ *tsp = ++ts;
+ return Py_None;
+}
+static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) {
+ int got_Z = 0;
+ while (1) {
+ switch(*ts) {
+ case 0:
+ if (ctx->enc_type != 0 && ctx->head == NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ if (ctx->head != NULL) {
+ __Pyx_BufFmt_RaiseExpected(ctx);
+ return NULL;
+ }
+ return ts;
+ case ' ':
+ case '\r':
+ case '\n':
+ ++ts;
+ break;
+ case '<':
+ if (!__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '>':
+ case '!':
+ if (__Pyx_IsLittleEndian()) {
+ PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler");
+ return NULL;
+ }
+ ctx->new_packmode = '=';
+ ++ts;
+ break;
+ case '=':
+ case '@':
+ case '^':
+ ctx->new_packmode = *ts++;
+ break;
+ case 'T':
+ {
+ const char* ts_after_sub;
+ size_t i, struct_count = ctx->new_count;
+ size_t struct_alignment = ctx->struct_alignment;
+ ctx->new_count = 1;
+ ++ts;
+ if (*ts != '{') {
+ PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'");
+ return NULL;
+ }
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ ctx->enc_count = 0;
+ ctx->struct_alignment = 0;
+ ++ts;
+ ts_after_sub = ts;
+ for (i = 0; i != struct_count; ++i) {
+ ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts);
+ if (!ts_after_sub) return NULL;
+ }
+ ts = ts_after_sub;
+ if (struct_alignment) ctx->struct_alignment = struct_alignment;
+ }
+ break;
+ case '}':
+ {
+ size_t alignment = ctx->struct_alignment;
+ ++ts;
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_type = 0;
+ if (alignment && ctx->fmt_offset % alignment) {
+ ctx->fmt_offset += alignment - (ctx->fmt_offset % alignment);
+ }
+ }
+ return ts;
+ case 'x':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->fmt_offset += ctx->new_count;
+ ctx->new_count = 1;
+ ctx->enc_count = 0;
+ ctx->enc_type = 0;
+ ctx->enc_packmode = ctx->new_packmode;
+ ++ts;
+ break;
+ case 'Z':
+ got_Z = 1;
+ ++ts;
+ if (*ts != 'f' && *ts != 'd' && *ts != 'g') {
+ __Pyx_BufFmt_RaiseUnexpectedChar('Z');
+ return NULL;
+ }
+ case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I':
+ case 'l': case 'L': case 'q': case 'Q':
+ case 'f': case 'd': case 'g':
+ case 'O': case 'p':
+ if (ctx->enc_type == *ts && got_Z == ctx->is_complex &&
+ ctx->enc_packmode == ctx->new_packmode) {
+ ctx->enc_count += ctx->new_count;
+ ctx->new_count = 1;
+ got_Z = 0;
+ ++ts;
+ break;
+ }
+ case 's':
+ if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL;
+ ctx->enc_count = ctx->new_count;
+ ctx->enc_packmode = ctx->new_packmode;
+ ctx->enc_type = *ts;
+ ctx->is_complex = got_Z;
+ ++ts;
+ ctx->new_count = 1;
+ got_Z = 0;
+ break;
+ case ':':
+ ++ts;
+ while(*ts != ':') ++ts;
+ ++ts;
+ break;
+ case '(':
+ if (!__pyx_buffmt_parse_array(ctx, &ts)) return NULL;
+ break;
+ default:
+ {
+ int number = __Pyx_BufFmt_ExpectNumber(&ts);
+ if (number == -1) return NULL;
+ ctx->new_count = (size_t)number;
+ }
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
+ buf->buf = NULL;
+ buf->obj = NULL;
+ buf->strides = __Pyx_zeros;
+ buf->shape = __Pyx_zeros;
+ buf->suboffsets = __Pyx_minusones;
+}
+static CYTHON_INLINE int __Pyx_GetBufferAndValidate(
+ Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags,
+ int nd, int cast, __Pyx_BufFmt_StackElem* stack)
+{
+ if (obj == Py_None || obj == NULL) {
+ __Pyx_ZeroBuffer(buf);
+ return 0;
+ }
+ buf->buf = NULL;
+ if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
+ if (buf->ndim != nd) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ nd, buf->ndim);
+ goto fail;
+ }
+ if (!cast) {
+ __Pyx_BufFmt_Context ctx;
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned)buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "d byte%s) does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "d byte%s)",
+ buf->itemsize, (buf->itemsize > 1) ? "s" : "",
+ dtype->name, (Py_ssize_t)dtype->size, (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
+ return 0;
+fail:;
+ __Pyx_ZeroBuffer(buf);
+ return -1;
+}
+static CYTHON_INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
+ if (info->buf == NULL) return;
+ if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
+ __Pyx_ReleaseBuffer(info);
+}
+
+static int
+__Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
+ int ndim,
+ __Pyx_memviewslice *memviewslice,
+ int memview_is_new_reference)
+{
+ __Pyx_RefNannyDeclarations
+ int i, retval=-1;
+ Py_buffer *buf = &memview->view;
+ __Pyx_RefNannySetupContext("init_memviewslice", 0);
+ if (!buf) {
+ PyErr_SetString(PyExc_ValueError,
+ "buf is NULL.");
+ goto fail;
+ } else if (memviewslice->memview || memviewslice->data) {
+ PyErr_SetString(PyExc_ValueError,
+ "memviewslice is already initialized!");
+ goto fail;
+ }
+ if (buf->strides) {
+ for (i = 0; i < ndim; i++) {
+ memviewslice->strides[i] = buf->strides[i];
+ }
+ } else {
+ Py_ssize_t stride = buf->itemsize;
+ for (i = ndim - 1; i >= 0; i--) {
+ memviewslice->strides[i] = stride;
+ stride *= buf->shape[i];
+ }
+ }
+ for (i = 0; i < ndim; i++) {
+ memviewslice->shape[i] = buf->shape[i];
+ if (buf->suboffsets) {
+ memviewslice->suboffsets[i] = buf->suboffsets[i];
+ } else {
+ memviewslice->suboffsets[i] = -1;
+ }
+ }
+ memviewslice->memview = memview;
+ memviewslice->data = (char *)buf->buf;
+ if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
+ Py_INCREF(memview);
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ memviewslice->memview = 0;
+ memviewslice->data = 0;
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+static CYTHON_INLINE void __pyx_fatalerror(const char *fmt, ...) {
+ va_list vargs;
+ char msg[200];
+ va_start(vargs, fmt);
+#ifdef HAVE_STDARG_PROTOTYPES
+ va_start(vargs, fmt);
+#else
+ va_start(vargs);
+#endif
+ vsnprintf(msg, 200, fmt, vargs);
+ Py_FatalError(msg);
+ va_end(vargs);
+}
+static CYTHON_INLINE int
+__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)++;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE int
+__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
+ PyThread_type_lock lock)
+{
+ int result;
+ PyThread_acquire_lock(lock, 1);
+ result = (*acquisition_count)--;
+ PyThread_release_lock(lock);
+ return result;
+}
+static CYTHON_INLINE void
+__Pyx_INC_MEMVIEW(__Pyx_memviewslice *memslice, int have_gil, int lineno)
+{
+ int first_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview || (PyObject *) memview == Py_None)
+ return;
+ if (__pyx_get_slice_count(memview) < 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ first_time = __pyx_add_acquisition_count(memview) == 0;
+ if (first_time) {
+ if (have_gil) {
+ Py_INCREF((PyObject *) memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_INCREF((PyObject *) memview);
+ PyGILState_Release(_gilstate);
+ }
+ }
+}
+static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW(__Pyx_memviewslice *memslice,
+ int have_gil, int lineno) {
+ int last_time;
+ struct __pyx_memoryview_obj *memview = memslice->memview;
+ if (!memview ) {
+ return;
+ } else if ((PyObject *) memview == Py_None) {
+ memslice->memview = NULL;
+ return;
+ }
+ if (__pyx_get_slice_count(memview) <= 0)
+ __pyx_fatalerror("Acquisition count is %d (line %d)",
+ __pyx_get_slice_count(memview), lineno);
+ last_time = __pyx_sub_acquisition_count(memview) == 1;
+ memslice->data = NULL;
+ if (last_time) {
+ if (have_gil) {
+ Py_CLEAR(memslice->memview);
+ } else {
+ PyGILState_STATE _gilstate = PyGILState_Ensure();
+ Py_CLEAR(memslice->memview);
+ PyGILState_Release(_gilstate);
+ }
+ } else {
+ memslice->memview = NULL;
+ }
+}
+
+static void __Pyx_RaiseArgumentTypeInvalid(const char* name, PyObject *obj, PyTypeObject *type) {
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%.200s' has incorrect type (expected %.200s, got %.200s)",
+ name, type->tp_name, Py_TYPE(obj)->tp_name);
+}
+static CYTHON_INLINE int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
+ const char *name, int exact)
+{
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (none_allowed && obj == Py_None) return 1;
+ else if (exact) {
+ if (likely(Py_TYPE(obj) == type)) return 1;
+ #if PY_MAJOR_VERSION == 2
+ else if ((type == &PyBaseString_Type) && likely(__Pyx_PyBaseString_CheckExact(obj))) return 1;
+ #endif
+ }
+ else {
+ if (likely(PyObject_TypeCheck(obj, type))) return 1;
+ }
+ __Pyx_RaiseArgumentTypeInvalid(name, obj, type);
+ return 0;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+ PyErr_Format(PyExc_ValueError,
+ "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+ PyErr_Format(PyExc_ValueError,
+ "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+ index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+ PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (unlikely(!type)) {
+ PyErr_SetString(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (likely(PyObject_TypeCheck(obj, type)))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %.200s to %.200s",
+ Py_TYPE(obj)->tp_name, type->tp_name);
+ return 0;
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+ if (s1 == s2) {
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ const char *ps1, *ps2;
+ Py_ssize_t length = PyBytes_GET_SIZE(s1);
+ if (length != PyBytes_GET_SIZE(s2))
+ return (equals == Py_NE);
+ ps1 = PyBytes_AS_STRING(s1);
+ ps2 = PyBytes_AS_STRING(s2);
+ if (ps1[0] != ps2[0]) {
+ return (equals == Py_NE);
+ } else if (length == 1) {
+ return (equals == Py_EQ);
+ } else {
+ int result = memcmp(ps1, ps2, (size_t)length);
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+ return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+ PyObject* owned_ref = NULL;
+#endif
+ int s1_is_unicode, s2_is_unicode;
+ if (s1 == s2) {
+ goto return_eq;
+ }
+ s1_is_unicode = PyUnicode_CheckExact(s1);
+ s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+ if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+ owned_ref = PyUnicode_FromObject(s2);
+ if (unlikely(!owned_ref))
+ return -1;
+ s2 = owned_ref;
+ s2_is_unicode = 1;
+ } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+ owned_ref = PyUnicode_FromObject(s1);
+ if (unlikely(!owned_ref))
+ return -1;
+ s1 = owned_ref;
+ s1_is_unicode = 1;
+ } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+ return __Pyx_PyBytes_Equals(s1, s2, equals);
+ }
+#endif
+ if (s1_is_unicode & s2_is_unicode) {
+ Py_ssize_t length;
+ int kind;
+ void *data1, *data2;
+ if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+ return -1;
+ length = __Pyx_PyUnicode_GET_LENGTH(s1);
+ if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+ goto return_ne;
+ }
+ kind = __Pyx_PyUnicode_KIND(s1);
+ if (kind != __Pyx_PyUnicode_KIND(s2)) {
+ goto return_ne;
+ }
+ data1 = __Pyx_PyUnicode_DATA(s1);
+ data2 = __Pyx_PyUnicode_DATA(s2);
+ if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+ goto return_ne;
+ } else if (length == 1) {
+ goto return_eq;
+ } else {
+ int result = memcmp(data1, data2, (size_t)(length * kind));
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & s2_is_unicode) {
+ goto return_ne;
+ } else if ((s2 == Py_None) & s1_is_unicode) {
+ goto return_ne;
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+return_eq:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_EQ);
+return_ne:
+ #if PY_MAJOR_VERSION < 3
+ Py_XDECREF(owned_ref);
+ #endif
+ return (equals == Py_NE);
+#endif
+}
+
+static CYTHON_INLINE Py_ssize_t __Pyx_div_Py_ssize_t(Py_ssize_t a, Py_ssize_t b) {
+ Py_ssize_t q = a / b;
+ Py_ssize_t r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) {
+#if CYTHON_COMPILING_IN_CPYTHON
+#if PY_MAJOR_VERSION >= 3
+ if (likely(PyUnicode_Check(n)))
+#else
+ if (likely(PyString_Check(n)))
+#endif
+ return __Pyx_PyObject_GetAttrStr(o, n);
+#endif
+ return PyObject_GetAttr(o, n);
+}
+
+static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
+ const char* cstring, Py_ssize_t start, Py_ssize_t stop,
+ const char* encoding, const char* errors,
+ PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
+ Py_ssize_t length;
+ if (unlikely((start < 0) | (stop < 0))) {
+ length = strlen(cstring);
+ if (start < 0) {
+ start += length;
+ if (start < 0)
+ start = 0;
+ }
+ if (stop < 0)
+ stop += length;
+ }
+ length = stop - start;
+ if (unlikely(length <= 0))
+ return PyUnicode_FromUnicode(NULL, 0);
+ cstring += start;
+ if (decode_func) {
+ return decode_func(cstring, length, errors);
+ } else {
+ return PyUnicode_Decode(cstring, length, encoding, errors);
+ }
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ *type = tstate->exc_type;
+ *value = tstate->exc_value;
+ *tb = tstate->exc_traceback;
+ Py_XINCREF(*type);
+ Py_XINCREF(*value);
+ Py_XINCREF(*tb);
+#else
+ PyErr_GetExcInfo(type, value, tb);
+#endif
+}
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = type;
+ tstate->exc_value = value;
+ tstate->exc_traceback = tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(type, value, tb);
+#endif
+}
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *local_type, *local_value, *local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+ PyThreadState *tstate = PyThreadState_GET();
+ local_type = tstate->curexc_type;
+ local_value = tstate->curexc_value;
+ local_tb = tstate->curexc_traceback;
+ tstate->curexc_type = 0;
+ tstate->curexc_value = 0;
+ tstate->curexc_traceback = 0;
+#else
+ PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+ PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+ if (unlikely(tstate->curexc_type))
+#else
+ if (unlikely(PyErr_Occurred()))
+#endif
+ goto bad;
+ #if PY_MAJOR_VERSION >= 3
+ if (local_tb) {
+ if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+ goto bad;
+ }
+ #endif
+ Py_XINCREF(local_tb);
+ Py_XINCREF(local_type);
+ Py_XINCREF(local_value);
+ *type = local_type;
+ *value = local_value;
+ *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = local_type;
+ tstate->exc_value = local_value;
+ tstate->exc_traceback = local_tb;
+ Py_XDECREF(tmp_type);
+ Py_XDECREF(tmp_value);
+ Py_XDECREF(tmp_tb);
+#else
+ PyErr_SetExcInfo(local_type, local_value, local_tb);
+#endif
+ return 0;
+bad:
+ *type = 0;
+ *value = 0;
+ *tb = 0;
+ Py_XDECREF(local_type);
+ Py_XDECREF(local_value);
+ Py_XDECREF(local_tb);
+ return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+ PyObject *tmp_type, *tmp_value, *tmp_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+ PyThreadState *tstate = PyThreadState_GET();
+ tmp_type = tstate->exc_type;
+ tmp_value = tstate->exc_value;
+ tmp_tb = tstate->exc_traceback;
+ tstate->exc_type = *type;
+ tstate->exc_value = *value;
+ tstate->exc_traceback = *tb;
+#else
+ PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+ PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+ *type = tmp_type;
+ *value = tmp_value;
+ *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
+ PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+ long q = a / b;
+ long r = a - q*b;
+ q -= ((r != 0) & ((r ^ b) < 0));
+ return q;
+}
+
+static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
+ CYTHON_UNUSED int lineno, CYTHON_UNUSED const char *filename,
+ int full_traceback) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
+ if (full_traceback) {
+ Py_XINCREF(old_exc);
+ Py_XINCREF(old_val);
+ Py_XINCREF(old_tb);
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ PyErr_PrintEx(1);
+ }
+ #if PY_MAJOR_VERSION < 3
+ ctx = PyString_FromString(name);
+ #else
+ ctx = PyUnicode_FromString(name);
+ #endif
+ __Pyx_ErrRestore(old_exc, old_val, old_tb);
+ if (!ctx) {
+ PyErr_WriteUnraisable(Py_None);
+ } else {
+ PyErr_WriteUnraisable(ctx);
+ Py_DECREF(ctx);
+ }
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+ PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+ PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
+#endif
+ if (!ob)
+ goto bad;
+ if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+ goto bad;
+ Py_DECREF(ob);
+ return 0;
+bad:
+ Py_XDECREF(ob);
+ return -1;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+ int start = 0, mid = 0, end = count - 1;
+ if (end >= 0 && code_line > entries[end].code_line) {
+ return count;
+ }
+ while (start < end) {
+ mid = (start + end) / 2;
+ if (code_line < entries[mid].code_line) {
+ end = mid;
+ } else if (code_line > entries[mid].code_line) {
+ start = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ if (code_line <= entries[mid].code_line) {
+ return mid;
+ } else {
+ return mid + 1;
+ }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+ PyCodeObject* code_object;
+ int pos;
+ if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+ return NULL;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+ return NULL;
+ }
+ code_object = __pyx_code_cache.entries[pos].code_object;
+ Py_INCREF(code_object);
+ return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+ int pos, i;
+ __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+ if (unlikely(!code_line)) {
+ return;
+ }
+ if (unlikely(!entries)) {
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (likely(entries)) {
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = 64;
+ __pyx_code_cache.count = 1;
+ entries[0].code_line = code_line;
+ entries[0].code_object = code_object;
+ Py_INCREF(code_object);
+ }
+ return;
+ }
+ pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+ if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+ PyCodeObject* tmp = entries[pos].code_object;
+ entries[pos].code_object = code_object;
+ Py_DECREF(tmp);
+ return;
+ }
+ if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+ int new_max = __pyx_code_cache.max_count + 64;
+ entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+ __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+ if (unlikely(!entries)) {
+ return;
+ }
+ __pyx_code_cache.entries = entries;
+ __pyx_code_cache.max_count = new_max;
+ }
+ for (i=__pyx_code_cache.count; i>pos; i--) {
+ entries[i] = entries[i-1];
+ }
+ entries[pos].code_line = code_line;
+ entries[pos].code_object = code_object;
+ __pyx_code_cache.count++;
+ Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+ const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ #if PY_MAJOR_VERSION < 3
+ py_srcfile = PyString_FromString(filename);
+ #else
+ py_srcfile = PyUnicode_FromString(filename);
+ #endif
+ if (!py_srcfile) goto bad;
+ if (c_line) {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #else
+ py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+ #endif
+ }
+ else {
+ #if PY_MAJOR_VERSION < 3
+ py_funcname = PyString_FromString(funcname);
+ #else
+ py_funcname = PyUnicode_FromString(funcname);
+ #endif
+ }
+ if (!py_funcname) goto bad;
+ py_code = __Pyx_PyCode_New(
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ __pyx_empty_bytes, /*PyObject *code,*/
+ __pyx_empty_tuple, /*PyObject *consts,*/
+ __pyx_empty_tuple, /*PyObject *names,*/
+ __pyx_empty_tuple, /*PyObject *varnames,*/
+ __pyx_empty_tuple, /*PyObject *freevars,*/
+ __pyx_empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ py_line,
+ __pyx_empty_bytes /*PyObject *lnotab*/
+ );
+ Py_DECREF(py_srcfile);
+ Py_DECREF(py_funcname);
+ return py_code;
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ return NULL;
+}
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+ int py_line, const char *filename) {
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+ py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+ if (!py_code) {
+ py_code = __Pyx_CreateCodeObjectForTraceback(
+ funcname, c_line, py_line, filename);
+ if (!py_code) goto bad;
+ __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+ }
+ py_frame = PyFrame_New(
+ PyThreadState_GET(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ __pyx_d, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = py_line;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+
+#if PY_MAJOR_VERSION < 3
+static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
+ if (PyObject_CheckBuffer(obj)) return PyObject_GetBuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pw_5numpy_7ndarray_1__getbuffer__(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_array_type)) return __pyx_array_getbuffer(obj, view, flags);
+ if (PyObject_TypeCheck(obj, __pyx_memoryview_type)) return __pyx_memoryview_getbuffer(obj, view, flags);
+ PyErr_Format(PyExc_TypeError, "'%.200s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
+ return -1;
+}
+static void __Pyx_ReleaseBuffer(Py_buffer *view) {
+ PyObject *obj = view->obj;
+ if (!obj) return;
+ if (PyObject_CheckBuffer(obj)) {
+ PyBuffer_Release(view);
+ return;
+ }
+ if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) { __pyx_pw_5numpy_7ndarray_3__releasebuffer__(obj, view); return; }
+ Py_DECREF(obj);
+ view->obj = NULL;
+}
+#endif
+
+
+ static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_import;
+ py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+ if (!py_import)
+ goto bad;
+ #endif
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(__pyx_m);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ {
+ #if PY_MAJOR_VERSION >= 3
+ if (level == -1) {
+ if (strchr(__Pyx_MODULE_NAME, '.')) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(1);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, 1);
+ #endif
+ if (!module) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ goto bad;
+ PyErr_Clear();
+ }
+ }
+ level = 0;
+ }
+ #endif
+ if (!module) {
+ #if PY_VERSION_HEX < 0x03030000
+ PyObject *py_level = PyInt_FromLong(level);
+ if (!py_level)
+ goto bad;
+ module = PyObject_CallFunctionObjArgs(py_import,
+ name, global_dict, empty_dict, list, py_level, NULL);
+ Py_DECREF(py_level);
+ #else
+ module = PyImport_ImportModuleLevelObject(
+ name, global_dict, empty_dict, list, level);
+ #endif
+ }
+ }
+bad:
+ #if PY_VERSION_HEX < 0x03030000
+ Py_XDECREF(py_import);
+ #endif
+ Py_XDECREF(empty_list);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+
+static int
+__pyx_typeinfo_cmp(__Pyx_TypeInfo *a, __Pyx_TypeInfo *b)
+{
+ int i;
+ if (!a || !b)
+ return 0;
+ if (a == b)
+ return 1;
+ if (a->size != b->size || a->typegroup != b->typegroup ||
+ a->is_unsigned != b->is_unsigned || a->ndim != b->ndim) {
+ if (a->typegroup == 'H' || b->typegroup == 'H') {
+ return a->size == b->size;
+ } else {
+ return 0;
+ }
+ }
+ if (a->ndim) {
+ for (i = 0; i < a->ndim; i++)
+ if (a->arraysize[i] != b->arraysize[i])
+ return 0;
+ }
+ if (a->typegroup == 'S') {
+ if (a->flags != b->flags)
+ return 0;
+ if (a->fields || b->fields) {
+ if (!(a->fields && b->fields))
+ return 0;
+ for (i = 0; a->fields[i].type && b->fields[i].type; i++) {
+ __Pyx_StructField *field_a = a->fields + i;
+ __Pyx_StructField *field_b = b->fields + i;
+ if (field_a->offset != field_b->offset ||
+ !__pyx_typeinfo_cmp(field_a->type, field_b->type))
+ return 0;
+ }
+ return !a->fields[i].type && !b->fields[i].type;
+ }
+ }
+ return 1;
+}
+
+static int
+__pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
+{
+ if (buf->shape[dim] <= 1)
+ return 1;
+ if (buf->strides) {
+ if (spec & __Pyx_MEMVIEW_CONTIG) {
+ if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
+ if (buf->strides[dim] != sizeof(void *)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly contiguous "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ } else if (buf->strides[dim] != buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_FOLLOW) {
+ Py_ssize_t stride = buf->strides[dim];
+ if (stride < 0)
+ stride = -stride;
+ if (stride < buf->itemsize) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer and memoryview are not contiguous "
+ "in the same dimension.");
+ goto fail;
+ }
+ }
+ } else {
+ if (spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not contiguous in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (spec & (__Pyx_MEMVIEW_PTR)) {
+ PyErr_Format(PyExc_ValueError,
+ "C-contiguous buffer is not indirect in "
+ "dimension %d", dim);
+ goto fail;
+ } else if (buf->suboffsets) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer exposes suboffsets but no strides");
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
+{
+ if (spec & __Pyx_MEMVIEW_DIRECT) {
+ if (buf->suboffsets && buf->suboffsets[dim] >= 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer not compatible with direct access "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ if (spec & __Pyx_MEMVIEW_PTR) {
+ if (!buf->suboffsets || (buf->suboffsets && buf->suboffsets[dim] < 0)) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer is not indirectly accessible "
+ "in dimension %d.", dim);
+ goto fail;
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int
+__pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
+{
+ int i;
+ if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = 0; i < ndim; i++) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not fortran contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
+ Py_ssize_t stride = 1;
+ for (i = ndim - 1; i >- 1; i--) {
+ if (stride * buf->itemsize != buf->strides[i] &&
+ buf->shape[i] > 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "Buffer not C contiguous.");
+ goto fail;
+ }
+ stride = stride * buf->shape[i];
+ }
+ }
+ return 1;
+fail:
+ return 0;
+}
+static int __Pyx_ValidateAndInit_memviewslice(
+ int *axes_specs,
+ int c_or_f_flag,
+ int buf_flags,
+ int ndim,
+ __Pyx_TypeInfo *dtype,
+ __Pyx_BufFmt_StackElem stack[],
+ __Pyx_memviewslice *memviewslice,
+ PyObject *original_obj)
+{
+ struct __pyx_memoryview_obj *memview, *new_memview;
+ __Pyx_RefNannyDeclarations
+ Py_buffer *buf;
+ int i, spec = 0, retval = -1;
+ __Pyx_BufFmt_Context ctx;
+ int from_memoryview = __pyx_memoryview_check(original_obj);
+ __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
+ if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
+ original_obj)->typeinfo)) {
+ memview = (struct __pyx_memoryview_obj *) original_obj;
+ new_memview = NULL;
+ } else {
+ memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ original_obj, buf_flags, 0, dtype);
+ new_memview = memview;
+ if (unlikely(!memview))
+ goto fail;
+ }
+ buf = &memview->view;
+ if (buf->ndim != ndim) {
+ PyErr_Format(PyExc_ValueError,
+ "Buffer has wrong number of dimensions (expected %d, got %d)",
+ ndim, buf->ndim);
+ goto fail;
+ }
+ if (new_memview) {
+ __Pyx_BufFmt_Init(&ctx, stack, dtype);
+ if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail;
+ }
+ if ((unsigned) buf->itemsize != dtype->size) {
+ PyErr_Format(PyExc_ValueError,
+ "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
+ "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
+ buf->itemsize,
+ (buf->itemsize > 1) ? "s" : "",
+ dtype->name,
+ dtype->size,
+ (dtype->size > 1) ? "s" : "");
+ goto fail;
+ }
+ for (i = 0; i < ndim; i++) {
+ spec = axes_specs[i];
+ if (!__pyx_check_strides(buf, i, ndim, spec))
+ goto fail;
+ if (!__pyx_check_suboffsets(buf, i, ndim, spec))
+ goto fail;
+ }
+ if (buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
+ new_memview != NULL) == -1)) {
+ goto fail;
+ }
+ retval = 0;
+ goto no_fail;
+fail:
+ Py_XDECREF(new_memview);
+ retval = -1;
+no_fail:
+ __Pyx_RefNannyFinishContext();
+ return retval;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_float(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 2,
+ &__Pyx_TypeInfo_float, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_dc_nn___pyx_t_5numpy_int32_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 1,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_double(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 2,
+ &__Pyx_TypeInfo_double, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int64_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 2,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_int64_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_uint64_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 2,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint64_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int32_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 2,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_int32_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_uint32_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 2,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_uint32_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE __Pyx_memviewslice __Pyx_PyObject_to_MemoryviewSlice_d_dc_nn___pyx_t_5numpy_int16_t(PyObject *obj) {
+ __Pyx_memviewslice result = { 0, 0, { 0 }, { 0 }, { 0 } };
+ __Pyx_BufFmt_StackElem stack[1];
+ int axes_specs[] = { (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_FOLLOW), (__Pyx_MEMVIEW_DIRECT | __Pyx_MEMVIEW_CONTIG) };
+ int retcode;
+ if (obj == Py_None) {
+ result.memview = (struct __pyx_memoryview_obj *) Py_None;
+ return result;
+ }
+ retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, __Pyx_IS_C_CONTIG,
+ (PyBUF_C_CONTIGUOUS | PyBUF_FORMAT | PyBUF_WRITABLE), 2,
+ &__Pyx_TypeInfo_nn___pyx_t_5numpy_int16_t, stack,
+ &result, obj);
+ if (unlikely(retcode == -1))
+ goto __pyx_fail;
+ return result;
+__pyx_fail:
+ result.memview = NULL;
+ result.data = NULL;
+ return result;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(long) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(long) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(long) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(long),
+ little, !is_unsigned);
+ }
+}
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return ::std::complex< float >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ return x + y*(__pyx_t_float_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_from_parts(float x, float y) {
+ __pyx_t_float_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_prodf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_float_complex a) {
+ __pyx_t_float_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE float __Pyx_c_absf(__pyx_t_float_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrtf(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypotf(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_float_complex a, __pyx_t_float_complex b) {
+ __pyx_t_float_complex z;
+ float r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ float denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(a, a);
+ case 3:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, a);
+ case 4:
+ z = __Pyx_c_prodf(a, a);
+ return __Pyx_c_prodf(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_absf(a);
+ theta = atan2f(a.imag, a.real);
+ }
+ lnr = logf(r);
+ z_r = expf(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cosf(z_theta);
+ z.imag = z_r * sinf(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+#if CYTHON_CCOMPLEX
+ #ifdef __cplusplus
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return ::std::complex< double >(x, y);
+ }
+ #else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ return x + y*(__pyx_t_double_complex)_Complex_I;
+ }
+ #endif
+#else
+ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(double x, double y) {
+ __pyx_t_double_complex z;
+ z.real = x;
+ z.imag = y;
+ return z;
+ }
+#endif
+
+#if CYTHON_CCOMPLEX
+#else
+ static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ return (a.real == b.real) && (a.imag == b.imag);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real + b.real;
+ z.imag = a.imag + b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real - b.real;
+ z.imag = a.imag - b.imag;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_prod(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ z.real = a.real * b.real - a.imag * b.imag;
+ z.imag = a.real * b.imag + a.imag * b.real;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double denom = b.real * b.real + b.imag * b.imag;
+ z.real = (a.real * b.real + a.imag * b.imag) / denom;
+ z.imag = (a.imag * b.real - a.real * b.imag) / denom;
+ return z;
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = -a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {
+ return (a.real == 0) && (a.imag == 0);
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_double_complex a) {
+ __pyx_t_double_complex z;
+ z.real = a.real;
+ z.imag = -a.imag;
+ return z;
+ }
+ #if 1
+ static CYTHON_INLINE double __Pyx_c_abs(__pyx_t_double_complex z) {
+ #if !defined(HAVE_HYPOT) || defined(_MSC_VER)
+ return sqrt(z.real*z.real + z.imag*z.imag);
+ #else
+ return hypot(z.real, z.imag);
+ #endif
+ }
+ static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_double_complex a, __pyx_t_double_complex b) {
+ __pyx_t_double_complex z;
+ double r, lnr, theta, z_r, z_theta;
+ if (b.imag == 0 && b.real == (int)b.real) {
+ if (b.real < 0) {
+ double denom = a.real * a.real + a.imag * a.imag;
+ a.real = a.real / denom;
+ a.imag = -a.imag / denom;
+ b.real = -b.real;
+ }
+ switch ((int)b.real) {
+ case 0:
+ z.real = 1;
+ z.imag = 0;
+ return z;
+ case 1:
+ return a;
+ case 2:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(a, a);
+ case 3:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, a);
+ case 4:
+ z = __Pyx_c_prod(a, a);
+ return __Pyx_c_prod(z, z);
+ }
+ }
+ if (a.imag == 0) {
+ if (a.real == 0) {
+ return a;
+ }
+ r = a.real;
+ theta = 0;
+ } else {
+ r = __Pyx_c_abs(a);
+ theta = atan2(a.imag, a.real);
+ }
+ lnr = log(r);
+ z_r = exp(lnr * b.real - theta * b.imag);
+ z_theta = theta * b.real + lnr * b.imag;
+ z.real = z_r * cos(z_theta);
+ z.imag = z_r * sin(z_theta);
+ return z;
+ }
+ #endif
+#endif
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+ if (is_unsigned) {
+ if (sizeof(int) < sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long)) {
+ return PyLong_FromUnsignedLong((unsigned long) value);
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ return PyLong_FromUnsignedLongLong((unsigned long long) value);
+ }
+ } else {
+ if (sizeof(int) <= sizeof(long)) {
+ return PyInt_FromLong((long) value);
+ } else if (sizeof(int) <= sizeof(long long)) {
+ return PyLong_FromLongLong((long long) value);
+ }
+ }
+ {
+ int one = 1; int little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&value;
+ return _PyLong_FromByteArray(bytes, sizeof(int),
+ little, !is_unsigned);
+ }
+}
+
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value) \
+ { \
+ func_type value = func_value; \
+ if (sizeof(target_type) < sizeof(func_type)) { \
+ if (unlikely(value != (func_type) (target_type) value)) { \
+ func_type zero = 0; \
+ if (is_unsigned && unlikely(value < zero)) \
+ goto raise_neg_overflow; \
+ else \
+ goto raise_overflow; \
+ } \
+ } \
+ return (target_type) value; \
+ }
+
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ #include "longintrepr.h"
+ #endif
+#endif
+
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+ const int neg_one = (int) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(int) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (int) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(int) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(int) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(int, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(int, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(int) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(int, long, PyLong_AsLong(x))
+ } else if (sizeof(int) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(int, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ int val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (int) -1;
+ }
+ } else {
+ int val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (int) -1;
+ val = __Pyx_PyInt_As_int(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to int");
+ return (int) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to int");
+ return (int) -1;
+}
+
+static int
+__pyx_memviewslice_is_contig(const __Pyx_memviewslice *mvs,
+ char order, int ndim)
+{
+ int i, index, step, start;
+ Py_ssize_t itemsize = mvs->memview->view.itemsize;
+ if (order == 'F') {
+ step = 1;
+ start = 0;
+ } else {
+ step = -1;
+ start = ndim - 1;
+ }
+ for (i = 0; i < ndim; i++) {
+ index = start + step * i;
+ if (mvs->suboffsets[index] >= 0 || mvs->strides[index] != itemsize)
+ return 0;
+ itemsize *= mvs->shape[index];
+ }
+ return 1;
+}
+
+static void
+__pyx_get_array_memory_extents(__Pyx_memviewslice *slice,
+ void **out_start, void **out_end,
+ int ndim, size_t itemsize)
+{
+ char *start, *end;
+ int i;
+ start = end = slice->data;
+ for (i = 0; i < ndim; i++) {
+ Py_ssize_t stride = slice->strides[i];
+ Py_ssize_t extent = slice->shape[i];
+ if (extent == 0) {
+ *out_start = *out_end = start;
+ return;
+ } else {
+ if (stride > 0)
+ end += stride * (extent - 1);
+ else
+ start += stride * (extent - 1);
+ }
+ }
+ *out_start = start;
+ *out_end = end + itemsize;
+}
+static int
+__pyx_slices_overlap(__Pyx_memviewslice *slice1,
+ __Pyx_memviewslice *slice2,
+ int ndim, size_t itemsize)
+{
+ void *start1, *end1, *start2, *end2;
+ __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
+ __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
+ return (start1 < end2) && (start2 < end1);
+}
+
+static __Pyx_memviewslice
+__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
+ const char *mode, int ndim,
+ size_t sizeof_dtype, int contig_flag,
+ int dtype_is_object)
+{
+ __Pyx_RefNannyDeclarations
+ int i;
+ __Pyx_memviewslice new_mvs = { 0, 0, { 0 }, { 0 }, { 0 } };
+ struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
+ Py_buffer *buf = &from_memview->view;
+ PyObject *shape_tuple = NULL;
+ PyObject *temp_int = NULL;
+ struct __pyx_array_obj *array_obj = NULL;
+ struct __pyx_memoryview_obj *memview_obj = NULL;
+ __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
+ for (i = 0; i < ndim; i++) {
+ if (from_mvs->suboffsets[i] >= 0) {
+ PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
+ "indirect dimensions (axis %d)", i);
+ goto fail;
+ }
+ }
+ shape_tuple = PyTuple_New(ndim);
+ if (unlikely(!shape_tuple)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(shape_tuple);
+ for(i = 0; i < ndim; i++) {
+ temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
+ if(unlikely(!temp_int)) {
+ goto fail;
+ } else {
+ PyTuple_SET_ITEM(shape_tuple, i, temp_int);
+ temp_int = NULL;
+ }
+ }
+ array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
+ if (unlikely(!array_obj)) {
+ goto fail;
+ }
+ __Pyx_GOTREF(array_obj);
+ memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
+ (PyObject *) array_obj, contig_flag,
+ dtype_is_object,
+ from_mvs->memview->typeinfo);
+ if (unlikely(!memview_obj))
+ goto fail;
+ if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
+ goto fail;
+ if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
+ dtype_is_object) < 0))
+ goto fail;
+ goto no_fail;
+fail:
+ __Pyx_XDECREF(new_mvs.memview);
+ new_mvs.memview = NULL;
+ new_mvs.data = NULL;
+no_fail:
+ __Pyx_XDECREF(shape_tuple);
+ __Pyx_XDECREF(temp_int);
+ __Pyx_XDECREF(array_obj);
+ __Pyx_RefNannyFinishContext();
+ return new_mvs;
+}
+
+static CYTHON_INLINE PyObject *
+__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
+{
+ PyObject *cobj;
+#if PY_VERSION_HEX >= 0x02070000
+ cobj = PyCapsule_New(p, sig, NULL);
+#else
+ cobj = PyCObject_FromVoidPtr(p, NULL);
+#endif
+ return cobj;
+}
+
+static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {
+ const char neg_one = (char) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(char) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (char) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(char) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(char) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(char, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(char, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(char, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(char) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(char, long, PyLong_AsLong(x))
+ } else if (sizeof(char) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(char, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ char val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (char) -1;
+ }
+ } else {
+ char val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (char) -1;
+ val = __Pyx_PyInt_As_char(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to char");
+ return (char) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to char");
+ return (char) -1;
+}
+
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+ const long neg_one = (long) -1, const_zero = 0;
+ const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_Check(x))) {
+ if (sizeof(long) < sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+ } else {
+ long val = PyInt_AS_LONG(x);
+ if (is_unsigned && unlikely(val < 0)) {
+ goto raise_neg_overflow;
+ }
+ return (long) val;
+ }
+ } else
+#endif
+ if (likely(PyLong_Check(x))) {
+ if (is_unsigned) {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (unlikely(Py_SIZE(x) < 0)) {
+ goto raise_neg_overflow;
+ }
+ if (sizeof(long) <= sizeof(unsigned long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long, PyLong_AsUnsignedLong(x))
+ } else if (sizeof(long) <= sizeof(unsigned long long)) {
+ __PYX_VERIFY_RETURN_INT(long, unsigned long long, PyLong_AsUnsignedLongLong(x))
+ }
+ } else {
+#if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(x)) {
+ case 0: return 0;
+ case 1: __PYX_VERIFY_RETURN_INT(long, digit, +(((PyLongObject*)x)->ob_digit[0]));
+ case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) ((PyLongObject*)x)->ob_digit[0]);
+ }
+ #endif
+#endif
+ if (sizeof(long) <= sizeof(long)) {
+ __PYX_VERIFY_RETURN_INT(long, long, PyLong_AsLong(x))
+ } else if (sizeof(long) <= sizeof(long long)) {
+ __PYX_VERIFY_RETURN_INT(long, long long, PyLong_AsLongLong(x))
+ }
+ }
+ {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+ PyErr_SetString(PyExc_RuntimeError,
+ "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+ long val;
+ PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+ if (likely(v) && !PyLong_Check(v)) {
+ PyObject *tmp = v;
+ v = PyNumber_Long(tmp);
+ Py_DECREF(tmp);
+ }
+ #endif
+ if (likely(v)) {
+ int one = 1; int is_little = (int)*(unsigned char *)&one;
+ unsigned char *bytes = (unsigned char *)&val;
+ int ret = _PyLong_AsByteArray((PyLongObject *)v,
+ bytes, sizeof(val),
+ is_little, !is_unsigned);
+ Py_DECREF(v);
+ if (likely(!ret))
+ return val;
+ }
+#endif
+ return (long) -1;
+ }
+ } else {
+ long val;
+ PyObject *tmp = __Pyx_PyNumber_Int(x);
+ if (!tmp) return (long) -1;
+ val = __Pyx_PyInt_As_long(tmp);
+ Py_DECREF(tmp);
+ return val;
+ }
+raise_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "value too large to convert to long");
+ return (long) -1;
+raise_neg_overflow:
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to long");
+ return (long) -1;
+}
+
+static int __Pyx_check_binary_version(void) {
+ char ctversion[4], rtversion[4];
+ PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
+ PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
+ if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
+ char message[200];
+ PyOS_snprintf(message, sizeof(message),
+ "compiletime version %s of module '%.100s' "
+ "does not match runtime version %s",
+ ctversion, __Pyx_MODULE_NAME, rtversion);
+ return PyErr_WarnEx(NULL, message, 1);
+ }
+ return 0;
+}
+
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(const char *name) {
+ PyObject *py_name = 0;
+ PyObject *py_module = 0;
+ py_name = __Pyx_PyIdentifier_FromString(name);
+ if (!py_name)
+ goto bad;
+ py_module = PyImport_Import(py_name);
+ Py_DECREF(py_name);
+ return py_module;
+bad:
+ Py_XDECREF(py_name);
+ return 0;
+}
+#endif
+
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
+ size_t size, int strict)
+{
+ PyObject *py_module = 0;
+ PyObject *result = 0;
+ PyObject *py_name = 0;
+ char warning[200];
+ Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+ PyObject *py_basicsize;
+#endif
+ py_module = __Pyx_ImportModule(module_name);
+ if (!py_module)
+ goto bad;
+ py_name = __Pyx_PyIdentifier_FromString(class_name);
+ if (!py_name)
+ goto bad;
+ result = PyObject_GetAttr(py_module, py_name);
+ Py_DECREF(py_name);
+ py_name = 0;
+ Py_DECREF(py_module);
+ py_module = 0;
+ if (!result)
+ goto bad;
+ if (!PyType_Check(result)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s.%.200s is not a type object",
+ module_name, class_name);
+ goto bad;
+ }
+#ifndef Py_LIMITED_API
+ basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+ py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+ if (!py_basicsize)
+ goto bad;
+ basicsize = PyLong_AsSsize_t(py_basicsize);
+ Py_DECREF(py_basicsize);
+ py_basicsize = 0;
+ if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+ goto bad;
+#endif
+ if (!strict && (size_t)basicsize > size) {
+ PyOS_snprintf(warning, sizeof(warning),
+ "%s.%s size changed, may indicate binary incompatibility",
+ module_name, class_name);
+ if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
+ }
+ else if ((size_t)basicsize != size) {
+ PyErr_Format(PyExc_ValueError,
+ "%.200s.%.200s has the wrong size, try recompiling",
+ module_name, class_name);
+ goto bad;
+ }
+ return (PyTypeObject *)result;
+bad:
+ Py_XDECREF(py_module);
+ Py_XDECREF(result);
+ return NULL;
+}
+#endif
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ #if PY_MAJOR_VERSION < 3
+ if (t->is_unicode) {
+ *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
+ } else if (t->intern) {
+ *t->p = PyString_InternFromString(t->s);
+ } else {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ }
+ #else
+ if (t->is_unicode | t->is_str) {
+ if (t->intern) {
+ *t->p = PyUnicode_InternFromString(t->s);
+ } else if (t->encoding) {
+ *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
+ } else {
+ *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
+ }
+ } else {
+ *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
+ }
+ #endif
+ if (!*t->p)
+ return -1;
+ ++t;
+ }
+ return 0;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+ return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+ Py_ssize_t ignore;
+ return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+ if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+ PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+ char* defenc_c;
+ PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+ if (!defenc) return NULL;
+ defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ {
+ char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+ char* c;
+ for (c = defenc_c; c < end; c++) {
+ if ((unsigned char) (*c) >= 128) {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+ }
+ }
+#endif
+ *length = PyBytes_GET_SIZE(defenc);
+ return defenc_c;
+#else
+ if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+ if (PyUnicode_IS_ASCII(o)) {
+ *length = PyUnicode_GET_LENGTH(o);
+ return PyUnicode_AsUTF8(o);
+ } else {
+ PyUnicode_AsASCIIString(o);
+ return NULL;
+ }
+#else
+ return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+ } else
+#endif
+#if !CYTHON_COMPILING_IN_PYPY
+ if (PyByteArray_Check(o)) {
+ *length = PyByteArray_GET_SIZE(o);
+ return PyByteArray_AS_STRING(o);
+ } else
+#endif
+ {
+ char* result;
+ int r = PyBytes_AsStringAndSize(o, &result, length);
+ if (unlikely(r < 0)) {
+ return NULL;
+ } else {
+ return result;
+ }
+ }
+}
+static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
+ int is_true = x == Py_True;
+ if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
+ else return PyObject_IsTrue(x);
+}
+static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
+ PyNumberMethods *m;
+ const char *name = NULL;
+ PyObject *res = NULL;
+#if PY_MAJOR_VERSION < 3
+ if (PyInt_Check(x) || PyLong_Check(x))
+#else
+ if (PyLong_Check(x))
+#endif
+ return Py_INCREF(x), x;
+ m = Py_TYPE(x)->tp_as_number;
+#if PY_MAJOR_VERSION < 3
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Int(x);
+ }
+ else if (m && m->nb_long) {
+ name = "long";
+ res = PyNumber_Long(x);
+ }
+#else
+ if (m && m->nb_int) {
+ name = "int";
+ res = PyNumber_Long(x);
+ }
+#endif
+ if (res) {
+#if PY_MAJOR_VERSION < 3
+ if (!PyInt_Check(res) && !PyLong_Check(res)) {
+#else
+ if (!PyLong_Check(res)) {
+#endif
+ PyErr_Format(PyExc_TypeError,
+ "__%.4s__ returned non-%.4s (type %.200s)",
+ name, name, Py_TYPE(res)->tp_name);
+ Py_DECREF(res);
+ return NULL;
+ }
+ }
+ else if (!PyErr_Occurred()) {
+ PyErr_SetString(PyExc_TypeError,
+ "an integer is required");
+ }
+ return res;
+}
+static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
+ Py_ssize_t ival;
+ PyObject *x;
+#if PY_MAJOR_VERSION < 3
+ if (likely(PyInt_CheckExact(b)))
+ return PyInt_AS_LONG(b);
+#endif
+ if (likely(PyLong_CheckExact(b))) {
+ #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+ #if CYTHON_USE_PYLONG_INTERNALS
+ switch (Py_SIZE(b)) {
+ case -1: return -(sdigit)((PyLongObject*)b)->ob_digit[0];
+ case 0: return 0;
+ case 1: return ((PyLongObject*)b)->ob_digit[0];
+ }
+ #endif
+ #endif
+ return PyLong_AsSsize_t(b);
+ }
+ x = PyNumber_Index(b);
+ if (!x) return -1;
+ ival = PyInt_AsSsize_t(x);
+ Py_DECREF(x);
+ return ival;
+}
+static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
+ return PyInt_FromSize_t(ival);
+}
+
+
+#endif /* Py_PYTHON_H */
diff --git a/silx/math/medianfilter/medianfilter.pyx b/silx/math/medianfilter/medianfilter.pyx
new file mode 100644
index 0000000..c7c9497
--- /dev/null
+++ b/silx/math/medianfilter/medianfilter.pyx
@@ -0,0 +1,383 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""This module provides median filter function for 1D and 2D arrays.
+"""
+
+__authors__ = ["H. Payno", "J. Kieffer"]
+__license__ = "MIT"
+__date__ = "02/05/2017"
+
+
+from cython.parallel import prange
+cimport cython
+cimport median_filter
+import numpy
+cimport numpy as cnumpy
+cdef Py_ssize_t size = 10
+from libcpp cimport bool
+
+ctypedef unsigned long uint64
+ctypedef unsigned int uint32
+ctypedef unsigned short uint16
+
+
+def medfilt1d(data, kernel_size=3, bool conditional=False):
+ """Function computing the median filter of the given input.
+ Behavior at boundaries: the algorithm is reducing the size of the
+ window/kernel for pixels at boundaries (there is no mirroring).
+
+ :param numpy.ndarray data: the array for which we want to apply
+ the median filter. Should be 1d.
+ :param kernel_size: the dimension of the kernel.
+ :type kernel_size: int
+ :param bool conditional: True if we want to apply a conditional median
+ filtering.
+
+ :returns: the array with the median value for each pixel.
+ """
+ return medfilt(data, kernel_size, conditional)
+
+
+def medfilt2d(image, kernel_size=3, bool conditional=False):
+ """Function computing the median filter of the given input.
+ Behavior at boundaries: the algorithm is reducing the size of the
+ window/kernel for pixels at boundaries (there is no mirroring).
+
+ :param numpy.ndarray data: the array for which we want to apply
+ the median filter. Should be 2d.
+ :param kernel_size: the dimension of the kernel.
+ :type kernel_size: For 1D should be an int for 2D should be a tuple or
+ a list of (kernel_height, kernel_width)
+ :param bool conditional: True if we want to apply a conditional median
+ filtering.
+
+ :returns: the array with the median value for each pixel.
+ """
+ return medfilt(image, kernel_size, conditional)
+
+
+def medfilt(data, kernel_size=3, bool conditional=False):
+ """Function computing the median filter of the given input.
+ Behavior at boundaries: the algorithm is reducing the size of the
+ window/kernel for pixels at boundaries (there is no mirroring).
+
+ :param numpy.ndarray data: the array for which we want to apply
+ the median filter. Should be 1d or 2d.
+ :param kernel_size: the dimension of the kernel.
+ :type kernel_size: For 1D should be an int for 2D should be a tuple or
+ a list of (kernel_height, kernel_width)
+ :param bool conditional: True if we want to apply a conditional median
+ filtering.
+
+ :returns: the array with the median value for each pixel.
+ """
+ reshaped = False
+ if len(data.shape) == 1:
+ data = data.reshape(data.shape[0], 1)
+ reshaped = True
+ elif len(data.shape) > 2:
+ raise ValueError("Invalid data shape. Dimemsion of the arary should be 1 or 2")
+
+ # simple median filter apply into a 2D buffer
+ output_buffer = numpy.zeros_like(data)
+ check(data, output_buffer)
+
+ if type(kernel_size) in (tuple, list):
+ if(len(kernel_size) == 1):
+ ker_dim = numpy.array(1, [kernel_size[0]], dtype=numpy.int32)
+ else:
+ ker_dim = numpy.array(kernel_size, dtype=numpy.int32)
+ else:
+ ker_dim = numpy.array([kernel_size, kernel_size], dtype=numpy.int32)
+
+ if data.dtype == numpy.float64:
+ medfilterfc = _median_filter_float64
+ elif data.dtype == numpy.float32:
+ medfilterfc = _median_filter_float32
+ elif data.dtype == numpy.int64:
+ medfilterfc = _median_filter_int64
+ elif data.dtype == numpy.uint64:
+ medfilterfc = _median_filter_uint64
+ elif data.dtype == numpy.int32:
+ medfilterfc = _median_filter_int32
+ elif data.dtype == numpy.uint32:
+ medfilterfc = _median_filter_uint32
+ elif data.dtype == numpy.int16:
+ medfilterfc = _median_filter_int16
+ elif data.dtype == numpy.uint16:
+ medfilterfc = _median_filter_uint16
+ else:
+ raise ValueError("%s type is not managed by the median filter" % data.dtype)
+
+ medfilterfc(input_buffer=data,
+ output_buffer=output_buffer,
+ kernel_size=ker_dim,
+ conditional=conditional)
+
+ if reshaped:
+ data = data.reshape(data.shape[0])
+ output_buffer = output_buffer.reshape(data.shape[0])
+
+ return output_buffer
+
+
+def check(input_buffer, output_buffer):
+ """Simple check on the two buffers to make sure we can apply the median filter
+ """
+ if (input_buffer.flags['C_CONTIGUOUS'] is False):
+ raise ValueError('<input_buffer> must be a C_CONTIGUOUS numpy array.')
+
+ if (output_buffer.flags['C_CONTIGUOUS'] is False):
+ raise ValueError('<output_buffer> must be a C_CONTIGUOUS numpy array.')
+
+ if not (len(input_buffer.shape) <= 2):
+ raise ValueError('<input_buffer> dimension must mo higher than 2.')
+
+ if not (len(output_buffer.shape) <= 2):
+ raise ValueError('<output_buffer> dimension must mo higher than 2.')
+
+ if not(input_buffer.dtype == output_buffer.dtype):
+ raise ValueError('input buffer and output_buffer must be of the same type')
+
+ if not (input_buffer.shape == output_buffer.shape):
+ raise ValueError('input buffer and output_buffer must be of the same dimension and same dimension')
+
+
+######### implementations of the include/median_filter.hpp function ############
+@cython.cdivision(True)
+@cython.boundscheck(False)
+@cython.wraparound(False)
+@cython.initializedcheck(False)
+def _median_filter_float32(float[:, ::1] input_buffer not None,
+ float[:, ::1] output_buffer not None,
+ cnumpy.int32_t[::1] kernel_size not None,
+ bool conditional):
+
+ cdef:
+ int x = 0
+ int image_dim = input_buffer.shape[1] - 1
+ int[2] buffer_shape
+ buffer_shape[0] = input_buffer.shape[0]
+ buffer_shape[1] = input_buffer.shape[1]
+
+ for x in prange(input_buffer.shape[0], nogil=True):
+ median_filter.median_filter[float](<float*> & input_buffer[0,0],
+ <float*> & output_buffer[0,0],
+ <int*>& kernel_size[0],
+ <int*>buffer_shape,
+ x,
+ 0,
+ image_dim,
+ conditional)
+
+
+@cython.cdivision(True)
+@cython.boundscheck(False)
+@cython.wraparound(False)
+@cython.initializedcheck(False)
+def _median_filter_float64(double[:, ::1] input_buffer not None,
+ double[:, ::1] output_buffer not None,
+ cnumpy.int32_t[::1] kernel_size not None,
+ bool conditional):
+
+ cdef:
+ int x = 0
+ int image_dim = input_buffer.shape[1] - 1
+ int[2] buffer_shape
+ buffer_shape[0] = input_buffer.shape[0]
+ buffer_shape[1] = input_buffer.shape[1]
+
+ for x in prange(input_buffer.shape[0], nogil=True):
+ median_filter.median_filter[double](<double*> & input_buffer[0, 0],
+ <double*> & output_buffer[0, 0],
+ <int*>&kernel_size[0],
+ <int*>buffer_shape,
+ x,
+ 0,
+ image_dim,
+ conditional)
+
+
+@cython.cdivision(True)
+@cython.boundscheck(False)
+@cython.wraparound(False)
+@cython.initializedcheck(False)
+def _median_filter_int64(cnumpy.int64_t[:, ::1] input_buffer not None,
+ cnumpy.int64_t[:, ::1] output_buffer not None,
+ cnumpy.int32_t[::1] kernel_size not None,
+ bool conditional):
+
+ cdef:
+ int x = 0
+ int image_dim = input_buffer.shape[1] - 1
+ int[2] buffer_shape
+ buffer_shape[0] = input_buffer.shape[0]
+ buffer_shape[1] = input_buffer.shape[1]
+
+ for x in prange(input_buffer.shape[0], nogil=True):
+ median_filter.median_filter[long](<long*> & input_buffer[0,0],
+ <long*> & output_buffer[0, 0],
+ <int*>&kernel_size[0],
+ <int*>buffer_shape,
+ x,
+ 0,
+ image_dim,
+ conditional);
+
+@cython.cdivision(True)
+@cython.boundscheck(False)
+@cython.wraparound(False)
+@cython.initializedcheck(False)
+def _median_filter_uint64(
+ cnumpy.uint64_t[:, ::1] input_buffer not None,
+ cnumpy.uint64_t[:, ::1] output_buffer not None,
+ cnumpy.int32_t[::1] kernel_size not None,
+ bool conditional):
+
+ cdef:
+ int x = 0
+ int image_dim = input_buffer.shape[1] - 1
+ int[2] buffer_shape
+ buffer_shape[0] = input_buffer.shape[0]
+ buffer_shape[1] = input_buffer.shape[1]
+
+ for x in prange(input_buffer.shape[0], nogil=True):
+ median_filter.median_filter[uint64](<uint64*> & input_buffer[0,0],
+ <uint64*> & output_buffer[0, 0],
+ <int*>&kernel_size[0],
+ <int*>buffer_shape,
+ x,
+ 0,
+ image_dim,
+ conditional)
+
+
+@cython.cdivision(True)
+@cython.boundscheck(False)
+@cython.wraparound(False)
+@cython.initializedcheck(False)
+def _median_filter_int32(cnumpy.int32_t[:, ::1] input_buffer not None,
+ cnumpy.int32_t[:, ::1] output_buffer not None,
+ cnumpy.int32_t[::1] kernel_size not None,
+ bool conditional):
+
+ cdef:
+ int x = 0
+ int image_dim = input_buffer.shape[1] - 1
+ int[2] buffer_shape
+ buffer_shape[0] = input_buffer.shape[0]
+ buffer_shape[1] = input_buffer.shape[1]
+
+ for x in prange(input_buffer.shape[0], nogil=True):
+ median_filter.median_filter[int](<int*> & input_buffer[0,0],
+ <int*> & output_buffer[0, 0],
+ <int*>&kernel_size[0],
+ <int*>buffer_shape,
+ x,
+ 0,
+ image_dim,
+ conditional)
+
+
+@cython.cdivision(True)
+@cython.boundscheck(False)
+@cython.wraparound(False)
+@cython.initializedcheck(False)
+def _median_filter_uint32(cnumpy.uint32_t[:, ::1] input_buffer not None,
+ cnumpy.uint32_t[:, ::1] output_buffer not None,
+ cnumpy.int32_t[::1] kernel_size not None,
+ bool conditional):
+
+ cdef:
+ int x = 0
+ int image_dim = input_buffer.shape[1] - 1
+ int[2] buffer_shape
+ buffer_shape[0] = input_buffer.shape[0]
+ buffer_shape[1] = input_buffer.shape[1]
+
+ for x in prange(input_buffer.shape[0], nogil=True):
+ median_filter.median_filter[uint32](<uint32*> & input_buffer[0,0],
+ <uint32*> & output_buffer[0, 0],
+ <int*>&kernel_size[0],
+ <int*>buffer_shape,
+ x,
+ 0,
+ image_dim,
+ conditional)
+
+
+@cython.cdivision(True)
+@cython.boundscheck(False)
+@cython.wraparound(False)
+@cython.initializedcheck(False)
+def _median_filter_int16(cnumpy.int16_t[:, ::1] input_buffer not None,
+ cnumpy.int16_t[:, ::1] output_buffer not None,
+ cnumpy.int32_t[::1] kernel_size not None,
+ bool conditional):
+
+ cdef:
+ int x = 0
+ int image_dim = input_buffer.shape[1] - 1
+ int[2] buffer_shape
+ buffer_shape[0] = input_buffer.shape[0]
+ buffer_shape[1] = input_buffer.shape[1]
+
+ for x in prange(input_buffer.shape[0], nogil=True):
+ median_filter.median_filter[short](<short*> & input_buffer[0,0],
+ <short*> & output_buffer[0, 0],
+ <int*>&kernel_size[0],
+ <int*>buffer_shape,
+ x,
+ 0,
+ image_dim,
+ conditional)
+
+
+@cython.cdivision(True)
+@cython.boundscheck(False)
+@cython.wraparound(False)
+@cython.initializedcheck(False)
+def _median_filter_uint16(
+ cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] input_buffer not None,
+ cnumpy.ndarray[cnumpy.uint16_t, ndim=2, mode='c'] output_buffer not None,
+ cnumpy.ndarray[cnumpy.int32_t, ndim=1, mode='c'] kernel_size not None,
+ bool conditional):
+
+ cdef:
+ int x = 0
+ int image_dim = input_buffer.shape[1] - 1
+ int[2] buffer_shape,
+ buffer_shape[0] = input_buffer.shape[0]
+ buffer_shape[1] = input_buffer.shape[1]
+
+ for x in prange(input_buffer.shape[0], nogil=True):
+ median_filter.median_filter[uint16](<uint16*> & input_buffer[0, 0],
+ <uint16*> & output_buffer[0, 0],
+ <int*>&kernel_size[0],
+ <int*>buffer_shape,
+ x,
+ 0,
+ image_dim,
+ conditional)
diff --git a/silx/math/medianfilter/setup.py b/silx/math/medianfilter/setup.py
new file mode 100644
index 0000000..d228357
--- /dev/null
+++ b/silx/math/medianfilter/setup.py
@@ -0,0 +1,59 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+
+__authors__ = ["D. Naudet"]
+__license__ = "MIT"
+__date__ = "02/05/2017"
+
+
+import numpy
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('medianfilter', parent_package, top_path)
+ config.add_subpackage('test')
+
+ # =====================================
+ # median filter
+ # =====================================
+ medfilt_src = ['medianfilter.pyx']
+ medfilt_inc = ['include', numpy.get_include()]
+ extra_link_args = ['-fopenmp']
+ extra_compile_args = ['-fopenmp']
+ config.add_extension('medianfilter',
+ sources=medfilt_src,
+ include_dirs=[medfilt_inc],
+ language='c++',
+ extra_link_args=extra_link_args,
+ extra_compile_args=extra_compile_args)
+
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration) \ No newline at end of file
diff --git a/silx/math/medianfilter/test/__init__.py b/silx/math/medianfilter/test/__init__.py
new file mode 100644
index 0000000..ec08d21
--- /dev/null
+++ b/silx/math/medianfilter/test/__init__.py
@@ -0,0 +1,36 @@
+# 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.
+#
+# ############################################################################*/
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "22/06/2016"
+
+import unittest
+
+from .test_medianfilter import suite as test_medianfilter
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(test_medianfilter())
+ return test_suite
diff --git a/silx/math/medianfilter/test/benchmark.py b/silx/math/medianfilter/test/benchmark.py
new file mode 100644
index 0000000..0d1da94
--- /dev/null
+++ b/silx/math/medianfilter/test/benchmark.py
@@ -0,0 +1,122 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2017 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.
+#
+# ############################################################################*/
+"""Tests of the median filter"""
+
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "02/05/2017"
+
+from silx.gui import qt
+from silx.math.medianfilter import medfilt2d as medfilt2d_silx
+import numpy
+import numpy.random
+from timeit import Timer
+from silx.gui.plot import Plot1D
+import logging
+
+try:
+ import scipy
+except:
+ scipy = None
+else:
+ import scipy.ndimage
+
+try:
+ import PyMca5.PyMca as pymca
+except:
+ pymca = None
+else:
+ from PyMca5.PyMca.median import medfilt2d as medfilt2d_pymca
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.INFO)
+
+
+class BenchmarkMedianFilter(object):
+ """Simple benchmark of the median fiter silx vs scipy"""
+
+ NB_ITER = 3
+
+ def __init__(self, imageWidth, kernels):
+ self.img = numpy.random.rand(imageWidth, imageWidth)
+ self.kernels = kernels
+
+ self.run()
+
+ def run(self):
+ self.execTime = {}
+ for kernel in self.kernels:
+ self.execTime[kernel] = self.bench(kernel)
+
+ def bench(self, width):
+ def execSilx():
+ medfilt2d_silx(self.img, width)
+
+ def execScipy():
+ scipy.ndimage.median_filter(input=self.img,
+ size=width,
+ mode='nearest')
+
+ def execPymca():
+ medfilt2d_pymca(self.img, width)
+
+ execTime = {}
+
+ t = Timer(execSilx)
+ execTime["silx"] = t.timeit(BenchmarkMedianFilter.NB_ITER)
+ logger.info(
+ 'exec time silx (kernel size = %s) is %s' % (width, execTime["silx"]))
+
+ if scipy is not None:
+ t = Timer(execScipy)
+ execTime["scipy"] = t.timeit(BenchmarkMedianFilter.NB_ITER)
+ logger.info(
+ 'exec time scipy (kernel size = %s) is %s' % (width, execTime["scipy"]))
+ if pymca is not None:
+ t = Timer(execPymca)
+ execTime["pymca"] = t.timeit(BenchmarkMedianFilter.NB_ITER)
+ logger.info(
+ 'exec time pymca (kernel size = %s) is %s' % (width, execTime["pymca"]))
+
+ return execTime
+
+ def getExecTimeFor(self, id):
+ res = []
+ for k in self.kernels:
+ res.append(self.execTime[k][id])
+ return res
+
+
+global app # QApplication must be global to avoid seg fault on quit
+app = qt.QApplication([])
+kernels = [3, 5, 7, 11, 15]
+benchmark = BenchmarkMedianFilter(imageWidth=1000, kernels=kernels)
+plot = Plot1D()
+plot.addCurve(x=kernels, y=benchmark.getExecTimeFor("silx"), legend='silx')
+if scipy is not None:
+ plot.addCurve(x=kernels, y=benchmark.getExecTimeFor("scipy"), legend='scipy')
+if pymca is not None:
+ plot.addCurve(x=kernels, y=benchmark.getExecTimeFor("pymca"), legend='pymca')
+plot.show()
+app.exec_()
diff --git a/silx/math/medianfilter/test/test_medianfilter.py b/silx/math/medianfilter/test/test_medianfilter.py
new file mode 100644
index 0000000..8a26d3a
--- /dev/null
+++ b/silx/math/medianfilter/test/test_medianfilter.py
@@ -0,0 +1,244 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2017 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.
+#
+# ############################################################################*/
+"""Tests of the median filter"""
+
+__authors__ = ["H. Payno"]
+__license__ = "MIT"
+__date__ = "02/05/2017"
+
+import unittest
+import numpy
+import os
+from silx.math.medianfilter import medfilt2d
+from silx.test.utils import ParametricTestCase
+try:
+ import scipy
+ import scipy.misc
+except:
+ scipy = None
+else:
+ import scipy.ndimage
+
+import logging
+_logger = logging.getLogger(__name__)
+
+
+class TestMedianFilterNearest(ParametricTestCase):
+ """Unit tests for the median filter in nearest mode"""
+
+ random_mat = numpy.array([
+ [0.05564293, 0.62717157, 0.75002406, 0.40555336, 0.70278975],
+ [0.76532598, 0.02839148, 0.05272484, 0.65166994, 0.42161216],
+ [0.23067427, 0.74219128, 0.56049024, 0.44406320, 0.28773158],
+ [0.81025249, 0.20303021, 0.68382382, 0.46372299, 0.81281709],
+ [0.94691602, 0.07813661, 0.81651256, 0.84220106, 0.33623165]])
+
+ def testFilter3_100(self):
+ """Test median filter on a 10x10 matrix with a 3x3 kernel."""
+ dataIn = numpy.arange(100, dtype=numpy.int32)
+ dataIn = dataIn.reshape((10, 10))
+
+ dataOut = medfilt2d(image=dataIn,
+ kernel_size=(3, 3),
+ conditional=False)
+ self.assertTrue(dataOut[0, 0] == 1)
+ self.assertTrue(dataOut[9, 0] == 90)
+ self.assertTrue(dataOut[9, 9] == 98)
+
+ self.assertTrue(dataOut[0, 9] == 9)
+ self.assertTrue(dataOut[0, 4] == 5)
+ self.assertTrue(dataOut[9, 4] == 93)
+ self.assertTrue(dataOut[4, 4] == 44)
+
+ def testFilter3_9(self):
+ "Test median filter on a 3x3 matrix a 3x3 kernel."
+ dataIn = numpy.array([0, -1, 1,
+ 12, 6, -2,
+ 100, 4, 12],
+ dtype=numpy.int16)
+ dataIn = dataIn.reshape((3, 3))
+ dataOut = medfilt2d(image=dataIn,
+ kernel_size=(3, 3),
+ conditional=False)
+ self.assertTrue(dataOut.shape == dataIn.shape)
+ self.assertTrue(dataOut[1, 1] == 4)
+ self.assertTrue(dataOut[0, 0] == 0)
+ self.assertTrue(dataOut[0, 1] == 0)
+ self.assertTrue(dataOut[1, 0] == 6)
+
+ def testFilterWidthOne(self):
+ """Make sure a filter of one by one give the same result as the input
+ """
+ dataIn = numpy.arange(100, dtype=numpy.int32)
+ dataIn = dataIn.reshape((10, 10))
+
+ dataOut = medfilt2d(image=dataIn,
+ kernel_size=(1, 1),
+ conditional=False)
+
+ self.assertTrue(numpy.array_equal(dataIn, dataOut))
+
+ def testInputDataIsNotModify(self):
+ """Make sure input data is not modify by the median filter"""
+ dataIn = numpy.arange(100, dtype=numpy.int32)
+ dataIn = dataIn.reshape((10, 10))
+ dataInCopy = dataIn.copy()
+
+ medfilt2d(image=dataIn,
+ kernel_size=(3, 3),
+ conditional=False)
+ self.assertTrue(numpy.array_equal(dataIn, dataInCopy))
+
+ def testThreads(self):
+ """Make sure the result doesn't depends on the number of threads used
+ """
+ dataIn = numpy.random.rand(100, 100)
+
+ former = os.environ.get("OMP_NUM_THREADS")
+ os.environ["OMP_NUM_THREADS"] = "1"
+ dataOut1Thr = medfilt2d(image=dataIn,
+ kernel_size=(3, 3),
+ conditional=False,
+ )
+ os.environ["OMP_NUM_THREADS"] = "2"
+ dataOut2Thr = medfilt2d(image=dataIn,
+ kernel_size=(3, 3),
+ conditional=False)
+ os.environ["OMP_NUM_THREADS"] = "4"
+ dataOut4Thr = medfilt2d(image=dataIn,
+ kernel_size=(3, 3),
+ conditional=False)
+ os.environ["OMP_NUM_THREADS"] = "8"
+ dataOut8Thr = medfilt2d(image=dataIn,
+ kernel_size=(3, 3),
+ conditional=False)
+ if former is None:
+ os.environ.pop("OMP_NUM_THREADS")
+ else:
+ os.environ["OMP_NUM_THREADS"] = former
+
+ self.assertTrue(numpy.array_equal(dataOut1Thr, dataOut2Thr))
+ self.assertTrue(numpy.array_equal(dataOut1Thr, dataOut4Thr))
+ self.assertTrue(numpy.array_equal(dataOut1Thr, dataOut8Thr))
+
+ def testFilter3Conditionnal(self):
+ """Test that the conditional filter apply correctly"""
+ dataIn = numpy.arange(100, dtype=numpy.int32)
+ dataIn = dataIn.reshape((10, 10))
+
+ dataOut = medfilt2d(image=dataIn,
+ kernel_size=(3, 3),
+ conditional=True)
+ self.assertTrue(dataOut[0, 0] == 1)
+ self.assertTrue(dataOut[0, 1] == 1)
+ self.assertTrue(numpy.array_equal(dataOut[1:8, 1:8], dataIn[1:8, 1:8]))
+ self.assertTrue(dataOut[9, 9] == 98)
+
+ def testTypes(self):
+ """Test that all needed types have their implementation of the median
+ filter
+ """
+ for testType in [numpy.float32, numpy.float64, numpy.int16,
+ numpy.uint16, numpy.int32, numpy.int64, numpy.uint64]:
+ data = (numpy.random.rand(10, 10) * 65000).astype(testType)
+ out = medfilt2d(image=data,
+ kernel_size=(3, 3),
+ conditional=False)
+ self.assertTrue(out.dtype.type is testType)
+
+ def testFilter3_1D(self):
+ """Simple test of a three by three kernel median filter"""
+ dataIn = numpy.arange(100, dtype=numpy.int32)
+
+ dataOut = medfilt2d(image=dataIn,
+ kernel_size=(5),
+ conditional=False)
+
+ self.assertTrue(dataOut[0] == 0)
+ self.assertTrue(dataOut[9] == 9)
+ self.assertTrue(dataOut[99] == 99)
+
+ @unittest.skipUnless(scipy, "scipy not available")
+ def testWithArange(self):
+ data = numpy.arange(10000, dtype=numpy.int32)
+ data = data.reshape(100, 100)
+
+ kernels = [(3, 7), (7, 5), (1, 1), (3, 3)]
+ for kernel in kernels:
+ with self.subTest(kernel=kernel):
+ resScipy = scipy.ndimage.median_filter(input=data,
+ size=kernel,
+ mode='nearest')
+ resSilx = medfilt2d(image=data,
+ kernel_size=kernel,
+ conditional=False)
+
+ self.assertTrue(numpy.array_equal(resScipy, resSilx))
+
+ @unittest.skipUnless(scipy, "scipy not available")
+ def testRandomMatrice(self):
+ kernels = [(3, 7), (7, 5), (1, 1), (3, 3)]
+ for kernel in kernels:
+ with self.subTest(kernel=kernel):
+ resScipy = scipy.ndimage.median_filter(input=self.random_mat,
+ size=kernel,
+ mode='nearest')
+
+ resSilx = medfilt2d(image=self.random_mat,
+ kernel_size=kernel,
+ conditional=False)
+
+ self.assertTrue(numpy.array_equal(resScipy, resSilx))
+
+ @unittest.skipUnless(scipy, "scipy not available")
+ def testAscentOrLena(self):
+ if hasattr(scipy.misc, 'ascent'):
+ img = scipy.misc.ascent()
+ else:
+ img = scipy.misc.lena()
+
+ kernels = [(3, 1), (3, 5), (5, 9), (9, 3)]
+ for kernel in kernels:
+ with self.subTest(kernel=kernel):
+ resScipy = scipy.ndimage.median_filter(input=img,
+ size=kernel,
+ mode='nearest')
+
+ resSilx = medfilt2d(image=img,
+ kernel_size=kernel,
+ conditional=False)
+
+ self.assertTrue(numpy.array_equal(resScipy, resSilx))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for test in [TestMedianFilterNearest, ]:
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(test))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/math/setup.py b/silx/math/setup.py
new file mode 100644
index 0000000..288eaf6
--- /dev/null
+++ b/silx/math/setup.py
@@ -0,0 +1,97 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+
+__authors__ = ["D. Naudet"]
+__license__ = "MIT"
+__date__ = "27/03/2017"
+
+import os.path
+
+import numpy
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('math', parent_package, top_path)
+ config.add_subpackage('test')
+ config.add_subpackage('fit')
+ config.add_subpackage('medianfilter')
+
+ # =====================================
+ # histogramnd
+ # =====================================
+ histo_dir = 'histogramnd'
+ histo_src = [os.path.join(histo_dir, srcf)
+ for srcf in ['chistogramnd.pyx',
+ 'src/histogramnd_c.c']]
+ histo_inc = [os.path.join(histo_dir, 'include'),
+ numpy.get_include()]
+
+ config.add_extension('chistogramnd',
+ sources=histo_src,
+ include_dirs=histo_inc,
+ language='c')
+ # =====================================
+ # =====================================
+
+ # =====================================
+ # histogramnd_lut
+ # =====================================
+ histo_dir = 'histogramnd'
+ histo_src = [os.path.join(histo_dir, srcf)
+ for srcf in ['chistogramnd_lut.pyx']]
+ histo_inc = [os.path.join(histo_dir, 'include'),
+ numpy.get_include()]
+
+ config.add_extension('chistogramnd_lut',
+ sources=histo_src,
+ include_dirs=histo_inc,
+ language='c')
+ # =====================================
+ # =====================================
+
+ # marching cubes
+ mc_dir = 'marchingcubes'
+ mc_src = [os.path.join(mc_dir, srcf)
+ for srcf in ['marchingcubes.pyx', 'mc_lut.cpp']]
+ config.add_extension('marchingcubes',
+ sources=mc_src,
+ include_dirs=[mc_dir, numpy.get_include()],
+ language='c++')
+
+ # min/max
+ combo_dir = 'combo'
+ config.add_extension('combo',
+ sources=[os.path.join(combo_dir, 'combo.pyx')],
+ include_dirs=[combo_dir],
+ language='c')
+
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/math/test/__init__.py b/silx/math/test/__init__.py
new file mode 100644
index 0000000..7171bda
--- /dev/null
+++ b/silx/math/test/__init__.py
@@ -0,0 +1,51 @@
+# 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.
+#
+# ############################################################################*/
+
+__authors__ = ["D. Naudet"]
+__license__ = "MIT"
+__date__ = "04/07/2016"
+
+import unittest
+
+from .test_histogramnd_error import suite as test_histo_error
+from .test_histogramnd_nominal import suite as test_histo_nominal
+from .test_histogramnd_vs_np import suite as test_histo_vs_np
+from .test_HistogramndLut_nominal import suite as test_histolut_nominal
+from ..fit.test import suite as test_fit_suite
+from .test_marchingcubes import suite as test_marchingcubes_suite
+from ..medianfilter.test import suite as test_medianfilter_suite
+from .test_combo import suite as test_combo_suite
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(test_histo_nominal())
+ test_suite.addTest(test_histo_error())
+ test_suite.addTest(test_histo_vs_np())
+ test_suite.addTest(test_fit_suite())
+ test_suite.addTest(test_histolut_nominal())
+ test_suite.addTest(test_marchingcubes_suite())
+ test_suite.addTest(test_medianfilter_suite())
+ test_suite.addTest(test_combo_suite())
+ return test_suite
diff --git a/silx/math/test/benchmark_combo.py b/silx/math/test/benchmark_combo.py
new file mode 100644
index 0000000..4acc26b
--- /dev/null
+++ b/silx/math/test/benchmark_combo.py
@@ -0,0 +1,204 @@
+# coding: utf-8
+# /*##########################################################################
+# Copyright (C) 2016-2017 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.
+#
+# ############################################################################*/
+"""Benchmarks of the combo module"""
+
+from __future__ import division
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "27/03/2017"
+
+
+import logging
+import os.path
+import time
+import unittest
+
+import numpy
+
+from silx.test.utils import ParametricTestCase, temp_dir
+
+from silx.math import combo
+
+
+logging.basicConfig()
+_logger = logging.getLogger(__name__)
+_logger.setLevel(logging.DEBUG)
+
+
+class BenchmarkMinMax(ParametricTestCase):
+ """Benchmark of min max combo"""
+
+ DTYPES = ('float32', 'float64',
+ 'int8', 'int16', 'int32', 'int64',
+ 'uint8', 'uint16', 'uint32', 'uint64')
+
+ ARANGE = 'ascent', 'descent', 'random'
+
+ EXPONENT = 3, 4, 5, 6, 7
+
+ def test_benchmark_min_max(self):
+ """Benchmark min_max without min positive.
+
+ Compares with:
+
+ - numpy.nanmin, numpy.nanmax and
+ - numpy.argmin, numpy.argmax
+
+ It runs bench for different types, different data size and 3
+ data sets: increasing , decreasing and random data.
+ """
+ durations = {'min/max': [], 'argmin/max': [], 'combo': []}
+
+ _logger.info('Benchmark against argmin/argmax and nanmin/nanmax')
+
+ for dtype in self.DTYPES:
+ for arange in self.ARANGE:
+ for exponent in self.EXPONENT:
+ size = 10**exponent
+ with self.subTest(dtype=dtype, size=size, arange=arange):
+ if arange == 'ascent':
+ data = numpy.arange(0, size, 1, dtype=dtype)
+ elif arange == 'descent':
+ data = numpy.arange(size, 0, -1, dtype=dtype)
+ else:
+ if dtype in ('float32', 'float64'):
+ data = numpy.random.random(size)
+ else:
+ data = numpy.random.randint(10**6, size=size)
+ data = numpy.array(data, dtype=dtype)
+
+ start = time.time()
+ ref_min = numpy.nanmin(data)
+ ref_max = numpy.nanmax(data)
+ durations['min/max'].append(time.time() - start)
+
+ start = time.time()
+ ref_argmin = numpy.argmin(data)
+ ref_argmax = numpy.argmax(data)
+ durations['argmin/max'].append(time.time() - start)
+
+ start = time.time()
+ result = combo.min_max(data, min_positive=False)
+ durations['combo'].append(time.time() - start)
+
+ _logger.info(
+ '%s-%s-10**%d\tx%.2f argmin/max x%.2f min/max',
+ dtype, arange, exponent,
+ durations['argmin/max'][-1] / durations['combo'][-1],
+ durations['min/max'][-1] / durations['combo'][-1])
+
+ self.assertEqual(result.minimum, ref_min)
+ self.assertEqual(result.maximum, ref_max)
+ self.assertEqual(result.argmin, ref_argmin)
+ self.assertEqual(result.argmax, ref_argmax)
+
+ self.show_results('min/max', durations, 'combo')
+
+ def test_benchmark_min_pos(self):
+ """Benchmark min_max wit min positive.
+
+ Compares with:
+
+ - numpy.nanmin(data[data > 0]); numpy.nanmin(pos); numpy.nanmax(pos)
+
+ It runs bench for different types, different data size and 3
+ data sets: increasing , decreasing and random data.
+ """
+ durations = {'min/max': [], 'combo': []}
+
+ _logger.info('Benchmark against min, max, positive min')
+
+ for dtype in self.DTYPES:
+ for arange in self.ARANGE:
+ for exponent in self.EXPONENT:
+ size = 10**exponent
+ with self.subTest(dtype=dtype, size=size, arange=arange):
+ if arange == 'ascent':
+ data = numpy.arange(0, size, 1, dtype=dtype)
+ elif arange == 'descent':
+ data = numpy.arange(size, 0, -1, dtype=dtype)
+ else:
+ if dtype in ('float32', 'float64'):
+ data = numpy.random.random(size)
+ else:
+ data = numpy.random.randint(10**6, size=size)
+ data = numpy.array(data, dtype=dtype)
+
+ start = time.time()
+ ref_min_positive = numpy.nanmin(data[data > 0])
+ ref_min = numpy.nanmin(data)
+ ref_max = numpy.nanmax(data)
+ durations['min/max'].append(time.time() - start)
+
+ start = time.time()
+ result = combo.min_max(data, min_positive=True)
+ durations['combo'].append(time.time() - start)
+
+ _logger.info(
+ '%s-%s-10**%d\tx%.2f min/minpos/max',
+ dtype, arange, exponent,
+ durations['min/max'][-1] / durations['combo'][-1])
+
+ self.assertEqual(result.min_positive, ref_min_positive)
+ self.assertEqual(result.minimum, ref_min)
+ self.assertEqual(result.maximum, ref_max)
+
+ self.show_results('min/max/min positive', durations, 'combo')
+
+ def show_results(self, title, durations, ref_key):
+ try:
+ from matplotlib import pyplot
+ except ImportError:
+ _logger.warning('matplotlib not available')
+ return
+
+ pyplot.title(title)
+ pyplot.xlabel('-'.join(self.DTYPES))
+ pyplot.ylabel('duration (sec)')
+ for label, values in durations.items():
+ pyplot.semilogy(values, label=label)
+ pyplot.legend()
+ pyplot.show()
+
+ pyplot.title(title)
+ pyplot.xlabel('-'.join(self.DTYPES))
+ pyplot.ylabel('Duration ratio')
+ ref = numpy.array(durations[ref_key])
+ for label, values in durations.items():
+ values = numpy.array(values)
+ pyplot.plot(values/ref, label=label + ' / ' + ref_key)
+ pyplot.legend()
+ pyplot.show()
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTests(
+ unittest.defaultTestLoader.loadTestsFromTestCase(BenchmarkMinMax))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/test/histo_benchmarks.py b/silx/math/test/histo_benchmarks.py
new file mode 100644
index 0000000..7d3216d
--- /dev/null
+++ b/silx/math/test/histo_benchmarks.py
@@ -0,0 +1,269 @@
+# 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.
+#
+# ############################################################################*/
+"""
+histogramnd benchmarks, vs numpy.histogramdd (bin counts and weights).
+"""
+
+import numpy as np
+
+import time
+
+from silx.math import histogramnd
+
+
+def print_times(t0s, t1s, t2s, t3s):
+ c_times = t1s - t0s
+ np_times = t2s - t1s
+ np_w_times = t3s - t2s
+
+ time_txt = 'min : {0: <7.3f}; max : {1: <7.3f}; avg : {2: <7.3f}'
+
+ print('\tTimes :')
+ print('\tC : ' + time_txt.format(c_times.min(),
+ c_times.max(),
+ c_times.mean()))
+ print('\tNP : ' + time_txt.format(np_times.min(),
+ np_times.max(),
+ np_times.mean()))
+ print('\tNP(W) : ' + time_txt.format(np_w_times.min(),
+ np_w_times.max(),
+ np_w_times.mean()))
+
+
+def commpare_results(txt,
+ times,
+ result_c,
+ result_np,
+ result_np_w,
+ sample,
+ weights,
+ raise_ex=False):
+
+ if result_np:
+ hits_cmp = np.array_equal(result_c[0], result_np[0])
+ else:
+ hits_cmp = None
+
+ if result_np_w and result_c[1] is not None:
+ weights_cmp = np.array_equal(result_c[1], result_np_w[0])
+ else:
+ weights_cmp = None
+
+ if((hits_cmp is not None and not hits_cmp) or
+ (weights_cmp is not None and not weights_cmp)):
+ err_txt = (txt + ' : results arent the same : '
+ 'hits : {0}, '
+ 'weights : {1}.'
+ ''.format('OK' if hits_cmp else 'NOK',
+ 'OK' if weights_cmp else 'NOK'))
+ print('\t' + err_txt)
+ if raise_ex:
+ raise ValueError(err_txt)
+ return False
+
+ result_txt = ' : results OK. c : {0: <7.3f};'.format(times[0])
+ if result_np or result_np_w:
+ result_txt += (' np : {0: <7.3f}; '
+ 'np (weights) {1: <7.3f}.'
+ ''.format(times[1], times[2]))
+ print('\t' + txt + result_txt)
+ return True
+
+
+def benchmark(n_loops,
+ sample_shape,
+ sample_rng,
+ weights_rng,
+ histo_range,
+ n_bins,
+ weight_min,
+ weight_max,
+ last_bin_closed,
+ dtype=np.double,
+ do_weights=True,
+ do_numpy=True):
+
+ int_min = 0
+ int_max = 100000
+
+ sample = np.random.randint(int_min,
+ high=int_max,
+ size=sample_shape).astype(np.double)
+ sample = (sample_rng[0] +
+ (sample - int_min) *
+ (sample_rng[1] - sample_rng[0]) /
+ (int_max - int_min))
+ sample = sample.astype(dtype)
+
+ if do_weights:
+ weights = np.random.randint(int_min,
+ high=int_max,
+ size=(ssetup.pyample_shape[0],))
+ weights = weights.astype(np.double)
+ weights = (weights_rng[0] +
+ (weights - int_min) *
+ (weights_rng[1] - weights_rng[0]) /
+ (int_max - int_min))
+ else:
+ weights = None
+
+ t0s = []
+ t1s = []
+ t2s = []
+ t3s = []
+
+ for i in range(n_loops):
+ t0s.append(time.time())
+ result_c = histogramnd(sample,
+ histo_range,
+ n_bins,
+ weights=weights,
+ weight_min=weight_min,
+ weight_max=weight_max,
+ last_bin_closed=last_bin_closed)
+ t1s.append(time.time())
+ if do_numpy:
+ result_np = np.histogramdd(sample,
+ bins=n_bins,
+ range=histo_range)
+ t2s.append(time.time())
+ result_np_w = np.histogramdd(sample,
+ bins=n_bins,
+ range=histo_range,
+ weights=weights)
+ t3s.append(time.time())
+ else:
+ result_np = None
+ result_np_w = None
+ t2s.append(0)
+ t3s.append(0)
+
+ commpare_results('Run {0}'.format(i),
+ [t1s[-1] - t0s[-1], t2s[-1] - t1s[-1], t3s[-1] - t2s[-1]],
+ result_c,
+ result_np,
+ result_np_w,
+ sample,
+ weights)
+
+ print_times(np.array(t0s), np.array(t1s), np.array(t2s), np.array(t3s))
+
+
+def run_benchmark(dtype=np.double,
+ do_weights=True,
+ do_numpy=True):
+ n_loops = 5
+
+ weights_rng = [0., 100.]
+ sample_rng = [0., 100.]
+
+ weight_min = None
+ weight_max = None
+ last_bin_closed = True
+
+ # ====================================================
+ # ====================================================
+ # 1D
+ # ====================================================
+ # ====================================================
+
+ print('==========================')
+ print(' 1D [{0}]'.format(dtype))
+ print('==========================')
+ sample_shape = (10**7,)
+ histo_range = [[0., 100.]]
+ n_bins = 30
+
+ benchmark(n_loops,
+ sample_shape,
+ sample_rng,
+ weights_rng,
+ histo_range,
+ n_bins,
+ weight_min,
+ weight_max,
+ last_bin_closed,
+ dtype=dtype,
+ do_weights=True,
+ do_numpy=do_numpy)
+
+ # ====================================================
+ # ====================================================
+ # 2D
+ # ====================================================
+ # ====================================================
+
+ print('==========================')
+ print(' 2D [{0}]'.format(dtype))
+ print('==========================')
+ sample_shape = (10**7, 2)
+ histo_range = [[0., 100.], [0., 100.]]
+ n_bins = 30
+
+ benchmark(n_loops,
+ sample_shape,
+ sample_rng,
+ weights_rng,
+ histo_range,
+ n_bins,
+ weight_min,
+ weight_max,
+ last_bin_closed,
+ dtype=dtype,
+ do_weights=True,
+ do_numpy=do_numpy)
+
+ # ====================================================
+ # ====================================================
+ # 3D
+ # ====================================================
+ # ====================================================
+
+ print('==========================')
+ print(' 3D [{0}]'.format(dtype))
+ print('==========================')
+ sample_shape = (10**7, 3)
+ histo_range = np.array([[0., 100.], [0., 100.], [0., 100.]])
+ n_bins = 30
+
+ benchmark(n_loops,
+ sample_shape,
+ sample_rng,
+ weights_rng,
+ histo_range,
+ n_bins,
+ weight_min,
+ weight_max,
+ last_bin_closed,
+ dtype=dtype,
+ do_weights=True,
+ do_numpy=do_numpy)
+
+if __name__ == '__main__':
+ types = (np.double, np.int32, np.float32,)
+
+ for t in types:
+ run_benchmark(t,
+ do_weights=True,
+ do_numpy=True)
diff --git a/silx/math/test/test_HistogramndLut_nominal.py b/silx/math/test/test_HistogramndLut_nominal.py
new file mode 100644
index 0000000..9c356bd
--- /dev/null
+++ b/silx/math/test/test_HistogramndLut_nominal.py
@@ -0,0 +1,571 @@
+# 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.
+#
+# ############################################################################*/
+"""
+Nominal tests of the HistogramndLut function.
+"""
+
+import unittest
+
+import numpy as np
+
+from silx.math import HistogramndLut
+
+
+def _get_bin_edges(histo_range, n_bins, n_dims):
+ edges = []
+ for i_dim in range(n_dims):
+ edges.append(histo_range[i_dim, 0] +
+ np.arange(n_bins[i_dim] + 1) *
+ (histo_range[i_dim, 1] - histo_range[i_dim, 0]) /
+ n_bins[i_dim])
+ return tuple(edges)
+
+
+# ==============================================================
+# ==============================================================
+# ==============================================================
+
+
+class _TestHistogramndLut_nominal(unittest.TestCase):
+ """
+ Unit tests of the HistogramndLut class.
+ """
+
+ ndims = None
+
+ def setUp(self):
+ ndims = self.ndims
+ self.tested_dim = ndims-1
+
+ if ndims is None:
+ raise ValueError('ndims class member not set.')
+
+ sample = np.array([5.5, -3.3,
+ 0., -0.5,
+ 3.3, 8.8,
+ -7.7, 6.0,
+ -4.0])
+
+ weights = np.array([500.5, -300.3,
+ 0.01, -0.5,
+ 300.3, 800.8,
+ -700.7, 600.6,
+ -400.4])
+
+ n_elems = len(sample)
+
+ if ndims == 1:
+ shape = (n_elems,)
+ else:
+ shape = (n_elems, ndims)
+
+ self.sample = np.zeros(shape=shape, dtype=sample.dtype)
+ if ndims == 1:
+ self.sample = sample
+ else:
+ self.sample[..., ndims-1] = sample
+
+ self.weights = weights
+
+ # the tests are performed along one dimension,
+ # all the other bins indices along the other dimensions
+ # are expected to be 2
+ # (e.g : when testing a 2D sample : [0, x] will go into
+ # bin [2, y] because of the bin ranges [-2, 2] and n_bins = 4
+ # for the first dimension)
+ self.other_axes_index = 2
+ self.histo_range = np.repeat([[-2., 2.]], ndims, axis=0)
+ self.histo_range[ndims-1] = [-4., 6.]
+
+ self.n_bins = np.array([4]*ndims)
+ self.n_bins[ndims-1] = 5
+
+ if ndims == 1:
+ def fill_histo(h, v, dim, op=None):
+ if op:
+ h[:] = op(h[:], v)
+ else:
+ h[:] = v
+ self.fill_histo = fill_histo
+ else:
+ def fill_histo(h, v, dim, op=None):
+ idx = [self.other_axes_index]*len(h.shape)
+ idx[dim] = slice(0, None)
+ if op:
+ h[idx] = op(h[idx], v)
+ else:
+ h[idx] = v
+ self.fill_histo = fill_histo
+
+ def test_nominal_bin_edges(self):
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ bin_edges = instance.bins_edges
+
+ expected_edges = _get_bin_edges(self.histo_range,
+ self.n_bins,
+ self.ndims)
+
+ for i_edges, edges in enumerate(expected_edges):
+ self.assertTrue(np.array_equal(bin_edges[i_edges],
+ expected_edges[i_edges]),
+ msg='Testing bin_edges for dim {0}'
+ ''.format(i_edges+1))
+
+ def test_nominal_histo_range(self):
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ histo_range = instance.histo_range
+
+ self.assertTrue(np.array_equal(histo_range, self.histo_range))
+
+ def test_nominal_last_bin_closed(self):
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ last_bin_closed = instance.last_bin_closed
+
+ self.assertEqual(last_bin_closed, False)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins,
+ last_bin_closed=True)
+
+ last_bin_closed = instance.last_bin_closed
+
+ self.assertEqual(last_bin_closed, True)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins,
+ last_bin_closed=False)
+
+ last_bin_closed = instance.last_bin_closed
+
+ self.assertEqual(last_bin_closed, False)
+
+ def test_nominal_n_bins_array(self):
+
+ test_n_bins = np.arange(self.ndims) + 10
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ test_n_bins)
+
+ n_bins = instance.n_bins
+
+ self.assertTrue(np.array_equal(test_n_bins, n_bins))
+
+ def test_nominal_n_bins_scalar(self):
+
+ test_n_bins = 10
+ expected_n_bins = np.array([test_n_bins] * self.ndims)
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ test_n_bins)
+
+ n_bins = instance.n_bins
+
+ self.assertTrue(np.array_equal(expected_n_bins, n_bins))
+
+ def test_nominal_histo_ref(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ instance.accumulate(self.weights)
+
+ histo = instance.histo()
+ w_histo = instance.weighted_histo()
+ histo_ref = instance.histo(copy=False)
+ w_histo_ref = instance.weighted_histo(copy=False)
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+ self.assertTrue(np.array_equal(histo_ref, expected_h))
+ self.assertTrue(np.array_equal(w_histo_ref, expected_c))
+
+ histo_ref[0, ...] = histo_ref[0, ...] + 10
+ w_histo_ref[0, ...] = w_histo_ref[0, ...] + 20
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+ self.assertFalse(np.array_equal(histo_ref, expected_h))
+ self.assertFalse(np.array_equal(w_histo_ref, expected_c))
+
+ histo_2 = instance.histo()
+ w_histo_2 = instance.weighted_histo()
+
+ self.assertFalse(np.array_equal(histo_2, expected_h))
+ self.assertFalse(np.array_equal(w_histo_2, expected_c))
+ self.assertTrue(np.array_equal(histo_2, histo_ref))
+ self.assertTrue(np.array_equal(w_histo_2, w_histo_ref))
+
+ def test_nominal_accumulate_once(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ instance.accumulate(self.weights)
+
+ histo = instance.histo()
+ w_histo = instance.weighted_histo()
+
+ self.assertEqual(w_histo.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+ self.assertTrue(np.array_equal(instance.histo(), expected_h))
+ self.assertTrue(np.array_equal(instance.weighted_histo(),
+ expected_c))
+
+ def test_nominal_accumulate_twice(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ # calling accumulate twice
+ expected_h *= 2
+ expected_c *= 2
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ instance.accumulate(self.weights)
+
+ instance.accumulate(self.weights)
+
+ histo = instance.histo()
+ w_histo = instance.weighted_histo()
+
+ self.assertEqual(w_histo.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+ self.assertTrue(np.array_equal(instance.histo(), expected_h))
+ self.assertTrue(np.array_equal(instance.weighted_histo(),
+ expected_c))
+
+ def test_nominal_apply_lut_once(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ histo, w_histo = instance.apply_lut(self.weights)
+
+ self.assertEqual(w_histo.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+ self.assertEqual(instance.histo(), None)
+ self.assertEqual(instance.weighted_histo(), None)
+
+ def test_nominal_apply_lut_twice(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ # calling apply_lut twice
+ expected_h *= 2
+ expected_c *= 2
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ histo, w_histo = instance.apply_lut(self.weights)
+ histo_2, w_histo_2 = instance.apply_lut(self.weights,
+ histo=histo,
+ weighted_histo=w_histo)
+
+ self.assertEqual(id(histo), id(histo_2))
+ self.assertEqual(id(w_histo), id(w_histo_2))
+ self.assertEqual(w_histo.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+ self.assertEqual(instance.histo(), None)
+ self.assertEqual(instance.weighted_histo(), None)
+
+ def test_nominal_accumulate_last_bin_closed(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 2])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 1101.1])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins,
+ last_bin_closed=True)
+
+ instance.accumulate(self.weights)
+
+ histo = instance.histo()
+ w_histo = instance.weighted_histo()
+
+ self.assertEqual(w_histo.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+
+ def test_nominal_accumulate_weight_min_max(self):
+ """
+ """
+ weight_min = -299.9
+ weight_max = 499.9
+
+ expected_h_tpl = np.array([0, 1, 1, 1, 0])
+ expected_c_tpl = np.array([0., -0.5, 0.01, 300.3, 0.])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ instance.accumulate(self.weights,
+ weight_min=weight_min,
+ weight_max=weight_max)
+
+ histo = instance.histo()
+ w_histo = instance.weighted_histo()
+
+ self.assertEqual(w_histo.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+
+ def test_nominal_accumulate_forced_int32(self):
+ """
+ double weights, int32 weighted_histogram
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700, 0, 0, 300, 500])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins,
+ dtype=np.int32)
+
+ instance.accumulate(self.weights)
+
+ histo = instance.histo()
+ w_histo = instance.weighted_histo()
+
+ self.assertEqual(w_histo.dtype, np.int32)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+
+ def test_nominal_accumulate_forced_float32(self):
+ """
+ int32 weights, float32 weighted_histogram
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700., 0., 0., 300., 500.])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.float32)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins,
+ dtype=np.float32)
+
+ instance.accumulate(self.weights.astype(np.int32))
+
+ histo = instance.histo()
+ w_histo = instance.weighted_histo()
+
+ self.assertEqual(w_histo.dtype, np.float32)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+
+ def test_nominal_accumulate_int32(self):
+ """
+ int32 weights
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700, 0, 0, 300, 500])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.int32)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ instance.accumulate(self.weights.astype(np.int32))
+
+ histo = instance.histo()
+ w_histo = instance.weighted_histo()
+
+ self.assertEqual(w_histo.dtype, np.int32)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+
+ def test_nominal_accumulate_int32_double(self):
+ """
+ int32 weights
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700, 0, 0, 300, 500])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.int32)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ instance = HistogramndLut(self.sample,
+ self.histo_range,
+ self.n_bins)
+
+ instance.accumulate(self.weights.astype(np.int32))
+ instance.accumulate(self.weights)
+
+ histo = instance.histo()
+ w_histo = instance.weighted_histo()
+
+ expected_h *= 2
+ expected_c *= 2
+
+ self.assertEqual(w_histo.dtype, np.int32)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(w_histo, expected_c))
+
+
+class TestHistogramndLut_nominal_1d(_TestHistogramndLut_nominal):
+ ndims = 1
+
+
+class TestHistogramndLut_nominal_2d(_TestHistogramndLut_nominal):
+ ndims = 2
+
+
+class TestHistogramndLut_nominal_3d(_TestHistogramndLut_nominal):
+ ndims = 3
+
+
+# ==============================================================
+# ==============================================================
+# ==============================================================
+
+
+test_cases = (TestHistogramndLut_nominal_1d,
+ TestHistogramndLut_nominal_2d,
+ TestHistogramndLut_nominal_3d,)
+
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/test/test_combo.py b/silx/math/test/test_combo.py
new file mode 100644
index 0000000..92eb8b4
--- /dev/null
+++ b/silx/math/test/test_combo.py
@@ -0,0 +1,168 @@
+# 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.
+#
+# ############################################################################*/
+"""Tests of the combo module"""
+
+from __future__ import division
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "20/12/2016"
+
+
+import unittest
+
+import numpy
+
+from silx.test.utils import ParametricTestCase
+
+from silx.math.combo import min_max
+
+
+class TestMinMax(ParametricTestCase):
+ """Tests of min max combo"""
+
+ FLOATING_DTYPES = 'float32', 'float64'
+ SIGNED_INT_DTYPES = 'uint8', 'uint16', 'uint32', 'uint64'
+ UNSIGNED_INT_DTYPES = 'uint8', 'uint16', 'uint32', 'uint64'
+ DTYPES = FLOATING_DTYPES + SIGNED_INT_DTYPES + UNSIGNED_INT_DTYPES
+
+ def _test_min_max(self, data, min_positive):
+ """Compare min_max with numpy for the given dataset
+
+ :param numpy.ndarray data: Data set to use for test
+ :param bool min_positive: True to test with positive min
+ """
+ result = min_max(data, min_positive)
+
+ minimum = numpy.nanmin(data)
+ if numpy.isnan(minimum): # All NaNs
+ self.assertTrue(numpy.isnan(result.minimum))
+ self.assertEqual(result.argmin, 0)
+
+ else:
+ self.assertEqual(result.minimum, minimum)
+
+ argmin = numpy.where(data == minimum)[0][0]
+ self.assertEqual(result.argmin, argmin)
+
+ maximum = numpy.nanmax(data)
+ if numpy.isnan(maximum): # All NaNs
+ self.assertTrue(numpy.isnan(result.maximum))
+ self.assertEqual(result.argmax, 0)
+
+ else:
+ self.assertEqual(result.maximum, maximum)
+
+ argmax = numpy.where(data == maximum)[0][0]
+ self.assertEqual(result.argmax, argmax)
+
+ if min_positive:
+ pos_data = data[data > 0]
+ if len(pos_data) > 0:
+ min_pos = numpy.min(pos_data)
+ argmin_pos = numpy.where(data == min_pos)[0][0]
+ else:
+ min_pos = None
+ argmin_pos = None
+ self.assertEqual(result.min_positive, min_pos)
+ self.assertEqual(result.argmin_positive, argmin_pos)
+
+ def test_different_datasets(self):
+ """Test min_max with different numpy.arange datasets."""
+ size = 1000
+
+ for dtype in self.DTYPES:
+
+ tests = {
+ '0 to N': (0, 1),
+ 'N-1 to 0': (size - 1, -1)}
+ if dtype not in self.UNSIGNED_INT_DTYPES:
+ tests['N/2 to -N/2'] = size // 2, -1
+ tests['0 to -N'] = 0, -1
+
+ for name, (start, step) in tests.items():
+ for min_positive in (True, False):
+ with self.subTest(dtype=dtype,
+ min_positive=min_positive,
+ data=name):
+ data = numpy.arange(
+ start, start + step * size, step, dtype=dtype)
+
+ self._test_min_max(data, min_positive)
+
+ def test_nodata(self):
+ """Test min_max with None and empty array"""
+ for dtype in self.DTYPES:
+ with self.subTest(dtype=dtype):
+ with self.assertRaises(TypeError):
+ min_max(None)
+
+ data = numpy.array((), dtype=dtype)
+ with self.assertRaises(ValueError):
+ min_max(data)
+
+ def test_nandata(self):
+ """Test min_max with NaN in data"""
+ tests = [
+ (float('nan'), float('nan')), # All NaNs
+ (float('nan'), 1.0), # NaN first and positive
+ (float('nan'), -1.0), # NaN first and negative
+ (1.0, 2.0, float('nan')), # NaN last and positive
+ (-1.0, -2.0, float('nan')), # NaN last and negative
+ (1.0, float('nan'), -1.0), # Some NaN
+ ]
+
+ for dtype in self.FLOATING_DTYPES:
+ for data in tests:
+ with self.subTest(dtype=dtype, data=data):
+ data = numpy.array(data, dtype=dtype)
+ self._test_min_max(data, min_positive=True)
+
+ def test_infdata(self):
+ """Test min_max with inf."""
+ tests = [
+ [float('inf')] * 3, # All +inf
+ [float('inf')] * 3, # All -inf
+ (float('inf'), float('-inf')), # + and - inf
+ (float('inf'), float('-inf'), float('nan')), # +/-inf, nan last
+ (float('nan'), float('-inf'), float('inf')), # +/-inf, nan first
+ (float('inf'), float('nan'), float('-inf')), # +/-inf, nan center
+ ]
+
+ for dtype in self.FLOATING_DTYPES:
+ for data in tests:
+ with self.subTest(dtype=dtype, data=data):
+ data = numpy.array(data, dtype=dtype)
+ self._test_min_max(data, min_positive=True)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTests(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestMinMax))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/test/test_histogramnd_error.py b/silx/math/test/test_histogramnd_error.py
new file mode 100644
index 0000000..575eaf0
--- /dev/null
+++ b/silx/math/test/test_histogramnd_error.py
@@ -0,0 +1,512 @@
+# 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.
+#
+# ############################################################################*/
+
+__authors__ = ["D. Naudet"]
+__license__ = "MIT"
+__date__ = "01/02/2016"
+
+"""
+Tests of the histogramnd function, error cases.
+"""
+import sys
+import platform
+import unittest
+
+import numpy as np
+
+from silx.math.chistogramnd import chistogramnd as histogramnd
+from silx.math import Histogramnd
+
+
+# ==============================================================
+# ==============================================================
+# ==============================================================
+
+
+class _Test_chistogramnd_errors(unittest.TestCase):
+ """
+ Unit tests of the chistogramnd error cases.
+ """
+ def setUp(self):
+ raise NotImplementedError('')
+
+ def test_weights_shape(self):
+ """
+ """
+
+ for err_w_shape in self.err_weights_shapes:
+ test_msg = ('Testing invalid weights shape : {0}'
+ ''.format(err_w_shape))
+
+ err_weights = np.random.randint(0,
+ high=10,
+ size=err_w_shape)
+ err_weights = err_weights.astype(np.double)
+
+ ex_str = None
+ try:
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=err_weights)[0:2]
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str,
+ '<weights> must be an array whose length '
+ 'is equal to the number of samples.')
+
+ def test_histo_range_shape(self):
+ """
+ """
+ n_dims = 1 if len(self.s_shape) == 1 else self.s_shape[1]
+ expected_txt_tpl = ('<histo_range> error : expected {n_dims} sets '
+ 'of lower and upper bin edges, '
+ 'got the following instead : {histo_range}. '
+ '(provided <sample> contains '
+ '{n_dims}D values)')
+
+ for err_histo_range in self.err_histo_range_shapes:
+ test_msg = ('Testing invalid histo_range shape : {0}'
+ ''.format(err_histo_range))
+
+ expected_txt = expected_txt_tpl.format(histo_range=err_histo_range,
+ n_dims=n_dims)
+
+ ex_str = None
+ try:
+ histo, cumul = histogramnd(self.sample,
+ err_histo_range,
+ self.n_bins,
+ weights=self.weights)[0:2]
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str, expected_txt, msg=test_msg)
+
+ def test_nbins_shape(self):
+ """
+ """
+
+ expected_txt = ('n_bins must be either a scalar (same number '
+ 'of bins for all dimensions) or '
+ 'an array (number of bins for each '
+ 'dimension).')
+
+ for err_n_bins in self.err_n_bins_shapes:
+ test_msg = ('Testing invalid n_bins shape : {0}'
+ ''.format(err_n_bins))
+
+ ex_str = None
+ try:
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ err_n_bins,
+ weights=self.weights)[0:2]
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str, expected_txt, msg=test_msg)
+
+ def test_nbins_values(self):
+ """
+ """
+ expected_txt = ('<n_bins> : only positive values allowed.')
+
+ for err_n_bins in self.err_n_bins_values:
+ test_msg = ('Testing invalid n_bins value : {0}'
+ ''.format(err_n_bins))
+
+ ex_str = None
+ try:
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ err_n_bins,
+ weights=self.weights)[0:2]
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str, expected_txt, msg=test_msg)
+
+ def test_histo_shape(self):
+ """
+ """
+ for err_h_shape in self.err_histo_shapes:
+
+ # windows & python 2.7 : numpy shapes are long values
+ if platform.system() == 'Windows':
+ version = (sys.version_info.major, sys.version_info.minor)
+ if version <= (2, 7):
+ err_h_shape = tuple([long(val) for val in err_h_shape])
+
+ test_msg = ('Testing invalid histo shape : {0}'
+ ''.format(err_h_shape))
+
+ expected_txt = ('Provided <histo> array doesn\'t have '
+ 'a shape compatible with <n_bins> '
+ ': should be {0} instead of {1}.'
+ ''.format(self.h_shape, err_h_shape))
+
+ histo = np.zeros(shape=err_h_shape, dtype=np.uint32)
+
+ ex_str = None
+ try:
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ histo=histo)[0:2]
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str, expected_txt, msg=test_msg)
+
+ def test_histo_dtype(self):
+ """
+ """
+ for err_h_dtype in self.err_histo_dtypes:
+ test_msg = ('Testing invalid histo dtype : {0}'
+ ''.format(err_h_dtype))
+
+ histo = np.zeros(shape=self.h_shape, dtype=err_h_dtype)
+
+ expected_txt = ('Provided <histo> array doesn\'t have '
+ 'the expected type '
+ ': should be {0} instead of {1}.'
+ ''.format(np.uint32, histo.dtype))
+
+ ex_str = None
+ try:
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ histo=histo)[0:2]
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str, expected_txt, msg=test_msg)
+
+ def test_weighted_histo_shape(self):
+ """
+ """
+ # using the same values as histo
+ for err_h_shape in self.err_histo_shapes:
+
+ # windows & python 2.7 : numpy shapes are long values
+ if platform.system() == 'Windows':
+ version = (sys.version_info.major, sys.version_info.minor)
+ if version <= (2, 7):
+ err_h_shape = tuple([long(val) for val in err_h_shape])
+
+ test_msg = ('Testing invalid weighted_histo shape : {0}'
+ ''.format(err_h_shape))
+
+ expected_txt = ('Provided <weighted_histo> array doesn\'t have '
+ 'a shape compatible with <n_bins> '
+ ': should be {0} instead of {1}.'
+ ''.format(self.h_shape, err_h_shape))
+
+ cumul = np.zeros(shape=err_h_shape, dtype=np.double)
+
+ ex_str = None
+ try:
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ weighted_histo=cumul)[0:2]
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str, expected_txt, msg=test_msg)
+
+ def test_cumul_dtype(self):
+ """
+ """
+ # using the same values as histo
+ for err_h_dtype in self.err_histo_dtypes:
+ test_msg = ('Testing invalid weighted_histo dtype : {0}'
+ ''.format(err_h_dtype))
+
+ cumul = np.zeros(shape=self.h_shape, dtype=err_h_dtype)
+
+ expected_txt = ('Provided <weighted_histo> array doesn\'t have '
+ 'the expected type '
+ ': should be {0} or {1} instead of {2}.'
+ ''.format(np.float64, np.float32, cumul.dtype))
+
+ ex_str = None
+ try:
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ weighted_histo=cumul)[0:2]
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str, expected_txt, msg=test_msg)
+
+ def test_wh_histo_dtype(self):
+ """
+ """
+ # using the same values as histo
+ for err_h_dtype in self.err_histo_dtypes:
+ test_msg = ('Testing invalid wh_dtype dtype : {0}'
+ ''.format(err_h_dtype))
+
+ expected_txt = ('<wh_dtype> type not supported : {0}.'
+ ''.format(err_h_dtype))
+
+ ex_str = None
+ try:
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ wh_dtype=err_h_dtype)[0:2]
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str, expected_txt, msg=test_msg)
+
+ def test_unmanaged_dtypes(self):
+ """
+ """
+ for err_unmanaged_dtype in self.err_unmanaged_dtypes:
+ test_msg = ('Testing unmanaged dtypes : {0}'
+ ''.format(err_unmanaged_dtype))
+
+ sample = self.sample.astype(err_unmanaged_dtype[0])
+ weights = self.weights.astype(err_unmanaged_dtype[1])
+
+ expected_txt = ('Case not supported - sample:{0} '
+ 'and weights:{1}.'
+ ''.format(sample.dtype,
+ weights.dtype))
+
+ ex_str = None
+ try:
+ histogramnd(sample,
+ self.histo_range,
+ self.n_bins,
+ weights=weights)
+ except TypeError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str, msg=test_msg)
+ self.assertEqual(ex_str, expected_txt, msg=test_msg)
+
+ def test_uncontiguous_histo(self):
+ """
+ """
+ # non contiguous array
+ shape = np.array(self.n_bins, ndmin=1)
+ shape[0] *= 2
+ histo_tmp = np.zeros(shape)
+ histo = histo_tmp[::2, ...]
+
+ expected_txt = ('<histo> must be a C_CONTIGUOUS numpy array.')
+
+ ex_str = None
+ try:
+ histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ histo=histo)
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str)
+ self.assertEqual(ex_str, expected_txt)
+
+ def test_uncontiguous_weighted_histo(self):
+ """
+ """
+ # non contiguous array
+ shape = np.array(self.n_bins, ndmin=1)
+ shape[0] *= 2
+ cumul_tmp = np.zeros(shape)
+ cumul = cumul_tmp[::2, ...]
+
+ expected_txt = ('<weighted_histo> must be a C_CONTIGUOUS numpy array.')
+
+ ex_str = None
+ try:
+ histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ weighted_histo=cumul)
+ except ValueError as ex:
+ ex_str = str(ex)
+
+ self.assertIsNotNone(ex_str)
+ self.assertEqual(ex_str, expected_txt)
+
+
+class Test_chistogramnd_1D_errors(_Test_chistogramnd_errors):
+ """
+ Unit tests of the 1D histogramnd error cases.
+ """
+
+ def setUp(self):
+ # nominal values
+ self.n_elements = 1000
+ self.s_shape = (self.n_elements,)
+ self.w_shape = (self.n_elements,)
+
+ self.histo_range = [0., 100.]
+ self.n_bins = 10
+
+ self.h_shape = (self.n_bins,)
+
+ self.sample = np.random.randint(0,
+ high=10,
+ size=self.s_shape)
+ self.sample = self.sample.astype(np.double)
+
+ self.weights = np.random.randint(0,
+ high=10,
+ size=self.w_shape)
+ self.weights = self.weights.astype(np.double)
+
+ self.err_weights_shapes = ((self.n_elements+1,),
+ (self.n_elements-1,),
+ (self.n_elements-1, 3))
+ self.err_histo_range_shapes = ([0.],
+ [0., 1., 2.],
+ [[0.], [1.]])
+ self.err_n_bins_shapes = ([10, 2],
+ [[10], [2]])
+ self.err_n_bins_values = (0,
+ [-10],
+ None)
+ self.err_histo_shapes = ((self.n_bins+1,),
+ (self.n_bins-1,),
+ (self.n_bins, self.n_bins))
+ # these are used for testing the histo parameter as well
+ # as the weighted_histo parameter.
+ self.err_histo_dtypes = (np.uint16,
+ np.float16)
+
+ self.err_unmanaged_dtypes = ((np.double, np.uint16),
+ (np.uint16, np.double),
+ (np.uint16, np.uint16))
+
+
+class Test_chistogramnd_ND_errors(_Test_chistogramnd_errors):
+ """
+ Unit tests of the 3D histogramnd error cases.
+ """
+
+ def setUp(self):
+ # nominal values
+ self.n_elements = 1000
+ self.s_shape = (self.n_elements, 3)
+ self.w_shape = (self.n_elements,)
+
+ self.histo_range = [[0., 100.], [0., 100.], [0., 100.]]
+ self.n_bins = (10, 20, 30)
+
+ self.h_shape = self.n_bins
+
+ self.sample = np.random.randint(0,
+ high=10,
+ size=self.s_shape)
+ self.sample = self.sample.astype(np.double)
+
+ self.weights = np.random.randint(0,
+ high=10,
+ size=self.w_shape)
+ self.weights = self.weights.astype(np.double)
+
+ self.err_weights_shapes = ((self.n_elements+1,),
+ (self.n_elements-1,),
+ (self.n_elements-1, 3))
+ self.err_histo_range_shapes = ([0.],
+ [0., 1.],
+ [[0., 10.], [0., 10.]],
+ [0., 10., 0, 10., 0, 10.])
+ self.err_n_bins_shapes = ([10, 2],
+ [[10], [20], [30]])
+ self.err_n_bins_values = (0,
+ [-10],
+ [10, 20, -4],
+ None,
+ [10, None, 30])
+ self.err_histo_shapes = ((self.n_bins[0]+1,
+ self.n_bins[1],
+ self.n_bins[2]),
+ (self.n_bins[0],
+ self.n_bins[1],
+ self.n_bins[2]-1),
+ (self.n_bins[0],
+ self.n_bins[1]),
+ (self.n_bins[1],
+ self.n_bins[0],
+ self.n_bins[2]),
+ (self.n_bins[0],
+ self.n_bins[1],
+ self.n_bins[2],
+ 10)
+ )
+ # these are used for testing the histo parameter as well
+ # as the weighted_histo parameter.
+ self.err_histo_dtypes = (np.uint16,
+ np.float16)
+
+ self.err_unmanaged_dtypes = ((np.double, np.uint16),
+ (np.uint16, np.double),
+ (np.uint16, np.uint16))
+# ==============================================================
+# ==============================================================
+# ==============================================================
+
+
+test_cases = (Test_chistogramnd_1D_errors,
+ Test_chistogramnd_ND_errors,)
+
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/test/test_histogramnd_nominal.py b/silx/math/test/test_histogramnd_nominal.py
new file mode 100644
index 0000000..f4550e4
--- /dev/null
+++ b/silx/math/test/test_histogramnd_nominal.py
@@ -0,0 +1,933 @@
+# 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.
+#
+# ############################################################################*/
+"""
+Nominal tests of the histogramnd function.
+"""
+
+import unittest
+
+import numpy as np
+
+from silx.math.chistogramnd import chistogramnd as histogramnd
+from silx.math import Histogramnd
+
+
+def _get_bin_edges(histo_range, n_bins, n_dims):
+ edges = []
+ for i_dim in range(n_dims):
+ edges.append(histo_range[i_dim, 0] +
+ np.arange(n_bins[i_dim] + 1) *
+ (histo_range[i_dim, 1] - histo_range[i_dim, 0]) /
+ n_bins[i_dim])
+ return tuple(edges)
+
+
+# ==============================================================
+# ==============================================================
+# ==============================================================
+
+
+class _Test_chistogramnd_nominal(unittest.TestCase):
+ """
+ Unit tests of the histogramnd function.
+ """
+
+ ndims = None
+
+ def setUp(self):
+ ndims = self.ndims
+ self.tested_dim = ndims-1
+
+ if ndims is None:
+ raise ValueError('ndims class member not set.')
+
+ sample = np.array([5.5, -3.3,
+ 0., -0.5,
+ 3.3, 8.8,
+ -7.7, 6.0,
+ -4.0])
+
+ weights = np.array([500.5, -300.3,
+ 0.01, -0.5,
+ 300.3, 800.8,
+ -700.7, 600.6,
+ -400.4])
+
+ n_elems = len(sample)
+
+ if ndims == 1:
+ shape = (n_elems,)
+ else:
+ shape = (n_elems, ndims)
+
+ self.sample = np.zeros(shape=shape, dtype=sample.dtype)
+ if ndims == 1:
+ self.sample = sample
+ else:
+ self.sample[..., ndims-1] = sample
+
+ self.weights = weights
+
+ # the tests are performed along one dimension,
+ # all the other bins indices along the other dimensions
+ # are expected to be 2
+ # (e.g : when testing a 2D sample : [0, x] will go into
+ # bin [2, y] because of the bin ranges [-2, 2] and n_bins = 4
+ # for the first dimension)
+ self.other_axes_index = 2
+ self.histo_range = np.repeat([[-2., 2.]], ndims, axis=0)
+ self.histo_range[ndims-1] = [-4., 6.]
+
+ self.n_bins = np.array([4]*ndims)
+ self.n_bins[ndims-1] = 5
+
+ if ndims == 1:
+ def fill_histo(h, v, dim, op=None):
+ if op:
+ h[:] = op(h[:], v)
+ else:
+ h[:] = v
+ self.fill_histo = fill_histo
+ else:
+ def fill_histo(h, v, dim, op=None):
+ idx = [self.other_axes_index]*len(h.shape)
+ idx[dim] = slice(0, None)
+ if op:
+ h[idx] = op(h[idx], v)
+ else:
+ h[idx] = v
+ self.fill_histo = fill_histo
+
+ def test_nominal(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul, bin_edges = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights)
+
+ expected_edges = _get_bin_edges(self.histo_range,
+ self.n_bins,
+ self.ndims)
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ for i_edges, edges in enumerate(expected_edges):
+ self.assertTrue(np.array_equal(bin_edges[i_edges],
+ expected_edges[i_edges]),
+ msg='Testing bin_edges for dim {0}'
+ ''.format(i_edges+1))
+
+ def test_nominal_wh_dtype(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.float32)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul, bin_edges = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ wh_dtype=np.float32)
+
+ self.assertEqual(cumul.dtype, np.float32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.allclose(cumul, expected_c))
+
+ def test_nominal_uncontiguous_sample(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ shape = list(self.sample.shape)
+ shape[0] *= 2
+ sample = np.zeros(shape, dtype=self.sample.dtype)
+ uncontig_sample = sample[::2, ...]
+ uncontig_sample[:] = self.sample
+
+ self.assertFalse(uncontig_sample.flags['C_CONTIGUOUS'],
+ msg='Making sure the array is not contiguous.')
+
+ histo, cumul, bin_edges = histogramnd(uncontig_sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights)
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ def test_nominal_uncontiguous_weights(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ shape = list(self.weights.shape)
+ shape[0] *= 2
+ weights = np.zeros(shape, dtype=self.weights.dtype)
+ uncontig_weights = weights[::2, ...]
+ uncontig_weights[:] = self.weights
+
+ self.assertFalse(uncontig_weights.flags['C_CONTIGUOUS'],
+ msg='Making sure the array is not contiguous.')
+
+ histo, cumul, bin_edges = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=uncontig_weights)
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ def test_nominal_wo_weights(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=None)[0:2]
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(cumul is None)
+
+ def test_nominal_wo_weights_w_cumul(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ # creating an array of ones just to make sure that
+ # it is not cleared by histogramnd
+ cumul_in = np.ones(self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=None,
+ weighted_histo=cumul_in)[0:2]
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(cumul is None)
+ self.assertTrue(np.array_equal(cumul_in,
+ np.ones(shape=self.n_bins,
+ dtype=np.double)))
+
+ def test_nominal_wo_weights_w_histo(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ # creating an array of ones just to make sure that
+ # it is not cleared by histogramnd
+ histo_in = np.ones(self.n_bins, dtype=np.uint32)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=None,
+ histo=histo_in)[0:2]
+
+ self.assertTrue(np.array_equal(histo, expected_h + 1))
+ self.assertTrue(cumul is None)
+ self.assertEqual(id(histo), id(histo_in))
+
+ def test_nominal_last_bin_closed(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 2])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 1101.1])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True)[0:2]
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ def test_int32_weights_double_weights_range(self):
+ """
+ """
+ weight_min = -299.9 # ===> will be cast to -299
+ weight_max = 499.9 # ===> will be cast to 499
+
+ expected_h_tpl = np.array([0, 1, 1, 1, 0])
+ expected_c_tpl = np.array([0., 0., 0., 300., 0.])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights.astype(np.int32),
+ weight_min=weight_min,
+ weight_max=weight_max)[0:2]
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ def test_reuse_histo(self):
+ """
+ """
+
+ expected_h_tpl = np.array([2, 3, 2, 2, 2])
+ expected_c_tpl = np.array([0.0, -7007, -5.0, 0.1, 3003.0])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights)[0:2]
+
+ sample_2 = self.sample[:]
+ if len(sample_2.shape) == 1:
+ idx = [slice(0, None)]
+ else:
+ idx = [slice(0, None), self.tested_dim]
+
+ sample_2[idx] += 2
+
+ histo_2, cumul = histogramnd(sample_2, # <==== !!
+ self.histo_range,
+ self.n_bins,
+ weights=10 * self.weights, # <==== !!
+ histo=histo)[0:2]
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+ self.assertEqual(id(histo), id(histo_2))
+
+ def test_reuse_cumul(self):
+ """
+ """
+
+ expected_h_tpl = np.array([0, 2, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -7007.5, -4.99, 300.4, 3503.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights)[0:2]
+
+ sample_2 = self.sample[:]
+ if len(sample_2.shape) == 1:
+ idx = [slice(0, None)]
+ else:
+ idx = [slice(0, None), self.tested_dim]
+
+ sample_2[idx] += 2
+
+ histo, cumul_2 = histogramnd(sample_2, # <==== !!
+ self.histo_range,
+ self.n_bins,
+ weights=10 * self.weights, # <==== !!
+ weighted_histo=cumul)[0:2]
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.allclose(cumul, expected_c, rtol=10e-15))
+ self.assertEqual(id(cumul), id(cumul_2))
+
+ def test_reuse_cumul_float(self):
+ """
+ """
+
+ expected_h_tpl = np.array([0, 2, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -7007.5, -4.99, 300.4, 3503.5],
+ dtype=np.float32)
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights)[0:2]
+
+ # converting the cumul array to float
+ cumul = cumul.astype(np.float32)
+
+ sample_2 = self.sample[:]
+ if len(sample_2.shape) == 1:
+ idx = [slice(0, None)]
+ else:
+ idx = [slice(0, None), self.tested_dim]
+
+ sample_2[idx] += 2
+
+ histo, cumul_2 = histogramnd(sample_2, # <==== !!
+ self.histo_range,
+ self.n_bins,
+ weights=10 * self.weights, # <==== !!
+ weighted_histo=cumul)[0:2]
+
+ self.assertEqual(cumul.dtype, np.float32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertEqual(id(cumul), id(cumul_2))
+ self.assertTrue(np.allclose(cumul, expected_c, rtol=10e-15))
+
+class _Test_Histogramnd_nominal(unittest.TestCase):
+ """
+ Unit tests of the Histogramnd class.
+ """
+
+ ndims = None
+
+ def setUp(self):
+ ndims = self.ndims
+ self.tested_dim = ndims-1
+
+ if ndims is None:
+ raise ValueError('ndims class member not set.')
+
+ sample = np.array([5.5, -3.3,
+ 0., -0.5,
+ 3.3, 8.8,
+ -7.7, 6.0,
+ -4.0])
+
+ weights = np.array([500.5, -300.3,
+ 0.01, -0.5,
+ 300.3, 800.8,
+ -700.7, 600.6,
+ -400.4])
+
+ n_elems = len(sample)
+
+ if ndims == 1:
+ shape = (n_elems,)
+ else:
+ shape = (n_elems, ndims)
+
+ self.sample = np.zeros(shape=shape, dtype=sample.dtype)
+ if ndims == 1:
+ self.sample = sample
+ else:
+ self.sample[..., ndims-1] = sample
+
+ self.weights = weights
+
+ # the tests are performed along one dimension,
+ # all the other bins indices along the other dimensions
+ # are expected to be 2
+ # (e.g : when testing a 2D sample : [0, x] will go into
+ # bin [2, y] because of the bin ranges [-2, 2] and n_bins = 4
+ # for the first dimension)
+ self.other_axes_index = 2
+ self.histo_range = np.repeat([[-2., 2.]], ndims, axis=0)
+ self.histo_range[ndims-1] = [-4., 6.]
+
+ self.n_bins = np.array([4]*ndims)
+ self.n_bins[ndims-1] = 5
+
+ if ndims == 1:
+ def fill_histo(h, v, dim, op=None):
+ if op:
+ h[:] = op(h[:], v)
+ else:
+ h[:] = v
+ self.fill_histo = fill_histo
+ else:
+ def fill_histo(h, v, dim, op=None):
+ idx = [self.other_axes_index]*len(h.shape)
+ idx[dim] = slice(0, None)
+ if op:
+ h[idx] = op(h[idx], v)
+ else:
+ h[idx] = v
+ self.fill_histo = fill_histo
+
+ def test_nominal(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo = Histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights)
+
+ histo, cumul, bin_edges = histo
+
+ expected_edges = _get_bin_edges(self.histo_range,
+ self.n_bins,
+ self.ndims)
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ for i_edges, edges in enumerate(expected_edges):
+ self.assertTrue(np.array_equal(bin_edges[i_edges],
+ expected_edges[i_edges]),
+ msg='Testing bin_edges for dim {0}'
+ ''.format(i_edges+1))
+
+ def test_nominal_wh_dtype(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.float32)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul, bin_edges = Histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ wh_dtype=np.float32)
+
+ self.assertEqual(cumul.dtype, np.float32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.allclose(cumul, expected_c))
+
+ def test_nominal_uncontiguous_sample(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ shape = list(self.sample.shape)
+ shape[0] *= 2
+ sample = np.zeros(shape, dtype=self.sample.dtype)
+ uncontig_sample = sample[::2, ...]
+ uncontig_sample[:] = self.sample
+
+ self.assertFalse(uncontig_sample.flags['C_CONTIGUOUS'],
+ msg='Making sure the array is not contiguous.')
+
+ histo, cumul, bin_edges = Histogramnd(uncontig_sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights)
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ def test_nominal_uncontiguous_weights(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ shape = list(self.weights.shape)
+ shape[0] *= 2
+ weights = np.zeros(shape, dtype=self.weights.dtype)
+ uncontig_weights = weights[::2, ...]
+ uncontig_weights[:] = self.weights
+
+ self.assertFalse(uncontig_weights.flags['C_CONTIGUOUS'],
+ msg='Making sure the array is not contiguous.')
+
+ histo, cumul, bin_edges = Histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=uncontig_weights)
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ def test_nominal_wo_weights(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+
+ histo, cumul = Histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=None)[0:2]
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(cumul is None)
+
+
+
+ def test_nominal_last_bin_closed(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 2])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 1101.1])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul = Histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True)[0:2]
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ def test_int32_weights_double_weights_range(self):
+ """
+ """
+ weight_min = -299.9 # ===> will be cast to -299
+ weight_max = 499.9 # ===> will be cast to 499
+
+ expected_h_tpl = np.array([0, 1, 1, 1, 0])
+ expected_c_tpl = np.array([0., 0., 0., 300., 0.])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo, cumul = Histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights.astype(np.int32),
+ weight_min=weight_min,
+ weight_max=weight_max)[0:2]
+
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ def test_nominal_no_sample(self):
+ """
+ """
+
+ histo_inst = Histogramnd(None,
+ self.histo_range,
+ self.n_bins)
+
+ histo, weighted_histo, edges = histo_inst
+
+ self.assertIsNone(histo)
+ self.assertIsNone(weighted_histo)
+ self.assertIsNone(edges)
+ self.assertIsNone(histo_inst.histo)
+ self.assertIsNone(histo_inst.weighted_histo)
+ self.assertIsNone(histo_inst.edges)
+
+ def test_empty_init_accumulate(self):
+ """
+ """
+ expected_h_tpl = np.array([2, 1, 1, 1, 1])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo_inst = Histogramnd(None,
+ self.histo_range,
+ self.n_bins)
+
+ histo_inst.accumulate(self.sample,
+ weights=self.weights)
+
+ histo = histo_inst.histo
+ cumul = histo_inst.weighted_histo
+ bin_edges = histo_inst.edges
+
+ expected_edges = _get_bin_edges(self.histo_range,
+ self.n_bins,
+ self.ndims)
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertEqual(histo.dtype, np.uint32)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+ for i_edges, edges in enumerate(expected_edges):
+ self.assertTrue(np.array_equal(bin_edges[i_edges],
+ expected_edges[i_edges]),
+ msg='Testing bin_edges for dim {0}'
+ ''.format(i_edges+1))
+
+ def test_accumulate(self):
+ """
+ """
+
+ expected_h_tpl = np.array([2, 3, 2, 2, 2])
+ expected_c_tpl = np.array([-700.7, -7007.5, -4.99, 300.4, 3503.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo_inst = Histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights)
+
+ sample_2 = self.sample[:]
+ if len(sample_2.shape) == 1:
+ idx = [slice(0, None)]
+ else:
+ idx = [slice(0, None), self.tested_dim]
+
+ sample_2[idx] += 2
+
+ histo_inst.accumulate(sample_2, # <==== !!
+ weights=10 * self.weights) # <==== !!
+
+ histo = histo_inst.histo
+ cumul = histo_inst.weighted_histo
+ bin_edges = histo_inst.edges
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.allclose(cumul, expected_c, rtol=10e-15))
+
+ def test_accumulate_no_weights(self):
+ """
+ """
+
+ expected_h_tpl = np.array([2, 3, 2, 2, 2])
+ expected_c_tpl = np.array([-700.7, -0.5, 0.01, 300.3, 500.5])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo_inst = Histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights)
+
+ sample_2 = self.sample[:]
+ if len(sample_2.shape) == 1:
+ idx = [slice(0, None)]
+ else:
+ idx = [slice(0, None), self.tested_dim]
+
+ sample_2[idx] += 2
+
+ histo_inst.accumulate(sample_2) # <==== !!
+
+ histo = histo_inst.histo
+ cumul = histo_inst.weighted_histo
+ bin_edges = histo_inst.edges
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.allclose(cumul, expected_c, rtol=10e-15))
+
+
+ def test_accumulate_no_weights_at_init(self):
+ """
+ """
+
+ expected_h_tpl = np.array([2, 3, 2, 2, 2])
+ expected_c_tpl = np.array([0.0, -700.7, -0.5, 0.01, 300.3])
+
+ expected_h = np.zeros(shape=self.n_bins, dtype=np.double)
+ expected_c = np.zeros(shape=self.n_bins, dtype=np.double)
+
+ self.fill_histo(expected_h, expected_h_tpl, self.ndims-1)
+ self.fill_histo(expected_c, expected_c_tpl, self.ndims-1)
+
+ histo_inst = Histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=None) # <==== !!
+
+ cumul = histo_inst.weighted_histo
+ self.assertIsNone(cumul)
+
+ sample_2 = self.sample[:]
+ if len(sample_2.shape) == 1:
+ idx = [slice(0, None)]
+ else:
+ idx = [slice(0, None), self.tested_dim]
+
+ sample_2[idx] += 2
+
+ histo_inst.accumulate(sample_2,
+ weights=self.weights) # <==== !!
+
+ histo = histo_inst.histo
+ cumul = histo_inst.weighted_histo
+ bin_edges = histo_inst.edges
+
+ self.assertEqual(cumul.dtype, np.float64)
+ self.assertTrue(np.array_equal(histo, expected_h))
+ self.assertTrue(np.array_equal(cumul, expected_c))
+
+class Test_chistogram_nominal_1d(_Test_chistogramnd_nominal):
+ ndims = 1
+
+
+class Test_chistogram_nominal_2d(_Test_chistogramnd_nominal):
+ ndims = 2
+
+
+class Test_chistogram_nominal_3d(_Test_chistogramnd_nominal):
+ ndims = 3
+
+
+class Test_Histogramnd_nominal_1d(_Test_Histogramnd_nominal):
+ ndims = 1
+
+
+class Test_Histogramnd_nominal_2d(_Test_Histogramnd_nominal):
+ ndims = 2
+
+
+class Test_Histogramnd_nominal_3d(_Test_Histogramnd_nominal):
+ ndims = 3
+
+
+# ==============================================================
+# ==============================================================
+# ==============================================================
+
+
+test_cases = (Test_chistogram_nominal_1d,
+ Test_chistogram_nominal_2d,
+ Test_chistogram_nominal_3d,
+ Test_Histogramnd_nominal_1d,
+ # Test_Histogramnd_nominal_2d,
+ # Test_Histogramnd_nominal_3d
+ )
+
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/test/test_histogramnd_vs_np.py b/silx/math/test/test_histogramnd_vs_np.py
new file mode 100644
index 0000000..36d71f9
--- /dev/null
+++ b/silx/math/test/test_histogramnd_vs_np.py
@@ -0,0 +1,848 @@
+# 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.
+#
+# ############################################################################*/
+"""
+Tests for the histogramnd function.
+Results are compared to numpy's histogramdd.
+"""
+
+import unittest
+import operator
+
+import numpy as np
+
+from silx.math.chistogramnd import chistogramnd as histogramnd
+
+# ==============================================================
+# ==============================================================
+# ==============================================================
+
+_RTOL_DICT = {np.float64: 10**-13,
+ np.float32: 10**-5}
+
+# ==============================================================
+# ==============================================================
+# ==============================================================
+
+
+def _add_values_to_array_if_missing(array, values, n_values):
+ max_in_col = np.any(array[:, ...] == values, axis=0)
+
+ if len(array.shape) == 1:
+ if not max_in_col:
+ rnd_idx = np.random.randint(0,
+ high=len(array)-1,
+ size=(n_values,))
+ array[rnd_idx] = values
+ else:
+ for i in range(len(max_in_col)):
+ if not max_in_col[i]:
+ rnd_idx = np.random.randint(0,
+ high=len(array)-1,
+ size=(n_values,))
+ array[rnd_idx, i] = values[i]
+
+
+def _get_values_index(array, values, op=operator.lt):
+ idx = op(array[:, ...], values)
+ if array.ndim > 1:
+ idx = np.all(idx, axis=1)
+ return np.where(idx)[0]
+
+
+def _get_in_range_indices(array,
+ minvalues,
+ maxvalues,
+ minop=operator.ge,
+ maxop=operator.lt):
+ idx = np.logical_and(minop(array, minvalues),
+ maxop(array, maxvalues))
+ if array.ndim > 1:
+ idx = np.all(idx, axis=1)
+ return np.where(idx)[0]
+
+
+class _TestHistogramnd(unittest.TestCase):
+
+ """
+ Unit tests of the histogramnd function.
+ """
+ sample_rng = None
+ weights_rng = None
+ n_dims = None
+
+ filter_min = None
+ filter_max = None
+
+ histo_range = None
+ n_bins = None
+
+ dtype_sample = None
+ dtype_weights = None
+
+ def generate_data(self):
+
+ self.longMessage = True
+
+ int_min = 0
+ int_max = 100000
+ n_elements = 10**5
+
+ if self.n_dims == 1:
+ shape = (n_elements,)
+ else:
+ shape = (n_elements, self.n_dims,)
+
+ self.rng_state = np.random.get_state()
+
+ self.state_msg = ('Current RNG state :\n'
+ '{0}'.format(self.rng_state))
+
+ sample = np.random.randint(int_min,
+ high=int_max,
+ size=shape)
+
+ sample = sample.astype(self.dtype_sample)
+ sample = (self.sample_rng[0] +
+ (sample-int_min) *
+ (self.sample_rng[1]-self.sample_rng[0]) /
+ (int_max-int_min)).astype(self.dtype_sample)
+
+ weights = np.random.randint(int_min,
+ high=int_max,
+ size=(n_elements,))
+ weights = weights.astype(self.dtype_weights)
+ weights = (self.weights_rng[0] +
+ (weights-int_min) *
+ (self.weights_rng[1]-self.weights_rng[0]) /
+ (int_max-int_min)).astype(self.dtype_weights)
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ # the bins range are cast to the same type as the sample
+ # in order to get the same results as numpy
+ # (which doesnt cast the range)
+ self.histo_range = np.array(self.histo_range).astype(self.dtype_sample)
+
+ # adding some values that are equal to the max
+ # in order to test the opened/closed last bin
+ bins_max = [b[1] for b in self.histo_range]
+ _add_values_to_array_if_missing(sample,
+ bins_max,
+ 100)
+
+ # adding some values that are equal to the min weight value
+ # in order to test the filters
+ _add_values_to_array_if_missing(weights,
+ self.weights_rng[0],
+ 100)
+
+ # adding some values that are equal to the max weight value
+ # in order to test the filters
+ _add_values_to_array_if_missing(weights,
+ self.weights_rng[1],
+ 100)
+
+ return sample, weights
+
+ def setUp(self):
+ self.sample, self.weights = self.generate_data()
+ self.rtol = _RTOL_DICT.get(self.dtype_weights, None)
+
+ def array_compare(self, ar_a, ar_b):
+ if self.rtol is None:
+ return np.array_equal(ar_a, ar_b)
+ return np.allclose(ar_a, ar_b, self.rtol)
+
+ def test_bin_ranges(self):
+ """
+
+ """
+ result_c = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True)
+
+ result_np = np.histogramdd(self.sample,
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ for i_edges, edges in enumerate(result_c[2]):
+ # allclose for now until I can try with the latest version (TBD)
+ # of numpy
+ self.assertTrue(np.allclose(edges,
+ result_np[1][i_edges]),
+ msg='{0}. Testing bin_edges for dim {1}.'
+ ''.format(self.state_msg, i_edges+1))
+
+ def test_last_bin_closed(self):
+ """
+
+ """
+ result_c = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True)
+
+ result_np = np.histogramdd(self.sample,
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ result_np_w = np.histogramdd(self.sample,
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=self.weights)
+
+ # comparing "hits"
+ hits_cmp = np.array_equal(result_c[0],
+ result_np[0])
+ # comparing weights
+ weights_cmp = np.array_equal(result_c[1],
+ result_np_w[0])
+
+ self.assertTrue(hits_cmp, msg=self.state_msg)
+ self.assertTrue(weights_cmp, msg=self.state_msg)
+
+ bins_min = [rng[0] for rng in self.histo_range]
+ bins_max = [rng[1] for rng in self.histo_range]
+ inrange_idx = _get_in_range_indices(self.sample,
+ bins_min,
+ bins_max,
+ minop=operator.ge,
+ maxop=operator.le)
+
+ self.assertEqual(result_c[0].sum(), inrange_idx.shape[0],
+ msg=self.state_msg)
+
+ # we have to sum the weights using the same precision as the
+ # histogramnd function
+ weights_sum = self.weights[inrange_idx].astype(result_c[1].dtype).sum()
+ self.assertTrue(self.array_compare(result_c[1].sum(), weights_sum),
+ msg=self.state_msg)
+
+ def test_last_bin_open(self):
+ """
+
+ """
+ result_c = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=False)
+
+ bins_max = [rng[1] for rng in self.histo_range]
+ filtered_idx = _get_values_index(self.sample, bins_max)
+
+ result_np = np.histogramdd(self.sample[filtered_idx],
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ result_np_w = np.histogramdd(self.sample[filtered_idx],
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=self.weights[filtered_idx])
+
+ # comparing "hits"
+ hits_cmp = np.array_equal(result_c[0], result_np[0])
+ # comparing weights
+ weights_cmp = np.array_equal(result_c[1],
+ result_np_w[0])
+
+ self.assertTrue(hits_cmp, msg=self.state_msg)
+ self.assertTrue(weights_cmp, msg=self.state_msg)
+
+ bins_min = [rng[0] for rng in self.histo_range]
+ bins_max = [rng[1] for rng in self.histo_range]
+ inrange_idx = _get_in_range_indices(self.sample,
+ bins_min,
+ bins_max,
+ minop=operator.ge,
+ maxop=operator.lt)
+
+ self.assertEqual(result_c[0].sum(), len(inrange_idx),
+ msg=self.state_msg)
+ # we have to sum the weights using the same precision as the
+ # histogramnd function
+ weights_sum = self.weights[inrange_idx].astype(result_c[1].dtype).sum()
+ self.assertTrue(self.array_compare(result_c[1].sum(), weights_sum),
+ msg=self.state_msg)
+
+ def test_filter_min(self):
+ """
+
+ """
+ result_c = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True,
+ weight_min=self.filter_min)
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ filter_min = self.dtype_weights(self.filter_min)
+
+ weight_idx = _get_values_index(self.weights,
+ filter_min, # <------ !!!
+ operator.ge)
+
+ result_np = np.histogramdd(self.sample[weight_idx],
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ result_np_w = np.histogramdd(self.sample[weight_idx],
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=self.weights[weight_idx])
+
+ # comparing "hits"
+ hits_cmp = np.array_equal(result_c[0],
+ result_np[0])
+ # comparing weights
+ weights_cmp = np.array_equal(result_c[1], result_np_w[0])
+
+ self.assertTrue(hits_cmp, msg=self.state_msg)
+ self.assertTrue(weights_cmp, msg=self.state_msg)
+
+ bins_min = [rng[0] for rng in self.histo_range]
+ bins_max = [rng[1] for rng in self.histo_range]
+ inrange_idx = _get_in_range_indices(self.sample[weight_idx],
+ bins_min,
+ bins_max,
+ minop=operator.ge,
+ maxop=operator.le)
+
+ inrange_idx = weight_idx[inrange_idx]
+
+ self.assertEqual(result_c[0].sum(), len(inrange_idx),
+ msg=self.state_msg)
+
+ # we have to sum the weights using the same precision as the
+ # histogramnd function
+ weights_sum = self.weights[inrange_idx].astype(result_c[1].dtype).sum()
+ self.assertTrue(self.array_compare(result_c[1].sum(), weights_sum),
+ msg=self.state_msg)
+
+ def test_filter_max(self):
+ """
+
+ """
+ result_c = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True,
+ weight_max=self.filter_max)
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ filter_max = self.dtype_weights(self.filter_max)
+
+ weight_idx = _get_values_index(self.weights,
+ filter_max, # <------ !!!
+ operator.le)
+
+ result_np = np.histogramdd(self.sample[weight_idx],
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ result_np_w = np.histogramdd(self.sample[weight_idx],
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=self.weights[weight_idx])
+
+ # comparing "hits"
+ hits_cmp = np.array_equal(result_c[0],
+ result_np[0])
+ # comparing weights
+ weights_cmp = np.array_equal(result_c[1], result_np_w[0])
+
+ self.assertTrue(hits_cmp, msg=self.state_msg)
+ self.assertTrue(weights_cmp, msg=self.state_msg)
+
+ bins_min = [rng[0] for rng in self.histo_range]
+ bins_max = [rng[1] for rng in self.histo_range]
+ inrange_idx = _get_in_range_indices(self.sample[weight_idx],
+ bins_min,
+ bins_max,
+ minop=operator.ge,
+ maxop=operator.le)
+
+ inrange_idx = weight_idx[inrange_idx]
+
+ self.assertEqual(result_c[0].sum(), len(inrange_idx),
+ msg=self.state_msg)
+
+ # we have to sum the weights using the same precision as the
+ # histogramnd function
+ weights_sum = self.weights[inrange_idx].astype(result_c[1].dtype).sum()
+ self.assertTrue(self.array_compare(result_c[1].sum(), weights_sum),
+ msg=self.state_msg)
+
+ def test_filter_minmax(self):
+ """
+
+ """
+ result_c = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True,
+ weight_min=self.filter_min,
+ weight_max=self.filter_max)
+
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ filter_min = self.dtype_weights(self.filter_min)
+ filter_max = self.dtype_weights(self.filter_max)
+
+ weight_idx = _get_in_range_indices(self.weights,
+ filter_min, # <------ !!!
+ filter_max, # <------ !!!
+ minop=operator.ge,
+ maxop=operator.le)
+
+ result_np = np.histogramdd(self.sample[weight_idx],
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ result_np_w = np.histogramdd(self.sample[weight_idx],
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=self.weights[weight_idx])
+
+ # comparing "hits"
+ hits_cmp = np.array_equal(result_c[0],
+ result_np[0])
+ # comparing weights
+ weights_cmp = np.array_equal(result_c[1], result_np_w[0])
+
+ self.assertTrue(hits_cmp)
+ self.assertTrue(weights_cmp)
+
+ bins_min = [rng[0] for rng in self.histo_range]
+ bins_max = [rng[1] for rng in self.histo_range]
+ inrange_idx = _get_in_range_indices(self.sample[weight_idx],
+ bins_min,
+ bins_max,
+ minop=operator.ge,
+ maxop=operator.le)
+
+ inrange_idx = weight_idx[inrange_idx]
+
+ self.assertEqual(result_c[0].sum(), len(inrange_idx),
+ msg=self.state_msg)
+
+ # we have to sum the weights using the same precision as the
+ # histogramnd function
+ weights_sum = self.weights[inrange_idx].astype(result_c[1].dtype).sum()
+ self.assertTrue(self.array_compare(result_c[1].sum(), weights_sum),
+ msg=self.state_msg)
+
+ def test_reuse_histo(self):
+ """
+
+ """
+ result_c_1 = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True)
+
+ result_np_1 = np.histogramdd(self.sample,
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ np.histogramdd(self.sample,
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=self.weights)
+
+ sample_2, weights_2 = self.generate_data()
+
+ result_c_2 = histogramnd(sample_2,
+ self.histo_range,
+ self.n_bins,
+ weights=weights_2,
+ last_bin_closed=True,
+ histo=result_c_1[0])
+
+ result_np_2 = np.histogramdd(sample_2,
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ result_np_w_2 = np.histogramdd(sample_2,
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=weights_2)
+
+ # comparing "hits"
+ hits_cmp = np.array_equal(result_c_2[0],
+ result_np_1[0] +
+ result_np_2[0])
+ # comparing weights
+ weights_cmp = np.array_equal(result_c_2[1],
+ result_np_w_2[0])
+
+ self.assertTrue(hits_cmp, msg=self.state_msg)
+ self.assertTrue(weights_cmp, msg=self.state_msg)
+
+ def test_reuse_cumul(self):
+ """
+
+ """
+ result_c = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True)
+
+ np.histogramdd(self.sample,
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ result_np_w = np.histogramdd(self.sample,
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=self.weights)
+
+ sample_2, weights_2 = self.generate_data()
+
+ result_c_2 = histogramnd(sample_2,
+ self.histo_range,
+ self.n_bins,
+ weights=weights_2,
+ last_bin_closed=True,
+ weighted_histo=result_c[1])
+
+ result_np_2 = np.histogramdd(sample_2,
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ result_np_w_2 = np.histogramdd(sample_2,
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=weights_2)
+
+ # comparing "hits"
+ hits_cmp = np.array_equal(result_c_2[0],
+ result_np_2[0])
+ # comparing weights
+
+ self.assertTrue(hits_cmp, msg=self.state_msg)
+ self.assertTrue(self.array_compare(result_c_2[1],
+ result_np_w[0] + result_np_w_2[0]),
+ msg=self.state_msg)
+
+ def test_reuse_cumul_float(self):
+ """
+
+ """
+ n_bins = np.array(self.n_bins, ndmin=1)
+ if len(self.sample.shape) == 2:
+ if len(n_bins) == self.sample.shape[1]:
+ shp = tuple([x for x in n_bins])
+ else:
+ shp = (self.n_bins,) * self.sample.shape[1]
+ cumul = np.zeros(shp, dtype=np.float32)
+ else:
+ shp = (self.n_bins,)
+ cumul = np.zeros(shp, dtype=np.float32)
+
+ result_c_1 = histogramnd(self.sample,
+ self.histo_range,
+ self.n_bins,
+ weights=self.weights,
+ last_bin_closed=True,
+ weighted_histo=cumul)
+
+ result_np_1 = np.histogramdd(self.sample,
+ bins=self.n_bins,
+ range=self.histo_range)
+
+ result_np_w_1 = np.histogramdd(self.sample,
+ bins=self.n_bins,
+ range=self.histo_range,
+ weights=self.weights)
+
+ # comparing "hits"
+ hits_cmp = np.array_equal(result_c_1[0],
+ result_np_1[0])
+
+ self.assertTrue(hits_cmp, msg=self.state_msg)
+ self.assertEqual(result_c_1[1].dtype, np.float32, msg=self.state_msg)
+
+ bins_min = [rng[0] for rng in self.histo_range]
+ bins_max = [rng[1] for rng in self.histo_range]
+ inrange_idx = _get_in_range_indices(self.sample,
+ bins_min,
+ bins_max,
+ minop=operator.ge,
+ maxop=operator.le)
+ weights_sum = \
+ self.weights[inrange_idx].astype(np.float32).sum(dtype=np.float64)
+ self.assertTrue(np.allclose(result_c_1[1].sum(dtype=np.float64),
+ weights_sum), msg=self.state_msg)
+ self.assertTrue(np.allclose(result_c_1[1].sum(dtype=np.float64),
+ result_np_w_1[0].sum(dtype=np.float64)),
+ msg=self.state_msg)
+
+
+class _TestHistogramnd_1d(_TestHistogramnd):
+
+ """
+ Unit tests of the 1D histogramnd function.
+ """
+
+ sample_rng = [-55., 100.]
+ weights_rng = [-70., 150.]
+ n_dims = 1
+ filter_min = -15.6
+ filter_max = 85.7
+
+ histo_range = [[-30.2, 90.3]]
+ n_bins = 30
+
+ dtype = None
+
+
+class _TestHistogramnd_2d(_TestHistogramnd):
+
+ """
+ Unit tests of the 1D histogramnd function.
+ """
+
+ sample_rng = [-50.2, 100.99]
+ weights_rng = [70., 150.]
+ n_dims = 2
+ filter_min = 81.7
+ filter_max = 135.3
+
+ histo_range = [[10., 90.], [20., 70.]]
+ n_bins = 30
+
+ dtype = None
+
+
+class _TestHistogramnd_3d(_TestHistogramnd):
+
+ """
+ Unit tests of the 1D histogramnd function.
+ """
+
+ sample_rng = [10.2, 200.9]
+ weights_rng = [0., 100.]
+ n_dims = 3
+ filter_min = 31.5
+ filter_max = 83.7
+
+ histo_range = [[30.8, 150.2], [20.1, 90.9], [10.1, 195.]]
+ n_bins = 30
+
+ dtype = None
+
+
+# ################################################################
+# ################################################################
+# ################################################################
+# ################################################################
+
+
+class TestHistogramnd_1d_double_double(_TestHistogramnd_1d):
+ dtype_sample = np.double
+ dtype_weights = np.double
+
+
+class TestHistogramnd_1d_double_float(_TestHistogramnd_1d):
+ dtype_sample = np.double
+ dtype_weights = np.float32
+
+
+class TestHistogramnd_1d_double_int32(_TestHistogramnd_1d):
+ dtype_sample = np.double
+ dtype_weights = np.int32
+
+
+class TestHistogramnd_1d_float_double(_TestHistogramnd_1d):
+ dtype_sample = np.float32
+ dtype_weights = np.double
+
+
+class TestHistogramnd_1d_float_float(_TestHistogramnd_1d):
+ dtype_sample = np.float32
+ dtype_weights = np.float32
+
+
+class TestHistogramnd_1d_float_int32(_TestHistogramnd_1d):
+ dtype_sample = np.float32
+ dtype_weights = np.int32
+
+
+class TestHistogramnd_1d_int32_double(_TestHistogramnd_1d):
+ dtype_sample = np.int32
+ dtype_weights = np.double
+
+
+class TestHistogramnd_1d_int32_float(_TestHistogramnd_1d):
+ dtype_sample = np.int32
+ dtype_weights = np.float32
+
+
+class TestHistogramnd_1d_int32_int32(_TestHistogramnd_1d):
+ dtype_sample = np.int32
+ dtype_weights = np.int32
+
+
+class TestHistogramnd_2d_double_double(_TestHistogramnd_2d):
+ dtype_sample = np.double
+ dtype_weights = np.double
+
+
+class TestHistogramnd_2d_double_float(_TestHistogramnd_2d):
+ dtype_sample = np.double
+ dtype_weights = np.float32
+
+
+class TestHistogramnd_2d_double_int32(_TestHistogramnd_2d):
+ dtype_sample = np.double
+ dtype_weights = np.int32
+
+
+class TestHistogramnd_2d_float_double(_TestHistogramnd_2d):
+ dtype_sample = np.float32
+ dtype_weights = np.double
+
+
+class TestHistogramnd_2d_float_float(_TestHistogramnd_2d):
+ dtype_sample = np.float32
+ dtype_weights = np.float32
+
+
+class TestHistogramnd_2d_float_int32(_TestHistogramnd_2d):
+ dtype_sample = np.float32
+ dtype_weights = np.int32
+
+
+class TestHistogramnd_2d_int32_double(_TestHistogramnd_2d):
+ dtype_sample = np.int32
+ dtype_weights = np.double
+
+
+class TestHistogramnd_2d_int32_float(_TestHistogramnd_2d):
+ dtype_sample = np.int32
+ dtype_weights = np.float32
+
+
+class TestHistogramnd_2d_int32_int32(_TestHistogramnd_2d):
+ dtype_sample = np.int32
+ dtype_weights = np.int32
+
+
+class TestHistogramnd_3d_double_double(_TestHistogramnd_3d):
+ dtype_sample = np.double
+ dtype_weights = np.double
+
+
+class TestHistogramnd_3d_double_float(_TestHistogramnd_3d):
+ dtype_sample = np.double
+ dtype_weights = np.float32
+
+
+class TestHistogramnd_3d_double_int32(_TestHistogramnd_3d):
+ dtype_sample = np.double
+ dtype_weights = np.int32
+
+
+class TestHistogramnd_3d_float_double(_TestHistogramnd_3d):
+ dtype_sample = np.float32
+ dtype_weights = np.double
+
+
+class TestHistogramnd_3d_float_float(_TestHistogramnd_3d):
+ dtype_sample = np.float32
+ dtype_weights = np.float32
+
+
+class TestHistogramnd_3d_float_int32(_TestHistogramnd_3d):
+ dtype_sample = np.float32
+ dtype_weights = np.int32
+
+
+class TestHistogramnd_3d_int32_double(_TestHistogramnd_3d):
+ dtype_sample = np.int32
+ dtype_weights = np.double
+
+
+class TestHistogramnd_3d_int32_float(_TestHistogramnd_3d):
+ dtype_sample = np.int32
+ dtype_weights = np.float32
+
+
+class TestHistogramnd_3d_int32_int32(_TestHistogramnd_3d):
+ dtype_sample = np.int32
+ dtype_weights = np.int32
+
+
+# ==============================================================
+# ==============================================================
+# ==============================================================
+
+
+test_cases = (TestHistogramnd_1d_double_double,
+ TestHistogramnd_1d_double_float,
+ TestHistogramnd_1d_double_int32,
+ TestHistogramnd_1d_float_double,
+ TestHistogramnd_1d_float_float,
+ TestHistogramnd_1d_float_int32,
+ TestHistogramnd_1d_int32_double,
+ TestHistogramnd_1d_int32_float,
+ TestHistogramnd_1d_int32_int32,
+ TestHistogramnd_2d_double_double,
+ TestHistogramnd_2d_double_float,
+ TestHistogramnd_2d_double_int32,
+ TestHistogramnd_2d_float_double,
+ TestHistogramnd_2d_float_float,
+ TestHistogramnd_2d_float_int32,
+ TestHistogramnd_2d_int32_double,
+ TestHistogramnd_2d_int32_float,
+ TestHistogramnd_2d_int32_int32,
+ TestHistogramnd_3d_double_double,
+ TestHistogramnd_3d_double_float,
+ TestHistogramnd_3d_double_int32,
+ TestHistogramnd_3d_float_double,
+ TestHistogramnd_3d_float_float,
+ TestHistogramnd_3d_float_int32,
+ TestHistogramnd_3d_int32_double,
+ TestHistogramnd_3d_int32_float,
+ TestHistogramnd_3d_int32_int32,)
+
+
+def suite():
+ loader = unittest.defaultTestLoader
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ tests = loader.loadTestsFromTestCase(test_class)
+ test_suite.addTests(tests)
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/math/test/test_marchingcubes.py b/silx/math/test/test_marchingcubes.py
new file mode 100644
index 0000000..d6aa8e9
--- /dev/null
+++ b/silx/math/test/test_marchingcubes.py
@@ -0,0 +1,188 @@
+# 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.
+#
+# ############################################################################*/
+"""Tests of the marchingcubes module"""
+
+from __future__ import division
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+import unittest
+
+import numpy
+
+from silx.test.utils import ParametricTestCase
+
+from silx.math import marchingcubes
+
+
+class TestMarchingCubes(ParametricTestCase):
+ """Tests of marching cubes"""
+
+ def assertAllClose(self, array1, array2, msg=None,
+ rtol=1e-05, atol=1e-08):
+ """Assert that the 2 numpy.ndarrays are almost equal.
+
+ :param str msg: Message to provide when assert fails
+ :param float rtol: Relative tolerance, see :func:`numpy.allclose`
+ :param float atol: Absolute tolerance, see :func:`numpy.allclose`
+ """
+ if not numpy.allclose(array1, array2, rtol, atol):
+ raise self.failureException(msg)
+
+ def test_cube(self):
+ """Unit tests with a single cube"""
+
+ # No isosurface
+ cube_zero = numpy.zeros((2, 2, 2), dtype=numpy.float32)
+
+ result = marchingcubes.MarchingCubes(cube_zero, 1.)
+ self.assertEqual(result.shape, cube_zero.shape)
+ self.assertEqual(result.isolevel, 1.)
+ self.assertEqual(result.invert_normals, True)
+
+ vertices, normals, indices = result
+ self.assertEqual(len(vertices), 0)
+ self.assertEqual(len(normals), 0)
+ self.assertEqual(len(indices), 0)
+
+ # Cube array dimensions: shape = (dim 0, dim 1, dim2)
+ #
+ # dim 0 (Z)
+ # ^
+ # |
+ # 4 +------+ 5
+ # /| /|
+ # / | / |
+ # 6 +------+ 7|
+ # | | | |
+ # |0 +---|--+ 1 -> dim 2 (X)
+ # | / | /
+ # |/ |/
+ # 2 +------+ 3
+ # /
+ # dim 1 (Y)
+
+ # isosurface perpendicular to dim 0 (Z)
+ cube = numpy.array(
+ (((0., 0.), (0., 0.)),
+ ((1., 1.), (1., 1.))), dtype=numpy.float32)
+ level = 0.5
+ vertices, normals, indices = marchingcubes.MarchingCubes(
+ cube, level, invert_normals=False)
+ self.assertAllClose(vertices[:, 0], level)
+ self.assertAllClose(normals, (1., 0., 0.))
+ self.assertEqual(len(indices), 2)
+
+ # isosurface perpendicular to dim 1 (Y)
+ cube = numpy.array(
+ (((0., 0.), (1., 1.)),
+ ((0., 0.), (1., 1.))), dtype=numpy.float32)
+ level = 0.2
+ vertices, normals, indices = marchingcubes.MarchingCubes(cube, level)
+ self.assertAllClose(vertices[:, 1], level)
+ self.assertAllClose(normals, (0., -1., 0.))
+ self.assertEqual(len(indices), 2)
+
+ # isosurface perpendicular to dim 2 (X)
+ cube = numpy.array(
+ (((0., 1.), (0., 1.)),
+ ((0., 1.), (0., 1.))), dtype=numpy.float32)
+ level = 0.9
+ vertices, normals, indices = marchingcubes.MarchingCubes(
+ cube, level, invert_normals=False)
+ self.assertAllClose(vertices[:, 2], level)
+ self.assertAllClose(normals, (0., 0., 1.))
+ self.assertEqual(len(indices), 2)
+
+ # isosurface normal in dim1, dim 0 (Y, Z) plane
+ cube = numpy.array(
+ (((0., 0.), (0., 0.)),
+ ((0., 0.), (1., 1.))), dtype=numpy.float32)
+ level = 0.5
+ vertices, normals, indices = marchingcubes.MarchingCubes(cube, level)
+ self.assertAllClose(normals[:, 2], 0.)
+ self.assertEqual(len(indices), 2)
+
+ def test_sampling(self):
+ """Test different sampling, comparing to reference without sampling"""
+ isolevel = 0.5
+ size = 9
+ chessboard = numpy.zeros((size, size, size), dtype=numpy.float32)
+ chessboard.reshape(-1)[::2] = 1 # OK as long as dimensions are odd
+
+ ref_result = marchingcubes.MarchingCubes(chessboard, isolevel)
+
+ samplings = [
+ (2, 1, 1),
+ (1, 2, 1),
+ (1, 1, 2),
+ (2, 2, 2),
+ (3, 3, 3),
+ (1, 3, 1),
+ (1, 1, 3),
+ ]
+
+ for sampling in samplings:
+ with self.subTest(sampling=sampling):
+ sampling = numpy.array(sampling)
+
+ data = 1e6 * numpy.ones(
+ sampling * size, dtype=numpy.float32)
+ # Copy ref chessboard in data according to sampling
+ data[::sampling[0], ::sampling[1], ::sampling[2]] = chessboard
+
+ result = marchingcubes.MarchingCubes(data, isolevel,
+ sampling=sampling)
+ # Compare vertices normalized with shape
+ self.assertAllClose(
+ ref_result.get_vertices() / ref_result.shape,
+ result.get_vertices() / result.shape,
+ atol=0., rtol=0.)
+
+ # Compare normals
+ # This comparison only works for normals aligned with axes
+ # otherwise non uniform sampling would make different normals
+ self.assertAllClose(ref_result.get_normals(),
+ result.get_normals(),
+ atol=0., rtol=0.)
+
+ self.assertAllClose(ref_result.get_indices(),
+ result.get_indices(),
+ atol=0., rtol=0.)
+
+
+test_cases = (TestMarchingCubes,)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ for test_class in test_cases:
+ test_suite.addTests(
+ unittest.defaultTestLoader.loadTestsFromTestCase(test_class))
+ return test_suite
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/opencl/__init__.py b/silx/opencl/__init__.py
new file mode 100644
index 0000000..b970338
--- /dev/null
+++ b/silx/opencl/__init__.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Project: S I L X project
+# https://github.com/silx-kit/silx
+#
+# Copyright (C) 2012-2017 European Synchrotron Radiation Facility, Grenoble, France
+#
+# Principal author: Jérôme Kieffer (Jerome.Kieffer@ESRF.eu)
+#
+# 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.
+#
+
+__author__ = "Jerome Kieffer"
+__contact__ = "Jerome.Kieffer@ESRF.eu"
+__license__ = "MIT"
+__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
+__date__ = "15/03/2017"
+__status__ = "stable"
+
+import logging
+
+
+logger = logging.getLogger("silx.opencl")
+
+
+from .common import *
diff --git a/silx/opencl/common.py b/silx/opencl/common.py
new file mode 100644
index 0000000..fcb4efa
--- /dev/null
+++ b/silx/opencl/common.py
@@ -0,0 +1,561 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Project: S I L X project
+# https://github.com/silx-kit/silx
+#
+# Copyright (C) 2012-2017 European Synchrotron Radiation Facility, Grenoble, France
+#
+# Principal author: Jérôme Kieffer (Jerome.Kieffer@ESRF.eu)
+#
+# 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.
+#
+
+__author__ = "Jerome Kieffer"
+__contact__ = "Jerome.Kieffer@ESRF.eu"
+__license__ = "MIT"
+__copyright__ = "2012-2017 European Synchrotron Radiation Facility, Grenoble, France"
+__date__ = "15/03/2017"
+__status__ = "stable"
+__all__ = ["ocl", "pyopencl", "mf", "release_cl_buffers", "allocate_cl_buffers",
+ "measure_workgroup_size", "kernel_workgroup_size"]
+
+import os
+import logging
+
+import numpy
+
+from .utils import get_opencl_code
+
+
+logger = logging.getLogger("silx.opencl")
+
+
+if os.environ.get("SILX_OPENCL") in ["0", "False"]:
+ logger.warning("Use of OpenCL has been disables from environment variable: SILX_OPENCL=0")
+ pyopencl = None
+else:
+ try:
+ import pyopencl
+ except ImportError:
+ logger.warning("Unable to import pyOpenCl. Please install it from: http://pypi.python.org/pypi/pyopencl")
+ pyopencl = None
+ class mf(object):
+ WRITE_ONLY = 1
+ READ_ONLY = 1
+ READ_WRITE = 1
+ else:
+ import pyopencl.array as array
+ mf = pyopencl.mem_flags
+
+
+FLOP_PER_CORE = {"GPU": 64, # GPU, Fermi at least perform 64 flops per cycle/multicore, G80 were at 24 or 48 ...
+ "CPU": 4, # CPU, at least intel's have 4 operation per cycle
+ "ACC": 8} # ACC: the Xeon-phi (MIC) appears to be able to process 8 Flops per hyperthreaded-core
+
+# Sources : https://en.wikipedia.org/wiki/CUDA
+NVIDIA_FLOP_PER_CORE = {(1, 0): 24, # Guessed !
+ (1, 1): 24, # Measured on G98 [Quadro NVS 295]
+ (1, 2): 24, # Guessed !
+ (1, 3): 24, # measured on a GT285 (GT200)
+ (2, 0): 64, # Measured on a 580 (GF110)
+ (2, 1): 96, # Measured on Quadro2000 GF106GL
+ (3, 0): 384, # Guessed!
+ (3, 5): 384, # Measured on K20
+ (3, 7): 384, # K80: Guessed!
+ (5, 0): 256, # Maxwell 4 warps/SM 2 flops/ CU
+ (5, 2): 256, # Titan-X
+ (5, 3): 256, # TX1
+ (6, 0): 128, # GP100
+ (6, 1): 128, # GP104
+ (6, 2): 128, # ?
+ (7, 0): 256, # Volta ?
+ (7, 1): 256, # Volta ?
+ }
+
+AMD_FLOP_PER_CORE = 160 # Measured on a M7820 10 core, 700MHz 1120GFlops
+
+
+class Device(object):
+ """
+ Simple class that contains the structure of an OpenCL device
+ """
+ def __init__(self, name="None", dtype=None, version=None, driver_version=None,
+ extensions="", memory=None, available=None,
+ cores=None, frequency=None, flop_core=None, idx=0, workgroup=1):
+ """
+ Simple container with some important data for the OpenCL device description.
+
+ :param name: name of the device
+ :param dtype: device type: CPU/GPU/ACC...
+ :param version: driver version
+ :param driver_version:
+ :param extensions: List of opencl extensions
+ :param memory: maximum memory available on the device
+ :param available: is the device deactivated or not
+ :param cores: number of SM/cores
+ :param frequency: frequency of the device
+ :param flop_core: Flopating Point operation per core per cycle
+ :param idx: index of the device within the platform
+ :param workgroup: max workgroup size
+ """
+ self.name = name.strip()
+ self.type = dtype
+ self.version = version
+ self.driver_version = driver_version
+ self.extensions = extensions.split()
+ self.memory = memory
+ self.available = available
+ self.cores = cores
+ self.frequency = frequency
+ self.id = idx
+ self.max_work_group_size = workgroup
+ if not flop_core:
+ flop_core = FLOP_PER_CORE.get(dtype, 1)
+ if cores and frequency:
+ self.flops = cores * frequency * flop_core
+ else:
+ self.flops = flop_core
+
+ def __repr__(self):
+ return "%s" % self.name
+
+ def pretty_print(self):
+ """
+ Complete device description
+
+ :return: string
+ """
+ lst = ["Name\t\t:\t%s" % self.name,
+ "Type\t\t:\t%s" % self.type,
+ "Memory\t\t:\t%.3f MB" % (self.memory / 2.0 ** 20),
+ "Cores\t\t:\t%s CU" % self.cores,
+ "Frequency\t:\t%s MHz" % self.frequency,
+ "Speed\t\t:\t%.3f GFLOPS" % (self.flops / 1000.),
+ "Version\t\t:\t%s" % self.version,
+ "Available\t:\t%s" % self.available]
+ return os.linesep.join(lst)
+
+
+class Platform(object):
+ """
+ Simple class that contains the structure of an OpenCL platform
+ """
+ def __init__(self, name="None", vendor="None", version=None, extensions=None, idx=0):
+ """
+ Class containing all descriptions of a platform and all devices description within that platform.
+
+ :param name: platform name
+ :param vendor: name of the brand/vendor
+ :param version:
+ :param extensions: list of the extension provided by the platform to all of its devices
+ :param idx: index of the platform
+ """
+ self.name = name.strip()
+ self.vendor = vendor.strip()
+ self.version = version
+ self.extensions = extensions.split()
+ self.devices = []
+ self.id = idx
+
+ def __repr__(self):
+ return "%s" % self.name
+
+ def add_device(self, device):
+ """
+ Add new device to the platform
+
+ :param device: Device instance
+ """
+ self.devices.append(device)
+
+ def get_device(self, key):
+ """
+ Return a device according to key
+
+ :param key: identifier for a device, either it's id (int) or it's name
+ :type key: int or str
+ """
+ out = None
+ try:
+ devid = int(key)
+ except ValueError:
+ for a_dev in self.devices:
+ if a_dev.name == key:
+ out = a_dev
+ else:
+ if len(self.devices) > devid > 0:
+ out = self.devices[devid]
+ return out
+
+
+def _measure_workgroup_size(device_or_context, fast=False):
+ """Mesure the maximal work group size of the given device
+
+ :param device_or_context: instance of pyopencl.Device or pyopencl.Context
+ or 2-tuple (platformid,deviceid)
+ :param fast: ask the kernel the valid value, don't probe it
+ :return: maximum size for the workgroup
+ """
+ if isinstance(device_or_context, pyopencl.Device):
+ ctx = pyopencl.Context(devices=[device_or_context])
+ device = device_or_context
+ elif isinstance(device_or_context, pyopencl.Context):
+ ctx = device_or_context
+ device = device_or_context.devices[0]
+ elif isinstance(device_or_context, (tuple, list)) and len(device_or_context) == 2:
+ ctx = ocl.create_context(platformid=device_or_context[0],
+ deviceid=device_or_context[1])
+ device = ctx.devices[0]
+ else:
+ raise RuntimeError("""given parameter device_or_context is not an
+ instanciation of a device or a context""")
+ shape = device.max_work_group_size
+ # get the context
+
+ assert ctx is not None
+ queue = pyopencl.CommandQueue(ctx)
+
+ max_valid_wg = 1
+ data = numpy.random.random(shape).astype(numpy.float32)
+ d_data = pyopencl.array.to_device(queue, data)
+ d_data_1 = pyopencl.array.zeros_like(d_data) + 1
+
+ program = pyopencl.Program(ctx, get_opencl_code("addition")).build()
+ if fast:
+ max_valid_wg = program.addition.get_work_group_info(pyopencl.kernel_work_group_info.WORK_GROUP_SIZE, device)
+ else:
+ maxi = int(round(numpy.log2(shape)))
+ for i in range(maxi + 1):
+ d_res = pyopencl.array.empty_like(d_data)
+ wg = 1 << i
+ try:
+ evt = program.addition(
+ queue, (shape,), (wg,),
+ d_data.data, d_data_1.data, d_res.data, numpy.int32(shape))
+ evt.wait()
+ except Exception as error:
+ logger.info("%s on device %s for WG=%s/%s", error, device.name, wg, shape)
+ program = queue = d_res = d_data_1 = d_data = None
+ break
+ else:
+ res = d_res.get()
+ good = numpy.allclose(res, data + 1)
+ if good:
+ if wg > max_valid_wg:
+ max_valid_wg = wg
+ else:
+ logger.warning("ArithmeticError on %s for WG=%s/%s", wg, device.name, shape)
+
+ return max_valid_wg
+
+
+def _is_nvidia_gpu(vendor, devtype):
+ return (vendor == "NVIDIA Corporation") and (devtype == "GPU")
+
+
+class OpenCL(object):
+ """
+ Simple class that wraps the structure ocl_tools_extended.h
+
+ This is a static class.
+ ocl should be the only instance and shared among all python modules.
+ """
+
+ platforms = []
+ nb_devices = 0
+ context_cache = {} # key: 2-tuple of int, value: context
+ if pyopencl:
+ platform = device = pypl = devtype = extensions = pydev = None
+ for idx, platform in enumerate(pyopencl.get_platforms()):
+ pypl = Platform(platform.name, platform.vendor, platform.version, platform.extensions, idx)
+ for idd, device in enumerate(platform.get_devices()):
+ ####################################################
+ # Nvidia does not report int64 atomics (we are using) ...
+ # this is a hack around as any nvidia GPU with double-precision supports int64 atomics
+ ####################################################
+ extensions = device.extensions
+ if (pypl.vendor == "NVIDIA Corporation") and ('cl_khr_fp64' in extensions):
+ extensions += ' cl_khr_int64_base_atomics cl_khr_int64_extended_atomics'
+ try:
+ devtype = pyopencl.device_type.to_string(device.type).upper()
+ except ValueError:
+ # pocl does not describe itself as a CPU !
+ devtype = "CPU"
+ if len(devtype) > 3:
+ devtype = devtype[:3]
+ if _is_nvidia_gpu(pypl.vendor, devtype) and "compute_capability_major_nv" in dir(device):
+ comput_cap = device.compute_capability_major_nv, device.compute_capability_minor_nv
+ flop_core = NVIDIA_FLOP_PER_CORE.get(comput_cap, min(NVIDIA_FLOP_PER_CORE.values()))
+ elif (pypl.vendor == "Advanced Micro Devices, Inc.") and (devtype == "GPU"):
+ flop_core = AMD_FLOP_PER_CORE
+ elif devtype == "CPU":
+ flop_core = FLOP_PER_CORE.get(devtype, 1)
+ else:
+ flop_core = 1
+ workgroup = device.max_work_group_size
+ if (devtype == "CPU") and (pypl.vendor == "Apple"):
+ logger.warning("For Apple's OpenCL on CPU: Measuring actual valid max_work_goup_size.")
+ workgroup = _measure_workgroup_size(device, fast=True)
+ if (devtype == "GPU") and os.environ.get("GPU") == "False":
+ # Environment variable to disable GPU devices
+ continue
+ pydev = Device(device.name, devtype, device.version, device.driver_version, extensions,
+ device.global_mem_size, bool(device.available), device.max_compute_units,
+ device.max_clock_frequency, flop_core, idd, workgroup)
+ pypl.add_device(pydev)
+ nb_devices += 1
+ platforms.append(pypl)
+ del platform, device, pypl, devtype, extensions, pydev
+
+ def __repr__(self):
+ out = ["OpenCL devices:"]
+ for platformid, platform in enumerate(self.platforms):
+ deviceids = ["(%s,%s) %s" % (platformid, deviceid, dev.name)
+ for deviceid, dev in enumerate(platform.devices)]
+ out.append("[%s] %s: " % (platformid, platform.name) + ", ".join(deviceids))
+ return os.linesep.join(out)
+
+ def get_platform(self, key):
+ """
+ Return a platform according
+
+ :param key: identifier for a platform, either an Id (int) or it's name
+ :type key: int or str
+ """
+ out = None
+ try:
+ platid = int(key)
+ except ValueError:
+ for a_plat in self.platforms:
+ if a_plat.name == key:
+ out = a_plat
+ else:
+ if len(self.platforms) > platid > 0:
+ out = self.platforms[platid]
+ return out
+
+ def select_device(self, dtype="ALL", memory=None, extensions=None, best=True, **kwargs):
+ """
+ Select a device based on few parameters (at the end, keep the one with most memory)
+
+ :param dtype: "gpu" or "cpu" or "all" ....
+ :param memory: minimum amount of memory (int)
+ :param extensions: list of extensions to be present
+ :param best: shall we look for the
+ """
+ if extensions is None:
+ extensions = []
+ if "type" in kwargs:
+ dtype = kwargs["type"].upper()
+ else:
+ dtype = dtype.upper()
+ if len(dtype) > 3:
+ dtype = dtype[:3]
+ best_found = None
+ for platformid, platform in enumerate(self.platforms):
+ for deviceid, device in enumerate(platform.devices):
+ if (dtype in ["ALL", "DEF"]) or (device.type == dtype):
+ if (memory is None) or (memory <= device.memory):
+ found = True
+ for ext in extensions:
+ if ext not in device.extensions:
+ found = False
+ if found:
+ if not best:
+ return platformid, deviceid
+ else:
+ if not best_found:
+ best_found = platformid, deviceid, device.flops
+ elif best_found[2] < device.flops:
+ best_found = platformid, deviceid, device.flops
+ if best_found:
+ return best_found[0], best_found[1]
+
+ def create_context(self, devicetype="ALL", useFp64=False, platformid=None,
+ deviceid=None, cached=True):
+ """
+ Choose a device and initiate a context.
+
+ Devicetypes can be GPU,gpu,CPU,cpu,DEF,ACC,ALL.
+ Suggested are GPU,CPU.
+ For each setting to work there must be such an OpenCL device and properly installed.
+ E.g.: If Nvidia driver is installed, GPU will succeed but CPU will fail.
+ The AMD SDK kit is required for CPU via OpenCL.
+ :param devicetype: string in ["cpu","gpu", "all", "acc"]
+ :param useFp64: boolean specifying if double precision will be used
+ :param platformid: integer
+ :param deviceid: integer
+ :param cached: True if we want to cache the context
+ :return: OpenCL context on the selected device
+ """
+ if (platformid is not None) and (deviceid is not None):
+ platformid = int(platformid)
+ deviceid = int(deviceid)
+ else:
+ if useFp64:
+ ids = ocl.select_device(type=devicetype, extensions=["cl_khr_int64_base_atomics"])
+ else:
+ ids = ocl.select_device(dtype=devicetype)
+ if ids:
+ platformid = ids[0]
+ deviceid = ids[1]
+ if (platformid is not None) and (deviceid is not None):
+ if (platformid, deviceid) in self.context_cache:
+ ctx = self.context_cache[(platformid, deviceid)]
+ else:
+ ctx = pyopencl.Context(devices=[pyopencl.get_platforms()[platformid].get_devices()[deviceid]])
+ if cached:
+ self.context_cache[(platformid, deviceid)] = ctx
+ else:
+ logger.warning("Last chance to get an OpenCL device ... probably not the one requested")
+ ctx = pyopencl.create_some_context(interactive=False)
+ return ctx
+
+ def device_from_context(self, context):
+ """
+ Retrieves the Device from the context
+
+ :param context: OpenCL context
+ :return: instance of Device
+ """
+ odevice = context.devices[0]
+ oplat = odevice.platform
+ device_id = oplat.get_devices().index(odevice)
+ platform_id = pyopencl.get_platforms().index(oplat)
+ return self.platforms[platform_id].devices[device_id]
+
+if pyopencl:
+ ocl = OpenCL()
+ if ocl.nb_devices == 0:
+ ocl = None
+else:
+ ocl = None
+
+
+def release_cl_buffers(cl_buffers):
+ """
+ :param cl_buffers: the buffer you want to release
+ :type cl_buffers: dict(str, pyopencl.Buffer)
+
+ This method release the memory of the buffers store in the dict
+ """
+ for key, buffer_ in cl_buffers.items():
+ if buffer_ is not None:
+ if isinstance(buffer_, pyopencl.array.Array):
+ try:
+ buffer_.data.release()
+ except pyopencl.LogicError:
+ logger.error("Error while freeing buffer %s", key)
+ else:
+ try:
+ buffer_.release()
+ except pyopencl.LogicError:
+ logger.error("Error while freeing buffer %s", key)
+ cl_buffers[key] = None
+ return cl_buffers
+
+
+def allocate_cl_buffers(buffers, device=None, context=None):
+ """
+ :param buffers: the buffers info use to create the pyopencl.Buffer
+ :type buffers: list(std, flag, numpy.dtype, int)
+ :param device: one of the context device
+ :param context: opencl contextdevice
+ :return: a dict containing the instanciated pyopencl.Buffer
+ :rtype: dict(str, pyopencl.Buffer)
+
+ This method instanciate the pyopencl.Buffer from the buffers
+ description.
+ """
+ mem = {}
+ if device is None:
+ device = ocl.device_from_context(context)
+
+ # check if enough memory is available on the device
+ ualloc = 0
+ for _, _, dtype, size in buffers:
+ ualloc += numpy.dtype(dtype).itemsize * size
+ memory = device.memory
+ logger.info("%.3fMB are needed on device which has %.3fMB",
+ ualloc / 1.0e6, memory / 1.0e6)
+ if ualloc >= memory:
+ memError = "Fatal error in allocate_buffers."
+ memError += "Not enough device memory for buffers"
+ memError += "(%lu requested, %lu available)" % (ualloc, memory)
+ raise MemoryError(memError) # noqa
+
+ # do the allocation
+ try:
+ for name, flag, dtype, size in buffers:
+ mem[name] = pyopencl.Buffer(context, flag,
+ numpy.dtype(dtype).itemsize * size)
+ except pyopencl.MemoryError as error:
+ release_cl_buffers(mem)
+ raise MemoryError(error)
+
+ return mem
+
+
+def measure_workgroup_size(device):
+ """Measure the actual size of the workgroup
+
+ :param device: device or context or 2-tuple with indexes
+ :return: the actual measured workgroup size
+
+ if device is "all", returns a dict with all devices with their ids as keys.
+ """
+ if (ocl is None) or (device is None):
+ return None
+
+ if isinstance(device, tuple) and (len(device) == 2):
+ # this is probably a tuple (platformid, deviceid)
+ device = ocl.create_context(platformid=device[0], deviceid=device[1])
+
+ if device == "all":
+ res = {}
+ for pid, platform in enumerate(ocl.platforms):
+ for did, _devices in enumerate(platform.devices):
+ tup = (pid, did)
+ res[tup] = measure_workgroup_size(tup)
+ else:
+ res = _measure_workgroup_size(device)
+ return res
+
+
+def kernel_workgroup_size(program, kernel):
+ """Extract the compile time maximum workgroup size
+
+ :param program: OpenCL program
+ :param kernel: kernel or name of the kernel
+ :return: the maximum acceptable workgroup size for the given kernel
+ """
+ assert isinstance(program, pyopencl.Program)
+ if not isinstance(kernel, pyopencl.Kernel):
+ kernel_name = kernel
+ assert kernel in (k.function_name for k in program.all_kernels()), "the kernel exists"
+ kernel = program.__getattr__(kernel_name)
+
+ device = program.devices[0]
+ query_wg = pyopencl.kernel_work_group_info.WORK_GROUP_SIZE
+ return kernel.get_work_group_info(query_wg, device)
+
diff --git a/silx/opencl/medfilt.py b/silx/opencl/medfilt.py
new file mode 100644
index 0000000..90cd49a
--- /dev/null
+++ b/silx/opencl/medfilt.py
@@ -0,0 +1,269 @@
+# -*- coding: utf-8 -*-
+#
+# Project: Azimuthal integration
+# https://github.com/silx-kit/pyFAI
+#
+# Copyright (C) 2012-2017 European Synchrotron Radiation Facility, Grenoble, France
+#
+# Principal author: Jérôme Kieffer (Jerome.Kieffer@ESRF.eu)
+#
+# 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.
+
+"""A module for performing the 1d, 2d and 3d median filter ...
+
+The target is to mimic the signature of scipy.signal.medfilt and scipy.medfilt2
+
+The first implementation targets 2D implementation where this operation is costly (~10s/2kx2k image)
+"""
+from __future__ import absolute_import, print_function, with_statement, division
+
+
+__author__ = "Jerome Kieffer"
+__license__ = "MIT"
+__date__ = "15/03/2017"
+__copyright__ = "2012-2017, ESRF, Grenoble"
+__contact__ = "jerome.kieffer@esrf.fr"
+
+import logging
+import numpy
+from collections import OrderedDict
+
+from .common import pyopencl, kernel_workgroup_size
+from .processing import EventDescription, OpenclProcessing, BufferDescription
+
+if pyopencl:
+ mf = pyopencl.mem_flags
+else:
+ raise ImportError("pyopencl is not installed")
+logger = logging.getLogger("silx.opencl.medfilt")
+
+
+class MedianFilter2D(OpenclProcessing):
+ """A class for doing median filtering using OpenCL"""
+ buffers = [
+ BufferDescription("result", 1, numpy.float32, mf.WRITE_ONLY),
+ BufferDescription("image_raw", 1, numpy.float32, mf.READ_ONLY),
+ BufferDescription("image", 1, numpy.float32, mf.READ_WRITE),
+ ]
+ kernel_files = ["preprocess.cl", "bitonic.cl", "medfilt.cl"]
+ mapping = {numpy.int8: "s8_to_float",
+ numpy.uint8: "u8_to_float",
+ numpy.int16: "s16_to_float",
+ numpy.uint16: "u16_to_float",
+ numpy.uint32: "u32_to_float",
+ numpy.int32: "s32_to_float"}
+
+ def __init__(self, shape, kernel_size=(3, 3),
+ ctx=None, devicetype="all", platformid=None, deviceid=None,
+ block_size=None, profile=False
+ ):
+ """Constructor of the OpenCL 2D median filtering class
+
+ :param shape: shape of the images to treat
+ :param kernel size: 2-tuple of odd values
+ :param ctx: actual working context, left to None for automatic
+ initialization from device type or platformid/deviceid
+ :param devicetype: type of device, can be "CPU", "GPU", "ACC" or "ALL"
+ :param platformid: integer with the platform_identifier, as given by clinfo
+ :param deviceid: Integer with the device identifier, as given by clinfo
+ :param block_size: preferred workgroup size, may vary depending on the outpcome of the compilation
+ :param profile: switch on profiling to be able to profile at the kernel level,
+ store profiling elements (makes code slightly slower)
+ """
+ OpenclProcessing.__init__(self, ctx=ctx, devicetype=devicetype,
+ platformid=platformid, deviceid=deviceid,
+ block_size=block_size, profile=profile)
+ self.shape = shape
+ self.size = self.shape[0] * self.shape[1]
+ self.kernel_size = self.calc_kernel_size(kernel_size)
+ self.workgroup_size = (self.calc_wg(self.kernel_size), 1) # 3D kernel
+ self.buffers = [BufferDescription(i.name, i.size * self.size, i.dtype, i.flags)
+ for i in self.__class__.buffers]
+
+ self.allocate_buffers()
+ self.local_mem = self._get_local_mem(self.workgroup_size[0])
+ OpenclProcessing.compile_kernels(self, self.kernel_files, "-D NIMAGE=%i" % self.size)
+ self.set_kernel_arguments()
+
+ def set_kernel_arguments(self):
+ """Parametrize all kernel arguments
+ """
+ for val in self.mapping.values():
+ self.cl_kernel_args[val] = OrderedDict(((i, self.cl_mem[i]) for i in ("image_raw", "image")))
+ self.cl_kernel_args["medfilt2d"] = OrderedDict((("image", self.cl_mem["image"]),
+ ("result", self.cl_mem["result"]),
+ ("local", self.local_mem),
+ ("khs1", numpy.int32(self.kernel_size[0] // 2)), # Kernel half-size along dim1 (lines)
+ ("khs2", numpy.int32(self.kernel_size[1] // 2)), # Kernel half-size along dim2 (columns)
+ ("height", numpy.int32(self.shape[0])), # Image size along dim1 (lines)
+ ("width", numpy.int32(self.shape[1]))))
+# ('debug', self.cl_mem["debug"]))) # Image size along dim2 (columns))
+
+ def _get_local_mem(self, wg):
+ return pyopencl.LocalMemory(wg * 32) # 4byte per float, 8 element per thread
+
+ def send_buffer(self, data, dest):
+ """Send a numpy array to the device, including the cast on the device if possible
+
+ :param data: numpy array with data
+ :param dest: name of the buffer as registered in the class
+ """
+
+ dest_type = numpy.dtype([i.dtype for i in self.buffers if i.name == dest][0])
+ events = []
+ if (data.dtype == dest_type) or (data.dtype.itemsize > dest_type.itemsize):
+ copy_image = pyopencl.enqueue_copy(self.queue, self.cl_mem[dest], numpy.ascontiguousarray(data, dest_type))
+ events.append(EventDescription("copy H->D %s" % dest, copy_image))
+ else:
+ copy_image = pyopencl.enqueue_copy(self.queue, self.cl_mem["image_raw"], numpy.ascontiguousarray(data))
+ kernel = getattr(self.program, self.mapping[data.dtype.type])
+ cast_to_float = kernel(self.queue, (self.size,), None, self.cl_mem["image_raw"], self.cl_mem[dest])
+ events += [EventDescription("copy H->D %s" % dest, copy_image), EventDescription("cast to float", cast_to_float)]
+ if self.profile:
+ self.events += events
+
+ def calc_wg(self, kernel_size):
+ """calculate and return the optimal workgroup size for the first dimension, taking into account
+ the 8-height band
+
+ :param kernel_size: 2-tuple of int, shape of the median window
+ :return: optimal workgroup size
+ """
+ needed_threads = ((kernel_size[0] + 7) // 8) * kernel_size[1]
+ if needed_threads < 8:
+ wg = 8
+ elif needed_threads < 32:
+ wg = 32
+ else:
+ wg = 1 << (int(needed_threads).bit_length())
+ return wg
+
+ def medfilt2d(self, image, kernel_size=None):
+ """Actually apply the median filtering on the image
+
+ :param image: numpy array with the image
+ :param kernel_size: 2-tuple if
+ :return: median-filtered 2D image
+
+
+ Nota: for window size 1x1 -> 7x7 up to 49 / 64 elements in 8 threads, 8elt/th
+ 9x9 -> 15x15 up to 225 / 256 elements in 32 threads, 8elt/th
+ 17x17 -> 21x21 up to 441 / 512 elements in 64 threads, 8elt/th
+
+ TODO: change window size on the fly,
+
+
+ """
+ events = []
+ if kernel_size is None:
+ kernel_size = self.kernel_size
+ else:
+ kernel_size = self.calc_kernel_size(kernel_size)
+ kernel_half_size = kernel_size // numpy.int32(2)
+ # this is the workgroup size
+ wg = self.calc_wg(kernel_size)
+
+ # check for valid work group size:
+ amws = kernel_workgroup_size(self.program, "medfilt2d")
+ logger.warning("max actual workgroup size: %s, expected: %s", amws, wg)
+ if wg > amws:
+ raise RuntimeError("Workgroup size is too big for medfilt2d: %s>%s" % (wg, amws))
+
+ localmem = self._get_local_mem(wg)
+
+ assert image.ndim == 2, "Treat only 2D images"
+ assert image.shape[0] <= self.shape[0], "height is OK"
+ assert image.shape[1] <= self.shape[1], "width is OK"
+
+ with self.sem:
+ self.send_buffer(image, "image")
+
+ kwargs = self.cl_kernel_args["medfilt2d"]
+ kwargs["local"] = localmem
+ kwargs["khs1"] = kernel_half_size[0]
+ kwargs["khs2"] = kernel_half_size[1]
+ kwargs["height"] = numpy.int32(image.shape[0])
+ kwargs["width"] = numpy.int32(image.shape[1])
+# for k, v in kwargs.items():
+# print("%s: %s (%s)" % (k, v, type(v)))
+ mf2d = self.program.medfilt2d(self.queue,
+ (wg, image.shape[1]),
+ (wg, 1), *list(kwargs.values()))
+ events.append(EventDescription("median filter 2d", mf2d))
+
+ result = numpy.empty(image.shape, numpy.float32)
+ ev = pyopencl.enqueue_copy(self.queue, result, self.cl_mem["result"])
+ events.append(EventDescription("copy D->H result", ev))
+ ev.wait()
+ if self.profile:
+ self.events += events
+ return result
+ __call__ = medfilt2d
+
+ @staticmethod
+ def calc_kernel_size(kernel_size):
+ """format the kernel size to be a 2-length numpy array of int32
+ """
+ kernel_size = numpy.asarray(kernel_size, dtype=numpy.int32)
+ if kernel_size.shape == ():
+ kernel_size = numpy.repeat(kernel_size.item(), 2).astype(numpy.int32)
+ for size in kernel_size:
+ if (size % 2) != 1:
+ raise ValueError("Each element of kernel_size should be odd.")
+ return kernel_size
+
+
+class _MedFilt2d(object):
+ median_filter = None
+
+ @classmethod
+ def medfilt2d(cls, ary, kernel_size=3):
+ """Median filter a 2-dimensional array.
+
+ Apply a median filter to the `input` array using a local window-size
+ given by `kernel_size` (must be odd).
+
+ :param ary: A 2-dimensional input array.
+ :param kernel_size: A scalar or a list of length 2, giving the size of the
+ median filter window in each dimension. Elements of
+ `kernel_size` should be odd. If `kernel_size` is a scalar,
+ then this scalar is used as the size in each dimension.
+ Default is a kernel of size (3, 3).
+ :return: An array the same size as input containing the median filtered
+ result. always work on float32 values
+
+ About the padding:
+
+ * The filling mode in scipy.signal.medfilt2d is zero-padding
+ * This implementation is equivalent to:
+ scipy.ndimage.filters.median_filter(ary, kernel_size, mode="nearest")
+
+ """
+ image = numpy.atleast_2d(ary)
+ shape = numpy.array(image.shape)
+ if cls.median_filter is None:
+ cls.median_filter = MedianFilter2D(image.shape, kernel_size)
+ elif (numpy.array(cls.median_filter.shape) < shape).any():
+ # enlarger the buffer size
+ new_shape = numpy.maximum(numpy.array(cls.median_filter.shape), shape)
+ ctx = cls.median_filter.ctx
+ cls.median_filter = MedianFilter2D(new_shape, kernel_size, ctx=ctx)
+ return cls.median_filter.medfilt2d(image)
+
+medfilt2d = _MedFilt2d.medfilt2d
diff --git a/silx/opencl/processing.py b/silx/opencl/processing.py
new file mode 100644
index 0000000..ca46701
--- /dev/null
+++ b/silx/opencl/processing.py
@@ -0,0 +1,275 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Project: S I L X project
+# https://github.com/silx-kit/silx
+#
+# Copyright (C) European Synchrotron Radiation Facility, Grenoble, France
+#
+# Principal author: Jérôme Kieffer (Jerome.Kieffer@ESRF.eu)
+#
+# 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.
+#
+
+"""
+Common OpenCL abstract base classes for different processing
+"""
+
+from __future__ import absolute_import, print_function, division
+
+
+__author__ = "Jerome Kieffer"
+__contact__ = "Jerome.Kieffer@ESRF.eu"
+__license__ = "MIT"
+__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
+__date__ = "03/02/2017"
+__status__ = "stable"
+
+
+import os
+import logging
+import gc
+from collections import namedtuple
+import numpy
+import threading
+from .common import ocl, pyopencl, release_cl_buffers
+from .utils import concatenate_cl_kernel
+
+
+BufferDescription = namedtuple("BufferDescription", ["name", "size", "dtype", "flags"])
+EventDescription = namedtuple("EventDescription", ["name", "event"])
+
+logger = logging.getLogger("pyFAI.opencl.processing")
+
+
+class OpenclProcessing(object):
+ """Abstract class for different types of OpenCL processing.
+
+ This class provides:
+ * Generation of the context, queues, profiling mode
+ * Additional function to allocate/free all buffers declared as static attributes of the class
+ * Functions to compile kernels, cache them and clean them
+ * helper functions to clone the object
+ """
+ # Example of how to create an output buffer of 10 floats
+ buffers = [BufferDescription("output", 10, numpy.float32, None),
+ ]
+ # list of kernel source files to be concatenated before compilation of the program
+ kernel_files = []
+
+ def __init__(self, ctx=None, devicetype="all", platformid=None, deviceid=None,
+ block_size=None, profile=False):
+ """Constructor of the abstract OpenCL processing class
+
+ :param ctx: actual working context, left to None for automatic
+ initialization from device type or platformid/deviceid
+ :param devicetype: type of device, can be "CPU", "GPU", "ACC" or "ALL"
+ :param platformid: integer with the platform_identifier, as given by clinfo
+ :param deviceid: Integer with the device identifier, as given by clinfo
+ :param block_size: preferred workgroup size, may vary depending on the outpcome of the compilation
+ :param profile: switch on profiling to be able to profile at the kernel level,
+ store profiling elements (makes code slightly slower)
+ """
+ self.sem = threading.Semaphore()
+ self.profile = None
+ self.events = [] # List with of EventDescription, kept for profiling
+ self.cl_mem = {} # dict with all buffer allocated
+ self.cl_program = None # The actual OpenCL program
+ self.cl_kernel_args = {} # dict with all kernel arguments
+ if ctx:
+ self.ctx = ctx
+ else:
+ self.ctx = ocl.create_context(devicetype=devicetype, platformid=platformid, deviceid=deviceid)
+ device_name = self.ctx.devices[0].name.strip()
+ platform_name = self.ctx.devices[0].platform.name.strip()
+ platform = ocl.get_platform(platform_name)
+ self.device = platform.get_device(device_name)
+ self.cl_kernel_args = {} # dict with all kernel arguments
+
+ self.set_profiling(profile)
+ self.block_size = block_size
+ self.program = None
+
+ def __del__(self):
+ """Destructor: release all buffers and programs
+ """
+ self.free_kernels()
+ self.free_buffers()
+ self.queue = None
+ self.ctx = None
+ gc.collect()
+
+ def allocate_buffers(self, buffers=None):
+ """
+ Allocate OpenCL buffers required for a specific configuration
+
+ :param buffers: a list of BufferDescriptions, leave to None for
+ paramatrized buffers.
+
+ Note that an OpenCL context also requires some memory, as well
+ as Event and other OpenCL functionalities which cannot and are
+ not taken into account here. The memory required by a context
+ varies depending on the device. Typical for GTX580 is 65Mb but
+ for a 9300m is ~15Mb In addition, a GPU will always have at
+ least 3-5Mb of memory in use. Unfortunately, OpenCL does NOT
+ have a built-in way to check the actual free memory on a
+ device, only the total memory.
+ """
+
+ if buffers is None:
+ buffers = self.buffers
+
+ with self.sem:
+ mem = {}
+
+ # check if enough memory is available on the device
+ ualloc = 0
+ for buf in buffers:
+ ualloc += numpy.dtype(buf.dtype).itemsize * buf.size
+ logger.info("%.3fMB are needed on device which has %.3fMB",
+ ualloc / 1.0e6, self.device.memory / 1.0e6)
+
+ if ualloc >= self.device.memory:
+ raise MemoryError("Fatal error in allocate_buffers. Not enough "
+ " device memory for buffers (%lu requested, %lu available)"
+ % (ualloc, self.device.memory))
+
+ # do the allocation
+ try:
+ for buf in buffers:
+ size = numpy.dtype(buf.dtype).itemsize * buf.size
+ mem[buf.name] = pyopencl.Buffer(self.ctx, buf.flags, size)
+ except pyopencl.MemoryError as error:
+ release_cl_buffers(mem)
+ raise MemoryError(error)
+
+ self.cl_mem.update(mem)
+
+ def free_buffers(self):
+ """free all device.memory allocated on the device
+ """
+ with self.sem:
+ for key, buf in list(self.cl_mem.items()):
+ if buf is not None:
+ if isinstance(buf, pyopencl.array.Array):
+ try:
+ buf.data.release()
+ except pyopencl.LogicError:
+ logger.error("Error while freeing buffer %s", key)
+ else:
+ try:
+ buf.release()
+ except pyopencl.LogicError:
+ logger.error("Error while freeing buffer %s", key)
+ self.cl_mem[key] = None
+
+ def compile_kernels(self, kernel_files=None, compile_options=None):
+ """Call the OpenCL compiler
+
+ :param kernel_files: list of path to the kernel
+ (by default use the one declared in the class)
+ :param compile_options: string of compile options
+ """
+ # concatenate all needed source files into a single openCL module
+ kernel_files = kernel_files or self.kernel_files
+ kernel_src = concatenate_cl_kernel(kernel_files)
+
+ compile_options = compile_options or ""
+ logger.info("Compiling file %s with options %s", kernel_files, compile_options)
+ try:
+ self.program = pyopencl.Program(self.ctx, kernel_src).build(options=compile_options)
+ except (pyopencl.MemoryError, pyopencl.LogicError) as error:
+ raise MemoryError(error)
+
+ def free_kernels(self):
+ """Free all kernels
+ """
+ for kernel in self.cl_kernel_args:
+ self.cl_kernel_args[kernel] = []
+ self.program = None
+
+ def set_profiling(self, value=True):
+ """Switch On/Off the profiling flag of the command queue to allow debugging
+
+ :param value: set to True to enable profiling, or to False to disable it.
+ Without profiling, the processing is marginally faster
+
+ Profiling information can then be retrieved with the 'log_profile' method
+ """
+ if bool(value) != self.profile:
+ with self.sem:
+ self.profile = bool(value)
+ if self.profile:
+ self.queue = pyopencl.CommandQueue(self.ctx,
+ properties=pyopencl.command_queue_properties.PROFILING_ENABLE)
+ else:
+ self.queue = pyopencl.CommandQueue(self.ctx)
+
+ def log_profile(self):
+ """If we are in profiling mode, prints out all timing for every single OpenCL call
+ """
+ t = 0.0
+ out = ["", "Profiling info for OpenCL %s" % self.__class__.__name__]
+ if self.profile:
+ for e in self.events:
+ if "__len__" in dir(e) and len(e) >= 2:
+ et = 1e-6 * (e[1].profile.end - e[1].profile.start)
+ out.append("%50s:\t%.3fms" % (e[0], et))
+ t += et
+
+ out.append("_" * 80)
+ out.append("%50s:\t%.3fms" % ("Total execution time", t))
+ logger.info(os.linesep.join(out))
+ return out
+
+# This should be implemented by concrete class
+# def __copy__(self):
+# """Shallow copy of the object
+#
+# :return: copy of the object
+# """
+# return self.__class__((self._data, self._indices, self._indptr),
+# self.size, block_size=self.BLOCK_SIZE,
+# platformid=self.platform.id,
+# deviceid=self.device.id,
+# checksum=self.on_device.get("data"),
+# profile=self.profile, empty=self.empty)
+#
+# def __deepcopy__(self, memo=None):
+# """deep copy of the object
+#
+# :return: deepcopy of the object
+# """
+# if memo is None:
+# memo = {}
+# new_csr = self._data.copy(), self._indices.copy(), self._indptr.copy()
+# memo[id(self._data)] = new_csr[0]
+# memo[id(self._indices)] = new_csr[1]
+# memo[id(self._indptr)] = new_csr[2]
+# new_obj = self.__class__(new_csr, self.size,
+# block_size=self.BLOCK_SIZE,
+# platformid=self.platform.id,
+# deviceid=self.device.id,
+# checksum=self.on_device.get("data"),
+# profile=self.profile, empty=self.empty)
+# memo[id(self)] = new_obj
+# return new_obj
diff --git a/silx/opencl/setup.py b/silx/opencl/setup.py
new file mode 100644
index 0000000..d0181cd
--- /dev/null
+++ b/silx/opencl/setup.py
@@ -0,0 +1,44 @@
+# 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.
+#
+
+from __future__ import division
+
+__contact__ = "jerome.kieffer@esrf.eu"
+__license__ = "MIT"
+__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
+__authors__ = ["J. Kieffer"]
+__date__ = "08/09/2016"
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('opencl', parent_package, top_path)
+ config.add_subpackage('sift')
+ config.add_subpackage('test')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
diff --git a/silx/opencl/test/__init__.py b/silx/opencl/test/__init__.py
new file mode 100644
index 0000000..24aa06e
--- /dev/null
+++ b/silx/opencl/test/__init__.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+#
+# Project: silx
+# https://github.com/silx-kit/silx
+#
+# Copyright (C) 2012-2016 European Synchrotron Radiation Facility, Grenoble, France
+# 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.
+
+__authors__ = ["J. Kieffer"]
+__license__ = "MIT"
+__date__ = "15/03/2017"
+
+import unittest
+from . import test_addition
+from . import test_medfilt
+from ..sift import test as test_sift
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTests(test_addition.suite())
+ test_suite.addTests(test_medfilt.suite())
+ test_suite.addTests(test_sift.suite())
+
+ return test_suite
diff --git a/silx/opencl/test/test_addition.py b/silx/opencl/test/test_addition.py
new file mode 100644
index 0000000..89e49be
--- /dev/null
+++ b/silx/opencl/test/test_addition.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Project: Sift implementation in Python + OpenCL
+# https://github.com/silx-kit/silx
+#
+# 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.
+
+"""
+Simple test of an addition
+"""
+
+from __future__ import division, print_function
+
+__authors__ = ["Henri Payno, Jérôme Kieffer"]
+__contact__ = "jerome.kieffer@esrf.eu"
+__license__ = "MIT"
+__copyright__ = "2013 European Synchrotron Radiation Facility, Grenoble, France"
+__date__ = "15/03/2017"
+
+import logging
+import numpy
+
+import unittest
+from ..common import ocl, _measure_workgroup_size
+if ocl:
+ import pyopencl
+ import pyopencl.array
+from ..utils import get_opencl_code
+logger = logging.getLogger(__name__)
+
+
+@unittest.skipUnless(ocl, "PyOpenCl is missing")
+class TestAddition(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestAddition, cls).setUpClass()
+ if ocl:
+ cls.ctx = ocl.create_context()
+ if logger.getEffectiveLevel() <= logging.INFO:
+ cls.PROFILE = True
+ cls.queue = pyopencl.CommandQueue(
+ cls.ctx,
+ properties=pyopencl.command_queue_properties.PROFILING_ENABLE)
+ else:
+ cls.PROFILE = False
+ cls.queue = pyopencl.CommandQueue(cls.ctx)
+ cls.max_valid_wg = 0
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestAddition, cls).tearDownClass()
+ print("Maximum valid workgroup size %s on device %s" % (cls.max_valid_wg, cls.ctx.devices[0]))
+ cls.ctx = None
+ cls.queue = None
+
+ def setUp(self):
+ if ocl is None:
+ return
+ self.shape = 4096
+ self.data = numpy.random.random(self.shape).astype(numpy.float32)
+ self.d_array_img = pyopencl.array.to_device(self.queue, self.data)
+ self.d_array_5 = pyopencl.array.zeros_like(self.d_array_img) - 5
+ self.program = pyopencl.Program(self.ctx, get_opencl_code("addition")).build()
+
+ def tearDown(self):
+ self.img = self.data = None
+ self.d_array_img = self.d_array_5 = self.program = None
+
+ @unittest.skipUnless(ocl, "pyopencl is missing")
+ def test_add(self):
+ """
+ tests the addition kernel
+ """
+ maxi = int(round(numpy.log2(self.shape)))
+ for i in range(maxi):
+ d_array_result = pyopencl.array.empty_like(self.d_array_img)
+ wg = 1 << i
+ try:
+ evt = self.program.addition(self.queue, (self.shape,), (wg,),
+ self.d_array_img.data, self.d_array_5.data, d_array_result.data, numpy.int32(self.shape))
+ evt.wait()
+ except Exception as error:
+ max_valid_wg = self.program.addition.get_work_group_info(pyopencl.kernel_work_group_info.WORK_GROUP_SIZE, self.ctx.devices[0])
+ msg = "Error %s on WG=%s: %s" % (error, wg, max_valid_wg)
+ self.assertLess(max_valid_wg, wg, msg)
+ break
+ else:
+ res = d_array_result.get()
+ good = numpy.allclose(res, self.data - 5)
+ if good and wg>self.max_valid_wg:
+ self.__class__.max_valid_wg = wg
+ self.assert_(good, "calculation is correct for WG=%s" % wg)
+
+ @unittest.skipUnless(ocl, "pyopencl is missing")
+ def test_measurement(self):
+ """
+ tests that all devices are working properly ...
+ """
+ for platform in ocl.platforms:
+ for did, device in enumerate(platform.devices):
+ meas = _measure_workgroup_size((platform.id, device.id))
+ self.assertEqual(meas, device.max_work_group_size,
+ "Workgroup size for %s/%s: %s == %s" % (platform, device, meas, device.max_work_group_size))
+
+
+def suite():
+ testSuite = unittest.TestSuite()
+ testSuite.addTest(TestAddition("test_add"))
+ testSuite.addTest(TestAddition("test_measurement"))
+ return testSuite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/opencl/test/test_medfilt.py b/silx/opencl/test/test_medfilt.py
new file mode 100644
index 0000000..f4e4cc8
--- /dev/null
+++ b/silx/opencl/test/test_medfilt.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Project: Median filter of images + OpenCL
+# https://github.com/silx-kit/silx
+#
+# 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.
+
+"""
+Simple test of the median filter
+"""
+
+from __future__ import division, print_function
+
+__authors__ = ["Jérôme Kieffer"]
+__contact__ = "jerome.kieffer@esrf.eu"
+__license__ = "MIT"
+__copyright__ = "2013-2017 European Synchrotron Radiation Facility, Grenoble, France"
+__date__ = "15/03/2017"
+
+
+import sys
+import time
+import logging
+import numpy
+import unittest
+from collections import namedtuple
+try:
+ import mako
+except ImportError:
+ mako = None
+from ..common import ocl
+if ocl:
+ import pyopencl
+ import pyopencl.array
+ from .. import medfilt
+
+logger = logging.getLogger(__name__)
+
+Result = namedtuple("Result", ["size", "error", "sp_time", "oc_time"])
+
+try:
+ from scipy.misc import ascent
+except:
+ def ascent():
+ """Dummy image from random data"""
+ return numpy.random.random((512, 512))
+try:
+ from scipy.ndimage import filters
+ median_filter = filters.median_filter
+ HAS_SCIPY = True
+except:
+ HAS_SCIPY = False
+ from silx.math import medfilt2d as median_filter
+
+@unittest.skipUnless(ocl and mako, "PyOpenCl is missing")
+class TestMedianFilter(unittest.TestCase):
+
+ def setUp(self):
+ if ocl is None:
+ return
+ self.data = ascent().astype(numpy.float32)
+ self.medianfilter = medfilt.MedianFilter2D(self.data.shape, devicetype="gpu")
+
+ def tearDown(self):
+ self.data = None
+ self.medianfilter = None
+
+ def measure(self, size):
+ "Common measurement of accuracy and timings"
+ t0 = time.time()
+ if HAS_SCIPY:
+ ref = median_filter(self.data, size, mode="nearest")
+ else:
+ ref = median_filter(self.data, size)
+ t1 = time.time()
+ try:
+ got = self.medianfilter.medfilt2d(self.data, size)
+ except RuntimeError as msg:
+ logger.error(msg)
+ return
+ t2 = time.time()
+ delta = abs(got - ref).max()
+ return Result(size, delta, t1 - t0, t2 - t1)
+
+ @unittest.skipUnless(ocl and mako, "pyopencl is missing")
+ def test_medfilt(self):
+ """
+ tests the median filter kernel
+ """
+ r = self.measure(size=11)
+ if r is None:
+ logger.info("test_medfilt: size: %s: skipped")
+ else:
+ logger.info("test_medfilt: size: %s error %s, t_ref: %.3fs, t_ocl: %.3fs" % r)
+ self.assert_(r.error == 0, 'Results are correct')
+
+ def benchmark(self, limit=36):
+ "Run some benchmarking"
+ try:
+ import PyQt5
+ from ...gui.matplotlib import pylab
+ from ...gui.utils import update_fig
+ except:
+ pylab = None
+
+ def update_fig(*ag, **kwarg):
+ pass
+
+ fig = pylab.figure()
+ fig.suptitle("Median filter of an image 512x512")
+ sp = fig.add_subplot(1, 1, 1)
+ sp.set_title(self.medianfilter.ctx.devices[0].name)
+ sp.set_xlabel("Window width & height")
+ sp.set_ylabel("Execution time (s)")
+ sp.set_xlim(2, limit + 1)
+ sp.set_ylim(0, 4)
+ data_size = []
+ data_scipy = []
+ data_opencl = []
+ plot_sp = sp.plot(data_size, data_scipy, "-or", label="scipy")[0]
+ plot_opencl = sp.plot(data_size, data_opencl, "-ob", label="opencl")[0]
+ sp.legend(loc=2)
+ fig.show()
+ update_fig(fig)
+ for s in range(3, limit, 2):
+ r = self.measure(s)
+ print(r)
+ if r.error == 0:
+ data_size.append(s)
+ data_scipy.append(r.sp_time)
+ data_opencl.append(r.oc_time)
+ plot_sp.set_data(data_size, data_scipy)
+ plot_opencl.set_data(data_size, data_opencl)
+ update_fig(fig)
+ fig.show()
+ if sys.version_info[0] < 3:
+ raw_input()
+ else:
+ input()
+
+
+def suite():
+ testSuite = unittest.TestSuite()
+ testSuite.addTest(TestMedianFilter("test_medfilt"))
+ return testSuite
+
+
+def benchmark():
+ testSuite = unittest.TestSuite()
+ testSuite.addTest(TestMedianFilter("benchmark"))
+ return testSuite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest="suite")
diff --git a/silx/opencl/utils.py b/silx/opencl/utils.py
new file mode 100644
index 0000000..58becb0
--- /dev/null
+++ b/silx/opencl/utils.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Project: Sift implementation in Python + OpenCL
+# https://github.com/silx-kit/silx
+#
+# 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.
+
+
+from __future__ import division
+
+__authors__ = ["Jérôme Kieffer", "Pierre Paleo"]
+__contact__ = "jerome.kieffer@esrf.eu"
+__license__ = "MIT"
+__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
+__date__ = "15/03/2017"
+__status__ = "Production"
+
+import os
+import numpy
+from ..resources import resource_filename
+from math import log, ceil
+
+
+def calc_size(shape, blocksize):
+ """
+ Calculate the optimal size for a kernel according to the workgroup size
+ """
+ if "__len__" in dir(blocksize):
+ return tuple((int(i) + int(j) - 1) & ~(int(j) - 1) for i, j in zip(shape, blocksize))
+ else:
+ return tuple((int(i) + int(blocksize) - 1) & ~(int(blocksize) - 1) for i in shape)
+
+
+def nextpower(n):
+ """Calculate the power of two
+
+ :param n: an integer, for example 100
+ :return: another integer, 100-> 128
+ """
+ return 1 << int(ceil(log(n, 2)))
+
+
+def sizeof(shape, dtype="uint8"):
+ """
+ Calculate the number of bytes needed to allocate for a given structure
+
+ :param shape: size or tuple of sizes
+ :param dtype: data type
+ """
+ itemsize = numpy.dtype(dtype).itemsize
+ cnt = 1
+ if "__len__" in dir(shape):
+ for dim in shape:
+ cnt *= dim
+ else:
+ cnt = int(shape)
+ return cnt * itemsize
+
+
+def get_cl_file(filename):
+ """get the full path of a openCL file
+
+ :return: the full path of the openCL source file
+ """
+ if not filename.endswith(".cl"):
+ filename += ".cl"
+ return resource_filename(os.path.join("opencl", filename))
+
+
+def read_cl_file(filename):
+ """
+ :param filename: read an OpenCL file and apply a preprocessor
+ :return: preprocessed source code
+ """
+ with open(get_cl_file(filename), "r") as f:
+ # Dummy preprocessor which removes the #include
+ lines = [i for i in f.readlines() if not i.startswith("#include ")]
+ return "".join(lines)
+
+get_opencl_code = read_cl_file
+
+
+def concatenate_cl_kernel(filenames):
+ """Concatenates all the kernel from the list of files
+
+ :param filenames: filenames containing the kernels
+ :type filenames: list of str which can be filename of kernel as a string.
+ :return: a string with all kernels concatenated
+
+ this method concatenates all the kernel from the list
+ """
+ return os.linesep.join(read_cl_file(fn) for fn in filenames)
diff --git a/silx/resources/__init__.py b/silx/resources/__init__.py
new file mode 100644
index 0000000..f5b06cb
--- /dev/null
+++ b/silx/resources/__init__.py
@@ -0,0 +1,310 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Access project's data and documentation files.
+
+All access to data and documentation files MUST be made through the functions
+of this modules to ensure access across different distribution schemes:
+
+- Installing from source or from wheel
+- Installing package as a zip (through the use of pkg_resources)
+- Linux packaging willing to install data files (and doc files) in
+ alternative folders. In this case, this file must be patched.
+- Frozen fat binary application using silx (frozen with cx_Freeze or py2app).
+ This needs special care for the resource files in the setup:
+
+ - With cx_Freeze, add silx/resources to include_files:
+
+ .. code-block:: python
+
+ import silx.resources
+ silx_include_files = (os.path.dirname(silx.resources.__file__),
+ os.path.join('silx', 'resources'))
+ setup(...
+ options={'build_exe': {'include_files': [silx_include_files]}}
+ )
+
+ - With py2app, add silx in the packages list of the py2app options:
+
+ .. code-block:: python
+
+ setup(...
+ options={'py2app': {'packages': ['silx']}}
+ )
+"""
+
+__authors__ = ["V.A. Sole", "Thomas Vincent", "J. Kieffer"]
+__license__ = "MIT"
+__date__ = "02/05/2017"
+
+
+import os
+import sys
+import threading
+import json
+import getpass
+import logging
+import tempfile
+import unittest
+from silx.third_party import six
+logger = logging.getLogger(__name__)
+
+
+# pkg_resources is useful when this package is stored in a zip
+# When pkg_resources is not available, the resources dir defaults to the
+# directory containing this module.
+try:
+ import pkg_resources
+except ImportError:
+ pkg_resources = None
+
+
+# For packaging purpose, patch this variable to use an alternative directory
+# E.g., replace with _RESOURCES_DIR = '/usr/share/silx/data'
+_RESOURCES_DIR = None
+
+# For packaging purpose, patch this variable to use an alternative directory
+# E.g., replace with _RESOURCES_DIR = '/usr/share/silx/doc'
+# Not in use, uncomment when functionality is needed
+# _RESOURCES_DOC_DIR = None
+
+# cx_Freeze frozen support
+# See http://cx-freeze.readthedocs.io/en/latest/faq.html#using-data-files
+if getattr(sys, 'frozen', False):
+ # Running in a frozen application:
+ # We expect resources to be located either in a silx/resources/ dir
+ # relative to the executable or within this package.
+ _dir = os.path.join(os.path.dirname(sys.executable), 'silx', 'resources')
+ if os.path.isdir(_dir):
+ _RESOURCES_DIR = _dir
+
+
+def resource_filename(resource):
+ """Return filename corresponding to resource.
+
+ resource can be the name of either a file or a directory.
+ The existence of the resource is not checked.
+
+ :param str resource: Resource path relative to resource directory
+ using '/' path separator.
+ :return: Absolute resource path in the file system
+ """
+ # Not in use, uncomment when functionality is needed
+ # If _RESOURCES_DOC_DIR is set, use it to get resources in doc/ subfoldler
+ # from an alternative directory.
+ # if _RESOURCES_DOC_DIR is not None and (resource is 'doc' or
+ # resource.startswith('doc/')):
+ # # Remove doc folder from resource relative path
+ # return os.path.join(_RESOURCES_DOC_DIR, *resource.split('/')[1:])
+
+ if _RESOURCES_DIR is not None: # if set, use this directory
+ return os.path.join(_RESOURCES_DIR, *resource.split('/'))
+ elif pkg_resources is None: # Fallback if pkg_resources is not available
+ return os.path.join(os.path.abspath(os.path.dirname(__file__)),
+ *resource.split('/'))
+ else: # Preferred way to get resources as it supports zipfile package
+ return pkg_resources.resource_filename(__name__, resource)
+
+
+class ExternalResources(object):
+ """Utility class which allows to download test-data from www.silx.org
+ and manage the temporary data during the tests.
+
+ """
+
+ def __init__(self, project,
+ url_base,
+ env_key=None,
+ timeout=60):
+ """Constructor of the class
+
+ :param project: name of the project, like "silx"
+ :param url_base: base URL for the data, like "http://www.silx.org/pub"
+ :param env_key: name of the environment variable which contains the
+ test_data directory like "SILX_DATA"
+ :param timeout: time in seconds before it breaks
+ """
+ self.project = project
+ self._initialized = False
+ self._tempdir = None
+ self.sem = threading.Semaphore()
+ self.env_key = env_key
+ self.url_base = url_base
+ self.all_data = set()
+ self.timeout = timeout
+
+ def _initialize_tmpdir(self):
+ """Initialize the temporary directory"""
+ if not self._tempdir:
+ with self.sem:
+ if not self._tempdir:
+ self._tempdir = tempfile.mkdtemp("_" + getpass.getuser(),
+ self.project + "_")
+
+ def _initialize_data(self):
+ """Initialize for downloading test data"""
+ if not self._initialized:
+ with self.sem:
+ if not self._initialized:
+
+ self.data_home = os.environ.get(self.env_key)
+ if self.data_home is None:
+ self.data_home = os.path.join(tempfile.gettempdir(),
+ "%s_testdata_%s" % (self.project, getpass.getuser()))
+ if not os.path.exists(self.data_home):
+ os.makedirs(self.data_home)
+ self.testdata = os.path.join(self.data_home, "all_testdata.json")
+ if os.path.exists(self.testdata):
+ with open(self.testdata) as f:
+ self.all_data = set(json.load(f))
+ self._initialized = True
+
+ @property
+ def tempdir(self):
+ if not self._tempdir:
+ self._initialize_tmpdir()
+ return self._tempdir
+
+ def clean_up(self):
+ """Removes the temporary directory (and all its content !)"""
+ with self.sem:
+ if not self._tempdir:
+ return
+ if not os.path.isdir(self._tempdir):
+ return
+ for root, dirs, files in os.walk(self._tempdir, topdown=False):
+ for name in files:
+ os.remove(os.path.join(root, name))
+ for name in dirs:
+ os.rmdir(os.path.join(root, name))
+ os.rmdir(self._tempdir)
+ self._tempdir = None
+
+ def getfile(self, filename):
+ """Downloads the requested file from web-server available
+ at https://www.silx.org/pub/silx/
+
+ :param: relative name of the image.
+ :return: full path of the locally saved file.
+ """
+ logger.debug("ExternalResources.getfile('%s')", filename)
+
+ if not self._initialized:
+ self._initialize_data()
+
+ if not os.path.exists(self.data_home):
+ os.makedirs(self.data_home)
+
+ fullfilename = os.path.abspath(os.path.join(self.data_home, filename))
+
+ if not os.path.isfile(fullfilename):
+ logger.debug("Trying to download image %s, timeout set to %ss",
+ filename, self.timeout)
+ dictProxies = {}
+ if "http_proxy" in os.environ:
+ dictProxies['http'] = os.environ["http_proxy"]
+ dictProxies['https'] = os.environ["http_proxy"]
+ if "https_proxy" in os.environ:
+ dictProxies['https'] = os.environ["https_proxy"]
+ if dictProxies:
+ proxy_handler = six.moves.urllib.request.ProxyHandler(dictProxies)
+ opener = six.moves.urllib.request.build_opener(proxy_handler).open
+ else:
+ opener = six.moves.urllib.request.urlopen
+
+ logger.debug("wget %s/%s", self.url_base, filename)
+ try:
+ data = opener("%s/%s" % (self.url_base, filename),
+ data=None, timeout=self.timeout).read()
+ logger.info("Image %s successfully downloaded.", filename)
+ except six.moves.urllib.error.URLError:
+ raise unittest.SkipTest("network unreachable.")
+
+ try:
+ with open(fullfilename, "wb") as outfile:
+ outfile.write(data)
+ except IOError:
+ raise IOError("unable to write downloaded \
+ data to disk at %s" % self.data_home)
+
+ if not os.path.isfile(fullfilename):
+ raise RuntimeError("Could not automatically \
+ download test images %s!\n \ If you are behind a firewall, \
+ please set both environment variable http_proxy and https_proxy.\
+ This even works under windows ! \n \
+ Otherwise please try to download the images manually from \n%s/%s"\
+ % (filename, self.url_base, filename))
+
+ if filename not in self.all_data:
+ self.all_data.add(filename)
+ image_list = list(self.all_data)
+ image_list.sort()
+ try:
+ with open(self.testdata, "w") as fp:
+ json.dump(image_list, fp, indent=4)
+ except IOError:
+ logger.debug("Unable to save JSON list")
+
+ return fullfilename
+
+ def getdir(self, dirname):
+ """Downloads the requested tarball from the server
+ https://www.silx.org/pub/silx/
+ and unzips it into the data directory
+
+ :param: relative name of the image.
+ :return: full path of the locally saved file.
+ """
+ lodn = dirname.lower()
+ if (lodn.endswith("tar") or lodn.endswith("tgz") or
+ lodn.endswith("tbz2") or lodn.endswith("tar.gz") or
+ lodn.endswith("tar.bz2")):
+ import tarfile
+ engine = tarfile.TarFile
+ elif lodn.endswith("zip"):
+ import zipfile
+ engine = zipfile.ZipFile
+ else:
+ raise RuntimeError("Unsupported archive format. Only tar and zip "
+ "are currently supported")
+ full_path = self.getfile(dirname)
+ with engine.open(full_path) as fd:
+ fd.extractall(self.data_home)
+ return full_path
+
+ def download_all(self, imgs=None):
+ """Download all data needed for the test/benchmarks
+
+ :param imgs: list of files to download, by default all
+ :return: list of path with all files
+ """
+ if not self._initialized:
+ self._initialize_data()
+ if not imgs:
+ imgs = self.all_data
+ res = []
+ for fn in imgs:
+ logger.info("Downloading from silx.org: %s", fn)
+ res.append(self.getfile(fn))
+ return res
diff --git a/silx/resources/gui/icons/3d-plane-normal-x.png b/silx/resources/gui/icons/3d-plane-normal-x.png
new file mode 100644
index 0000000..bf8cf45
--- /dev/null
+++ b/silx/resources/gui/icons/3d-plane-normal-x.png
Binary files differ
diff --git a/silx/resources/gui/icons/3d-plane-normal-x.svg b/silx/resources/gui/icons/3d-plane-normal-x.svg
new file mode 100644
index 0000000..6bd2986
--- /dev/null
+++ b/silx/resources/gui/icons/3d-plane-normal-x.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)" stroke="#000">
+ <path d="m12.5 1039.9v-18" fill="none" stroke="#008000" stroke-linecap="round" stroke-miterlimit="2" stroke-width="2"/>
+ <path d="m30.5 1039.9h-18" fill="none" stroke="#F00" stroke-linecap="round" stroke-miterlimit="2" stroke-width="2"/>
+ <path transform="matrix(1 0 -.69517 .71885 0 0)" d="m1018.3 1461.8v-15.133" fill="none" stroke="#00F" stroke-linecap="round" stroke-miterlimit="0" stroke-width="2.3589"/>
+ <rect transform="matrix(0 -1 -.70641 .70781 0 0)" x="-1062.6" y="-31.854" width="18" height="15.399" fill="#f7941e" fill-opacity=".81569" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1898"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/3d-plane-normal-y.png b/silx/resources/gui/icons/3d-plane-normal-y.png
new file mode 100644
index 0000000..733b92a
--- /dev/null
+++ b/silx/resources/gui/icons/3d-plane-normal-y.png
Binary files differ
diff --git a/silx/resources/gui/icons/3d-plane-normal-y.svg b/silx/resources/gui/icons/3d-plane-normal-y.svg
new file mode 100644
index 0000000..b2977e0
--- /dev/null
+++ b/silx/resources/gui/icons/3d-plane-normal-y.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)" stroke="#000">
+ <path d="m12.5 1039.9v-18" fill="none" stroke="#008000" stroke-linecap="round" stroke-miterlimit="2" stroke-width="2"/>
+ <path d="m30.5 1039.9h-18" fill="none" stroke="#F00" stroke-linecap="round" stroke-miterlimit="2" stroke-width="2"/>
+ <path transform="matrix(1 0 -.69517 .71885 0 0)" d="m1018.3 1461.8v-15.133" fill="none" stroke="#00F" stroke-linecap="round" stroke-miterlimit="0" stroke-width="2.3589"/>
+ <rect transform="matrix(1 0 -.70625 .70796 0 0)" x="1041.7" y="1457.5" width="18" height="15.365" fill="#f7941e" fill-opacity=".81569" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1885"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/3d-plane-normal-z.png b/silx/resources/gui/icons/3d-plane-normal-z.png
new file mode 100644
index 0000000..0ab61e6
--- /dev/null
+++ b/silx/resources/gui/icons/3d-plane-normal-z.png
Binary files differ
diff --git a/silx/resources/gui/icons/3d-plane-normal-z.svg b/silx/resources/gui/icons/3d-plane-normal-z.svg
new file mode 100644
index 0000000..ce540fb
--- /dev/null
+++ b/silx/resources/gui/icons/3d-plane-normal-z.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)">
+ <path d="m12.5 1039.9v-18" fill="none" stroke="#008000" stroke-linecap="round" stroke-miterlimit="2" stroke-width="2"/>
+ <path d="m30.5 1039.9h-18" fill="none" stroke="#F00" stroke-linecap="round" stroke-miterlimit="2" stroke-width="2"/>
+ <path transform="matrix(1 0 -.69517 .71885 0 0)" d="m1018.3 1461.8v-15.133" fill="none" stroke="#00F" stroke-linecap="round" stroke-miterlimit="0" stroke-width="2.3589"/>
+ <g transform="translate(-24.646 -1.4219)" stroke="#000">
+ <rect x="31.61" y="1029.2" width="18" height="18" ry="0" fill="#f7941e" fill-opacity=".81569" stroke-miterlimit="2"/>
+ </g>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/3d-plane.png b/silx/resources/gui/icons/3d-plane.png
new file mode 100644
index 0000000..6181d42
--- /dev/null
+++ b/silx/resources/gui/icons/3d-plane.png
Binary files differ
diff --git a/silx/resources/gui/icons/3d-plane.svg b/silx/resources/gui/icons/3d-plane.svg
new file mode 100644
index 0000000..a473593
--- /dev/null
+++ b/silx/resources/gui/icons/3d-plane.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path d="m12.5 19.538v-18" fill="none" stroke="#008000" stroke-linecap="round" stroke-miterlimit="2" stroke-width="2"/>
+ <path d="m30.5 19.538h-18" fill="none" stroke="#F00" stroke-linecap="round" stroke-miterlimit="2" stroke-width="2"/>
+ <path d="m2.1003 30.446 10.52-10.879" fill="none" stroke="#00F" stroke-linecap="round" stroke-miterlimit="0" stroke-width="2"/>
+ <path d="m12.881 4.6102-7.7285 22.78 21.694-7.729z" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-width="1px"/>
+</svg>
diff --git a/silx/resources/gui/icons/animated/process-working-00.png b/silx/resources/gui/icons/animated/process-working-00.png
new file mode 100644
index 0000000..a787ab7
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-00.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-01.png b/silx/resources/gui/icons/animated/process-working-01.png
new file mode 100644
index 0000000..297ed4e
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-01.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-02.png b/silx/resources/gui/icons/animated/process-working-02.png
new file mode 100644
index 0000000..f2c3a59
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-02.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-03.png b/silx/resources/gui/icons/animated/process-working-03.png
new file mode 100644
index 0000000..75a4b85
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-03.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-04.png b/silx/resources/gui/icons/animated/process-working-04.png
new file mode 100644
index 0000000..12fe098
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-04.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-05.png b/silx/resources/gui/icons/animated/process-working-05.png
new file mode 100644
index 0000000..ec0b2bf
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-05.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-06.png b/silx/resources/gui/icons/animated/process-working-06.png
new file mode 100644
index 0000000..9dca9eb
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-06.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-07.png b/silx/resources/gui/icons/animated/process-working-07.png
new file mode 100644
index 0000000..ca8a18c
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-07.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-08.png b/silx/resources/gui/icons/animated/process-working-08.png
new file mode 100644
index 0000000..abd1210
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-08.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-09.png b/silx/resources/gui/icons/animated/process-working-09.png
new file mode 100644
index 0000000..a0f362f
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-09.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-10.png b/silx/resources/gui/icons/animated/process-working-10.png
new file mode 100644
index 0000000..cc8b968
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-10.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-11.png b/silx/resources/gui/icons/animated/process-working-11.png
new file mode 100644
index 0000000..f5da609
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-11.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-12.png b/silx/resources/gui/icons/animated/process-working-12.png
new file mode 100644
index 0000000..92e2159
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-12.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-13.png b/silx/resources/gui/icons/animated/process-working-13.png
new file mode 100644
index 0000000..6e9e8d7
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-13.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-14.png b/silx/resources/gui/icons/animated/process-working-14.png
new file mode 100644
index 0000000..3f2141b
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-14.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-15.png b/silx/resources/gui/icons/animated/process-working-15.png
new file mode 100644
index 0000000..1043659
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-15.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-16.png b/silx/resources/gui/icons/animated/process-working-16.png
new file mode 100644
index 0000000..a8d89fc
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-16.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-17.png b/silx/resources/gui/icons/animated/process-working-17.png
new file mode 100644
index 0000000..5b68f03
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-17.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-18.png b/silx/resources/gui/icons/animated/process-working-18.png
new file mode 100644
index 0000000..cf0ff96
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-18.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-19.png b/silx/resources/gui/icons/animated/process-working-19.png
new file mode 100644
index 0000000..661effd
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-19.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-20.png b/silx/resources/gui/icons/animated/process-working-20.png
new file mode 100644
index 0000000..e1c77aa
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-20.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-21.png b/silx/resources/gui/icons/animated/process-working-21.png
new file mode 100644
index 0000000..10861e7
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-21.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-22.png b/silx/resources/gui/icons/animated/process-working-22.png
new file mode 100644
index 0000000..38907dc
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-22.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-23.png b/silx/resources/gui/icons/animated/process-working-23.png
new file mode 100644
index 0000000..7ec4915
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-23.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-24.png b/silx/resources/gui/icons/animated/process-working-24.png
new file mode 100644
index 0000000..2e90357
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-24.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-25.png b/silx/resources/gui/icons/animated/process-working-25.png
new file mode 100644
index 0000000..6ffa1a7
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-25.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-26.png b/silx/resources/gui/icons/animated/process-working-26.png
new file mode 100644
index 0000000..b8ae153
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-26.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-27.png b/silx/resources/gui/icons/animated/process-working-27.png
new file mode 100644
index 0000000..4d3c716
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-27.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-28.png b/silx/resources/gui/icons/animated/process-working-28.png
new file mode 100644
index 0000000..dd88b9c
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-28.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-29.png b/silx/resources/gui/icons/animated/process-working-29.png
new file mode 100644
index 0000000..985e115
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-29.png
Binary files differ
diff --git a/silx/resources/gui/icons/animated/process-working-30.png b/silx/resources/gui/icons/animated/process-working-30.png
new file mode 100644
index 0000000..f2c6d3d
--- /dev/null
+++ b/silx/resources/gui/icons/animated/process-working-30.png
Binary files differ
diff --git a/silx/resources/gui/icons/arrow-keys.png b/silx/resources/gui/icons/arrow-keys.png
new file mode 100644
index 0000000..bf83e29
--- /dev/null
+++ b/silx/resources/gui/icons/arrow-keys.png
Binary files differ
diff --git a/silx/resources/gui/icons/arrow-keys.svg b/silx/resources/gui/icons/arrow-keys.svg
new file mode 100644
index 0000000..5b573c3
--- /dev/null
+++ b/silx/resources/gui/icons/arrow-keys.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata>
+<g transform="translate(0 -2.4249)"><g transform="translate(-12.499 4.4866)"><rect x="12.999" y="15.013" width="9" height="9" fill="none" stroke="#f7941e"/><g transform="translate(-20.022 -1.5293)"><path transform="translate(20.1 1.5293)" d="m17.469 16.375-3.2188 3.2188 3.2188 3.2188v-2.125h3.0625l0.0625-1.0938-0.0625-1.0938h-3.0625v-2.125z"/></g></g><g transform="matrix(0 -1 1 0 -3.5134 41.499)"><rect x="12.999" y="15.013" width="9" height="9" fill="none" stroke="#f7941e"/><g transform="translate(-20.022 -1.5293)"><path transform="translate(20.1 1.5293)" d="m17.469 16.375-3.2188 3.2188 3.2188 3.2188v-2.125h3.0625l0.0625-1.0938-0.0625-1.0938h-3.0625v-2.125z"/></g></g><g transform="matrix(-1 0 0 -1 44.499 43.513)"><rect x="12.999" y="15.013" width="9" height="9" fill="none" stroke="#f7941e"/><g transform="translate(-20.022 -1.5293)"><path transform="translate(20.1 1.5293)" d="m17.469 16.375-3.2188 3.2188 3.2188 3.2188v-2.125h3.0625l0.0625-1.0938-0.0625-1.0938h-3.0625v-2.125z"/></g></g><g transform="matrix(0 1 -1 0 35.513 -4.6495)"><rect x="12.999" y="15.013" width="9" height="9" fill="none" stroke="#f7941e"/><g transform="translate(-20.022 -1.5293)"><path transform="translate(20.1 1.5293)" d="m17.469 16.375-3.2188 3.2188 3.2188 3.2188v-2.125h3.0625l0.0625-1.0938-0.0625-1.0938h-3.0625v-2.125z"/></g></g></g></svg>
diff --git a/silx/resources/gui/icons/camera.png b/silx/resources/gui/icons/camera.png
new file mode 100644
index 0000000..ec3e62c
--- /dev/null
+++ b/silx/resources/gui/icons/camera.png
Binary files differ
diff --git a/silx/resources/gui/icons/camera.svg b/silx/resources/gui/icons/camera.svg
new file mode 100644
index 0000000..d0335fa
--- /dev/null
+++ b/silx/resources/gui/icons/camera.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)">
+ <g transform="translate(-.25 -.037824)">
+ <rect x="3.5" y="1030.4" width="16" height="12" rx="2"/>
+ <path d="m22 1033.1 6-2c0.52557-0.1752 1 0.446 1 1v8c0 0.554-0.47443 1.1752-1 1l-6-2c-0.52557-0.1752-1-0.446-1-1v-4c0-0.554 0.47443-0.8248 1-1z"/>
+ </g>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/clipboard.png b/silx/resources/gui/icons/clipboard.png
new file mode 100644
index 0000000..03b6297
--- /dev/null
+++ b/silx/resources/gui/icons/clipboard.png
Binary files differ
diff --git a/silx/resources/gui/icons/clipboard.svg b/silx/resources/gui/icons/clipboard.svg
new file mode 100644
index 0000000..7754fd1
--- /dev/null
+++ b/silx/resources/gui/icons/clipboard.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<path d="m18.462 32" stroke="#fff" stroke-miterlimit="10" stroke-width=".51"/>
+ <path d="M24.652,29.335c0,0.279-0.229,0.51-0.51,0.51H7.933 c-0.28,0-0.51-0.23-0.51-0.51V9.894c0-0.28,0.229-0.51,0.51-0.51h16.21c0.28,0,0.51,0.229,0.51,0.51V29.335z" fill="none" stroke="#F7941E" stroke-miterlimit="10" stroke-width="2"/>
+<path d="m21.096 14.341c-3.148 0.465-6.283 0.526-9.449 0.201-0.412-0.042-1.197 1.319-0.892 1.35 3.167 0.326 6.3 0.265 9.451-0.201 0.455-0.067 1.085-1.379 0.89-1.35z" fill="#58595B"/>
+<path d="m20.494 17.759c-2.973-0.041-5.935 0.023-8.898 0.252-0.449 0.035-1.12 1.367-0.892 1.35 2.964-0.23 5.926-0.293 8.897-0.25 0.435 5e-3 1.164-1.348 0.893-1.352z" fill="#414042"/>
+<path d="m14.21 20.825c-0.835 0.094-1.675 0.059-2.513 0.102-0.304 0.014-0.622 0.486-0.766 0.707-0.041 0.061-0.407 0.656-0.126 0.643 0.838-0.041 1.678-0.01 2.513-0.102 0.313-0.035 0.613-0.473 0.766-0.705 0.034-0.053 0.407-0.674 0.126-0.645z" fill="#6D6E71"/>
+<path d="m20.997 23.892c-3.111-0.518-6.223 0.045-9.351-0.051-0.43-0.014-1.168 1.344-0.892 1.35 3.127 0.096 6.24-0.467 9.35 0.051 0.393 0.068 1.22-1.296 0.893-1.35z" fill="#414042"/>
+ <path d="m22.104 11.433c0.28 0.473 0.06 0.862-0.49 0.864l-11.152 0.041c-0.55 2e-3 -0.773-0.385-0.496-0.86l5.534-9.49c0.277-0.475 0.733-0.477 1.013-3e-3l5.591 9.448z" fill="#fff"/>
+ <path d="m20.53 10.277c0.287 0.469 0.072 0.852-0.478 0.851l-7.951-0.019c-0.55-1e-3 -0.772-0.391-0.495-0.865l3.847-6.572c0.278-0.475 0.74-0.479 1.027-0.01l4.05 6.615z" fill="#F7941E"/>
+<path d="m17.557 7.12c0 0.816-0.66 1.48-1.478 1.48-0.819 0-1.481-0.664-1.481-1.48 0-0.82 0.662-1.482 1.481-1.482 0.818 0 1.478 0.662 1.478 1.482z" fill="#fff"/>
+<circle cx="16.037" cy="3.481" r="1.142" fill="#F7941E"/>
+</svg>
diff --git a/silx/resources/gui/icons/close.png b/silx/resources/gui/icons/close.png
new file mode 100755
index 0000000..181b3fd
--- /dev/null
+++ b/silx/resources/gui/icons/close.png
Binary files differ
diff --git a/silx/resources/gui/icons/close.svg b/silx/resources/gui/icons/close.svg
new file mode 100644
index 0000000..f98ec95
--- /dev/null
+++ b/silx/resources/gui/icons/close.svg
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3086"
+ xml:space="preserve"><metadata
+ id="metadata3115"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3113"><filter
+ x="-0.14179821"
+ y="-0.14627124"
+ width="1.2835964"
+ height="1.2925425"
+ color-interpolation-filters="sRGB"
+ id="filter7174"><feGaussianBlur
+ id="feGaussianBlur7176"
+ stdDeviation="0.9522046" /></filter></defs><radialGradient
+ cx="13.553"
+ cy="18.115999"
+ r="9.3607998"
+ fx="17.403"
+ fy="10.383"
+ id="a"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3706,0,0,1.3276,-2.5752,-8.0518)"><stop
+ id="stop3089"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0.0279" /><stop
+ id="stop3091"
+ style="stop-color:#ffeddb;stop-opacity:1"
+ offset="0.3066" /><stop
+ id="stop3093"
+ style="stop-color:#fed09e;stop-opacity:1"
+ offset="0.5122" /><stop
+ id="stop3095"
+ style="stop-color:#fdc587;stop-opacity:1"
+ offset="0.58660001" /><stop
+ id="stop3097"
+ style="stop-color:#f9a13c;stop-opacity:1"
+ offset="0.83029997" /><stop
+ id="stop3099"
+ style="stop-color:#f7941e;stop-opacity:1"
+ offset="0.94080001" /></radialGradient><ellipse
+ cx="16"
+ cy="16"
+ rx="12.83"
+ ry="12.427"
+ id="ellipse3101"
+ style="fill:url(#a)" /><path
+ d="m 22.89734,9.1277334 c -0.39375,0.002 -0.79775,0.17675 -1.09375,0.46875 l -5.375,5.2500006 -5.4375,-5.2187506 c -0.602,-0.58 -1.5592499,-0.583 -2.1562499,0 -0.598,0.5840006 -0.602,1.5470006 0,2.1250006 l 5.4374999,5.21875 -5.3749999,5.25 c -0.599,0.583 -0.605,1.51675 0,2.09375 0.601,0.577 1.5904999,0.586 2.1874999,0 l 5.375,-5.25 5.4375,5.1875 c 0.605,0.578 1.55825,0.584 2.15625,0 0.596,-0.58 0.598,-1.51475 0,-2.09375 l -5.4375,-5.21875 5.375,-5.25 c 0.594,-0.584 0.602,-1.547999 0,-2.1250006 -0.301,-0.29 -0.7,-0.4395 -1.09375,-0.4375 z"
+ id="path3107-3"
+ style="filter:url(#filter7174)" /><g
+ id="g3105"
+ style="fill:#414042;stroke:#414042;stroke-width:0.30000001;stroke-miterlimit:10"><path
+ d="M 10.627,23.362 C 10.03,23.948 9.058,23.95 8.457,23.373 7.852,22.796 7.847,21.852 8.446,21.269 L 21.373,8.637 c 0.592,-0.584 1.57,-0.59 2.172,-0.01 0.602,0.577 0.604,1.519 0.01,2.103 L 10.627,23.362 z"
+ id="path3107" /><path
+ d="m 21.439,23.315 c 0.605,0.578 1.578,0.575 2.176,-0.009 0.596,-0.58 0.588,-1.526 -0.01,-2.105 L 10.558,8.685 C 9.956,8.105 8.984,8.109 8.387,8.692 7.789,9.276 7.794,10.219 8.396,10.797 l 13.043,12.518 z"
+ id="path3109" /></g></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/colormap.png b/silx/resources/gui/icons/colormap.png
new file mode 100755
index 0000000..48a6e52
--- /dev/null
+++ b/silx/resources/gui/icons/colormap.png
Binary files differ
diff --git a/silx/resources/gui/icons/colormap.svg b/silx/resources/gui/icons/colormap.svg
new file mode 100644
index 0000000..03c9672
--- /dev/null
+++ b/silx/resources/gui/icons/colormap.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+ <path d="m16.831 7c-0.206-1.621-2.504-1.482-3.643-1.048-2.667 1.016-4.664 2.552-6.696 4.454-3.776 3.541-8.54 12.757-2.391 16.604 6.31 3.944 26.231-2.853 26.321-15.534 0.082-12.117-14.64 5.746-14.425-0.618 1e-3 -2e-3 1.022-2.418 0.834-3.858z" fill="#fff" stroke="#F7941E" stroke-miterlimit="10"/>
+ <path d="m19.262 28.469c0.038 0 0.038-5 0-5s-0.038 5 0 5z" fill="#D7DF23"/>
+<path d="m14.216 10.831c0.152-0.559-0.308-0.789-0.849-0.863-0.023-0.055-0.07-0.108-0.182-0.152-0.608-0.242-1.633-0.077-2.37 0.173-0.926 0.314-1.871 0.75-2.547 1.467-0.318 0.334-0.643 0.925-0.548 1.278 0.127 0.47 0.724 0.541 1.262 0.569 0.931 0.052 1.991-0.207 2.955-0.574 0.912-0.35 2.043-1.032 2.279-1.898z" fill="#662D91"/>
+<path d="m9.098 17.668c-0.35-0.522-1.401-0.48-2.124-0.383-0.062 0.011-0.123 0.029-0.186 0.039-0.174 0.011-0.329 0.032-0.435 0.052-1.153 0.212-3.174 0.919-3.162 2.206 4e-3 0.481 0.471 0.744 0.973 0.819 1.062 0.171 2.336-0.032 3.482-0.549 0.957-0.428 1.954-1.438 1.452-2.184z" fill="#00A651"/>
+<path d="m13.634 21.941c-3e-3 0-3e-3 -2e-3 -4e-3 -7e-3 -0.569-0.318-1.617-0.156-2.364 0.121-1.063 0.396-3.026 1.591-2.856 2.666 0.227 1.424 2.97 0.937 4.311 0.316 0.952-0.442 1.777-1.213 2.123-2.054 0.32-0.781-0.374-1.017-1.21-1.042z" fill="#EE2A7B"/>
+<path d="m22.801 17.544c-0.244 2e-3 -0.565 0.041-0.89 0.124-0.365 0.043-0.732 0.129-1.039 0.266-0.981 0.437-2.025 1.201-2.153 2.134-0.18 1.311 2.097 1.17 3.199 0.897 1.008-0.25 2.228-1.003 2.668-1.893 0.595-1.198-0.703-1.535-1.785-1.528z" fill="#414042"/>
+<path d="m27.213 12.542c-0.141-0.507-1.073-0.548-1.627-0.527-0.952 0.038-1.935 0.333-2.865 0.785-0.366 0.176-0.526 0.388-0.516 0.568-0.074 0.049-0.155 0.09-0.223 0.144-0.458 0.36-0.852 0.904-0.652 1.321 0.268 0.548 1.23 0.547 1.911 0.541 0.906-0.011 1.964-0.319 2.818-0.846 0.811-0.497 1.337-1.311 1.154-1.986z" fill="#00AEEF"/>
+<path d="m17.314 14.29c-0.246 2e-3 -0.567 0.042-0.892 0.124-0.363 0.043-0.732 0.128-1.039 0.266-0.981 0.436-2.025 1.201-2.154 2.133-0.181 1.311 2.095 1.17 3.2 0.898 1.009-0.249 2.227-1.004 2.667-1.893 0.598-1.197-0.701-1.535-1.782-1.528z" fill="#D7DF23"/>
+<ellipse cx="13.257" cy="15.517" rx=".152" ry=".001" fill="#EE2A7B"/>
+</svg>
diff --git a/silx/resources/gui/icons/crop.png b/silx/resources/gui/icons/crop.png
new file mode 100755
index 0000000..65dd7d1
--- /dev/null
+++ b/silx/resources/gui/icons/crop.png
Binary files differ
diff --git a/silx/resources/gui/icons/crop.svg b/silx/resources/gui/icons/crop.svg
new file mode 100644
index 0000000..acb27ec
--- /dev/null
+++ b/silx/resources/gui/icons/crop.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<path d="m27.023 7.818h-17.505c-0.455 0-0.844 0.276-1.011 0.67-0.056 0.131-0.087 0.276-0.087 0.427v17.506c0 0.607 0.491 1.098 1.097 1.098s1.097-0.49 1.097-1.098v-16.409h16.409c0.607 0 1.098-0.49 1.098-1.097 0-0.606-0.49-1.097-1.098-1.097z" fill="#00A651" stroke="#006838" stroke-miterlimit="10" stroke-width=".1"/>
+<path d="m24.787 5.58c0-0.606-0.492-1.098-1.098-1.098s-1.098 0.491-1.098 1.098l2e-3 16.409-16.408 2e-3c-0.606 0-1.098 0.49-1.098 1.098 0 0.605 0.491 1.096 1.098 1.096l17.506-2e-3c0.605 0 1.098-0.49 1.098-1.096l-2e-3 -17.507z" fill="#00A651" stroke="#006838" stroke-miterlimit="10" stroke-width=".1"/>
+</svg>
diff --git a/silx/resources/gui/icons/crosshair.png b/silx/resources/gui/icons/crosshair.png
new file mode 100644
index 0000000..1d516a3
--- /dev/null
+++ b/silx/resources/gui/icons/crosshair.png
Binary files differ
diff --git a/silx/resources/gui/icons/crosshair.svg b/silx/resources/gui/icons/crosshair.svg
new file mode 100644
index 0000000..d8bd07e
--- /dev/null
+++ b/silx/resources/gui/icons/crosshair.svg
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3208"
+ xml:space="preserve"><defs
+ id="defs3220"><filter
+ x="-0.18998802"
+ y="-0.11593667"
+ width="1.379976"
+ height="1.2318733"
+ color-interpolation-filters="sRGB"
+ id="filter4582"><feGaussianBlur
+ id="feGaussianBlur4584"
+ stdDeviation="1.239375" /></filter></defs><metadata
+ id="metadata3210"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><path
+ d="m 0.13559,5.2881 h 31.864"
+ id="path3212"
+ style="fill:none;stroke:#f7941e;stroke-width:3" /><path
+ d="m 6.8475,0.067797 v 31.864"
+ id="path3214"
+ style="fill:none;stroke:#f7941e;stroke-width:3" /><path
+ d="m 6.9515363,5.88374 c 0,7.668296 0,14.727377 0,21.468749 1.562499,-1.562499 3.1249987,-3.124999 4.6874987,-4.687499 1.286105,2.960737 2.595999,5.911189 3.875001,8.874999 1.679854,-0.586234 3.057686,-1.123669 4.5625,-1.687499 -1.355248,-2.924576 -2.785698,-5.815806 -4.1875,-8.71875 2.239583,0 4.479167,0 6.71875,0 C 17.237387,15.822506 11.545303,10.466868 6.9515363,5.88374 z"
+ transform="matrix(0.83268173,0,0,0.83268173,1.0722105,0.21558257)"
+ id="path3222-6"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter4582);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+ d="m 7.5738363,5.8489159 0,15.8905341 3.6382357,-3.638237 3.317217,7.597496 2.996195,-1.123574 -3.584734,-7.436982 5.243342,0 z"
+ id="path3222"
+ style="fill:#000000;stroke:#ffffff;stroke-width:0.83268172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/cube-back.png b/silx/resources/gui/icons/cube-back.png
new file mode 100644
index 0000000..2e326df
--- /dev/null
+++ b/silx/resources/gui/icons/cube-back.png
Binary files differ
diff --git a/silx/resources/gui/icons/cube-back.svg b/silx/resources/gui/icons/cube-back.svg
new file mode 100644
index 0000000..1157ca1
--- /dev/null
+++ b/silx/resources/gui/icons/cube-back.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)" stroke="#000">
+ <rect transform="matrix(1 0 -.69517 .71885 0 0)" x="1018.3" y="1446.7" width="18" height="15.133" fill="none" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1795"/>
+ <rect x="12.5" y="1021.9" width="18" height="18" ry="0" fill="#f7941e" fill-opacity=".81569" stroke-miterlimit="2"/>
+ <rect transform="matrix(1 0 -.70625 .70796 0 0)" x="1031.7" y="1443.4" width="18" height="15.365" fill="none" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1885"/>
+ <rect x="1.5" y="1032.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/cube-bottom.png b/silx/resources/gui/icons/cube-bottom.png
new file mode 100644
index 0000000..0b2aaaf
--- /dev/null
+++ b/silx/resources/gui/icons/cube-bottom.png
Binary files differ
diff --git a/silx/resources/gui/icons/cube-bottom.svg b/silx/resources/gui/icons/cube-bottom.svg
new file mode 100644
index 0000000..aa9dfcf
--- /dev/null
+++ b/silx/resources/gui/icons/cube-bottom.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)" stroke="#000">
+ <rect transform="matrix(1 0 -.69517 .71885 0 0)" x="1018.3" y="1446.7" width="18" height="15.133" fill="#f7941e" fill-opacity=".81569" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1795"/>
+ <rect x="12.5" y="1021.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ <rect transform="matrix(1 0 -.70625 .70796 0 0)" x="1031.7" y="1443.4" width="18" height="15.365" fill="none" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1885"/>
+ <rect x="1.5" y="1032.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/cube-front.png b/silx/resources/gui/icons/cube-front.png
new file mode 100644
index 0000000..9165bd5
--- /dev/null
+++ b/silx/resources/gui/icons/cube-front.png
Binary files differ
diff --git a/silx/resources/gui/icons/cube-front.svg b/silx/resources/gui/icons/cube-front.svg
new file mode 100644
index 0000000..c17ba31
--- /dev/null
+++ b/silx/resources/gui/icons/cube-front.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)" stroke="#000">
+ <rect transform="matrix(1 0 -.69517 .71885 0 0)" x="1018.3" y="1446.7" width="18" height="15.133" fill="none" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1795"/>
+ <rect x="12.5" y="1021.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ <rect transform="matrix(1 0 -.70625 .70796 0 0)" x="1031.7" y="1443.4" width="18" height="15.365" fill="none" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1885"/>
+ <rect x="1.5" y="1032.9" width="18" height="18" ry="0" fill="#f7941e" fill-opacity=".81569" stroke-miterlimit="2"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/cube-left.png b/silx/resources/gui/icons/cube-left.png
new file mode 100644
index 0000000..c84ad8e
--- /dev/null
+++ b/silx/resources/gui/icons/cube-left.png
Binary files differ
diff --git a/silx/resources/gui/icons/cube-left.svg b/silx/resources/gui/icons/cube-left.svg
new file mode 100644
index 0000000..a7626fe
--- /dev/null
+++ b/silx/resources/gui/icons/cube-left.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)" stroke="#000">
+ <rect transform="matrix(0 -1 -.70641 .70781 0 0)" x="-1052.2" y="-17.566" width="18" height="15.399" fill="#f7941e" fill-opacity=".81569" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1898"/>
+ <rect transform="matrix(0 -1 -.70641 .70781 0 0)" x="-1070.6" y="-43.173" width="18" height="15.399" fill="none" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1898"/>
+ <rect x="12.5" y="1021.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ <rect x="1.5" y="1032.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/cube-right.png b/silx/resources/gui/icons/cube-right.png
new file mode 100644
index 0000000..6a913bb
--- /dev/null
+++ b/silx/resources/gui/icons/cube-right.png
Binary files differ
diff --git a/silx/resources/gui/icons/cube-right.svg b/silx/resources/gui/icons/cube-right.svg
new file mode 100644
index 0000000..f9230f6
--- /dev/null
+++ b/silx/resources/gui/icons/cube-right.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)" stroke="#000">
+ <rect transform="matrix(0 -1 -.70641 .70781 0 0)" x="-1052.2" y="-17.566" width="18" height="15.399" fill="none" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1898"/>
+ <rect x="12.5" y="1021.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ <rect x="1.5" y="1032.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ <rect transform="matrix(0 -1 -.70641 .70781 0 0)" x="-1070.6" y="-43.173" width="18" height="15.399" fill="#f7941e" fill-opacity=".81569" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1898"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/cube-top.png b/silx/resources/gui/icons/cube-top.png
new file mode 100644
index 0000000..d6c1a62
--- /dev/null
+++ b/silx/resources/gui/icons/cube-top.png
Binary files differ
diff --git a/silx/resources/gui/icons/cube-top.svg b/silx/resources/gui/icons/cube-top.svg
new file mode 100644
index 0000000..0b872ee
--- /dev/null
+++ b/silx/resources/gui/icons/cube-top.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)" stroke="#000">
+ <rect transform="matrix(1 0 -.69517 .71885 0 0)" x="1018.3" y="1446.7" width="18" height="15.133" fill="none" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1795"/>
+ <rect x="12.5" y="1021.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ <rect transform="matrix(1 0 -.70625 .70796 0 0)" x="1031.7" y="1443.4" width="18" height="15.365" fill="#f7941e" fill-opacity=".81569" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1885"/>
+ <rect x="1.5" y="1032.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/cube.png b/silx/resources/gui/icons/cube.png
new file mode 100644
index 0000000..0dae173
--- /dev/null
+++ b/silx/resources/gui/icons/cube.png
Binary files differ
diff --git a/silx/resources/gui/icons/cube.svg b/silx/resources/gui/icons/cube.svg
new file mode 100644
index 0000000..1ea0435
--- /dev/null
+++ b/silx/resources/gui/icons/cube.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1020.4)" stroke="#000">
+ <rect transform="matrix(1 0 -.69517 .71885 0 0)" x="1018.3" y="1446.7" width="18" height="15.133" fill="none" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1795"/>
+ <rect x="12.5" y="1021.9" width="18" height="18" ry="0" fill="none" stroke-miterlimit="2"/>
+ <rect transform="matrix(1 0 -.70625 .70796 0 0)" x="1031.7" y="1443.4" width="18" height="15.365" fill="#f7941e" fill-opacity=".81569" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1885"/>
+ <rect x="1.5" y="1032.9" width="18" height="18" ry="0" fill="#f7941e" fill-opacity=".81569" stroke-miterlimit="2"/>
+ <path transform="matrix(0 -1 -.70641 .70781 0 0)" d="m-1070.3-42.826 17.725-0.01751 0.026 14.9-18.077 0.01751z" fill="#f7941e" fill-opacity=".81569" stroke-linejoin="bevel" stroke-miterlimit="0" stroke-width=".5949"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/document-open.png b/silx/resources/gui/icons/document-open.png
new file mode 100755
index 0000000..15ca326
--- /dev/null
+++ b/silx/resources/gui/icons/document-open.png
Binary files differ
diff --git a/silx/resources/gui/icons/document-open.svg b/silx/resources/gui/icons/document-open.svg
new file mode 100644
index 0000000..26c7466
--- /dev/null
+++ b/silx/resources/gui/icons/document-open.svg
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata54"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs52"><linearGradient
+ x1="7.8379002"
+ y1="15.27"
+ x2="18.125"
+ y2="23.115"
+ id="b-2"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop9-9"
+ style="stop-color:#dedfe3;stop-opacity:1"
+ offset="0" /><stop
+ id="stop11-1"
+ style="stop-color:#97989c;stop-opacity:1"
+ offset="0.31040001" /><stop
+ id="stop13-2"
+ style="stop-color:#626365;stop-opacity:1"
+ offset="0.55800003" /><stop
+ id="stop15-7"
+ style="stop-color:#343435;stop-opacity:1"
+ offset="0.73269999" /><stop
+ id="stop17-0"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0.81879997" /></linearGradient><filter
+ x="-0.32558218"
+ y="-0.40255472"
+ width="1.6511643"
+ height="1.8051095"
+ color-interpolation-filters="sRGB"
+ id="filter4474"><feGaussianBlur
+ id="feGaussianBlur4476"
+ stdDeviation="3.0979788" /></filter></defs><path
+ d="m 26.494328,25.327094 c 0.161,0.526 -0.149,1.033 -0.691,1.128 l -16.5839999,2.9 c -0.542,0.095 -1.117,-0.258 -1.279,-0.784 l -4.1969996,-13.629 c -0.162,-0.525 0.149,-1.033 0.69,-1.128 l 16.5829995,-2.898 c 0.542,-0.095 1.118,0.258 1.279,0.783 l 4.199,13.628 z"
+ id="path19-9"
+ style="opacity:0.5;fill:#000000;filter:url(#filter4474)" /><path
+ d="M 18.462,31.115"
+ id="path4"
+ style="stroke:#ffffff;stroke-width:0.50999999;stroke-miterlimit:10" /><linearGradient
+ x1="7.8379002"
+ y1="15.27"
+ x2="18.125"
+ y2="23.115"
+ id="b"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop9"
+ style="stop-color:#dedfe3;stop-opacity:1"
+ offset="0" /><stop
+ id="stop11"
+ style="stop-color:#97989c;stop-opacity:1"
+ offset="0.31040001" /><stop
+ id="stop13"
+ style="stop-color:#626365;stop-opacity:1"
+ offset="0.55800003" /><stop
+ id="stop15"
+ style="stop-color:#343435;stop-opacity:1"
+ offset="0.73269999" /><stop
+ id="stop17"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0.81879997" /></linearGradient><path
+ d="m 24.989,24.866 c 0.161,0.526 -0.149,1.033 -0.691,1.128 l -16.584,2.9 C 7.172,28.989 6.597,28.636 6.435,28.11 L 2.238,14.481 c -0.162,-0.525 0.149,-1.033 0.69,-1.128 l 16.583,-2.898 c 0.542,-0.095 1.118,0.258 1.279,0.783 l 4.199,13.628 z"
+ id="path19"
+ style="fill:url(#b)" /><path
+ d="m 24.989,24.866 c 0.161,0.526 -0.149,1.033 -0.691,1.128 l -16.584,2.9 C 7.172,28.989 6.597,28.636 6.435,28.11 L 2.238,14.481 c -0.162,-0.525 0.149,-1.033 0.69,-1.128 l 16.583,-2.898 c 0.542,-0.095 1.118,0.258 1.279,0.783 l 4.199,13.628 z"
+ id="path21"
+ style="fill:none;stroke:#414042;stroke-width:0.1;stroke-miterlimit:10" /><linearGradient
+ x1="7.0897999"
+ y1="20.499001"
+ x2="29.940001"
+ y2="20.499001"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop24"
+ style="stop-color:#f1f2f2;stop-opacity:1"
+ offset="0" /><stop
+ id="stop26"
+ style="stop-color:#f2e7db;stop-opacity:1"
+ offset="0.0395" /><stop
+ id="stop28"
+ style="stop-color:#f4d3ae;stop-opacity:1"
+ offset="0.1471" /><stop
+ id="stop30"
+ style="stop-color:#f5c188;stop-opacity:1"
+ offset="0.2586" /><stop
+ id="stop32"
+ style="stop-color:#f5b36a;stop-opacity:1"
+ offset="0.37180001" /><stop
+ id="stop34"
+ style="stop-color:#f6a74f;stop-opacity:1"
+ offset="0.48710001" /><stop
+ id="stop36"
+ style="stop-color:#f79e39;stop-opacity:1"
+ offset="0.60509998" /><stop
+ id="stop38"
+ style="stop-color:#f79829;stop-opacity:1"
+ offset="0.727" /><stop
+ id="stop40"
+ style="stop-color:#f79520;stop-opacity:1"
+ offset="0.85519999" /><stop
+ id="stop42"
+ style="stop-color:#f7941e;stop-opacity:1"
+ offset="1" /></linearGradient><path
+ d="m 25.415,24.895 c -0.191,0.516 -0.791,1.016 -1.332,1.112 L 7.786,28.892 C 7.244,28.989 6.958,28.645 7.149,28.129 l 4.463,-12.022 c 0.191,-0.516 0.791,-1.016 1.333,-1.112 l 16.299,-2.888 c 0.541,-0.096 0.828,0.248 0.637,0.763 l -4.466,12.025 z"
+ id="path44"
+ style="fill:url(#a)" /><path
+ d="m 25.415,24.895 c -0.191,0.516 -0.791,1.016 -1.332,1.112 L 7.786,28.892 C 7.244,28.989 6.958,28.645 7.149,28.129 l 4.463,-12.022 c 0.191,-0.516 0.791,-1.016 1.333,-1.112 l 16.299,-2.888 c 0.541,-0.096 0.828,0.248 0.637,0.763 l -4.466,12.025 z"
+ id="path46"
+ style="fill:none;stroke:#f7941e;stroke-width:0.1;stroke-miterlimit:10" /><path
+ d="M 26.084,6.26 C 22.891,1.053 17.66,3.32 17.66,3.32 L 9.84,6.835 c 0,0 10.569,-4.773 14.794,0.259 -1.424,0.883 -2.508,1.723 -2.508,1.723 l 4.616,1.042 0.19,-0.024 c -0.027,-0.222 2.092,-4.694 2.092,-4.694 -0.89,0.143 -1.935,0.588 -2.94,1.119 z"
+ id="path48"
+ style="fill:#00a651;stroke:#000000;stroke-width:0.1;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/document-print.png b/silx/resources/gui/icons/document-print.png
new file mode 100755
index 0000000..217f685
--- /dev/null
+++ b/silx/resources/gui/icons/document-print.png
Binary files differ
diff --git a/silx/resources/gui/icons/document-print.svg b/silx/resources/gui/icons/document-print.svg
new file mode 100644
index 0000000..49cc20e
--- /dev/null
+++ b/silx/resources/gui/icons/document-print.svg
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+ <linearGradient id="c" x1="3.1421" x2="28.861" y1="14.73" y2="14.73" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#414042" offset="0"/>
+ <stop stop-color="#464547" offset=".0326"/>
+ <stop stop-color="#49494B" offset=".0976"/>
+ <stop stop-color="#5B5B5E" offset=".1472"/>
+ <stop stop-color="#747678" offset=".2417"/>
+ <stop stop-color="#828487" offset=".3215"/>
+ <stop stop-color="#88898C" offset=".3763"/>
+ <stop stop-color="#97999C" offset=".4912"/>
+ <stop stop-color="#C2C4C6" offset=".7271"/>
+ <stop stop-color="#DBDCDD" offset=".8467"/>
+ <stop stop-color="#fff" offset="1"/>
+ </linearGradient>
+ <path d="m28.861 20.263c0 0.275-0.225 0.5-0.5 0.499l-24.719-0.037c-0.275-1e-3 -0.5-0.226-0.5-0.501v-11.027c0-0.275 0.225-0.5 0.5-0.499l24.719 0.037c0.275 0 0.5 0.226 0.5 0.501v11.027z" fill="url(#c)"/>
+ <path d="m28.861 20.263c0 0.275-0.225 0.5-0.5 0.499l-24.719-0.037c-0.275-1e-3 -0.5-0.226-0.5-0.501v-11.027c0-0.275 0.225-0.5 0.5-0.499l24.719 0.037c0.275 0 0.5 0.226 0.5 0.501v11.027z" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".1"/>
+<ellipse cx="26.886" cy="11.038" rx=".62" ry=".652" stroke="#fff" stroke-miterlimit="10" stroke-width=".45"/>
+<path d="m2.83 9.676m0 5.901m5.598-5.193m-5.598 0.012" fill="none" stroke="#fff" stroke-miterlimit="10"/>
+<path d="m26.886 15.388c0 0.537-0.728 0.972-1.625 0.972h-18.006c-0.897 0-1.626-0.435-1.626-0.972 0-0.538 0.729-0.973 1.626-0.973h18.006c0.897 1e-3 1.625 0.436 1.625 0.973z" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".7"/>
+<linearGradient id="b" x1="23.558" x2="25.852" y1="24.5" y2="24.5" gradientUnits="userSpaceOnUse">
+ <stop offset="0"/>
+ <stop stop-color="#141515" offset=".0088"/>
+ <stop stop-color="#656668" offset=".0453"/>
+ <stop stop-color="#97999C" offset=".071"/>
+ <stop stop-color="#ABADB0" offset=".0836"/>
+ <stop stop-color="#BABCBE" offset=".2532"/>
+ <stop stop-color="#C6C8CA" offset=".4286"/>
+ <stop stop-color="#D0D2D3" offset=".4925"/>
+ <stop stop-color="#EAEBEB" offset=".6865"/>
+ <stop stop-color="#FAFAFA" offset=".8616"/>
+ <stop stop-color="#fff" offset="1"/>
+</linearGradient>
+<line x1="23.558" x2="25.852" y1="25.428" y2="23.571" fill="url(#b)" stroke="#414042" stroke-miterlimit="10" stroke-width=".1"/>
+ <linearGradient id="a" x1="6.8477" x2="25.852" y1="20.151" y2="20.151" gradientUnits="userSpaceOnUse">
+ <stop offset="0"/>
+ <stop stop-color="#141515" offset=".0088"/>
+ <stop stop-color="#656668" offset=".0453"/>
+ <stop stop-color="#97999C" offset=".071"/>
+ <stop stop-color="#ABADB0" offset=".0836"/>
+ <stop stop-color="#BABCBE" offset=".1984"/>
+ <stop stop-color="#C6C8CA" offset=".3171"/>
+ <stop stop-color="#D3D4D6" offset=".4107"/>
+ <stop stop-color="#EBECEC" offset=".6305"/>
+ <stop stop-color="#FAFAFA" offset=".8329"/>
+ <stop stop-color="#fff" offset="1"/>
+ </linearGradient>
+ <path d="m25.852 14.875v8.699c0 5e-3 -5e-3 0.01-0.01 0.01h-2.233c-5e-3 0-0.01 5e-3 -0.01 0.01l-0.041 1.824c0 5e-3 -5e-3 0.01-0.01 0.01h-16.691c-5e-3 0-0.01-5e-3 -0.01-0.01v-10.543" fill="url(#a)"/>
+ <path d="m25.852 14.875v8.699c0 5e-3 -5e-3 0.01-0.01 0.01h-2.233c-5e-3 0-0.01 5e-3 -0.01 0.01l-0.041 1.824c0 5e-3 -5e-3 0.01-0.01 0.01h-16.691c-5e-3 0-0.01-5e-3 -0.01-0.01v-10.543" fill="none" stroke="#414042" stroke-miterlimit="10" stroke-width=".1"/>
+ <path d="m12.146 17.77c0.568 1.652 1.558 3.131 2.264 4.729 0.375 0.851 0.797 1.645 1.315 2.416-0.207-0.309 1.19-2.995 1.358-3.425 0.462-1.182 0.426-1.742 1.26-0.426 0.222-0.223 0.382-0.483 0.48-0.781 0 0 0.638 1.393 0.679 1.515 0.389 1.16 1.012-0.942 1.249-1.424 0.576-1.167 1.432-2.186 2.137-3.274 0.309-0.477-0.3-1.538 0-2-1.111 1.717-2.107 3.454-3.17 5.194 0.146-0.241-0.742-1.771-0.895-2.01-0.099 0.298-0.259 0.559-0.48 0.781-0.253 0.322-0.336-2.152-1.003-0.26-0.325 0.922-0.707 1.826-1.072 2.733-0.185 0.457-0.366 0.916-0.543 1.377 0.035-0.089-0.945-1.617-1.032-1.794-0.861-1.736-1.918-3.522-2.547-5.352 0.203 0.592-0.207 1.4 0 2.001z" fill="#ED1C24"/>
+<path d="m8.077 9.676l-3.91 5e-3c-9e-3 0-0.017-5e-3 -0.025-5e-3 -0.194 0-0.35 0.161-0.35 0.359v4.023c0 0.197 0.156 0.357 0.35 0.357s0.351-0.16 0.351-0.357v-3.66l3.586-6e-3c0.193 0 0.35-0.16 0.349-0.358 0-0.198-0.158-0.359-0.351-0.358z" fill="#fff" stroke="#fff" stroke-miterlimit="10" stroke-width=".3"/>
+<path d="m18.462 31.115" stroke="#fff" stroke-miterlimit="10" stroke-width=".51"/>
+</svg>
diff --git a/silx/resources/gui/icons/document-save.png b/silx/resources/gui/icons/document-save.png
new file mode 100755
index 0000000..5229d2b
--- /dev/null
+++ b/silx/resources/gui/icons/document-save.png
Binary files differ
diff --git a/silx/resources/gui/icons/document-save.svg b/silx/resources/gui/icons/document-save.svg
new file mode 100644
index 0000000..1e156bc
--- /dev/null
+++ b/silx/resources/gui/icons/document-save.svg
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata16"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs14" /><path
+ d="m 27.458,27.45 c 0,0.275 -0.225,0.5 -0.5,0.5 H 5.942 c -0.275,0 -0.5,-0.225 -0.5,-0.5 V 6.437 c 0,-0.275 0.225,-0.5 0.5,-0.5 h 16.271 c 0.275,0 0.656,0.162 0.847,0.36 l 4.051,4.201 c 0.19,0.198 0.347,0.585 0.347,0.86 V 27.45 z"
+ inkscape:connector-curvature="0"
+ id="path4" /><path
+ d="m 25.169,24.58 c 0,0.165 -0.135,0.3 -0.3,0.3 H 8.365 c -0.165,0 -0.3,-0.135 -0.3,-0.3 v -7.015 c 0,-0.165 0.135,-0.3 0.3,-0.3 h 16.504 c 0.165,0 0.3,0.135 0.3,0.3 v 7.015 z"
+ inkscape:connector-curvature="0"
+ id="path6"
+ style="fill:#ffffff" /><path
+ d="m 20.925,11.322 c 0,0.165 -0.135,0.3 -0.3,0.3 H 8.365 c -0.165,0 -0.3,-0.135 -0.3,-0.3 v -5.41 c 0,-0.165 0.135,-0.3 0.3,-0.3 h 12.26 c 0.165,0 0.3,0.135 0.3,0.3 v 5.41 z"
+ inkscape:connector-curvature="0"
+ id="path8"
+ style="fill:#ffffff" /><rect
+ width="2.1359999"
+ height="4.277"
+ x="15.422"
+ y="5.9369998"
+ id="rect10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/draw-brush.png b/silx/resources/gui/icons/draw-brush.png
new file mode 100755
index 0000000..6184079
--- /dev/null
+++ b/silx/resources/gui/icons/draw-brush.png
Binary files differ
diff --git a/silx/resources/gui/icons/draw-brush.svg b/silx/resources/gui/icons/draw-brush.svg
new file mode 100644
index 0000000..60895e8
--- /dev/null
+++ b/silx/resources/gui/icons/draw-brush.svg
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+ <linearGradient id="b" x1="9.7979" x2="22.185" y1="7.9565" y2="7.9565" gradientTransform="matrix(-.9657 .2596 -.2596 -.9657 34.576 28.902)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#FFF33B" offset="0"/>
+ <stop stop-color="#FFE029" offset=".0595"/>
+ <stop stop-color="#FFD218" offset=".1303"/>
+ <stop stop-color="#FEC90F" offset=".2032"/>
+ <stop stop-color="#FDC70C" offset=".2809"/>
+ <stop stop-color="#F3903F" offset=".6685"/>
+ <stop stop-color="#ED683C" offset=".8876"/>
+ <stop stop-color="#E93E3A" offset="1"/>
+ </linearGradient>
+ <path d="m21.632 20.113c1.117 1.159 2.026 6.063 1.582 7.539-0.228-0.428-0.642-0.679-0.759-1.139l-0.111 0.031c-0.101 0.521-0.45 0.988-0.583 1.394-0.059-0.23-0.255-0.542-0.313-0.771-0.05 0.258-0.291 0.694-0.344 0.954-0.166-0.198-0.583-0.449-0.751-0.648-0.022 0.373-0.182 0.666-0.093 1.011-0.168-0.199-0.478-0.482-0.564-0.826-0.021 0.375-0.289 0.696-0.311 1.073-0.118-0.463-0.455-0.857-0.465-1.346-0.021 0.375-0.262 0.811-0.391 1.217-0.088-0.345-0.426-0.743-0.565-0.825-0.048 0.261-0.29 0.695-0.421 1.103-0.119-0.458-0.481-0.971-0.601-1.429-0.291 0.695-0.304 1.56-0.564 2.369-0.256-0.54-0.543-1.197-0.579-1.801 0.036 0.604-0.176 1.152-0.387 1.703-0.227-0.427-0.703-0.907-0.82-1.363-0.098 0.518-0.391 1.214-0.352 1.818-0.335-0.399-0.625-1.057-0.659-1.658 6e-3 0.489-0.313 1.071-0.307 1.562-0.225-0.429-0.622-1.054-0.74-1.514-0.022 0.375-0.233 0.926-0.222 1.416-1.139-2.139-1.923-4.742-1.605-7.166" fill="url(#b)"/>
+ <path d="m21.5 20.179c0.81 1.016 1.094 2.381 1.363 3.624 0.193 0.892 0.286 1.804 0.318 2.715 0.039 1.111-0.137 0.718-0.595-0.069-0.028-0.05-0.111-0.053-0.16-0.039-0.574 0.161-0.45 1.663-0.835 0.72-0.045-0.11-0.245-0.088-0.284 0.02-0.231 0.646-0.32 0.691-0.844 0.239-0.08-0.069-0.241-4e-3 -0.259 0.096-0.115 0.677-0.033 0.748-0.378 0.109-0.049-0.091-0.245-0.043-0.271 0.046-0.263 0.912-0.304 0.376-0.491-0.292-0.04-0.143-0.264-0.06-0.292 0.049-0.154 0.722-0.38 0.827-0.677 0.316-0.068-0.071-0.233-0.058-0.271 0.046-0.32 0.89-0.46 0.313-0.737-0.346-0.044-0.105-0.25-0.093-0.284 0.02-0.319 1.092-0.488 2.647-0.859 0.549-0.024-0.136-0.279-0.067-0.292 0.049-0.163 1.479-0.468 1.576-0.915 0.291-0.06-0.127-0.261-0.073-0.292 0.049-0.277 1.096-0.458 1.536-0.719 0.111-0.026-0.142-0.271-0.061-0.292 0.049-0.205 1.037-0.176 1.495-0.755-1e-3 -0.05-0.129-0.27-0.073-0.292 0.049-0.319 1.716-1.017-1.203-1.172-1.703-0.411-1.315-0.471-2.702-0.361-4.066 0.013-0.155-0.283-0.118-0.294 0.02-0.209 2.581 0.469 4.924 1.62 7.222 0.055 0.108 0.266 0.026 0.279-0.075 0.186-1.423 0.218-0.668 0.682 0.173 0.061 0.11 0.26 0.024 0.279-0.075 0.289-1.469 0.199-0.569 0.687 0.172 0.063 0.096 0.27 0.037 0.279-0.075 0.12-1.443 0.129-1.553 0.893-0.38 0.057 0.087 0.24 0.046 0.271-0.046 0.485-1.41 0.177-1.013 0.682 0.117 0.058 0.128 0.263 0.073 0.292-0.049 0.168-0.698 0.236-2.408 0.874-0.892 0.047 0.112 0.241 0.086 0.284-0.02 0.283-0.713 0.313-1.012 0.715-0.231 0.05 0.097 0.239 0.036 0.271-0.046 0.347-0.911 0.211-0.727 0.571 0.148 0.043 0.106 0.251 0.093 0.284-0.02 0.195-0.675 0.152-0.719 0.604-0.201 0.067 0.078 0.277 0.05 0.279-0.075 6e-3 -0.675 0.073-0.709 0.585-0.267 0.068 0.059 0.221 0.017 0.251-0.066 0.204-0.566 0.142-0.734 0.373-0.164 0.047 0.117 0.237 0.081 0.284-0.02 0.399-0.861 0.569-1.051 1.182-0.24 0.073 0.098 0.256 0.034 0.279-0.075 0.484-2.255-0.154-5.783-1.598-7.595-0.084-0.11-0.359 8e-3 -0.262 0.129z" fill="#808285"/>
+ <path d="m20.565 20.018c0.842 0.827 1.445 2.232 1.27 3.42 0.097-0.021 0.192-0.041 0.288-0.063-0.257-1.372-1.012-2.411-2.133-3.22-0.047-0.034-0.303 0.011-0.28 0.09 0.179 0.64 0.448 1.235 0.73 1.835 0.036 0.078 0.316-0.021 0.289-0.078-0.282-0.6-0.552-1.195-0.73-1.835-0.094 0.03-0.187 0.061-0.28 0.09 1.11 0.802 1.86 1.839 2.115 3.196 0.013 0.069 0.278 1e-3 0.288-0.063 0.18-1.217-0.418-2.624-1.285-3.475-0.058-0.056-0.324 0.051-0.272 0.103z" fill="#808285"/>
+ <path d="m14.377 28.327c6e-3 0.021 0.012 0.04 0.026 0.057 0.061 0.077 0.242 0.055 0.271-0.046 0.197-0.668-0.347-1.911-0.505-2.535-0.036-0.141-0.267-0.061-0.292 0.049-0.246 1.07-0.334 2.126-0.219 3.219 0.097-0.026 0.193-0.052 0.29-0.078-0.402-1.116-0.693-2.25-0.878-3.423-0.021-0.129-0.249-0.067-0.284 0.021-0.469 1.151-0.442 2.305-0.16 3.501 0.093-0.035 0.185-0.069 0.277-0.104-0.994-1.354-1.377-3.172-1.5-4.821-0.012-0.157-0.304-0.115-0.294 0.02 0.126 1.693 0.507 3.54 1.529 4.933 0.072 0.098 0.309 0.028 0.277-0.104-0.274-1.16-0.308-2.267 0.148-3.386-0.095 7e-3 -0.189 0.014-0.284 0.021 0.186 1.172 0.477 2.306 0.878 3.423 0.05 0.14 0.305 0.063 0.29-0.078-0.114-1.076-0.019-2.109 0.223-3.16-0.097 0.017-0.194 0.032-0.292 0.049 0.139 0.547 0.271 1.095 0.386 1.647 0.038 0.182 0.185 0.585 0.13 0.771 0.09-0.016 0.181-0.03 0.271-0.046v-5e-3c-0.041-0.142-0.331-0.063-0.288 0.075z" fill="#808285"/>
+ <linearGradient id="a" x1="7.7773" x2="19.356" y1="25.019" y2="17.299" gradientTransform="matrix(-.9657 .2596 -.2596 -.9657 34.911 28.453)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#fff" offset="0"/>
+ <stop offset="1"/>
+ </linearGradient>
+ <path d="m22.109 20.613c-3.689-0.191-8.254 1.217-11.383 3.2-0.383-1.49-0.873-2.946-1.119-4.353 7.214-2.025 5.45-2.454 11.464-3.347 0.137 1.436 0.628 2.896 1.011 4.384m-1.011-4.383c-0.745-0.16-2.115-0.265-2.889-0.537-2.82-0.928-1.906-3.763-2.474-6.429-0.363-1.863-1.203-6.045-3.088-6.989-3.026-1.732-2.68 3.723-2.239 5.442 0.353 1.373 0.645 2.616 1.297 3.781 0.405 0.723 1.864 3.042 1.93 3.76 0.145 1.926-3.541 2.469-4.002 4.319m3.045-15.103c-0.108-3.162-1.982 1.418 0.08-0.146" fill="url(#a)"/>
+ <g fill="#414042">
+ <path d="m22.161 20.515c-2.445-0.057-4.9 0.336-7.201 1.183-1.263 0.464-2.527 0.97-3.684 1.668-0.642 0.387-1.081-2.038-1.134-2.232-0.333-1.205 0-1.722 1.179-2.073 1.801-0.538 3.515-1.273 5.284-1.896 0.811-0.285 1.656-0.461 2.498-0.628 1.464-0.29 1.824-0.089 2.129 1.352 0.188 0.891 0.47 1.771 0.706 2.649 0.033 0.125 0.323 0.047 0.289-0.078-0.391-1.457-0.801-2.887-1.011-4.384-7e-3 -0.052-0.09-0.066-0.13-0.06-4.03 0.619-7.601 2.235-11.503 3.354-0.056 0.015-0.135 0.06-0.121 0.13 0.302 1.471 0.729 2.903 1.119 4.353 0.027 0.1 0.182 0.056 0.239 0.021 3.381-2.04 7.27-3.252 11.237-3.161 0.131 2e-3 0.3-0.194 0.104-0.198z"/>
+ <path d="m21.123 16.016c-1.26-0.217-2.426-0.331-3.637-0.896-1.429-0.667-1.342-2.966-1.416-4.231-0.128-2.19-0.717-4.402-1.508-6.438-0.55-1.415-2.238-3.579-3.88-2.332-1.795 1.364-0.366 5.897 0.091 7.489 0.622 2.165 4.057 5.336 1.528 7.294-1.077 0.833-2.26 1.245-2.832 2.546-0.064 0.146 0.228 0.134 0.275 0.025 0.812-1.845 4.568-2.431 3.872-4.848-0.516-1.793-1.916-3.325-2.553-5.095-0.62-1.72-0.878-3.53-0.792-5.351 0.066-1.388 0.819-3.761 3.227-1.048 0.703 0.792 1.044 2.066 1.365 3.063 0.587 1.823 0.857 3.735 0.968 5.639 0.205 3.487 2.176 3.862 5.188 4.38 0.134 0.023 0.298-0.164 0.104-0.197z"/>
+ <path d="m12.797 4.345c-0.013-0.299 0.021-1.151-0.418-1.223-0.308-0.05-0.513 0.269-0.622 0.507-0.115 0.253-0.233 0.662-0.038 0.906 0.272 0.34 0.88-0.097 1.106-0.264 0.159-0.117-0.081-0.199-0.188-0.119-0.127 0.093-0.563 0.466-0.689 0.203-0.086-0.18-0.013-0.437 0.049-0.612 0.024-0.068 0.203-0.455 0.267-0.42 0.255 0.137 0.231 0.828 0.24 1.048 7e-3 0.145 0.298 0.093 0.293-0.026z"/>
+ </g>
+ <path d="m20.86 19.058c0.084 0 0.316-0.127 0.123-0.127-0.084 0-0.316 0.127-0.123 0.127z" fill="#808285"/>
+ <path d="m16.907 17.413c0.741-0.269 2.147-1.106 2.839-0.538 0.634 0.521 0.562 1.77 0.765 2.492 0.054 0.193 0.922-0.044 0.869-0.232-0.249-0.889-0.168-2.654-1.389-2.804-1.129-0.138-2.355 0.518-3.383 0.891-0.584 0.212-0.029 0.31 0.299 0.191z" fill="#fff"/>
+</svg>
diff --git a/silx/resources/gui/icons/draw-pencil.png b/silx/resources/gui/icons/draw-pencil.png
new file mode 100755
index 0000000..be47b74
--- /dev/null
+++ b/silx/resources/gui/icons/draw-pencil.png
Binary files differ
diff --git a/silx/resources/gui/icons/draw-pencil.svg b/silx/resources/gui/icons/draw-pencil.svg
new file mode 100644
index 0000000..2e376ac
--- /dev/null
+++ b/silx/resources/gui/icons/draw-pencil.svg
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3269"
+ xml:space="preserve"><defs
+ id="defs14" /><metadata
+ id="metadata3307"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><path
+ d="m 25,4.21875 c -0.67775,0.05775 -1.15625,0.375 -1.15625,0.375 l -16.625,14.5 3.75,4.46875 16.625,-14.5 c 0,0 1.4995,-1.6845 -0.1875,-3.6875 C 26.56425,4.373 25.67775,4.161 25,4.21875 z"
+ id="polyline3271"
+ style="color:#000000;fill:#00a651;fill-opacity:1;fill-rule:nonzero;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /><path
+ d="m 10.643414,23.625677 0.03636,-0.01996 0.09119,-0.07157 -0.04187,-0.103214 -3.4430644,-4.090587 -0.1148987,-0.06232 -0.1275569,0.09737 -1.8938804,4.360306 -0.021422,0.115872 c 0,0.07303 0.022396,0.150927 0.069134,0.207402 l 0.5579401,0.662128 c 0.058423,0.06816 0.1548211,0.107109 0.2453768,0.107109 z"
+ id="path3275"
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.14605762;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><path
+ d="m 26.004375,10.457844 -4.667906,4.063094 -3.75136,-4.467439 4.630952,-4.0364839 z"
+ id="polygon3277"
+ style="fill:#f7941e" /><path
+ d="m 5.325,23.114 c 0.079,-0.153 0.238,-0.172 0.352,-0.04 l 1.146,1.298 c 0.115,0.126 0.079,0.284 -0.079,0.344 L 4.247,25.661 C 4.09,25.722 4.025,25.642 4.104,25.491 l 1.221,-2.377 z"
+ id="path3301" /><path
+ d="m 8.697,18.552 c 1.172,-1.087 2.338,-2.179 3.532,-3.238 1.182,-1.073 2.384,-2.124 3.587,-3.174 1.199,-1.057 2.408,-2.098 3.627,-3.129 1.211,-1.04 2.431,-2.07 3.665,-3.083 L 23.09,5.945 c 0.269,-0.296 0.573,-0.527 0.916,-0.711 0.172,-0.089 0.353,-0.163 0.542,-0.209 0.188,-0.044 0.383,-0.075 0.575,-0.065 0.098,-0.004 0.193,0.007 0.289,0.028 0.094,0.02 0.191,0.026 0.279,0.066 0.185,0.056 0.355,0.135 0.517,0.239 0.326,0.193 0.592,0.462 0.841,0.738 C 26.78,5.773 26.498,5.525 26.17,5.361 26.008,5.273 25.838,5.208 25.659,5.168 25.574,5.136 25.482,5.137 25.393,5.125 25.305,5.111 25.214,5.107 25.124,5.118 24.945,5.121 24.77,5.162 24.601,5.215 24.431,5.272 24.269,5.345 24.114,5.433 23.807,5.612 23.52,5.851 23.301,6.117 l -0.008,0.009 -0.011,0.008 c -1.182,1.073 -2.378,2.13 -3.584,3.177 -1.196,1.056 -2.403,2.102 -3.625,3.132 -1.213,1.038 -2.427,2.074 -3.661,3.087 -1.221,1.026 -2.471,2.02 -3.715,3.022 z"
+ id="path3303"
+ style="fill:#ffffff" /><path
+ d="m 22.216292,6.0087433 3.802575,4.4385707"
+ id="path3766"
+ style="fill:none;stroke:#ffffff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /><path
+ d="m 17.567985,10.061979 3.783044,4.458102"
+ id="path3766-3"
+ style="fill:none;stroke:#ffffff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/draw-rubber.png b/silx/resources/gui/icons/draw-rubber.png
new file mode 100755
index 0000000..b1b24c1
--- /dev/null
+++ b/silx/resources/gui/icons/draw-rubber.png
Binary files differ
diff --git a/silx/resources/gui/icons/draw-rubber.svg b/silx/resources/gui/icons/draw-rubber.svg
new file mode 100644
index 0000000..a234415
--- /dev/null
+++ b/silx/resources/gui/icons/draw-rubber.svg
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata19"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs17" /><linearGradient
+ x1="15.354"
+ y1="11.431"
+ x2="21.164"
+ y2="16.003"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop5"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" /><stop
+ id="stop7"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1" /></linearGradient><polygon
+ points="20.579,5.13 26.72,10.594 16.148,22.471 10.009,17.007 "
+ id="polygon9"
+ style="fill:url(#a);stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:10" /><path
+ d="m 15.574,22.779 c 0.073,-0.082 0.065,-0.209 -0.017,-0.282 L 9.948,17.505 C 9.866,17.432 9.739,17.44 9.666,17.522 l -2.879,3.233 c -0.073,0.082 -0.065,0.209 0.017,0.282 l 3.292,2.93 c 0.082,0.073 0.239,0.133 0.35,0.133 h 3.752 c 0.11,0 0.26,-0.067 0.333,-0.149 l 1.043,-1.172 z"
+ inkscape:connector-curvature="0"
+ id="path11"
+ style="fill:#ffffff" /><path
+ d="m 15.574,22.779 c 0.073,-0.082 0.065,-0.209 -0.017,-0.282 L 9.948,17.505 C 9.866,17.432 9.739,17.44 9.666,17.522 l -2.879,3.233 c -0.073,0.082 -0.065,0.209 0.017,0.282 l 3.292,2.93 c 0.082,0.073 0.239,0.133 0.35,0.133 h 3.752 c 0.11,0 0.26,-0.067 0.333,-0.149 l 1.043,-1.172 z"
+ inkscape:connector-curvature="0"
+ id="path13"
+ style="fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/edit-copy.png b/silx/resources/gui/icons/edit-copy.png
new file mode 100644
index 0000000..8fe3281
--- /dev/null
+++ b/silx/resources/gui/icons/edit-copy.png
Binary files differ
diff --git a/silx/resources/gui/icons/edit-copy.svg b/silx/resources/gui/icons/edit-copy.svg
new file mode 100644
index 0000000..44796b7
--- /dev/null
+++ b/silx/resources/gui/icons/edit-copy.svg
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3453"
+ xml:space="preserve"><metadata
+ id="metadata3491"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3489"><filter
+ x="-0.15908387"
+ y="-0.13152882"
+ width="1.3181677"
+ height="1.2630576"
+ color-interpolation-filters="sRGB"
+ id="filter6624"><feGaussianBlur
+ id="feGaussianBlur6626"
+ stdDeviation="1.1601338" /></filter></defs><path
+ d="M 18.462,31.115"
+ id="path3455"
+ style="stroke:#ffffff;stroke-width:0.50999999;stroke-miterlimit:10" /><path
+ d="m 19.959,22.647 c 0,0.28 -0.229,0.51 -0.51,0.51 H 3.895 c -0.28,0 -0.51,-0.229 -0.51,-0.51 V 3.55 c 0,-0.28 0.229,-0.51 0.51,-0.51 H 19.45 c 0.28,0 0.51,0.229 0.51,0.51 v 19.097 z"
+ id="path3457"
+ style="fill:#f1f2f2" /><path
+ d="m 19.959,22.647 c 0,0.28 -0.229,0.51 -0.51,0.51 H 3.895 c -0.28,0 -0.51,-0.229 -0.51,-0.51 V 3.55 c 0,-0.28 0.229,-0.51 0.51,-0.51 H 19.45 c 0.28,0 0.51,0.229 0.51,0.51 v 19.097 z"
+ id="path3459"
+ style="fill:none;stroke:#f7941e;stroke-width:2;stroke-miterlimit:10" /><path
+ d="M 16.858,5.889 C 13.71,6.354 10.576,6.416 7.409,6.09 6.997,6.048 6.212,7.409 6.517,7.44 c 3.167,0.326 6.3,0.265 9.451,-0.201 0.456,-0.067 1.086,-1.379 0.89,-1.35 z"
+ id="path3461"
+ style="fill:#58595b" /><path
+ d="M 16.257,9.307 C 13.284,9.266 10.322,9.33 7.359,9.559 c -0.449,0.035 -1.12,1.367 -0.892,1.35 2.964,-0.23 5.926,-0.293 8.897,-0.25 0.435,0.006 1.163,-1.348 0.893,-1.352 z"
+ id="path3463"
+ style="fill:#414042" /><path
+ d="M 9.973,12.374 C 9.138,12.468 8.298,12.433 7.46,12.476 7.156,12.49 6.838,12.962 6.694,13.183 6.653,13.244 6.287,13.839 6.568,13.826 7.406,13.785 8.246,13.816 9.081,13.724 9.394,13.689 9.694,13.251 9.847,13.019 9.881,12.965 10.253,12.344 9.973,12.374 z"
+ id="path3465"
+ style="fill:#6d6e71" /><path
+ d="m 16.76,15.44 c -3.111,-0.518 -6.223,0.045 -9.351,-0.051 -0.43,-0.014 -1.168,1.344 -0.892,1.35 3.127,0.096 6.24,-0.467 9.35,0.051 0.393,0.068 1.22,-1.295 0.893,-1.35 z"
+ id="path3467"
+ style="fill:#414042" /><path
+ d="m 28.65,27.848 c 0,0.28 -0.229,0.51 -0.51,0.51 H 12.586 c -0.28,0 -0.51,-0.229 -0.51,-0.51 V 8.75 c 0,-0.28 0.229,-0.51 0.51,-0.51 h 15.555 c 0.28,0 0.51,0.229 0.51,0.51 v 19.098 z"
+ id="path3469"
+ style="fill:#d1d3d4" /><path
+ d="m 28.65,27.848 c 0,0.28 -0.229,0.51 -0.51,0.51 H 12.586 c -0.28,0 -0.51,-0.229 -0.51,-0.51 V 8.75 c 0,-0.28 0.229,-0.51 0.51,-0.51 h 15.555 c 0.28,0 0.51,0.229 0.51,0.51 v 19.098 z"
+ id="path3471"
+ style="fill:none;stroke:#f7941e;stroke-width:1.60000002;stroke-miterlimit:10" /><path
+ d="m 25.146,11.089 c -3.148,0.465 -6.282,0.526 -9.449,0.201 -0.412,-0.042 -1.196,1.319 -0.892,1.35 3.166,0.326 6.3,0.265 9.45,-0.201 0.456,-0.067 1.086,-1.379 0.891,-1.35 z"
+ id="path3473"
+ style="fill:#58595b" /><path
+ d="m 24.544,14.986 c -2.973,-0.041 -5.935,0.023 -8.898,0.252 -0.449,0.035 -1.12,1.367 -0.892,1.35 2.964,-0.23 5.926,-0.293 8.897,-0.25 0.435,0.005 1.163,-1.348 0.893,-1.352 z"
+ id="path3475"
+ style="fill:#414042" /><path
+ d="m 18.26,18.053 c -0.835,0.094 -1.676,0.059 -2.514,0.102 -0.304,0.014 -0.621,0.486 -0.766,0.707 -0.041,0.061 -0.406,0.656 -0.126,0.643 0.838,-0.041 1.679,-0.01 2.513,-0.102 0.313,-0.035 0.613,-0.473 0.767,-0.705 0.034,-0.053 0.407,-0.675 0.126,-0.645 z"
+ id="path3477"
+ style="fill:#6d6e71" /><path
+ d="m 25.047,21.117 c -3.111,-0.518 -6.223,0.045 -9.351,-0.051 -0.431,-0.014 -1.168,1.344 -0.892,1.35 3.127,0.096 6.239,-0.467 9.35,0.051 0.393,0.068 1.22,-1.295 0.893,-1.35 z"
+ id="path3479"
+ style="fill:#414042" /><path
+ d="m 4.0143008,8.8697034 -0.71875,0.0625 -0.71875,0.03125 c 2.84e-4,0.020548 -3.11e-4,0.041942 0,0.0625 0.00108,0.010632 -0.00109,0.020622 0,0.03125 0.02814,1.7823956 0.134739,3.5889086 0.4375,5.3750006 0.146,0.911 0.34875,1.82375 0.59375,2.71875 l 0.4375,1.34375 0.5,1.3125 c 0.177,0.432 0.417,0.831 0.625,1.25 0.197,0.424 0.503,0.7895 0.75,1.1875 0.238,0.405 0.57,0.73375 0.875,1.09375 0.291,0.374 0.66325,0.698 1.03125,1 l 0.5625,0.4375 0.59375,0.375 c 0.407,0.243 0.82325,0.496 1.2812502,0.625 0.451,0.134 0.872751,0.36825 1.343751,0.40625 l 1.125,0.1875 0.125,3.0625 c 0.014,0.132 -0.0305,0.26475 0.0625,0.46875 0.051,0.154 0.313,0.16875 0.375,0.09375 0.098,-0.06 0.09425,-0.10725 0.15625,-0.15625 l 0.625,-0.53125 1.25,-1.09375 c 0.83,-0.724 1.656,-1.44925 2.5,-2.15625 l 0.9375,-0.8125 0.3125,-0.25 0.625,-0.53125 0.28125,-0.21875 c 0.132,-0.111 0.123,-0.3055 0,-0.4375 -1.556,-1.678 -3.13125,-3.3555 -4.65625,-5.0625 l -1.125,-1.28125 -0.59375,-0.625 -0.28125,-0.34375 -0.03125,-0.03125 c -0.035,-0.023 -0.079,-0.0525 -0.125,-0.0625 -0.094,-0.034 -0.211,0.02375 -0.25,0.09375 -0.077,0.126 -0.08775,0.2375 -0.09375,0.3125 l -0.09375,3.09375 -0.6875,-0.09375 c -0.332,-0.025 -0.65375,-0.0905 -0.96875,-0.1875 -0.312001,-0.103 -0.647501,-0.1545 -0.937501,-0.3125 -0.2960002,-0.139 -0.5860002,-0.25925 -0.8750002,-0.40625 l -0.8125,-0.53125 c -0.263,-0.188 -0.502,-0.42 -0.75,-0.625 -0.255,-0.198 -0.43225,-0.48875 -0.65625,-0.71875 -0.228,-0.228 -0.40375,-0.489 -0.59375,-0.75 -0.198,-0.257 -0.37425,-0.55875 -0.53125,-0.84375 -0.169,-0.276 -0.3045,-0.577 -0.4375,-0.875 -0.147,-0.291 -0.265,-0.565 -0.375,-0.875 -0.124,-0.303 -0.2215,-0.6215 -0.3125,-0.9375 -0.205,-0.623 -0.33975,-1.26125 -0.46875,-1.90625 -0.104577,-0.531118 -0.222699,-1.0886966 -0.28125,-1.6250006 -0.00389,-0.094527 0.00365,-0.186536 0,-0.28125 l -0.03125,0 c -0.00182,-0.020634 0.00171,-0.041876 0,-0.0625 z"
+ id="path3483-3"
+ style="fill:#000000;filter:url(#filter6624)" /><path
+ d="m 19.92,22.149 -6.764,-7.176 c -0.124,-0.132 -0.225,-0.063 -0.225,0.148 l 0.023,3.469 C 4.777,18.356 3.435,9.55 3.226,7.296 c 0.097,3.02 0.339,16.219 9.705,17.19 v 3.541 c 0,0.213 0.109,0.296 0.243,0.185 l 6.728,-5.62 c 0.132,-0.111 0.141,-0.311 0.018,-0.443 z"
+ id="path3483"
+ style="fill:#ffffff" /><path
+ d="m 19.92,22.149 c -1.584,-1.652 -3.153,-3.318 -4.767,-4.942 l -1.203,-1.226 -0.608,-0.606 -0.294,-0.291 -0.04,-0.032 c 0.002,0.009 0.005,0.007 0.017,0.012 0.021,0.009 0.082,-0.012 0.08,-0.027 0,0 -0.009,0.053 -0.003,0.118 l 0.14,3.433 0.012,0.308 -0.308,-0.019 -1.055,-0.066 C 11.536,18.807 11.188,18.735 10.841,18.656 10.497,18.569 10.133,18.541 9.805,18.393 9.471,18.265 9.129,18.149 8.798,18.007 L 7.85,17.483 C 7.543,17.294 7.267,17.057 6.974,16.844 6.673,16.637 6.445,16.353 6.177,16.109 5.904,15.866 5.695,15.572 5.463,15.295 5.224,15.021 5.029,14.719 4.834,14.417 4.627,14.12 4.447,13.809 4.286,13.488 4.112,13.173 3.958,12.849 3.825,12.518 3.676,12.191 3.546,11.859 3.433,11.521 2.949,10.177 2.64,8.788 2.496,7.364 L 3.958,7.273 c 0.069,1.793 0.18,3.552 0.439,5.299 0.129,0.872 0.308,1.731 0.494,2.588 l 0.338,1.268 0.427,1.233 c 0.153,0.406 0.34,0.795 0.508,1.195 0.155,0.409 0.411,0.755 0.611,1.139 0.193,0.393 0.478,0.711 0.731,1.059 0.24,0.362 0.548,0.656 0.861,0.949 l 0.461,0.449 0.531,0.36 c 0.352,0.245 0.702,0.501 1.112,0.643 l 0.594,0.261 c 0.194,0.099 0.399,0.17 0.615,0.205 l 1.277,0.296 0.251,0.058 -0.007,0.213 -0.113,3.305 c -0.005,0.137 -0.016,0.295 0.01,0.337 -0.004,-0.005 -0.063,-0.015 -0.024,-0.02 0.024,-0.003 0.1,-0.073 0.148,-0.107 l 0.648,-0.513 1.29,-1.032 c 0.86,-0.688 1.722,-1.375 2.568,-2.08 l 1.275,-1.05 0.638,-0.525 c 0.101,-0.093 0.225,-0.164 0.306,-0.273 0.081,-0.115 0.064,-0.275 -0.027,-0.381 z m 0,0 c 0.093,0.104 0.112,0.267 0.033,0.381 -0.082,0.113 -0.204,0.185 -0.304,0.279 l -0.63,0.534 -1.261,1.068 c -0.844,0.707 -1.673,1.433 -2.503,2.157 l -1.246,1.085 -0.62,0.547 c -0.062,0.049 -0.08,0.085 -0.178,0.145 -0.062,0.075 -0.317,0.071 -0.368,-0.083 -0.093,-0.204 -0.058,-0.34 -0.072,-0.472 l -0.113,-3.305 0.244,0.271 -1.378,-0.219 C 11.053,24.499 10.634,24.258 10.183,24.124 9.725,23.995 9.323,23.747 8.916,23.504 L 8.302,23.143 7.759,22.687 C 7.391,22.385 7.027,22.079 6.736,21.705 6.431,21.345 6.091,21.004 5.853,20.599 5.606,20.201 5.299,19.828 5.102,19.404 4.894,18.985 4.65,18.577 4.473,18.145 L 3.96,16.84 3.545,15.508 C 3.3,14.613 3.103,13.708 2.957,12.797 2.649,10.98 2.518,9.131 2.493,7.319 L 3.955,7.228 c 0.054,0.65 0.159,1.305 0.286,1.95 0.129,0.645 0.272,1.291 0.477,1.914 0.091,0.316 0.198,0.626 0.322,0.929 0.11,0.31 0.237,0.61 0.384,0.901 0.133,0.298 0.271,0.594 0.44,0.87 0.157,0.285 0.313,0.571 0.511,0.828 0.19,0.261 0.359,0.543 0.587,0.771 0.224,0.23 0.41,0.506 0.665,0.704 0.248,0.205 0.479,0.436 0.742,0.624 l 0.816,0.527 c 0.289,0.147 0.591,0.271 0.887,0.41 0.29,0.158 0.621,0.202 0.933,0.305 0.315,0.097 0.634,0.187 0.966,0.212 l 0.99,0.131 -0.295,0.289 0.095,-3.434 c 0.006,-0.075 -0.005,-0.173 0.072,-0.299 0.039,-0.07 0.169,-0.138 0.263,-0.104 0.046,0.01 0.079,0.034 0.114,0.057 l 0.042,0.038 0.295,0.333 0.569,0.643 1.152,1.273 c 1.525,1.707 3.096,3.371 4.652,5.049 z"
+ id="path3485"
+ style="fill:#f7941e" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/first.png b/silx/resources/gui/icons/first.png
new file mode 100644
index 0000000..fe3b87c
--- /dev/null
+++ b/silx/resources/gui/icons/first.png
Binary files differ
diff --git a/silx/resources/gui/icons/first.svg b/silx/resources/gui/icons/first.svg
new file mode 100644
index 0000000..8704281
--- /dev/null
+++ b/silx/resources/gui/icons/first.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="b" x1="11.913" x2="27.737" y1="10.398" y2="16.471" gradientTransform="matrix(-1 0 0 1 32.506 0)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#002839" offset="0"/>
+ <stop stop-color="#00f" stop-opacity=".2585" offset="1"/>
+ </linearGradient>
+ <linearGradient id="a" x1="11.913" x2="27.737" y1="10.398" y2="16.471" gradientTransform="matrix(-1 0 0 1 32.506 0)" gradientUnits="userSpaceOnUse">
+ <stop offset="0"/>
+ <stop stop-color="#00f" stop-opacity=".30612" offset="1"/>
+ </linearGradient>
+ </defs>
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g>
+ <path d="m25.451 4.9951c-6.6141 3.9114-12.473 7.571-18.396 11.252l18.307 10.806z" fill="url(#b)" stroke="url(#a)" stroke-linejoin="round" stroke-width=".4"/>
+ <path d="m6.5357 6.2992-1e-7 9.9456v9.9456" fill="none" stroke="#00006a"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/folder.png b/silx/resources/gui/icons/folder.png
new file mode 100755
index 0000000..61c8f55
--- /dev/null
+++ b/silx/resources/gui/icons/folder.png
Binary files differ
diff --git a/silx/resources/gui/icons/folder.svg b/silx/resources/gui/icons/folder.svg
new file mode 100644
index 0000000..7ee9be1
--- /dev/null
+++ b/silx/resources/gui/icons/folder.svg
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3031"
+ xml:space="preserve"><metadata
+ id="metadata3081"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3079"><linearGradient
+ x1="7.2104001"
+ y1="11.63"
+ x2="18.261"
+ y2="20.056999"
+ id="b-3"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop3038-6"
+ style="stop-color:#dedfe3;stop-opacity:1"
+ offset="0" /><stop
+ id="stop3040-7"
+ style="stop-color:#97989c;stop-opacity:1"
+ offset="0.31040001" /><stop
+ id="stop3042-5"
+ style="stop-color:#626365;stop-opacity:1"
+ offset="0.55800003" /><stop
+ id="stop3044-3"
+ style="stop-color:#343435;stop-opacity:1"
+ offset="0.73269999" /><stop
+ id="stop3046-5"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0.81879997" /></linearGradient><filter
+ x="-0.32505301"
+ y="-0.4033666"
+ width="1.650106"
+ height="1.8067333"
+ color-interpolation-filters="sRGB"
+ id="filter3903"><feGaussianBlur
+ id="feGaussianBlur3905"
+ stdDeviation="3.2938311" /></filter></defs><path
+ d="m 26.653703,23.838789 c 0.048,0.158 -0.045,0.311 -0.208,0.339 l -18.8620008,3.298 c -0.163,0.028 -0.335,-0.077 -0.384,-0.235 l -4.84,-15.719 c -0.049,-0.158 0.044,-0.31 0.207,-0.338 L 21.427703,7.8867879 c 0.163,-0.028 0.336,0.077 0.384,0.235 l 4.842,15.7170011 z"
+ id="path3048-6"
+ style="opacity:0.5;fill:#000000;filter:url(#filter3903)" /><linearGradient
+ x1="7.2104001"
+ y1="11.63"
+ x2="18.261"
+ y2="20.056999"
+ id="b"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop3038"
+ style="stop-color:#dedfe3;stop-opacity:1"
+ offset="0" /><stop
+ id="stop3040"
+ style="stop-color:#97989c;stop-opacity:1"
+ offset="0.31040001" /><stop
+ id="stop3042"
+ style="stop-color:#626365;stop-opacity:1"
+ offset="0.55800003" /><stop
+ id="stop3044"
+ style="stop-color:#343435;stop-opacity:1"
+ offset="0.73269999" /><stop
+ id="stop3046"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0.81879997" /></linearGradient><path
+ d="m 25.561,22.518 c 0.048,0.158 -0.045,0.311 -0.208,0.339 L 6.491,26.155 C 6.328,26.183 6.156,26.078 6.107,25.92 L 1.267,10.201 C 1.218,10.043 1.311,9.891 1.474,9.863 L 20.335,6.566 c 0.163,-0.028 0.336,0.077 0.384,0.235 l 4.842,15.717 z"
+ id="path3048"
+ style="fill:url(#b)" /><path
+ d="m 25.561,22.518 c 0.048,0.158 -0.045,0.311 -0.208,0.339 L 6.491,26.155 C 6.328,26.183 6.156,26.078 6.107,25.92 L 1.267,10.201 C 1.218,10.043 1.311,9.891 1.474,9.863 L 20.335,6.566 c 0.163,-0.028 0.336,0.077 0.384,0.235 l 4.842,15.717 z"
+ id="path3050"
+ style="fill:none;stroke:#414042;stroke-width:0.1;stroke-miterlimit:10" /><linearGradient
+ x1="6.2392998"
+ y1="17.226"
+ x2="30.867001"
+ y2="17.226"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop3053"
+ style="stop-color:#f1f2f2;stop-opacity:1"
+ offset="0" /><stop
+ id="stop3055"
+ style="stop-color:#f2e7db;stop-opacity:1"
+ offset="0.0395" /><stop
+ id="stop3057"
+ style="stop-color:#f4d3ae;stop-opacity:1"
+ offset="0.1471" /><stop
+ id="stop3059"
+ style="stop-color:#f5c188;stop-opacity:1"
+ offset="0.2586" /><stop
+ id="stop3061"
+ style="stop-color:#f5b36a;stop-opacity:1"
+ offset="0.37180001" /><stop
+ id="stop3063"
+ style="stop-color:#f6a74f;stop-opacity:1"
+ offset="0.48710001" /><stop
+ id="stop3065"
+ style="stop-color:#f79e39;stop-opacity:1"
+ offset="0.60509998" /><stop
+ id="stop3067"
+ style="stop-color:#f79829;stop-opacity:1"
+ offset="0.727" /><stop
+ id="stop3069"
+ style="stop-color:#f79520;stop-opacity:1"
+ offset="0.85519999" /><stop
+ id="stop3071"
+ style="stop-color:#f7941e;stop-opacity:1"
+ offset="1" /></linearGradient><path
+ d="m 25.951,22.025 c -0.191,0.516 -0.791,1.016 -1.332,1.112 L 6.935,26.267 C 6.393,26.364 6.107,26.02 6.298,25.504 l 4.854,-13.077 c 0.191,-0.516 0.791,-1.016 1.333,-1.112 L 30.17,8.181 c 0.541,-0.096 0.828,0.248 0.637,0.763 l -4.856,13.081 z"
+ id="path3073"
+ style="fill:url(#a)" /><path
+ d="m 25.951,22.025 c -0.191,0.516 -0.791,1.016 -1.332,1.112 L 6.935,26.267 C 6.393,26.364 6.107,26.02 6.298,25.504 l 4.854,-13.077 c 0.191,-0.516 0.791,-1.016 1.333,-1.112 L 30.17,8.181 c 0.541,-0.096 0.828,0.248 0.637,0.763 l -4.856,13.081 z"
+ id="path3075"
+ style="fill:none;stroke:#f7941e;stroke-width:0.1;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/image-mask.png b/silx/resources/gui/icons/image-mask.png
new file mode 100644
index 0000000..44032e0
--- /dev/null
+++ b/silx/resources/gui/icons/image-mask.png
Binary files differ
diff --git a/silx/resources/gui/icons/image-mask.svg b/silx/resources/gui/icons/image-mask.svg
new file mode 100644
index 0000000..698efb2
--- /dev/null
+++ b/silx/resources/gui/icons/image-mask.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(-.4361 -.1802)">
+ <path d="m7.9557 1.6942c-2.4733 3.0522-4.0586 7.3933-4.0586 12.242 0 9.2281 5.6201 16.73 12.539 16.73s12.539-7.5015 12.539-16.73c0-4.5475-1.354-8.6683-3.5637-11.681-6.001 1.9433-11.808 1.5682-17.455-0.5608z"/>
+ <path transform="matrix(1.0559 0 0 1.0559 -2.567 -1.5541)" d="m16.644 11.458a3.8814 2.9492 0 1 1 -7.7627 0 3.8814 2.9492 0 1 1 7.7627 0z" fill="#FFF"/>
+ <path transform="matrix(1.0559 0 0 1.0559 8.869 -1.5541)" d="m16.644 11.458a3.8814 2.9492 0 1 1 -7.7627 0 3.8814 2.9492 0 1 1 7.7627 0z" fill="#FFF"/>
+ <path d="m16.563 13.059-2.0993 5.8501c1.2282 0.78863 2.6176 1.0247 4.3666 0.02799z" color="#000000" fill="#FFF"/>
+ <path d="m13.111 21.648h7.0723c1.1245 0 2.0297 0.90526 2.0297 2.0297h-11.132c0-1.1245 0.90526-2.0297 2.0297-2.0297z" fill="#FFF" stroke-linecap="round" stroke-linejoin="round"/>
+ <path d="m13.111 27.422h7.0723c1.1245 0 2.0297-0.90526 2.0297-2.0297h-11.132c0 1.1245 0.90526 2.0297 2.0297 2.0297z" fill="#FFF" stroke-linecap="round" stroke-linejoin="round"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/image-select-add.png b/silx/resources/gui/icons/image-select-add.png
new file mode 100755
index 0000000..8a89cc3
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-add.png
Binary files differ
diff --git a/silx/resources/gui/icons/image-select-add.svg b/silx/resources/gui/icons/image-select-add.svg
new file mode 100644
index 0000000..1856bd8
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-add.svg
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <path d="m9.085 25.873" fill="none" stroke="#00A14B" stroke-miterlimit="10" stroke-width="1.5"/>
+<image transform="matrix(.0667 0 0 .0739 .0044 0)" width="480" height="456" overflow="visible" xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEEOAQ4AAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA EAMCAwYAABj9AAAyXwAAVa3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAf4B7wMBIgACEQEDEQH/ xADOAAACAwEBAQAAAAAAAAAAAAAAAwIEBQEHBgEAAwEBAQEAAAAAAAAAAAAAAAIDAQQFBhAAAgIC AQMDAwQDAAICAwAAAQIAAxEEEiETBTEiJxAgMEAyIxRQQQZgByQVcEIzEQABAwIEAwYEBQIEBQUB AAABABECITFBURIDEGEicYEyE0OjIJFCBDBAobHBUFJiktI00eFyIwVw8PEUFTMSAAIBAgUDAwMD BQEBAAAAAAABESECECAxQVFhcRIwgSJAkTKhsQNg8MHRUkIT/9oADAMBAAIRAxEAAAD4IAwAAAAA AAAAAAAAAAAAAAABwJ7uac4fIx+3rrP5A08yvUAboAAAAAAAAAAAAAAAAAAAAAAAAAAAHvoBvgQB gAAAAAAAAAAAAAAAAEgiy7tpGl9BF/Jyw4yU0jDvTE/G/bZ12+PJw6/SAAAAAAAAAAAAAAAAAAAA AAAAAAAA99AN8CAMAAAAAAAAAAAAAACV/Mp/Rr1occ2qbzS7PnUpyUW5sItgKqDk0jjfNfbY/XXA NSNezNO82gAAAAAAAAAAAAAAAAAAAAAAAHvoBvgQBgAAAAAAAAAAAADgu34XI8DLCGyk1qrUrSjL sqTZKMmiTrNnK6afTN2a1F3qtfHbswPtMxd+cNuVdyobVtc+Vlv9puEvdq9S5ZOEHDoHAMAAAAAA AAAAPfQDfAgDAAAAAAAAAAAAC5T0MXUsKdHzZWq9mVWsg6FS3DkKE4oGnkiOkhGymrpG9HTKfMo7 lWytLTDW5tyLOpOMoprZ7Tjm6Te+HyFrdR6HNR5onbDIz9hG92MSj59wDAAAAAAD30A3wIAwAAAA AAAAAAAA08zZWd2xWfHgsOrWJWtPrd57NktGUnUhyzLnxmvCPYD8jKJQhNRaN2lZLbM0v4XShC+j gsQhF8sWM9uK2rb6/ItMZ+v5VGruVOy3ztTSzeL0wCOgAAAAAe+gG+BAGAAAAAAAAAAAAT1czTSV 1qWz47DkkrOmhiWI9Mp1cllIThzXdXI5XnOxa00cS1JMpyZtq7kWue/F8i3MCRktWq16TPZWsS5e 5etWr52Tx8/U8zNpfRTvT46v9t8onZUAl1AAAAe+gG+BAGAAAAAAAAAdDjJ2KJy4h8o2iMpQc5Dp 2Z1RO7ZnEr2DElOJnWajU1kvS0hLmqsu2TsoPsRXogyKBOqIPzScq1j2XVXwzQsVHc/nWElZuFHW I7PJcHOzm7kaaO2vyHLdTj9wAUAA99AN8CAMAAAAAAA6A/tqk4PcvebnF9hS21bZTlYRYSvGrfLo bXXVyljsZllZ+jRetWxN793GrknbPiI6NEs2YlTdjyU2jw5B2E7KrEY9sLdLjci1NOPI7cz+zx5z rWO3k5J50JSofQrpT4VP0/zEPXAJW99AN8CAMAAAAA6BY7arItwfvKqHYREvRZld/Yiqx6LEuiKr XVrQusfPppTnV125mjUe7azhuqVewnWgicXg4HrXPugD4SYnXGwvqbZfn9nzaHaVpOC7YpPlxKoN j1+YmM2W8+mXOVFSnDsSp8x9P8w/pLA5u330A3wIAwAAAAt1r1Ucxkm45Ha0kESI9DGQ6rMsVr86 tZWuxfibK1ouLOl682ROji3VCqimy7XqrbC9eVG4t+etaS7WswVFOhvFDSaxTVm59Z0oXblG1zwt yS2PNVz9TN7PMVLk+jz3dj1KclxnTOv8/wDT1+vPhS1Vl7nvoGN4EAYAAAA7TpanRyz7GKcsa9ip CwyMk6Ot79DCnLOtS82vz16s7tyMXvSna7uSvVlOvR69C6uz11Xq1LcuV3Z1pLFLVkuS2noh2XpR 4yWKgsyIqsTfHlrW+9TifCa84pUuQ6fMh2PLcTJweEWzZXa0b6OuWH8v9r8bnp+9AS7vAgDAACcH MXblN1eKclK5870lO/XmjNj6r5iXHb6vNxFRa0Ib1Y2dNGPr10OS3KwPVuRqZr1fUu03s19dm9Dq dqGCUOeyJfXMe02jNXu9q9TLTE2E5XWKdmXJc7yMuWjXuV+3yYpeU41vR1iy+s+2uVGXUmV8j9H8 zvo++gQ7vAgDAAOvW+i2pRu5x1pNXzkYwYWjNdnBEZWB26mf2Idqba2jUuUkpcq9r5axJvM6qEkT qPo6NAtyZZa8Jqbj0mWKjRvIeyXZTY5Tcq3rZnNZtU5xlpMq3OeMKl+lTjWrq+vyuuU3Yci2KtXk 9NUZ2tz0ZYuLbqT9330BK+BAGAAMtI0aRnaTPOKdOypdVBq527YQ1d5Ncsdq325WVrZ9qFaGhWvZ ahT08120EWqSdOfdqbVHr1XpLVtHP0i6IWa40VWINzru1OY2jLOszo5b7U4UrvZrxRLFQ5LVTkKc io950+Y/sJKs5Q6jshKePVyd7P7Z/GHeU9n30A3wIAwAB17Lm66bqFunPYjGc4CWo56MlEx5ddaS q9Kjsc9qiJmPC1StZSk+lvZagm3mbRexnaedSM/VqG5mlQlZdBZOfbUZMeKmsWvM/iriZWdY6kuX FSnB9Sws5s5dmPb5a+zW3LJM2Alj2K6WTgr85CHXD5Gnt4lvX99Ay3gQBgAAAFq5malZzO9hzKfY TMi+TkrNd9kK17y1zqtEr+sipp4o9jZztCPUjB+kyXEaOJoUpfUyXP2Z9bRrdHNTc2LFhubcn0T5 aEkldq1nJn3q0iNyLIynRdTT18b+LdXzzspKlSb6zLYZVar2uoaV5Ut0PQ5sHGsV99j30Ba+BAGA AANB+q3k/P61b0jUfC5luRnydrXIMlfvOi0r7+HuwrXxvocQZWnk3aUvItR5en55elT7oPu5VpOm 2qzyNcqWhn25rUIW12ndnxVsdRdjKGbq1n5qz8e3080s+2i/A5+Rpk2zXOTdW6OMiRCkZ8idM24W lh9fo4wEe730APAgDAAO69TUTmd3vE4YW6ljBFmq/Ktah87KvUrk78W5K1Xu4l+VdLL1VclPn+Tb 6C3reHq8fTHG+jotlCv2/wBC1dWgmddSMmxM1WvQtzOdm6Snat7OJaCaj2girah08EFWuNz5nLZR nOy7CZoSQ2NiDeZtano5XpRrZ9/G6fpawHPxe+gG+BAGAODRuRnLzrCX18jJy25lec1FXuRYnVdm rNL61e5DlrlNTYu+tYx9vzrZCtj53oyxCzJmtyytGFM+pv4152WUrhsXyqoaMFskmLauYvXDVWo2 OZeqI6eXQcmwkJEyVqK7tS/O+HLC6kucStdsFNN2XpZvfajg7WJb2gCPP76Ab4EDDIbK75x8lIly sWziqtqW6MrW6is59N+W70gtdTQ+f2eW1etqZGszQqqyn0edy/w0+X1l1O5davJsGdGhdUxnX8bp nqOznqVdDLjWWomMTlquePCrm7OTXLd7F11x/Yy57RTYWyRiSaY2nzS7Wai2Rz5q9P06GRdpQ7QB Ie+gG+BbGPpNHQmxG+farWExRzqzZrWes2lmlYjmQ6txR6eGM+xUsztrUlX+dsyxTlV57GciT7Xz 27WRVW/n9CrXaVjLE2lVmE8zSVXrK1lXqzzc7M0NSzODoquhpVmzMdPlm0G5OhHLQqcbQ4yLIuna xe+enmKl3+kzncyftUYhzeaAGe+gG+BTgGfRmXtV81T60knF0Eya5VdBMmyrMznZIKPajorLFSat as1KybrY+pn4XGZ10ZOjh3zWZ2kjYtSl+5U0Myw23W1LE4dr3Vq2HqUW2fRYl0FFsjm1IW6tpMrv fmqfT7m6EVsnStgatH2uuM506+ujP4cMADJAAe+gG+BAGS28LSeO1Sk6vAkklG49aZNOQtWswS5F nFINcV12S7X5I19vF1lSlatLzEIv0NLVnN0FR6mk9o1Z1b10bVWykHx6SfLq6mf0Po2sfQnOyRbG iVWVNPOfKpfNVSLKFSxn1+l5C2+l78sOzmczAEOUAAAD30A3wIAwao0+mdja3V5dhbE7CS7Ihm2G MnTNho0kpOFyM50LtW0lLkW2YwwWORW2i9FyETH280rU0c3RoluUZ81M2jq5fStm5kaAl3h2DwpX lvPMmu5Zm2c1ssvq7ybLz7uT6AkZzv8AV4MqnXYoVU8ud4EoABgAAAHvoBvgQBgABYrm5rOw31ju W/ne1nu3MbVXh5nalFNtnLE5Yt1Yl9VybHMmVT08ilNa5QvQmyhoISvz2vVOldZtW1y6iloqdMN4 nopr2MjThNkJwQz0aGd0l+v17pmuoW7dLaKXdXexi+P6M8B9XkgATgAAAAAAAB76Ab4EAYAAAAAA d4Bb3fmdSvLu1+IpwN08bcRM+vdpK9/RxtjnxGN9Dn7tLSynpuxHsuemfQ2cW8rd/JtIX4MhF6Wb t4/VkbGW9q/Qwq2oc6M9+N39Dp9Z2+tXepKVWunzkm5cRUAMUAAAAAAAAAD30A3wIAwAAAAAAAAY s01o5g8tH6b4je3lvVe19lc1MPRSWtTsQyeJZpQOjct4mtFJZGvm0nQsY9nez6Czj6EuWOfc+X6L PlXbb1rNvEnONigmK30XZANYrgiAGKAAAAAAAAAAAAAB76Ab4EAYAAAAAAAAAAAATgBbUk1W62JI X7R/x5Xz9PCjyfoWbGcZv2GJl8aPdDODr1atQFsVwXQDAAMAAAAAAAAAAAAAAAAAAAAAA99AN8CA MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA99AN8CAMAAAAAAAAA AAAAAAAAAAAAAAAHo1wUr6dhvw59Bth8IbGOYAAAAAAAAAAAAAAAAAAAAAAAAAB76Ab4EejBnnJ6 MB5yejAecnowHnJ6MB5yejAecnowHnJ6MB5yejAecnowHnJ6MB5yejAecnowHxutuBuGbgGQrcAw 8n7IDzk9GDPOT0YDzk9GA85PRgPOT0YDzk9GA85PRgPOT0YDzk9GA85PRgPOT0YDzk9GA85PRgPt wDf/2gAIAQIAAQUA/HmG5RBesBBH6prAJZZynIY9JS/E/qCQJY5hPQmGAxTK36ch+mMJjRjiZ65O FGYiGLgQtK7hnurDbgpdSSKq3Ugg4P529DHjHq3VePJq6woBnKZmAJba6T+1aVqpsJS5kNFyOVIM spVgRg/kf0Mb1InEmKoEJnX6CMOjeqonHrCOqWBTrXq4DGbC4s/I8MIhA+ghgH0CzjHrBYDpgxzi EShypr2GhbmHqwPxKkuOWMaETOYIB1CGcQIXAnImYBmIcYYRg3KtTEPStjKypDrxb8CriMY5yTGj GBIYnqWhzAsxMAQmHpHIjEQPg1sGFTLhTOKtLa+B+5VwMywwwxiJyEd25DqE6QdAPXpCcQkEZxGy YayYVABAzWOMzg13ERLSZewZPtqHVjmMYTDHaNgAEzMJJCzj0yVgPQ4IAEwIcxo4BhBBoPQ+g9a2 g9wIx9qjCsYTmEy65a1TYL2N6lwIOUGTFwICct1i9R9ORheNZC4MXhyrTBxMAxFlctXH2IMlmjtC YzGbFDXCnRKsR17YnECAESvoFhEBwc4hAMK5hURgkYLADmsnAJEyIkrBEvI+xRgOYZiYE9Iy5LkK EzAuLM+7HRD1LYJgORyKnkDDGUGMCDSSYoxGgMrsINTAhzlvqPTEYCH6GM4Bs90sY8kOQvVnbBX1 sPVTkAwhWjIRC7LGcMFPKIhBHoQYRAcGh/tVpxj+n0LYlzYC9Fce61uCJ7hafdWwywDD0JYGZzDy ENkbrK8gqenrMkAuIMMal6kYP2B/a75mYzQucN7ozBK6jyW85ahxLEzAcFWhYRkIgeF2EYBlX1Fe RjAJgYGMoiIQaV6Mcn7CxMMYmf7I6/72c41mzLVyFbBVsrYmQrYisGh5rGbkG5KamwxqGaxgOpEM Bg6ypAYV4p9jH6NGh9X9R+69Swqfg5MvqIlFuISVjotgyRK7A0sUg1DMFZVkJADdeUZIVMBImn7m 2D1+w+oh9PWNGGQGIZsTYUo1D9xS4EeoqabAwZSD++BWUp/Iqpg8AwbpMnKsCCSJ3DMBppAhr/3/ AFYdDP8AZgjCYl1eDWSyuocBWpsOLFxxhrKsh5hq4a+SqmJylZzLF6mKZ6E15lNRlNfAWNlvovq4 hEP0EMxGAnE1sVBD1iwUngXpBldYwKyDgNEGIVAjHErMOCHTEIwQZr08wlAQW2YX7B7gVjJj6Y+h EKwplUGIVwWrBi9BxAhUEssVurdQ3qIpzMkQqCAuDqJiqxsITn7U9SpMKmGuFZj64jCcwYpBjiAg MI/oPVTkOkORFM/cFrYMmuSVwq3WZ+4RCGVh0IhWMsKxhCxB/wBOcSlvc8PrWfa6/RGwW9GQEAET Vp5kVIpscBWtJH3gkRLMzAx/thCI69CvVR7bBKzhmGQ4wUbE9RYmIIgJCUnJoMoArj2ASyzkfxo0 MAjDo6xBLK8wLgoOliZCgysEgr0FZzRWBMIB3AqmxiSSfzdyI3UwjMVIVjVdVTA7ZM7J5LWFUGow CoFrCT3XhJP6LkYDiCwCM2TmFzhHZSzliWJ/8s//2gAIAQMAAQUA/GSBH2q1g3FiOrj9VZeqxmdz whGZRb23/UMwWXXliBAIBGEcYmtscYL6y36UnAusOQIFgEwIQYaSYmuogTIVGSchMmFsBbFb9DYf aTkgRRAIBAsCwLAkCZhoGCgEYAw0gNdfYsGw2aXJX8txwgHVRFEAgEAgWKsCRElidGU8uEKS7VDi yk1NRshSpBH5LvQCJBFEAgEVYqzpEbqy+01deAhq6WACbKZBKgrt2LNba7p/EzgQnkR0KxRAIBAI DER2lekzRdepJapWMJXVk3YlmJd6Wj3EdaGZHU5H4HcAcySigA9WURRAIqzh0ooUBCihthcBwSbG YpWTC0dGMsrMsSbKEMwIhZou1cp17u6n3WWSx+qjIPQKuSqwLERQFHUL1Puaw5UljFVmVK2VghYE IosuUS6wsXzNif7yZhM6OMfbY2FLxRyKDE45irBBEETAnOVOS3AOGqwauSs1tsNrxmJjNHeO02uo mRgqJTcabFYMv2Xt1wTKgDAIqwjAEUQEQGBCYUAFXSPlXLHOAQUWPSseiW14loOL2+gBnE4srxNB yU+p9HGSEzAAAOkRsRrIDA0XrFh6tZ0iNLBkBOcWyxIuyBH2I9thju0sM2wMzOIDHYMNBcV/VjgO 4WBiZlRGtRTzgOYogEHUcRwqPuuBxUhNYM61syq4dCISRGtIjPmXHAvfMWFYy4hryaE4VfW1sR+Z icxFJjBTADFWCIOg/cxPHWTkrkFdQ/x2LiNnCXFF76GWBGli4jnEtsjnLQGYBCYSz7GqVjbWVmOq AwLkrFH0U9KFyzHB1eldqkii0rOQZWXClis5qY3SM0tIxc5BJ6/7FZM4uodmmu/Or7Ng5UYyHLFY oEEUZJ6GnoLRKLYTkOMRXYRdhWFgEedwx2llktbJCwqRFdpzBlnV6E4V/UnAsuZ2ZmnLArPUQSuN K2h6j0aq2P1hJU81MLkRnBlhj2dLXOSGUqYy5hypYnPjNXuN9mxYcR4PQRTmAxDD1AMrfIsEVsxb SI5BjEg9zMdsSyzpa8OYLMj0isDGUEV1hrsLVrfUkAWPyZesJ6IcwGIYDFMU5h6EGB8hjgh4XxGY GF8G23o1uR+48RxYcSoBhqGOTIdMc9vYJB+hIE2bsrn2r+9pUfojQGBoGxCQQGxMzl054Jshs6W2 RmJi4ViArCOs9QtpEsYGeJ1WD7LA2/TYBNY9yoYwjdRWQrZKlDhg+JyxA+YHhsxO507vV7IbwQLT m31QZjdDzUrkqVbIZREra19TSVWJWqsnJ+hGZahrdlzMBgnQskHuXBwCSFbkK7AC1hUu/tW/Bawg 2NmZOSuJZ7kQnDDpATMkTlkePryFUILbWsP2bCBkHFIOJJCtBMcWCHOeDqOL3oVYvyWtsxxhsZVV yn+z6Vt0IKEYMdcQdYSMV0WO2trhE2LBj7SMi+tkZfUMQXsJiPlRawNhUqpM5MyKuTji1v7x6Ker rxb1B6Rj0B4xjka9ZexNVJWgUWX9PvIBh1q8vpITdWyioiHo7nKJ6V4K19GeWFXFRyGGG6Mq5BaI QR1Beqzhq6vbSpMS+zk349qrkqIZsAhk6hejE8ScZ6EKPcDxZgJWRyevo5xNTXLlKFyFCg2tCzH8 pGR2Fzua+RWhlqlYXBhrLJkgI38j67GMSs1ddrCKa4dKgtyAi3MCWLH9B6wIoltSuD45i1VK1o1S EVaddbBiIyqx/wDLP//aAAgBAQABBQD9SATODf5urVvuOp/zjvK/EamuP6muy3+G17T5Lw9uof8A LU69t76fhlpZNfXpq6ADNkJrChJbX3F8jpPqX/5NUZjqeJuuOrq066/1FEWquwNWXCqaU5c2cI04 sB5Tx43aba3qf/I00Pa3j/HVVtalNSduuqsVLei5KgGoB7HLWosCVhnXBdSq+X8el6MpRv8AHKrM 1PjwBpai9xSEvvIWWUqUr7llVS9qBLXte/hATxYq54V8G5S1SRueNpvNfia1s3fHU1qysv8Ai8TT 11QLXyWtCtFSgV11B1IsvVH7VdVdpsuaxoiBA9o54qUv22NltazZ2axNjcdo7WMaKWzsaVdlFiNW 30o07b5br20tAjGDXsMZGX/BatfctqWVVdwqhtVEa9VWywVDtVU1vXZfa9kTCILQ7ZqSbNy1rf5P Cta7Gws0NYn8hGDy1tRn193xq2GjwHdqbxulVXWAIla2V2f81sWO3gtqhX09mpbaq3W2vg0CsYUY TB/W6AlI4tUWQ65c105qTXBpGvz71zva4KpXrvzj3Io2NmutdraLthnZszjOJyVzAgWDaYS5nJ1l a9P/AKZmA8Dt0jW8e1Qp00rr2+wK8qJveOsth072anxoAXUEbXXlbp1Y2NY1frNBeiEc1I7us/Bt UnnUr2bGxYA72pUmue5WXAF14RbbS5wLbHK4ZiCCcYABInQAt1QMyaSkHVsMusNhY1Vjc8q/K2x7 AMKFTI2dblKkGTU7FqRWt6ENbUGSxCj/AKrRX+MYKOA2xWAdtuI29m1ZxSutQjobHcXbC1h7Myxh mqlgpUmBQBy4gkmDpHaDJOspaUIipXsCsW73aUeUa5jXwHKUKbA9tVcbaVpa6lqbq2rsJY30lpll O+gFn6rxoU0gBaWHCH+EunarAVI9nJ3cCW7RK8zghmiqpY2e17WIY2E+pzyh6xiuQ+RrsiNrWDir Jy8s3A66pQvMOS6mDYtsZEqWLli2uLBbq2VGtq2Bp9u1qq43aWZf1NKdyzVIAAIgOYByPLq1xc9x hHYkheUs4gOuFAY111pjkMmwFjkj1DsojNO4M125Onewh2VVbn7lhs6DkxJVyj5NNQlaLAwzYlLr t6+WXY2EjbNzCzVvsj+Fvl+jsUD9Prg93V/eHIisOJYZYs0WHqy+pZQxJZ7GLgL7gxw7MYAqQtkc 0Aa4EtYI1gi29dVwTZZmPYABYqK9wcizM16zK+g7hJpUgES+rIIBbsqCtYECCWa6PX5HVGtsfpUq LSlAtlZCWHqEPRegBg/b3MRVaKoDP6DoleAwYCx7AC9glly4a2G0xUttNeixiaiKMcGssOGcmMwy z8prgZrOJ3MnSoLBV4sygyxcTarlf8lYBEIMIGPLapsrIIP6IAk11RVwFqdTaOuvYSi9ID1Xohb2 8SzBCDafdlQO4AEZ5fY1dlm0I1zNBzcrqWNKtJVgRVHpC2S9YeXLYsx0KmJXk1oFiv1ReC6+zwUX V5NykHYZS5DBCa35jLWBR3czZRuPkKgln6EAk114iVsT2SBfaBHs5DXwsTrB1PUgV5tUfyK6x2Cg 3DhXXzG1eDNzuNFQMyamZXQiQATMzmOcBcgPfgFy06xUioFHcLGkBILFMUoZWa8JxsF2mrAc6md8 JW3OPVgmpjE1mMv8Fq3HY/5lAuzq26tn5gCTXViVU5gQKLbDm2spKRKxgp0C4C1dTUenJVLXhTZe 7mulMMQ84rN24l11ygDDHPqTxHe5Sy3jMgwuONrYdRmBYFCh7DYaaTgUsTXrjC08ZVSDEqxChxtV BlyVP8lT1btbEWVMBYueWVd8jy+ul9JGD+QDJqrAFNWYigCw8VqT22N3HqQAVAFk6gMMZFdfc4K1 jNB3LDTpnXVrS78VEc8UK8trbZURKzgYRdhiFNgRO8rMpJDMSG5FqACvtUFWsldSqEAi4leI1iJK rsyt+tg4i0qxvQGVj2vVO0RAb0ibbKP7KNNpwRevG78YBJq1mBCKq1L0VZse57mFddS5KSoEsr+2 rICaljz+qpllSY8fbXVZsXpa9/FFraxo37L0OeCse2QMgreAyqRha63OuMr2wY+uMrQYlQX6BgJ3 VAN5MWx4lbsaq2Ir1zCjBWZktt9yrkRYaw07XGdvMenM2Ndwl+e9+PTrXKguRX7FX2ueC5UBibWr XiM8QuRNXXa5rjUi6/JquDKLAyN/XqcVjtLYpsmvR7LmCM61MrEVNVeGJrXFlXJrawljISVznX2C SzosOwkN87pgLNFrcxK1AQSlFlXGDBjLmbNS2KeYZsstQKlfQ4MC4JTIZOnm/HEfjVeR16ugTivE kMOK23ZVyWFY68upPVFLH+rdr1moEpSERnWMy8V5MvCEcCHV4+O3ZegS+xnal0Va7WwoWbdQBNeV dCJWFsU64aHWxCpWAtFd4LIrJKwGNVLkJVcsrLrO4rSzGNjKsTKsBAcQEEAz/TYK3UrYnkdNtTY/ DQuTrr0OInrtXdOIrUEmDoFySlfXw/i+I3aEd2pI2HIFZX20phF1xXV2zXLg5Y1qs2NgI7qzMNUt LqghrDIUfptMxPIGvlk0P278TGYUE7QM7JE4PKajhaWEUe6t7lCbFmP7Cc2ckXDJSZOOeJ3QAlmZ ljDyEzPOave1vwAZOumSAFXpGt6CpUljGx1XECkxEnh/DK4ZcnfpwNfAtbLGuprGGuEl7W8i5dbb JdsKi9gOS6ZBM2MG9v8A+g6C1Q1aYEDDLjFynK/QfQKIi4iKY1K8hUVNYM2tcMFusEdiYCVYAtEo UstFYKoggxggYsqXjsAcbV42ffWuTqATkBAXsJdKpZY9hVJxBNNDuadIV26j09r0PlvJalVVDZmW LW7LVTvU2y6xQbb0WwlitaLzvACetvP2t02Wx3cjgMEWIFsesMLD0q2DxW1WiP1EBndQQbaiVbVr Su60FbUcqoMcYm1UCAC07Yj1ssW1RBsUkq4MTMyGDnpuvwNrcrPvr6Cj2oP5C9xhzAMAKxlVAErs qrrG0kHklqF3n7L04VMKlCvY39dq7Q6uQgqFu0HCU1Jf3TccKz51qqyQVHDZADE8ipMHpfVyUMcK iWo+uFKICxpsMVrUgS1wutZmrUEGuwAosMpQVlCrQ3KZaeTEAMrZnGNrhmCrmnjzJnc4ksGXz13a U/eBkqOtaHiSXlVMVUwSBG2A0W5kY3w2tkI7tp1VIbWr7d7kWNcxanhm5UG1491WeX2GL6lYSbao iNaewOKarKeGwelINlSHBGZkFbVZG1rcMUDB6SCuQQVIVcOtvCU3iV2KTXiFAYyNxORC2ZYclPX/ AEVhUEFLEi32rFtV5yxP+ks5X/fUBKAOTOWNWuK6zkHkgZnzDrHglOTZoqFKhZTXgjoXu4w2sW09 QBfIbCrRYD29N+FjN/Y3qwJsKrDaIVkLMpGa9pVCeOllSmYKFcGOgYWoKzQ/crwDHpBhqZYozEUR agyhb6F17ldamGXdTLjwaxwkUiL1gOBAOrL0dIQVll+E8lf39r76/SpTimnhFrYA1swNTczTie5Q trCG6xi3tnVQtwmWdqdcBKn/APhUKdiyyoYSjtNTgX0ZK7NvbLsbLbKjVKSjJtVdNAkWkZDrg8Aw DWIbytg03KIlqkKQZwDQ6wJ7TKahk1O4H9VSabGDsRxsJYHJdnUwAcf9AzpMCMmY1c8yXr1vX8Gs vM1oqRbiINrEO30awsCbLHRW5EDJUotbAvbbxTxmrW8prXav2K2R3sC6WiMVE5beYLWo61cQNtZQ mdl1BBqatrX7o1EI2RHXMIKwOpjVrk6xwVvSLeylNphK9pAEfXsB16+VaMrCuXpyFN+VdozBTXxd u6AwYEAiZgMxCs8prd3WIwfv1rxSy7VTTnma4WEV4ewGsIGJHalSgLaQQU4wUPY5rOdWtQfIcONg YjxzDBcl9+wkeO1hbUw7RYCaKct0pCuDtjhZz/lrcMJYBitAWC9XqtpNNqvDRW8OpVhKghFFbGqg 1mvBhBAsQ4sqblzdoKjinjHAw1VrMr7CkM8qaGxRBaDLAHTymv8A19z8FR9ysyFH42c1abDIycxw Lgs4fJbmNXUdwlQrNAZ9qigUrtjlaW666mtXYKuwTbdq0iqjfr9vePb8VWORPV1mxr90dh0dGZGq tBDKCDQWPAoUaX0LXEssQrZiBEcf1zlFyDU6Cq4OLiwVz16ZJjqRGcvUoIQL0StYakMbXTL1ERXw f+krAt/ADiVtzTUJazjxDdvCVWM3ZKraHUa9IVKbSKko2bJr0mioWF18hhVUM721ChLbAdfxesHs XqNxcpsLwfTsCBGDQASwYOxVzU8boRZSaNnMrdWnbDRqCpIDBKDao0tvWmtetkryZwGHII7nastf 2s3UdYOsxHqIPc9weI8Bz9GGZcvF/wDorM2fhrYhqWNKCnlBVxIqAFrnjrabM3Z5XtUoro2O2osF hoPE77BW8TqlU8gvtPW3Sr7Zr6S1QZvaoleaXpuwysGjIGHEq23rZGvYlqW6HE83rNO1gJZVYG1x FUpKXIXd0mFmltLeAJZ1G6jYp2QylubY4qomIUltJzUWaFGUrYRFcNGOBtWgTe2DsbP4dLSsudNe tCKAStVYSzmDRrEmr2tYcblL5AwDXy7p9uzfrm/yCKAm3Xzru1kM07TmtuQZch6ww2aQlw/glNkR gZZXkATa1XRtfaDE1U2g+OAAoas69nECtXAqKlR03tZK21twWKz5GyOjVKGpRUXoYIIRGEMS0xus DOIbWI8tsMy/h1qTdbSqoHBUoxirlavbarGL1t3KwDrOCbRg0tymwy9xbyNqvBlqjG8OzZcq1zWu XCEMLFnkNcFa1BGDRNbZ6Vsrh6hAuRs6bVNr7C2hHOAxYf1laauwiOWViMAbSB0Is17FuLLYMy12 Vatwh6X5LyimYzCuYymNAxWOwEu2BXX5BiKfwKpZtDV7AIwLPdWh6VHoxAdWin33446+Ua3DJUOI 2ayraq9q7WcOrDI8nQWWleYUPqtr3Azoy3VclvrNViKltb02UHX2sSm1LVtpMVQJt+Pmtsh2UgRV EvoXYr19ntWcxi1ulyKw7XB+1mXVey7SDGi56HrsVwCIpmIVjpkMvTZs7aKzOfJ2e38Hja+TV9Z/ +iEFV6Gs9McpU4JXpLulJHG79yKhxu8uLEPXqbAMQhhtVc0tQ12W1G6rWsZDq7AcOuRtai2rySmy pg4u0FMpsat69hOBrUzj08jpV8NLYZmQcYHAHkUJmludxWYGXvmFRApMZfbjq1Nd9f8AV2KjRtBo tgiuJkGERh08hjiDxG7Zzu/B42rjRX0KLkVHqRiyoRMi2vo/+3y1HV9fVs5111Ht7CHGo3Whu1bq W8lcZHkNNWOrlDdqhpRd25rXrajJ18jpoRr3GsggztU2D+t2G1rgXKiW1dxN3Xs1zpbIuqLiWsrC 5uzsJtrYnM2vgGVpHXMuq9zX4srZWjaq2H+kQP5VK2kRbAwb08h+7Zft0MSx+/UpN99ahIejVmMO N1kTqNhQrscWKCRXkyk8XpJS7XYMl9ZKlXo2bKw66ewZSwsS6jkm33dfZ1bVtqv0l2Ereyiyi9rQ 9ZxvaLVDT2C8GBKpsUNrWU3hoXliratxs0r0vFyl8jYqJ2AAr0AhEEBhliAha8FKmQowEBzCuY9Q nIqefIb/AFu8mQur94BJ8VqmqWjjdjK1mbSlbB7lpabA5UseSVvkK3A3HhbYTx0dgGEAtt0ZlJY1 lWDae2VOVsXyen3EpubWtrt62LVtIgtpem1XFqKw2tR9WzW3q71SziS3cQW/19w2CPaZd27R/Wto bLmPSc7JUW6VosVTB9GEKxW6WDBSzEDAgjM2OkVwrXPzv8uwFX3U0vc+rqJU1fSbagSs5VJudaqm ijDgcl/YytxdSSLAXrrfkKy1NmtcHS9eaWWCi5QAtnOieM3ltV8CeQ00J1LewyNxj5uRNzhe1ocM y2Dep/pWVWpbVXa2PLITXob6uhcmBuoPToZanJFp5TVdte5WUxSJkQjMZcQepw0ckGu0giwGbFqi WXzAUeTv7l33eLrVa70KOPR0NtNLERejcVcYNVmeoY4sytigOALEgaNhLU/kr1L2WBwy7mqjzV2A VrcxlfXt095dlLgeO471tpba7NNOwZvcrF1N3D8+uyi7CV2Np380aOUsR6hSat0MlV/Ig8gEjoZb zquvDE6u2yRbBA2YrZDAGFPcwjdVduJ/sLWtuxbe1SkC+wIljcn+7xt+A6i2lHPGl8C9e3Yp5BGx NrkWRuSIxxbW1ioSCSMVXGXqStB5BqRculuMtje4bdHauqu5rS6WKrf1r0tDpt6lN4au/Rvq3HuS m0TyINV1G2bqeZmxRXeFo2KoRYp2PdahHdXGUUGKMBvS6tWL0gFqEsSi80lHBCtmAwxo5xNjcc3F neKMTlxXyGzy/BTaa31bg63oVatphbUrZqXDjLDmqk12BsEWSwFWVo3VVZWRWVGqs4HaIK6ey7rs qLErsanZRyG2K1uq0N167O713UN1dFza7rYoG8vcq0Lu0/PBRsHmBDkzZqXi5cNSQa62EzCY4Bj1 kSo8Ht10tCi3WNWwrxLMzIhl7BUZWMrywPRdvdxCST+Dx+wVNOL1ZGrZXltfdVHIKW9NheQrsyA0 b3qpM5ZStiQTkV7LEH+WurYai0XAze18trX5FTzf/juo2BbUrTYoS2drYqiMQrqBZkFqrBivJgAx YvS5TXNG1itYgE6RgIRLlKtTfkYDi7TZTXazSq3MPQeRuxXWsVevk7jXWST+JHKNobRqN1tGwrZE ruEvVWVLThLJaprcPFaWjiy4wPawGYTwapyDt/u1L+5WcWV3VtU9N6MNyoWIliUGu5CUwZ6jZbt1 pUlurTkWIpErZ1AJMebteGRnRqXyqtkEZnHoVlico4atqbmMX3TYozA5JF+a7rO7aqxWwfIXd3Y/ H42wFForytKMH0uSolyk6heHuUsti2AhqzVZgllZRYyS1y66lwKXVcgvOo3YsSi1qbKba2HaqsB0 KgRrEC+sI2uFsNZAla5l9QddquyhaHPdCo0pDAYjCbVRZWRlNF70FbAQjhgI4hGJYgsBJqajbZTZ corGyDdsbTFacFegG7vEQnP5Ne00265RgqAWKvXYQcjTmPSgSun39kS+hAURwzUCwHWCDBolGw+e 3XYr6ClWpKOq83pJATLQrgeQXjZpSkAxRiEZnkasq1QApcMK+kxGEI6bFMRMmq3+u1dqYRwwJjgG BQo3jDt2Kq7Fl6KglyexHFdW35AtCST+Xxm2qhbMsXEucEUkOprHK2pUuRCRsVKUQN36l5BqgJdU SEU8akBHD27PKuajlrKepQDBHTySKW1rFGymVdDkek3QWWzAXWsKPTcAQQYYcy5cpYSj1iu6u7TN Y1rWCm2sTPKW2EHYvNthTkBSBKhk7uyiPds2W/oB0lW5fXKvMExt6tl1vI0pF26XNuRbR1W8BgGI 2NYqW2QqywsDrHlTQPbmeRBDa2VvqPFkPT/Xk1LVVuqPRaLqqjlfWXLk7euCCvWq3rr3BgMQxus3 KMDXuKFbq3VwqBuTzR2Lkm9silUHRciDAl99dFVlhsf9HVsFYLlINiGUbfdq0nDLaATeiltRh3Ll UzYB7uqSF12BUieRQNXhhKrOSVnK/wCrqxYn9VMa9nbapwrKRLB145O3VxsSVWnOvatiHpCZcOQt rFTUNruGFFNdmyWbV260r3nayygkpyCx76kG7tf2H/TZM0nbnoXdbcEPxC6rENYoZLF5FTwOq2Co yu1WXq7ZMovFY1bVYAZBBE2l42WDjZRYStNgdXXM45G7TlWIQq4BouNNgbmrNiMxM27VArV1N1bO lIEVQJu31m5t8qrbVzRnZv1KOyN4/ZzGuJWy0Y1rB3U4vS5AJGZQ5EqbKsBLkFdpUF6v/i2IwIYA y+oPXf0ZHLSm01sMMpHW8AjfqZYLMii9TNLb5B8FdraWta9g23AYg6qilTvbyqpJJ/WU2mp69wFX 2UmrtqNjUuBrtOGsbjYGE0rQ1fWbw9lzAWVultehdlSQI6zerCPVdgiwLNO4FCAwtZlPkNtKUUMx 7NjijaSoN5B3TbvCJXeqsfIpKvJUJXdu3WnJP6/JEyYCVOjvZqazMvbC03AjTs4utgI2UFlezkHW 2QpXY4Wa+wl1bMOPkcdo7PG1b2ca1q4rsATa3K6039ru31bNaIN+pRZtJY7eRwruzn/DV2vWf/sL ZbtW2yrYsqnj90WSjYV1Zxjze3SoW11I3rwPH+QZNmzyevUPJ+YOxMnOt5Ltrt+SQgeS2s27l1o/ yFdj1snldpZZ5bccFix+pJP/AOO9PT2d7ZX/AJ3zD7Vfh/JW6n+b/wCauenyCpovdb5HR2B4DTTa 8Q+54urf81sVbOj/AJfwlngEb+x/6+n9j/19P7H/AK+ieS/4avX/ALH/AK+n9j/19PN2eAdv1nxl PjKfGU+Mp8ZT4ynxlPjKfGU+Mp8ZT4ynxlPjKfGU+Mp8ZT4ynxlPjKfGU+Mp8ZT4ynxlPjKfGU+M p8ZT4ynxlPjKfGU+Mp8ZT4ynxlPjKfGU+Mp8ZT4ynxlPjKfGU+Mp8ZT4ynxlPjKfGU+Mp8ZT4ynx lPjKfGU+Mp8ZT4y+v//aAAgBAgIGPwD1I1K0JX1dKicuN4OpBG31ULgUt1/UfR0RRK5m/U7EP6iW Ve5126IaUV1uISotxJJor++LTZCqdCLr4J/jv8iH9E/7qRvcq9BUi1P7kx7E5JG7I9xeSU3cHn/J dFZglM+X5EQOFDIfr91AktFr1P7hYQsrlNiuir0KlfsjgVVKwb2ur9DTPpjQllGyGxeVTyWnpzce 2Z40wWR8YLpg7XvQdvHo9SpOWhRFM0sls1KMkjfD5IXD0zy8Ixrh4pU5KUwjPqaihiw1wt5TzTxl iasVcIZTGosNcmpQjJBHou65ktxOiF0IJdZ1EU98e2b/AGQ1E5k+clclBKWoFf8AyPR0SO5wyNXw RyPJUkoyrwlfphGW1ZJ5zSJsnSaDu4Uki7zhGEEYVOuFUTlbyLM+m4urOw29xiRKdMtCqbwh4Tk9 ssE5YEPqJLVknZFcdSHryanBV1INCMNCc9dsYG7VI29US/Yl9xshkoqR9mRdQm0i6jKQ1weVum64 wVyxqRi/Q7ogjoWzokQiUQJ/clHizxu12ZRkXEVjk6MlaMgnLKyxkQnhO4jpcSiGTqmTbRoi48bv ZkDsu0ehDxqSq4pMVvpP7kM6XHlseM6HjfpyeVv4s8Ln2I0Hbc6xRnY8X+SwXY7YV2JtZWpTD29P yRG6PFkcHklXdEa2v9BNaM8bvy2ZO6Fcuzwqh5ZWEvcb9OHhK3Ia+VujIuRK/Fng/ZnVE6PGhUrl bdWQtX6scHiyeDyjU8XoSqk5oIdUSiCeR9s0YVzyVIwUjrM+jPAktEjxWdPPRk5VkroSnhUlJe+E LT0KEXMo16ElMFhOFcIg8d8Oi9SMzyRhUgXkUSK7DfJX1tCueinDyZVIbE1RLTCv0WuM4RoSiSrn +rP/2gAIAQMCBj8A9OpSbuxWy72qTa5X1cL5XHy4K/iTSnsV/G7X/D+pqeNug3AtuWOrSKx0od+D wv02Ykm67xT7/TTh74VJepsypLUsiIN2nXDTCjnt9C/T0KFDztoyNDUTbmfWk92L0aUGsdajk8Xo Jr1X0RPpSsIKogncraiFEDtai5enQ7qB28PP8UTe/FGksbimEkLFlBPeRPn0qEjeSpLPmoKLQlDe g03ph42ac4VWE7ErQgStvccMl0a1zwsEluQskzXBPhyeT02IXFBQ12ZQ0k+XxXCNkclFg08NCYgu h8ejOaWVI0RShcuCjrxyilqSKtlZw0wbWEYJ7f4FctHljCFotXmphX2F3gcPQdZ8kW3La4k0KUxo PChVk6jt/wCar3ytnC4IWMLGSS37ifDQ+pO6ItoyGRcn3PjacFcJxkfJ5f8AWVN76H+hT7CTeuVL lkDXSD2Lb0QeSdJE+cKFcJWWhZbwskGhVQVYpSnYSyLC57yQ6Mh8kkTQVrVEVPi8jyWt6eSy11Hb yKZ1HwK7K29iGd2ONSu5Q09ymhxkgnDghQyGWXPj9sqUfIqxJaEZIIJRDwle6E7XKIZKwh4PJOCS LbXsq++SXsUotjUSX3FkkjGGSiVoSUeShF2+Shf/ADfyKbf47X49bsrtXuTw8F0ELLXDqiGUJWE4 yeN3yX6oo/JY22PS5njaon45G3oi581Ll0nDuv2FlklEMlZIwjCMIdCjIeh/Gl1Zbbwpxljtt05L X7C60Gjs5w7epqS9imjqsJI3IZQ/+9yhRFpdG1MXBH/I7H7dzsK72ZXR6kbFdyMskYcM1od6ksk8 WvfgrpyQMat2Jv8AkyeFQnGGN7HlaTvuO16P98Otp2Z21GlqiHvgruSHoJpyJ8rCRXL/AM4wR+hK +xJdc/8A04+x5PYl6bLK5XciW0eVr02KOpD1ROxrS4dr00E9U9yVo6oh6rdHi5ggmC5rTHxZynjG 5G542rXUttWx4L3zQx8YdhM7IiaCmrZRsd3CjC1kta1whPc6YTwVqmUdMFGi1JVqklwjxs059CGp JSjsSm0Q9qDT3IE8Hb3GhNbVJUyiBtFSHg7X7EQ+xHjM6Ffyu1whfjb6jawTGthpncla698I5J+5 PJ4kkPU8mviv1J8VPYljihVv1YZqJ2kE8CYmtUVoKCUtR2tHncosT15KweVzbXAlakktETQlufoa kpIez5NUkeOvLY1CqeX5MoeTttnt/Vv/2gAIAQEBBj8A/M0Vj/WwIQJfkhLflpGQQlo1fqUI+UA9 nCbyxF8lrgDLb/b+riG3EklRn9y0v8KBAiC3JO4pgUAAGxITGhCbUSbgqUNwCUWY9iMDWJrE8v6o 0QSeSB3OiOLptpjLMCqE92btVkJM4Fl0s+KqHzZOY0FiV0mvJaolyL80QBp3Y1gc+SMJhpC4P9SA ApmoR0uWeRQhCIfJAsHuUJGgWjao1FWpuh0ERxWk0lkrM66JMDcJpdQOOK1wpuR/91RjKhF/6fpj UlCW4XOSEWYBiVHbFpCvcgebBCW4SaWwTbbRH8I9WqZzWucdMRbmtLEk2WqQqtJqEwp+6MSXyKJm 3aEZjokccCh5+60MwvM+1nrGMTdVDf0wSNZYp0N7k7LzvrkMVHekXesY4ImBYChWiHVIYLzN1ojA IQ24uTjkq1OZQiMUXABWoA1yLKpZEEEDDmmDAWWJQO5LSMlIgOwocUYyDEcXjQc1pnEgjhQKyqP6 EAbCpTDGy8t6AVRi7Q26EZoCJ0wFCvL2aCNCTgF5UDqndGe6zysAtO3AnnghqviU0QSM8EaNJAyj qyCaG0Y9v8LVPx4DALqqiWL4MFYRH6p7nFCRkBOX0f8ANSkQ0x4gpbsp6IRORLomMjI87/JAQwR1 QO5gyG4ANuEqsDqTgiQ5hlrlB4Zxr/zXVdNccKBVH54nMgKJIvQBTFpFHbh4i7ryoVkMO1SEq7kq sFrmGGAWjbgeZVcApPWITR+QTkOVqkWa2TITkKN0hWTmn7rIcBmhAFCQNLFS2RMiDORzR29rbE9Q 8ZNk5jEg3Log1Jr2ICVSpQkQCiIPKt8EdzaiBuXIGK0ziQcihqurMtLAldQZahWP5wHmoE2ijuSD RkKDNT3SL2HIKe7Ohl4Y5BRkRpiLviow2x1OyGo1ayJkOkmgK0wpkEavJEk0QBcgVl2YJkwoqRrm VzTD5pzdOq07EdNGxzQL3QH0QI1LWOo5vQLydovI5YBMTa5VcU7dydq4FGJDSGCaIonPiTmroxwK MTh+bByW3EXJqtuA8MRVaRWLOclCMDRiZckBAvI2AQ3NxvMa5QnuC9nWkdMPktO3cXKcl+SaIdGR pqNUdGH1JyKXJzTteyeVeSsqJ0xIC6S5xKLgvgtYkerxBHbuMAEZSPXK/Zki5onI6eaYkR/dFhI5 UQPhmLEp/qxROC6Q6MZBihMfV+bgJYkk9icX1U7FEv1SFVHTeVzzUdwHqk2rNamGrAlDUNXIrrLA YJoeEC6r/wDKc0AyUpE0iHUWLQuAtG2KYoA0AwTnCwV2CpQZnFVchMKLqNk7u6qLrTEeJanOso+Z LSMGuVZohCGx0wFDJOSdyeckzJpDvWrbLjEIRetmN07BE2kLELnH80IZqMY5sjE2gf3UZHAISlX+ 1A7gfThgnyQoxR1VOSawFSgwTksMlIBojFCUj2AqgoESbKlAtMbnHBldzwpbNBaSexVqcFr3C5Fh gODytiSmjTbFzmtEKBObp0wwumDg4lPHpmMc0zk8isE7AOiQRXBPOPTmK/mIkZqlhUKQP1XXl/qh EWAC7U2IQ5hElBORQWCYD5IxYyJqyOqpBZgtIo+SJKcnTHMrVKmQVFXi+SsyYCuaedCVlEfqmAon N12LTFNnUlVRMfkg4raSYjvTX4SBAMcQpRj4DWJ/LwHOq0titQxQIVVFsP3VbuuxF6C4TyRa6IF7 BPI2GCmCGBk/caqif9U5LnBPiqKgTyKqnFAndldPIueFVRaY43QkcahHLhyWuN8QgcVVUR/xBSYO bhMfybBOUwDKMyGaqE2utJ4Mn/tqgBcrRGw8RTu8RmolElGRzoiYh5SqBgyckGch1E4NkqFyr0TA OnlRPK6oODDg2qiu/wAGmNynxRAIiHxRJmE2paJVyTpvoOKbLHhzC1YZLULS/JME+KGa5lRhAv8A 3c0AO9OcQVW6daI4hCLvGIGrtyTANEURGCk9ZWCqvM3OmAsM0I7QbmFA6WbHNMnKtX4HdalRVrxc 0TR+a1SqVa6BIdeEdq0zAORZdJMZCxWjc7jgUQcVGMBWVyVmyyTTkSE8zLkyJ2twg5EIw3Q2RwP4 7BWqnKstELlaiXJsrOuwFcyET3BR01LMgM3c5pnWmJ7Vpjc3KBkTNrgWQJLQy7E4izmnYvLF3+SG 5IMFQqlU5XTVMSxKZ3zTIVohwcpo+FVouSqgw4U4EEVzWncrkVr2zQWyTboY54J4kEKiomRp1RqC m/FZOn4VuVr1c6qlgnQByQJyVb2ARL9ZpFCIucUTVlpgHJwC17oeRwyQgA0Rds0yJFwmleRcLQKl BNinKsnnUiwTsz8GNlUp1Wgy+Fnc5IlRwfND90QFyRibxVAqEgq+pNKJCrRFrKY5n8RggZYpzVrI PwjAGqEIntT8CxrEOgcAEZaeo45BapUjzyQJN1pAZrBT1AAWfJCMWZGQADD5rWSwFlzUDab0KY1K DmgsyZGJWk3wREqSTE2TMnF+FfgpRUJK6qLTG3JOwRES3LBEEUKKJONPgzVEdPyU3oXNPxNcsLIy +SMpIZIlEyu7lOeFL/ytIN/EUIWhGpPJCMBZHVJySiHoPChMVEvEvMqIz+l8U3iLsCckXqnlYYJt LRzWb4rktLJwrsMUBAnm6fFEfUFonXIqpVKqnCjlVICzPPgCSqcWtK4K04i6MeYqjG/BiqLmiDij 9xti3jH8/hsuRsgEInHBPkgBd0y5JkAm/RA7kjEz+gXbtQAk4Qk9E1ybJneSZq4ps11UcUXSDTxZ J7haRfJUsLpwGK04KyEhghLNawKx/ZPHvVSrqisqBVge5XI7kwm3agRuAvgFRiAusMqXTrVnQoHK jc0Hvc/DRGJqDQqUCOk1ieX4Tp8E5stR7kw7ghKXiNk3Ci7UPud6NDWET+6Oq6G3AvieQQiaZlNH 5oC8pXVfFIfotRqSfDiyEzDo5oSFAbqW2aRCOixTgs91GETV6lMbjgMkwwXIowwPG3BwUytXNWTV HOyDTcLri4zCaIqVkUQcVLVUiyYFCvAMrFWPA7kfFt17vwWTBCITm60xqV5u6a4BElPwEQKlDf3a gYZqMQOnLkpSAdwpyMS727E8qZBCIxsgARq/4ISNxktQDSFwoxAuhEdUhYI7m9WRq2SMYgBuG23e igi+SZaT3KJzQ+KlFeiDVe6bnw1xpK60yoyrinwxTfS90ytwZMU6lE2IZTjkSPwScgtcu7kqUGaL VkqlMuSDBhmoltUQzugIkDkgTYIwjMS3TQAVQJkLIY0CEm0NYBRnGREse1RlcOgYFzYgLWzHBPLx OtQqMexS02URiUFLgxsmwXPAoagRIYoOeGk93G6oukADMp5GLfJUIKomRakhYqtxweHeEJGhGCZ1 Q0TngxR5BSlmT+DXH+ETKkR+q0xo1gFW65q1CgZF+SYM+KcSFU5myGxtSMYyLS3MW5ISnE6Rc3da duXQc7hCUscFMyDjJCQkxeyvp245XKMtIYItWIZ0dyOCJNmZGXKqBUZx71GWYr3JsOGoXC7FUVxT gJwSOSBEyU0pUwcKm4qnvTmqoqhVgJfonidIGCa6IGJ4Hlw1YpiLI0YfzxYq9ZBh+AAmQMqALTAI mVwnxxRkQgBTmruMVSV00ZV5LqkSUDuEM+KPlgGOBCBjQkiyiN16tQ/wn8sxg1DIM/NUqKj5qUc6 ofbwpqv3og4qn1YJraiyAbqnROj+i6amOCYoJlyKY2PBwrJpBULDmq24MycqgTxpIW5rU7Vr2oEd /DkeNU8CU0lz4bcRgCfwCck5QiPkqVkbo0ZVLc0xsgQX5LSe5A4smAqMUCA5ReIBXTQWKiY1k6G/ utKZGOC0xxsyafjiOmWYRJrR0JGwNOwBfogDUhAC11CJ7UwRzUgnsUxtgrpmTi6EvnwpwYprnmgB Q5p5DVHNahbJOfkqYJzaVxzTYHBPJOc/icLIi6lJ3AoO78ENcp2eRuU71RrUIg3KIOFk18lGQFjV dRusyVS4FUxLlCJdj8qIkCju6MjRgf0Upy8MHPzWnMUVbDFZAEsU6liUxxuoSZ4gMV0l0XRjxrfN MeoYHFUoclXE/A4ui4dZFNLqjiDkjLZOk5I7e4wkOBBsUBch0ImmJQ+IsjKFDQHsP4LZJ8V/Cs4V IrzNOnEBcyOxVuFKI8RoyDm2K1SHSEW+vAqW/wDcFoRws5RkAI7UKQHJCIpE4KW1jpKgD9ReQ7F1 KlCaJhnUoF8EeZQicT+iZGW33hMQxxRGSbhyTSTTDxNin2pUyNU5j8lVwhYhAyVJBAxLk5KqcXK1 CkxcppmoThOMaFDEpiCI4FUPEcdyDOSKdqbL8Akh3TAqhojrqXoEHDAFz2IwasW0k5FPuSY8qURa r2WuXjNXTZ0ftTE6jgBmtUmpRltfaxNy8u9S0DpEmHYKKDeMGi03pXm6r9Ib9VVaXcupbsuwIxlb Aokl0TcRJTKqBAZRntlj9SrfjIG+DrQagp49UP2VVUArw/KiLVHNYg8kJRkZNgnKou9PAtIXC0kV Tm+ATM0hinkaE9y1bUgBkmnH5FVTEhUIon4TiPCeod/4NcUAC8ZUZW1lv1dAbl3qBkjMBgXER/02 QlPHBamN6BB6ALSA5FQB/K1zPYMVIyu7gIaPGbHJaP1QB8LoAdhUpivUQex0Z/qhCN5myjt2IuiQ pRNwFLc+pApwmsQjEFifktMumWSzVECCxCc15rTcHBeZtS0k/Tmh5o0koUcJ2qV00TSLEYp4mqb6 hcIsHLIfqnbhqje6iDfFAAMQq1dWVgnAZOK8lyyW1uD6gR8vwgCWIxTs5IY96JHVIuxyAUYmT4nv TEdODokh6KhdxdDB7lEbUam8zgpGI1CPiJRmR/3Hd1Q3xUNN3QjHxToFoa1zzUhiLI78y5HhRKLV T2rVDRjf4NUR1BaJBpixxTTBbCSu6omThCOP7Iw3GIOJujKI8zawRADSjeKzThMXa47VqwzxTgs9 kHT8HWsYVIUW+J1tbeMQSe/8JhjRGMKzP1d1Qg4Zgzpo15rW780QKvQBDzTUAOpw8MIkAjFAQiNI C0EARKkGYtbkVLbysok4gr/7O4OqXgGQRPetJNCi1ImwVOGtu1A/STXkhjE48WwWuA6swvLmOoXW raNbtgut4lNKvNXTxVUxqF5/29DG4zR25DTuxvFVNMlWgwVHM3tyWidCE0K5oAfBqhfJaZBOB8Ac s1+5T3MCWHYPwhPwwGKAHeSqmnJEDEVOKENsuTgtUxUDpHPNae902Ex+qO3yVRZSmWqGA7FqsMVt 7fptqJWkWFAmyRgBUVfmjCRrGiEgqIiQupQbpxT32jbkUGNE5ThaTZebtC1+aYhuSaQuuiZGQNV/ 3RTAxshHVqjg904T/oivNgNMv7gbFaT440KwLISHYTyKJY9qcG93+NpJwnBVbrchGwDE/hRgO9CI DAU4sicTYp/kgfmob0fFGqfNPgbpxUAoZtULaEQ8g8ZdirimzVKvcclH7iNHIEkGNk4xVl5gv/CM J1BwTMTDA5K7xVLKiMZLztq4qyAdp4hZkIghPE6SMUdvfcHA4FUDBHmpDkiRQYoF7q9FZwEQSwwC BPxVXK6vREisjYKT3l+CIi5RlKspISXYmRyT/wCIj5oDkj8vkonB696MP7D+iBwxQZDdehLEdqlq Dzdwcwn+S7VryupbO5UYIbZOqMi8T/CAHAxIoUYkWrFCtUTt1hkhK4xAQKeNExqjvbR0yFV5e4NO 4McCgU4ryRGI8JyKOxuhjYHBclRdVXTRNDgnemC5KlDgUNvetgcE4PxEJyaYDMoyl3BaM/wZz/tH EjNEI5MtwDNwjI4gALvQIwYqG5/cGPaEY4KmCBwyUd2IeUP2xUWsWQ5qUcxZDCUb802dQcitMj1x oefNNinC1Gkhio6Q2BBTI7m0RHc/dGMuk5ZoP3rWBVGJqhOFKv2FeTu0OEs1eiIJvZebHxC6MJGs fmnUQyeQdUsi60yLaUzd6J2pOBgtO50yCpVV4lQH+JOjkPwSTef8JkUxzZckRyRfFSjgDRNgMUQK lqImPiHVHtCic0+KI+QW5H+025FGD9JrFA44p2Q3bdiOxu1I8J5IkUkPDMIA0mLjsXPJVsjuQj/1 AIbc7fSXQp3ppxB7QtcAJQxCNtJHaqVe60rW2qJq2SpWUaSzonbvXUHjYjktewNAjhmhMMHwVmim w4gnwfUENAbbFDzWoG6JZ3T7cjEjC66w/MJ8OMRzUpIk4/gR28Ca9i04AqiIUh3/ADUZBOFCYsaF AnEN8kOE9s/SbcjVGApG8exAA4J2eQWsjomWPJ1QtMViQg9G8QV+xGJqOaBkT04DELU7LVtU3BYo Q3AYTHyKaQETgjkboyj/APzdxLELy9zxRF8+a5ZrMG4wQ3dskbcj1DAKvbROKojcDhebCP8A2pYB CUbZJkBCpkLZMjAyMS+CAd+fwELSR3r/AA/A4omF8k2OKAyCIzI/AYBycEZ7gaZoOS5FA5J/0QmR SQb5KlgmRAuKjuQPYfknGNlehUZgUmNJP7ITF4V7sUz0Nk4saFShhJV8UOmS8yGHjAx5qJfpNind aoh5xr2oxmCIE9wQlAvmyaQaYtLF0dqcXN4yzCEJGpRhMPE0Zaw8oDwkc8CmHjHiCEXHJkYSZiht yk0R4Sck4LhFzewC0yDjmn2iTA3irMV5jtprIp4HsXMfExQ4U4OqVfBSkKiyjHEn49EA5TSDzF+E J93EHEVCZdqqjD+007EwsahczZafqw7Qg98UB9J8J/hDMq1Rir9MmEx+xQlnZeZth4fVH+QtL1Vn RmBe7ryZg6T4ZkXTg3QFtwVjLmhDehpkL/8AEISFlomOllHc2wXJcNiFHchUGrKlORUd2NxdDbnf BUpwqmCMc6FSgY9YNCiJViTXkgc1f4KourUzTWTYpitEL8NItD4xL6pVJUZi0roHAoxxCY3FCFyK Y1GSMcrdiEgiy1GxWnvBQnqcWITjHFEC0q960P1XByIRhKhBqhiUZgdoUvtzKsfCeS0kv2rz9oNE +IBXaQuMUQMboxJkdJeKiX6sURJgRgtW22qPJeXOgxGRTWWk3iCxWmT+WSxGAK1CylHA0RMZETBc DmENXiF0wp2q/CiJ2vFLOyecnlkENrdtgVfhX4GF0xDFaibIkUBsqoklGRxPx6DgtPy7VoOH78Bu Dwzv2pwua8xqChTY8GCrQihVbG68uXcU48UahOC2IKE4y6xiF5G7f6ZIxNQboShQioK1YihGRWmV 8QqHTjE/whIF3RBDSzdDy6RNxmgQUxL5rXCxqozjexPNOUxDSWjVqhgrFOQ0kAc04oQn4h7A1T3Y 0KJiKheXuPpwKeJp8LqUI0AoSmkaDBOnJXlg9v4AkMLoVwcLzBY34GBxR254Y58NINCtMrhOFzWr CXBu8FAnJaD4JY5LQQYkeE5qM20nEjNGM/FFE/ULJpHpnfkVVcwHXkTNDZ0xVD1RsjGdIyx5q7uq XB/RHal4JWJpVVZs093XPh5gDkKMiGi6BI41TIgWVU5TM8Ew8SY0PEyOAK14mqtVF6Ly9v5pzf8A B0E2stF9QRjKhC5rUPGLLSaEYHhriOoJuBBTG4uuYRAwqmK8uY1aKAnJNdVNLHsQexWsUiVomeuN jmFUvyWqNGqFGYNxUrNEaWJxWmQJjhJNIE9yMtPQ6HlTeB+nJMqjgRguusXOleXI9ipwqqcKJkxD rVtFjkmnSYTG/DQPqLIA2VAhCJYyVfwhIXCjuSrCWOSd2OBTHuKZa40kLjNOO/hqHhl+6fDgJYHx KqcWTixWvCxVDQpzRCLuY0daZVeyEgLfsqVJuhIiyjpPRK8cl4mTu65IyArgtyZP/cDnsWk/ULpn 7kxHBlm9kJN4ShIVXP4XFCnJQN1rhSYWqJaQujqwVPDHh+6LF4xoPxJbUsKhOBdN81q2yRMYFaZB GUKHEJpWTGoRiaxNkYk2THFaZ4LpwQBuniFpkKYFDFafokhqTJ4kgptRKL1YrU2mtgmCdMiQWibg FAmoOJQdwUxLjDiGuOFawP6ITiaFU+Cl8SmdCMvCbLUSwUjaKMdqgN5IMnKO3tmpufxRMd/Yom8Z Ig2wQqxCgcXunBYtdV6pHNaAOY700g4XTQixWk3C6u4p9XaEDmUBIU5piOxdJYtZAA05p49JFwgS suFrqQyqn4gkO6FKYAIPcUKoafA4F0QbIxlWBsUDEuCnHBiiyJsI3K8PZVNIsMgsSrsgZURht2zT n8bytws3hKFXCqgRgVa6bBbYj9QL9ychyi4aWCIIalO5VR1B0wctUIFqFlR+BkB4cFKTNanwRMiw xKERWJo/waVU9b2REvCUxxsqcGC5pwgCKrXtybkoyl2FVkAnjUZo5Ix+iJrzITBUotJNkIk2wTO0 cvyIaTgLTuRVAUxLJhMPgozJcEkDvHAg3UdWbAohkSENN6v2KMsxXuT8DkVEG0qJk/B8iuqxxGaE x4hcJ+AC1xFRcKtkIyuLFMfg1BMC4WmZZ0Y7U3F+QUuoUzQhN9JX+I0A5rt4VRmb4Izlc/lGKdXY 5oCReW2Q5RGITGyeH0l37E+a6k4syMe8cdX9qBFCC6juDvQ4GJUgR1BOLGkk2B4Oqogdqc3FlqFx dA448HRinKcsTzR3NycRSkVrjAmL3RkanCKEp42GSHJVTykypSEbfl7oxe4/ZdqdEZoDKico0dRO Dse9GL3snUoi6IaqMZ+GX6FMC4w4iYFJUKIFpLRPxRscwqcXFwv4WsWN1qBeJugRYqzokprywCcS IOS1SkZHmtOCsyZ3YLTthuarIrqJP5kSjcIYEK6qjzYrsDr+FOBvgoSPeu1WRADCSMDZ1GQJ8qV3 wKBw4EC+CzINUJC8cOSErxKcY8GzwT6exNXsXlmmS0SFBYpwiTYfMqRneVuQy4MmkGq7ry9ouTeS c/nXFsVdXshElwaKhejIk5oHAqmNe9APUcBIXCEsCtEquEdmfjhTtGHB3oiAKGoTPfNVPQb8itJL kW4WJiMU5Ik9o5o7kWD4BOCBLArTPpmLhadtyTjgpazqnIUGSEjgumJRkXM8Io1YHJV/P04Ai4QA xuU7rU9kMclylYqqIe6Mck3yUd2NTYjNCcS73TRWo0IsiAXitOkl8gsYmgIK6ijWuSe4FGGCYlZl azQiwWmA71qkXP8AR3iWWC6jRULjJGJJEwXQc1VShHaIO4bsnBqmdR82ZjE4iyBnMMbVR29mkMTm nQjIVGKE9mm5jkh10GCYmh/qOqBYhXB7kRqYHJOS5OPwVP8A6dw+1+12zu7+4+iAudIMj+gW79mP tpefsiMtyBo2vwfPBbv3kNiR2NgyG5LLR46f4Xr/AFzclt+Ud6Wxuw2hvvplKY06RUVIdb/2f2c9 r7bdG99j9zvQgSNsS24y/wDsCByhKTqX/kdvcgPt/t4/+ThuQJaUpfdTmdlo46xML/yTxhrhvfZk Tm3THVumbE8hVbMNofb+Ru/e/eDfHlwIOyYDREvHwuv/ABe+8D91LZ3B9wYRjAvHdkIahAAUj/WN 7/8Aa2t3diRHyfJOljXU9RyX+0+7/wA5/wBS/wBp93/nP+pf7T7v/Of9S3ftofb/AHY2N8wO7DV4 jtvo+rByv9p93/nP+pf7T7v/ADn/AFLZ/wDxdrd2ogS87zjqc00tU8/zvpe+vS99el769L316Xvr 0vfXpe+vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+ vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+vS99el7 69L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vf4//9k=">
+</image>
+ <image transform="matrix(.24 0 0 .24 8.8525 -.2686)" width="114" height="114" opacity=".75" overflow="visible" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHkAAAB5CAYAAAAd+o5JAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAACydJREFUeNrsnYly4zgOhkGZPtKd nt73f8qdmcRJfIgT1xI7fxCAuijbSoAqVi7HkvUJIAgCEJGLi4uLi4uLi8tVJPjn+78kvwjL/Exj ISeHfN+fpeurBrbrq0O+Q7jW0CBb48vADl8IMI4mD/l9UAC3ecjvLeAO+YaAGeQqj0Z83yiQGeoZ RgtfvwTo8IUAr8RYv48Ig0GzMMyTMhB4u3TQS4asAY4Z7ga+bgToAFp8AXrM45DHEQbD1sz3YiR+ IcDrPLbvYye+MvRV/j/U4gvY1zxWQttZzkteU8cFWx50qmIGeQH6kMePPB4AdBSQGfDL+9jnv6/g OKi9Z3Hs5JCvo8kBtHiTNfcC9hEGw94C5JTN8VuGu8/vgeZcG61r8nVBN2Ie3gLgP2Bcfv6Z/84g 2wz5osXP7+NvocHS4z4D4MVJXBhYUrxqaap/Zrj/yeOP/LuHDDkA5Jes/Qw/GR639LQXZbKXOCcH Q5N3APnX+/idIf/OPz8ITT5kyBsBGD3tt/wzg26WuJRa+pwsl00MmU02g/6VTbmEvM3vkTLIN/C0 X8Ajb5YcOFr6nNwIx2sLnjXD/pWBs5fdgGfNn58Bs5ctl12NuLnc8brifIwmewNrYwT9U3jYDJnn ZwbMy62dWHJhtCwsUaOX5niFgjZHodE4GPwGILPZfgOwqMF9AC9Cq5dsri3QEaJfGxhrmJNX+f+P xmvWArCEHJbkfMWFAw4CBG5QRGOwJluvkTtXizXTS9dkKdr+cWkQfdyOLL02FPyDxVycpUow5mkt gSB0/K0xNLcrs8Qh3wi4BsaCNOZ/HPKdArf+1mfJ5pC/+E3hkBfokX9LaVyLHbKLQ3ZxyC4O2cUh uzhkF4fs4pAd8v1L+GbHnSRxwRdjzu3AIe9d87Ome4YcrgA69Bg0Ebb2PtfaW05UbnlxE8hWxsRc mRRauo/c5G864FvnW0o00I5Xs4w1ifNJBfDpmpBLfTpKwKceCxPqV8poyN5Hpo7zs0piZd4YX/ja hen4Xtb3o7JD48QL3pVWUxO0VjWBmZUyGc/K0dLeW8v4jMpx2vz6c0VtlkCxgrJ0jDQH5GDc8aXk uVAJtgaZS1W1fGmtVwieRyI9Sd/K397li3553akiZASsNahpyW5p0Vur40jApTRYLftxLshcKSEr H9biXELBqbKS8zkh/wCADzNAllC5glL2LpHls71Bx5GAV8qdH4XpXFUELaGgJnPN00+ALeuYLNBa PRVWRyLgDUBuK0DWAGtNariqMtDHEtreoOPAi6z16FiDBm0MTZqaoK5pHperXjT5Vx6PCujYATkq gB/zxUXAr/Rvs5hakDXAWDp7yJ+VG9WQ4YFP0uRQuMByzpImc2OYzKkeNp4DH/sRQLNGb0GbtXOQ NywWsZ8A8DrfSG8K5LGeNf+PBIx10a9iSOndrGaI46W1b8AGLD/E/Cg1qakEWXO+sPic+4RgZWJj QJadCn7ki81mcJ3f+9WYj6dATgIyA8ZGNVp9tNWsZpQmB7LLRLf0sQkLX9xHoUmli1zLZEvQXKq6 Kzhg2k27Aw1l+DsAXMtUSy3GVlPYqAZ7nARjWZUUZ2zSnLwSFxb7c/ymj41YfoA2R+VunApaM7XW tCF9Azw+WoQWNHiVfyfN9FlZztSAfAQtvjSqecrH15rVtDSwWU0cqEFRmb+0/hyszVa1PlXUZrzx NsInQE3WomAroRVBWKtDAXBtyNzpgK0gtqM6C0/7KK7nKO869LigaK5lt53HGSFTRxCjtJQLwscg AE1iGjiS3WeTKkCWrR8Z8o4+NpVDU84j0seuRMX4dl9Nbozlhtab4zdA3pLdXKWWpx0KceamEM+W yyi8ac75M2JvzVoeNRU0eQtMWgGfx2ClGepd92nE8tgT8tSdLyu8uuoIr5Jyk8iI2lmEGDUTXSvS xaZ4Azy4cc2LsVoZdD3HrpO1tg1aj46tOCmaEbQGvLTdmISnLVcSVjf7GrtOSThTR/rcDlLG5NeF 3bZQY51cmqNx7ovGzlBNyEN3xEr7yUmZp+VW4hy9rhEyOldWawsrPBv6muAp5oaMu3yxvaG/osSB UGWkBhuMasH1FdyptzDXJa3V9nHbQtBhTnN9onIHfa2Lfm8liiPgnmEeOQr3/hWcLb6wpxmWUH0c r6QEQFKPnaD2Ro6XjFfzNcVu+tZ6PdXS5FYsymWc9RmiNATru7UScZqyjBqyhEoCdijsArWK9lx7 CfWSo11P+Xru8+8wtHpSNkkmm2t51yFghotxVoI7c0uft/tqrpFLwZAWHJguLdb2b28VDLlczz/f x1/0vz7cDLsUQx8FORW0GE3LXmxCsHl+NdbJtZMHrLAmBzNI2ZSgwgYBbvUdbhTW5CbrCHoPJvyk aHPxnMZqMp9QFM7VSYTnNjNBLm1Q4HZgaS0pY8KyDTLOi7fYoGDQrM0vpO9pV0n/IQVyI9a+SURp nnvuAk3VYm2rEQFbuWaJ9G0+PvdnuLC32mp8AtglyJPm5CRMG7cNlh5tEnHWPWhxrf3kvkkDJzjX RgkqhIIjydPP3zAk6GsnDewLzlfb94YbEruWoMkw43vSH7o1VYuJyuk/R9Bg+RAwdsQaxbOWWvSU 50I2lU9gum+Z/vOmAK4SDJEf4GzAx4doWf2ip6b/lBL5MOkOM1d2ylxKxppfc3z+FI7PLRL5Jj91 Lg6880jcQdqFigXAc6TkYtosg9dMmxaKbY11/5PwcJ+Fyb5FSu5oD7+vdx2EidGiYLiHW7tftJVc L/OiHwxHqQRZ83BfhJf7lH93D8n1gzdNhmhyUDSao0noxGjPLaaZIMu86LdCZCgZO0xaJO9Niebt Z4IsTXdXmcxgpy8OPKFAej1OS/YmfK1NCQkZAWtwux6Na222nIyYPAYjblHwNvrp7HHkCWnwA8Ce u3SVLcgRwHY9ka2PA3Q25sSj4vzconR11LHihBPStNraeKhZvorLJO15iqUdI+28tR231tioOBlr 5RpwrZByl5LNBlkeMBgnV/OpK0FYDG2+Ku0Dp55mMinv2VVKSjPAplrXLs54gnM9MykVBlVa1nQd Z67Ml7tuDDP3CYcBsOe8ka4GpqYstY9X+mbH/ZaQXRyyi0N2yC4O2cUhuzhkF4fs4pDHy2KjVQ7Z 5dtCHhrPnnvTwSFfySwPhZkc8v1qrwUzDQBfY8vyriR+AbBWgbw1qMdrrrF37JAHmFILrEzmK0G2 XttSpRQchzxNkzVYJ9KT8jhN2EpkxzFnqo9D7qHBVvUBZlQe6GPJCbe4YMhWKUof0IuCHhcEOBQg Y/ostifkfOlNhnsWkLnLnVVYdurQ5uSQr2OmsSKQ4Wp9TLgRGkLGWmSs5udk/T6gHfLMXrWsY8LK ROwISPRva0OGzKWqXOv0RHZ/jpoVEw55IGwJWetyQPk1b/l3QZjrC+T/kt6fY1Q98L3JakHnqlVl yC5AWvuIRHqHHSw25/FXHk/0uRmL1GjX5JmdL6sdBLaPkBqLTeRa+txCggFr/Tm0Hh3uXd/AXK8y nAYCHieYe7EbvOwlvRfz8ugmLA657npZa1aDRXFn0FZ+6IhsR3WApdNeLKlKTVgc8hXXy1azGmnG sdWUfA0WneMau+R0+Zx8xcgXe85S2Iwf6HMXIjT1uMY+KpGvwU1YluCxLu28S09OlaMhu8VT3/bD 5JBvC1q2Ql6R3qCGFNBaA5ZRTVgc8nVAy6Y0Vg8xbQ+6T68Oh3xj0Bpw63kNfYrNaemAvwrkEmz5 Ga2HZKWOr+SQ7/cz9f18i8/++G6Qx34+f/KNi4uLi4uLi4uLi0uH/CPAAB14HVjMf2bWAAAAAElF TkSuQmCC">
+ </image>
+ <path d="m30.32 10.546h-6.973v-6.973c0-1.017-0.824-1.841-1.841-1.841s-1.841 0.824-1.841 1.841v6.973h-6.973c-1.016 0-1.841 0.824-1.841 1.84 0 1.017 0.825 1.841 1.841 1.841h6.973v6.972c0 1.016 0.824 1.841 1.841 1.841s1.841-0.825 1.841-1.841v-6.972h6.973c1.018 0 1.841-0.824 1.841-1.841 0-1.016-0.823-1.84-1.841-1.84z" fill="#fff"/>
+</svg>
diff --git a/silx/resources/gui/icons/image-select-box.png b/silx/resources/gui/icons/image-select-box.png
new file mode 100755
index 0000000..ffc9ddc
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-box.png
Binary files differ
diff --git a/silx/resources/gui/icons/image-select-box.svg b/silx/resources/gui/icons/image-select-box.svg
new file mode 100644
index 0000000..2db5392
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-box.svg
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata52"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><g
+ id="g4"
+ style="opacity:0.5"><defs
+ id="defs6"><rect
+ width="31.155001"
+ height="32.41"
+ x="0.47"
+ y="-0.015"
+ id="h" /></defs><clipPath
+ id="g"><use
+ id="use10"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#h" /></clipPath><g
+ clip-path="url(#g)"
+ id="g12"><defs
+ id="defs14"><rect
+ width="31.156"
+ height="32.41"
+ x="0.46900001"
+ y="-0.016000001"
+ id="f" /></defs><clipPath
+ id="e"><use
+ id="use18"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#f" /></clipPath><g
+ clip-path="url(#e)"
+ id="g20"><defs
+ id="defs22"><rect
+ width="31.155001"
+ height="32.41"
+ x="0.47"
+ y="-0.015"
+ id="d" /></defs><clipPath
+ id="c"><use
+ id="use26"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#d" /></clipPath><g
+ clip-path="url(#c)"
+ id="g28"><image
+ xlink:href="data:image/jpeg;base64,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 9Qc3VqLNVya6MFSJ3OvrXYyWVkAr4Hw3aPNrOn9upZxFLiCWD7rKw63KyMhwaL+BrIZTiGbSc1Ct W9dRaNrcajs1htdqVr3b3turIKgiFgJ3Da81/pdn9WnePSfoB2E81ppXEjRs6W5liAJp2fdcuRcg Mqbi2o5IIyN+vNJXprWBkofkuDggS1Aj5KNTaHVGyHBzxM3aSp6LEbidPZKMxzGYCM2RuMMUbGwh 2tjatWutGVKwBtMPPO/XUrdycy3aus+p2f1ad49J+lRcam0NjIe4EWWZmm48xkDVOq4P+utZh0OV sRWD0IhFZc6dj12rGWbdRK2NixHwdW7DEZHXOygI28I3mnFVoYa2ylqWL02L661W87DqMRhyrpHX d21pVnZm+t2f1ad49J+nqbBqYbIK2XAjR2FNtVgNLt93LjYpImu/JD1m6ArFuFzgWV6totqMsDza Ty2ptEWw517edbKTLLBy7jZUFXIP/RRq7Cot3cRx3bs169qq53KBF2aFqu7gzRmLH6/Z/Vp3j0n6 gtcA2OZTaa7NbdHlPYxNrkGqwGaNuIHBG7WXr2GmrsKJr7AptUo6uQF7kAAuyA42VYa9uAtmU2rq UTe2jdfXcgQbVKhraza29Si23Pa3wyf4XZ/Vp3j0n69G29U/JrL917ZRvsk0twOtVoYO2R3myug1 7diN+UbHau62va21Uo7t3VLYtjBtbc1cbO/Xrkd+umx3K26EknJmT/I7P6tO8ek/w9bZfXavvZSX d/vdbLHsb4KSpsvts/8AB7P6tO8ek/8At9n9WnePSf8A2+z+rTvHpP8ALpouvddLcY/1djyP5vZ/ Vp3j0n+X7Uvs17dVWp2tqxD2rsPadbc7f/U7LSPcFWql38rs/q07x6T/ACuza/t26pdT2KhGr7GE /qexuKN7MTS/qexodL2IZ3irtFWx/J7P6tL6U2KP157bn689tz9ee25+vPbc/Xntufrz23P157bn 689tz9ee25+vPbc/Xntufrz23P157bn689tz9ee25+vPbc/Xntufrz23P157bn689tz9ee25+vPb c/Xntufrz23P157bn689tz9ee25+vPbc/Xntufrz23P157bn689tz9ee25+vPbc/Xntufrz23P15 7bn689tz9ee25+vPbc/Xntufrz23P157bn689tz9ee25+vPbc/Xntufrz23P157bn689tz9ee25+ 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 fV8EvfMmjCWpNnyxDlvgtQR0Zk6X/I0T3e1f+R9qX2Xb7jHK/b790PqNLxx2dd6fV8EvfOr1dHRl r6v2hADT1TpagjKQzGJjXDBZOn6mWrp6fXTl1s56maR0jpj/AJZE94CoWpKEv/1x6CMIwEu5/wCR 9z+1+a60NbU0BqS/8+OnqzJI/wAOSMiDUUUNM9Jo6mbpuo1pSlKT59KZyCkqWXTavS6cNIa/T6er PT0+UTkO8zkt730PqNLxx2dd6fV8Eve9Q/8AcdXqdNqiTacYQlMGLX7oOKzQ/wC16iJ3jS1AfCi3 /a9QM3M2lqV7e6sn/wCV6jI75ftajP2ZUehh/wBrrx0DqfdLaOoJZmEb5eC//q9Ru/4tT6VX/tNc tQPpan0qMf8AqNefUaBi8pziYESezSA966H1Gl447NTp9R/t6sJQm1DlkMpXJq+YVyavmFcmr5hX Jq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcm r5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyav mFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+Y VyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFcmr5hXJq+YVyavmFafUacN X7mlOM4PqEjNE5h/6A//2Q=="
+ width="480"
+ height="456"
+ transform="matrix(0.0649,0,0,0.0711,0.4697,-0.0151)"
+ id="image30"
+ style="overflow:visible" /></g></g></g></g><path
+ d="M 9.085,25.873"
+ inkscape:connector-curvature="0"
+ id="path32"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><rect
+ width="6.915"
+ height="1"
+ x="9.085"
+ y="203"
+ id="rect34"
+ style="fill:none;stroke:#ffffff;stroke-miterlimit:10" /><image
+ xlink:href="data:image/png;base64,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 T4ABAGzCmEeBhCMDAAAAAElFTkSuQmCC"
+ width="159"
+ height="166"
+ transform="matrix(0.24,0,0,0.24,-2,-2)"
+ id="image36"
+ style="opacity:0.75;overflow:visible" /><defs
+ id="defs38"><rect
+ width="18.552999"
+ height="17.054001"
+ x="6.783"
+ y="4.3000002"
+ id="a" /></defs><clipPath
+ id="b"><use
+ id="use42"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#a" /></clipPath><g
+ clip-path="url(#b)"
+ id="g44"><image
+ xlink:href="data:image/jpeg;base64,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 9dqsiAGEkYGzqMgT5UrvgUDhwIF8FmQaoSF44ckJXiU4x4Nngn09iavYvLNMlokKCxThEmw+ZUjO 8rchlwZNINV3Xl7Rcm8k5/NuLYq6vZCJLg0VC9GRJzQOBVMa96Aeo4CQuEJYFaJVcI7M/HCnaMOD vREAUNQme+aqeg35FaSXItwsTEYpyRJ7RzR3IsHwCcECWBWmfTMXC07bknHBS1nVOQoMkJHBdMSj IuZ4RRqwOSr+dpwBFwgBjcp3Wp7IY5LlKxVUQ90Y5Jvko7samxGaE4l3umitRoRZEAvFadJL5BYx NAQV1FGtck9wKMMExKzK1mhFgtMB3rVIuf6K8SywXUaKhcZIxJImC6DmqqUI7RB3Ddk4NUzqPmzM YnEWQM5hjaqO3s0hic06EZCoxQns03MckOugwTE0P9P1QLEK4PciNTA5JyXJx+Cp/wDTWH2v2u2d 3f3H0QFzpBkf0C3fsx9tLz9kRluQNG1+D54Ld+8hsSOxsGQ3JZaPHT/C9f61uS2/KO9LY3YbQ330 ylMadIqKkOt/7P7Oe19tuje+x+53oQJG2JbcZf8A2BA5QlJ1L/yO3uQH2/28f/Jw3IEtKUvupzOy 0cdYmF/5J4w1w3vsyJzbpjq3TNieQqtmG0Pt/I3fvfvBvjy4EHZMBoiXj4XX/i994H7qWzuD7gwj GBeO7IQ1CAApH+rb3/7W1u7sSI+T5J0sa6nqOS/2n3f+c/6l/tPu/wDOf9S/2n3f+c/6lu/bQ+3+ 7GxvmB3YavEdt9H1YOV/tPu/85/1L/afd/5z/qWz/wDi7W7tRAl53nHU5ppap5/m/S99el769L31 6Xvr0vfXpe+vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vf Xpe+vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+vS9 9el769L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+vS99el769L316Xvr0vfXpe+v/2Q=="
+ width="480"
+ height="456"
+ transform="scale(0.0667,0.0739)"
+ id="image46"
+ style="overflow:visible" /></g><use
+ id="use48"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-miterlimit:10;overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#a" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/image-select-brush.png b/silx/resources/gui/icons/image-select-brush.png
new file mode 100755
index 0000000..33c4d1e
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-brush.png
Binary files differ
diff --git a/silx/resources/gui/icons/image-select-brush.svg b/silx/resources/gui/icons/image-select-brush.svg
new file mode 100644
index 0000000..d04ba7e
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-brush.svg
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata56"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><g
+ id="g4"
+ style="opacity:0.5"><defs
+ id="defs6"><rect
+ width="31.155001"
+ height="32.250999"
+ x="0.41100001"
+ y="0.153"
+ id="i" /></defs><clipPath
+ id="h"><use
+ id="use10"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#i" /></clipPath><g
+ clip-path="url(#h)"
+ id="g12"><defs
+ id="defs14"><rect
+ width="31.156"
+ height="32.250999"
+ x="0.41"
+ y="0.153"
+ id="g" /></defs><clipPath
+ id="f"><use
+ id="use18"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#g" /></clipPath><g
+ clip-path="url(#f)"
+ id="g20"><defs
+ id="defs22"><rect
+ width="31.155001"
+ height="32.250999"
+ x="0.41100001"
+ y="0.153"
+ id="e" /></defs><clipPath
+ id="d"><use
+ id="use26"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#e" /></clipPath><g
+ clip-path="url(#d)"
+ id="g28"><image
+ xlink:href="data:image/jpeg;base64,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 zghWiatrzU0xULLQg+a+n1Fel1LKQFJxWx5XNhqmOGPJkGGsH3hRxIJrqMsOJxDIvSMIozMxORHE s9FIVUpxHuOP4SimX66gAENbllpefRs4a3EU9OZWf4s/UIcF1zM9CcH0rLFp03462lwI4Kbrww/j IBFtBDvViuqWCE5CE4RhLMRh9qt0cypS6W1Mk19V7SlSgMFSO5Y/zEAwqCP9Uqz67FX5VnU+9m1X BtDqdegmu/ScCrRsZk4qCymM5P8AWfXrc11V1/Diuf8A5d//2gAIAQEAAQUA8l3tjt/Y/wA+8nn5 95PPz7yefn3k8/PvJ5+feTz8+8nn595PPz7yefn3k8/PvJ5+feTz8+8nn595PPz7yefn3k8/PvJ5 +feTz8+8nn595PPz7yefn3k8/PvJ5+feTz8+8nn595PPz7yefn3k8/PvJ5+feTz8+8nn595PPz7y efn3k8/PvJ5+feTz8+8nn595PPz7yefn3k8/PvJ5+feTz8+8nn595PPz7yefn3k8/PvJ5+feTz8+ 8nn595PPz7yefn3k8/PvJ5+feTz8+8nn595PPz7yefn3k8/PvJ5415j37uHfJ5n7Y/rpW7nW7JuX yrx2hY/j2kRf486i6iyh/wC94Z7nnmftj+rXW9jdu7J6jVdq1daY4jitjMnGYYDu2hXtUMpVv7vh nueeZ+2P6YBM1e2bGwdHQTWFetathqYtYjGDgiqqMzh1LdB3ztzI/wDd8M9zzzP2x/S19d737f2e nk2tShFNdBal7C7PxVxWOSWxlr4rUMN6kuRXTuvbDrWf3PDPc88z9sf0FVmNPbmM7dpLy18Bj9t1 tbcnaxkQ+lVTl2a6pQK68uvIvWyixiRs0rYmx2i1W1+zX2zb07dV/wCz4Z7nnmftj+dVLHU1lrCo QVBoCg0LWjJY/q2s9y116wfL2FrFrRSxRyKq1VgBGZRNjYrl+4SXusZqaXtHcNBUT4rr3MhBHwCk zg39Hwz3PPM/bH8+jVyepItZYHlZCtlsb1riW4V6w4K13O4BEHJLJwqQbF1FbbHcqhGtbNv3k1os wJUT6l2k/o7faeJr7BsMjdprolQCm/t+tag7Buc//wA3Yqj1cZfqKQQQZg/y+Ge555n7Y/n0VwlP SKzLr/e9RYiuthTRpnCh/Vvs4IlQS1GetTffTXNjZLMASWMxADkpylShHG65LEl/Rt26bO02PE7X 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 Je5741ZTTDw0rUaVGXJPUhtEkR49yd+XhCWSh8kKsV6CQpIy1KUKEOr5E1zgkou7s+X4G+GmLxlH i/1W/ln5ufQpRHJPLZM/pK7jtf7WaGmaDUbkUcw/fLBT79CBrjCP4vB2s8rXRicSUtr3ZwVbKjxq Qzla5W9kcV0Kk8EqmWeT1GXWvghkp1HY/wBpNuGpXBrJDLr+0ZJKGqJn7DnREorltT5HvaxNb4cM bWp8kVKPCMkYJb2uMkM8rdthsUIgWRIUCfCwnaaEMlVOGRd9yVjQrjKdSZLrdrlP2yv0HO+yPG0q 5eWcO2HYhuHsytUVphTDXGSCLiR3vdQsvha9NSeRxrgs05IeFcWNp1W2SGW2LSfl6HhaoVtqWSm9 MI4H6wNEdCUyHhGDHhwyXS7lf8xktuiJTbHdy8jtX7BMfca5J5PTLDxjCHixYThEE2uCGWd7Lfxy O2zVasa/kegnxRiZH2KkdNyySEq26ehGMohidy8bNWW/1r/YydmJrY8luO3+R6He07i5R3IwkjBX FKnA/wDzk4u/Mh0wVq3Ym/lB5OEkN7aLJ3Q7LtUc2vUlE7rUnbcRByJrR1JWq1Ha3ErCuvI7Xvoe hUduxGMnP5kMUaW1JPGfjbpmcpdmRcpISlHlayjEm6rQTt1RF1LkQ3W3c1PJCcLjCLtCVoySSd9m Q8ZtUyTESct6s8bdfyz01RW1iY1tGLwjka7kGumhAimpGDtIuIiRWrVuBWonYi2nfpQ0jytUbMfq eR64JiuWELRsnZiIe5OCaPK1SPzo3oh33vyuenYq0eNkxu+pDwZ6PF4pnizuJw6ExqeTXjYt2KKJ CbfscLjr1Q1FGOFInA01Q8R+I7Gq9hedJE7GnBP9j8bV92K1Ki0IdqZGi4X003I+FsYTCnn/AC// 2gAIAQEBBj8A5vnOVkIb+zGJhIgSAJnGNj1rzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwr zMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPp bfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwr zMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPp bfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwr zMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPp bfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrzMPpbfwrlOT5rfjPY3pSE4jbhEkCEpXA 6OHP9yPiQ/MNEEnoTmOiOZX+dMv+i7MpeouidmRLZhGG5Egj8/yHfl4c+HP9yPiQ/LCMASTkh/qK ZRQMIDUqinQhS2JTwZ8lqIfMBSltwbdFY0qUYyDEXH57kO/Lw58Of7kfEh+Uon0tHEoCEQdw4lDc 3TpawC1ykSBYLSAT60xunBLZLslwmmKGxX+p2g8Je10H89yHfl4c+HP9yPiQ/JiMbHFNKpFyo7UH rSiB/lmtZk0BgtO3F+lDWrUGKYU6ke0T1rSwLWKMJUe8TYoz267ZqRl+d5Dvy8OfDn+5HxIfkWiH KBnjgnAYRUoAMY3Qp2jZCW5KgrpCA240zNE0qnFkZzB04OtIZ8lqapRIOnNAxLkJzGowREhQ3BRO z2o5Yo65DbA/uK0zqMJCoP5rkO/Lw58Of7kfEh+QAFynvLNCSGGq3rRkSTKZqV83cLnAZIFuw90I ipRnuBgbAoQhfErUQCc2RiUf6le2WyRr60+pwMETEMndyh8z2cHXzIBjjl6GuMSYjFV42/I8h35e HPhz/cj4kPyBmbBCIWv+MKkKO5I/5cTQZoSJbbjXrWmA7JvJRhAaiA1ETuit+pRjtua1yVW6SiBb MJ43OOK/zNXULJtuJL2Wo1l+wRJFUCe10J47Yj11KFySgZgSDOwqy1QNDZR3JbkYQliXdRMpieaa LMn0HXK2gVdHssMNTuhGW1qOBH/2tM4aDkQtUaHJMfx+Q78vDnw5/uR8SH5CIzqpU7RstMcfaKjt QFMShtwjqLNRCJrLFlKU6ICAcYnBOGBWqYdCIYJwHKMjV8EZzoTYZDhX9MVZhwByWgHrWkjsO9UI iQEY0DYoR2tqZnG5wWiW1IE4kKMGaWJQMqlPEgSF1oI+YLLVCMjtnodlYp5BUiiNKoWOSaX4XId+ Xhz4c/3I+JD8gPUpSllQKRmOkBdoPKVgjKXtkuQpSkGhg6EIVBuiHA6AomYQjEBsl2W1HELVL1Iy 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 2Q=="
+ width="480"
+ height="456"
+ transform="matrix(0.0649,0,0,0.0707,0.4111,0.1533)"
+ id="image30"
+ style="overflow:visible" /></g></g></g></g><path
+ d="M 9.08,25.873"
+ inkscape:connector-curvature="0"
+ id="path32"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><defs
+ id="defs34"><path
+ d="m 29.414,18.217 c -1.871,-0.678 0.144,-3.833 -0.466,-5.545 -0.066,-0.414 -1.702,-3.034 -2.118,-2.998 -2.93,-0.511 -5.872,5.612 -8.911,5.765 -0.366,0.018 -0.441,-0.135 -0.473,-0.196 0.434,-0.787 0.95,-1.54 1.395,-2.317 1.115,-1.95 4.476,-4.491 4.268,-6.766 C 22.437,-1.178 13.646,3.46 12.567,4.248 8.135,7.482 6.138,15.404 4.671,20.639 c -0.73,2.607 2.609,0.291 3.19,-0.24 1.66,-1.517 1.74,-0.953 2.638,-3.075 0.361,-0.108 0.772,-0.318 0.878,-0.104 0.47,0.947 0.457,0.149 0.122,0.745 -0.839,1.491 -1.671,3.074 -1.94,4.781 -0.816,5.176 7.249,0.398 9.932,-0.521 -0.322,1.715 -3.244,6.927 -0.517,7.915 3.104,1.123 11.856,-11.41 10.44,-11.923 z"
+ inkscape:connector-curvature="0"
+ id="a" /></defs><clipPath
+ id="c"><use
+ id="use38"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#a" /></clipPath><g
+ clip-path="url(#c)"
+ id="g40"><defs
+ id="defs42"><rect
+ width="32"
+ height="32.374001"
+ x="-0.0049999999"
+ y="-0.37400001"
+ id="b" /></defs><clipPath
+ id="j"><use
+ id="use46"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#b" /></clipPath><g
+ clip-path="url(#j)"
+ id="g48"><image
+ xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEEOAQ4AAD/7AARRHVja3kAAQAEAAAAHgAA/+4AIUFkb2JlAGTAAAAAAQMA EAMCAwYAABnBAAA1awAAXJ3/2wCEABALCwsMCxAMDBAXDw0PFxsUEBAUGx8XFxcXFx8eFxoaGhoX Hh4jJSclIx4vLzMzLy9AQEBAQEBAQEBAQEBAQEABEQ8PERMRFRISFRQRFBEUGhQWFhQaJhoaHBoa JjAjHh4eHiMwKy4nJycuKzU1MDA1NUBAP0BAQEBAQEBAQEBAQP/CABEIAg0B7wMBIgACEQEDEQH/ xADWAAACAwEBAQAAAAAAAAAAAAAAAwIEBQEGBwEAAwEBAQEAAAAAAAAAAAAAAAIDAQQFBhAAAgIC AQMBCAIBBQACAwAAAQIAAxEEEiETBSIQIDAxNQYWF0AUMlBBIzMVYEIkNCURAAEDAgMDCAgFBAED BQEAAAEAEQIhMUESAxBRYSBxgZEiMhME0aLSszR0BTUwQKGxQlDBUiNi4RQG8XKCMxU2EgACAQIF AgQGAQQBBQAAAAAAAREhAhAgMUFRYRIwcYGRQKGxIjJCUlBgYgPwwdHhchP/2gAMAwEAAhEDEQAA APoAUgunxkD7MfGQPsx8ZA+zHxkD7MfGQPsx8ZA+zHxkD7MfGQPsx8ZA+zHxkD7MfGQPsx8a4H2Y +NAfZT40B9lPjIH2Y+MgfZj4yB9mPjIH2Y+MgfZj4yB9mPjIH2Y+MgfZj4yB9mPjIH2Y+MgfZj4y B9mPjIH2Y+MgfZj4yB9mPjIH2bP0M8PiQBgAAAAAAAAAAAAAAAAAAEgjLY9BKHmdLchHlzafo4Kv hUe18b1dsAHsAAAAAAAAAAAAAAAAAAAAAAAAAAAB99z9DPN+JAGAAAAAAAAAAAAAAAAAz0Cpj72g 3m5F2CcEUzvcFdZExWDvrqngjYx+30wDWAAAAAAAAAAAAAAAAAAAAAAAAAA++5+hnm/EgDAAAAAA AAAAAAAAO3HX0hLXqWOfjaxLJM6RGVeO4xdVF3BUKam0KmDu53Vucm02nbjGvktXgG6DIBwOhwlH QAwAAAAAAAAAAAAAA++5+hnm/EgDAAAAAAAAAAAACxXv4uhbU+PnNam1Le2VsjaXeWpU7Hk5NCuz KsraMY9Wqr2R6V+vllLuHvV57iN9DXdc5ly+h5Nvvq+Z4qt6XF9SONyxZyucbMaJkGjRnSAE9AAA AAAAA++5+hnm/EgDAAAAAAAAAAAADTzNZZ6bFPj57LCLEbMdFsKtETnRiVU3aNaUuhhLojq7KI/O SgVjYrXspb2M93A92WaleW5mQ51oTLLTyC/V7/MVzRqepzZlW8mvqYY5PmdAAoAAAAAB99z9DPN+ JAGAAAAAAAAAAAAG5jbKRtPrvlxvch8r2e1ZyraTXhlOQaujwfXZjxg1I5GJturYjayuZzdt6KWd a4mz+xh08NiNYC1KvZxWQtsSOM+/lel5Ds+0v0o4FPbzuf1apKMKAAAAAAffc/QzzfiQBgAAAAAA AAAAE9GadS4nPZfXnLnucS6dpzXJLd7CS1jBsB1dmgoR6raz4lDVsJRF2myFjb3W1GRt3ldTc9gq 2NW5eqNg1l6rEeCNPQQ/n5Epu9Hylyn3rnR8t7bztO3HA5fSAAAA++5+hnm/EgDAAAAAAAAA69iN iTqQg45zpc6tkpMch6W7wbPonx1edGJ5HacrOzXo1C21smd5+d1K3PidhyAAhyWhCDOtCFuItrLq 9iPPpMzXw4LladV+Hq4nV5LxXOznnRsy638en0udD1ss7yVwAPvufoZ5vxIAwAAAAAA6PbC123Tm jFkElVZF8LvauaSY+s+d2NrKnezUVb23Gc6lk0tHMe0rXEP32O8rZV8VJaVqaOAtta7s+NktOmDZ WcxT2WITRYJz4WzkyfDlVdPP7vIVcrq6uPR7m96U1UpOhcLD9R5iXs8A5+n77n6Geb8SAMAAAAAu Ni7c515mN51OdEeojYtLajsktyN1jnxvVLaFq1lXqX4rrWqmpoLa9UlJ78rXKuslc4vz2Z1bq9Ne dqK14xXMpYnTnk7XVPnyFntyXIp7ex5ctVqn2+UTVOvCcs8NrLt97ExvN+38rbvogQ7/AL7n6Geb 8SAMAAAAlfq6d4znOWcca868W4RZLoYQar9v3m81cy7UvmxUC0OXEp0IOy2ykSzqbByo2poTp3E7 6UWSeFV/ObkoXBb0+2OCcavqye5Lp89qzSuQ5rLUQnzdzdCh1ebBiZX4bPa81Zs0zupRuc7JeFhu Yc/d++5+hnrX4kAYAAd4zSzp1LXRxT4qUJcqM5HoJdelY71P2HBeGZsZ3C+I0PSTr4NnXnOoWort elK/LeXWtqraqPdj0vOmFe7SJi5weeiJZL0ZyhNW7Pklm19ZkuRsx6cPa17hw5yWL7PIXxqqcs3c eb1qnWYRaT1yyPJes8mel98z9DPh2/EgDAAB6X0y8xfd5GJlPnFy71Ku1MaaPtWfMrm/qM+voJkG U5a7VWqWPam2gl3LObeWdZ69I1LtF6Name3fXdJXqzRaZKs7iDVuJYvAsrOFhtiEqtxs5czOKrZy CHI7PK7wa3LUm6LDXUHXLXEnZHB89qZc/b++5+hnz6PiQBgADLNe1VH20XE4UQfTk3Od7lotH4tW ypyvYnXUjz1qGzHorUu2spCm+vtdBbqqdVF9S5bG52rn5ecl3Dprthzc5WtV9jf7XtS7UQuhGmxk d4WN5blzttZ7oxs0LVOnJBfOdfksbDqrOPZKy021vlYZjeiuPXBPa++5+hn43xIAwACxoUrtOey2 g45rCAXFQsKjWLTuNwBa2n80IWp2uISjLSGztXoOdRrGberrejqUdTeiim/ntq9DP0NvBNpWUWqT W56w6wImxEm1t2c+crDYW5csaejSbjEp51cADKcHZLThblVYu2ewmlo4m5X7J+EGLr7H33P0M834 kAYAANV3dvW6Nu/O/i+w52oi6NOEnq3LTETqzYo3+a2b3qnbtiKFpU9BmbEunJp6mJbLmhRuz7YU NRI2JYejohc5Tsp1wlaF1SbIccbKYLO30tTnGU+JBiEzflrwDr8vqmmwWxDt2bOMlaELXNal2xT7 uXzGdqZdPY++5+hnrb4kAYAAAA3Tpam86u2mR51qmxd42yud7FmEIWbzkVpV0c70SUysrex327ez tCPUvE9BW1sLSoT6V1oqtcvdUpai6xqVm23nTvRWtL6UaMsTb5KfNl37GTXm1lw6k8ycs/u4LbYO OQ72U2VWurdITiwxjKvaM+ha873ZjJBPZ++5+hn5vxIAwAAcrYyd2M+S82bEW8Wtco21vNcpJZ3U WZdEoSrrR21gb3PWGJ6DFGqaWfK7bS+u4erATsZPdDl5Ffa7Sk6HL0Us3ZjXnrWKL9SxBrp4PpSS VqjcrtDIurT28U0OTTihfx7W7ozSyJODOpStCyukYc5V7pu89oZXR7+eBBfvufoZ5vxIAwAC9qVb c+FpNa80bNd+Fa1XZlnOQ2deWqdyd5Iv1Z0VqZNjK7lKzLgr53r2+gidXGsRto5muqD4VuvPsmtt uCvb5Vuw2OTuIaFK7jalUtZF9GSmZGjbmjDjKcXIWY4tJbe1SrdZWxrraUpPbjBiOnJ18j1NRia2 HX3eAR5PvufoZ5vxIAwenayT5cnPgfWtV1SbkOFXFqSr3ofOq2okvRv1ZP4qYbpHQ97V83s8VjD9 Ph6Oro1LFXQRCTOxPR1jKNjL0L5aqWOyHdy7uJDK1anRzNhTdTmo8tZ/RHWdWtQRhzsr1q19Nudd qMM2zCLJ2rcsVbQdk3830ezPyNPMPUAJw++5+hnm/EpR29kjTQ7ODjCEpvXOSqmaH6zatqlmtfWn lW96haXNrBvc9rWdq5StYWS2muzA3ON8Rl7C613OosQZdjO62WMbYpVmx+ReZaV1OZWW5GtPOWxy PVRWVsZ9jmphaBul1M+d5KfHNSd48UMK1p6FXmV1VtIjDt+iyanecfOAYn33P0M834ltYtlpb0GI bzrlWc4oOqOmKYIHtonPEQxE9q9XHKMZWtJW47Lvw3Lsyz6vrLhFG2srlmeZGlTTc2Me9RxNQzbR NMbc2jUp6lNlq3s3VZnOWznyNS4llz42e2zlyiJulOq6LzhNZqsjSwfXd/Yz6/YnlzzeLo4BPhAA ++5+hnm/EgDNfR87v14VuZTyE+MTNrVeLZZydWYzVsUDZQ5mMcleZejylm7eTaYqrs5V8ajqZ8tN CjYcsc+xaTu5trina82ranJqHwm+Ndqw6H13V7HPMhPmMmrdRWc+0bgVn2aptrtN+FCnLvt+wUtD Bn3o4HJxgBgAH33P0M834kAYa+Rbeesyc7+bTjqIXaHNFM2Qpr0avNMp72LIZtuNa+sq8by8ypqZ Tzby3unGpQ3MVqM0KF/Eaqz2L4irdTpa9arWpwnycZPQpbOfcldy7BmlOs/nfinpZaiL2b0Lotwe 2tbrpj1djmLo19aWV3nHygCzAAAA++5+hnm/EgDAAN695a90cXoFUpPy6UFuyddqrqFCtfpTrZXc Wksy7V0J2suG88sQlC1NC3Vt86dydfKKqv4+vWduUJ81aGfrZ3RKGhkW23VFt59Wmwtky7Ndl9Lk ayLpwxreO/Js0fT6Aazr9aFWzgc1H1g5uYAxQAAAAAPvufoZ5vxIAwAAADtmqOX553aZ6HT8zvb5 bKN6sTtSr3JyybHIpfXZVu8y5NDXyqPpXcrS50bUuQnTCstp9Ka9jOvczQS+Orhlup0vb0sS5NdC HYSWtRv5/YXJ5HerojfznU66tml07b/chCVfUCHKAYoAAAAAAAH33P0M834kAYAAAAAAAA3ZwbLy 9HXrqtxaGv5r0S89WnYrK17VwtiKyzNbPMzbtK1j64h3K9XK2sTom+7lvQ2IRnFq+JtZ3VlGzQ7X t9JLIsS4u5HanZ6mjOq+3dFVWpzocCEAAAAAAAAAAAAAAPvufoZ5vxIAwAAAAAAAAACfImjPSeXs tDcr067S29LyuwsPQ1uTfhwGoyk9L0+r4rRSfosm3gUiuzi62+pr3vNqTi9D5flN+vSbkG9d1uYK TgCId4ZgAAAAAAAAAAAAAAAAAH33P0M834kAYAAAAAAAAAAAAAAAAPQbmvzJNlKILY7wBiwAADvA NADAAAAAAAAAAAAAAAAAAAAAAAAAAPvufoZ5vxIAwAAAAAAAAAAAAAAAAAAAAAAAACQRJ8CIAAAA AAAAAAAAAAAAAAAAAAAAAAAAAffc/QzzfiQBgAAAAAAAAAAAAAAAAAAAAAAAB6Gvqm6dFXArWbVU MbL9XhmUAAAAAAAAAAAAAAAAAAAAAAAAAA++oeG+MPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeM PZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMP ZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgeMPZgf/aAAgBAgABBQD/AEt7lWG9jBc0rs5D+SzhQ92Y zEwkzlK34lWBH8ctHOYfmfkxEDRYhInIiBgfcx/BY9DGOI56McH/AHqQkqoE5YhaV2Op/sdWuUSn yZDV7aWDtkn+u0ep0+M/yMfEY9SIlc+QBmfYxxLh3INd8V1IgLYOtsERDmMFYMOLfEeGNCpgQQGG D2CMuQ1bAjPHEOBBYQdTcGFtSXqC3wwCZYMEwiGH2iBYFhwIy+rhCuA4JLECVPg12ERHj18k+Cq5 nRZZ/kY0JxB1mMRFzMAQuBCxMxBn2E5jQoAawsXpKwZW+I9Z5e+q5mI7YDHMMaEEk4WExJ8wBmBZ iHpM5jOAGshYkcjmlshLsRLVMVhNhAD7qqWJAUExjkmMcRmnIwrlugCtiZin2NkTkTMEwpCFEdwJ zyayDDEc5reWsWX3axgMYzQwmNcpdzPlA4MyIizpGBEBOD8uU5CEAxowM4EmgYhExiV5idQwwfaB knoHaEwmbuyUXXc9w9S3KBYoGF9QWNFPSEGGEmMGhLCI+GQDAOYDElcvGPcSO0Y59jKTDrq0WtK4 V6jBgyWGOS9AsMBwTkANmEiE4jOY1mYleYg6E4nKVkGVrLWy3tGAG6wqfaYRLWMGFgEXPIxD1YkN 84uYwIIsnIGMY6ZFK4gEPWZxEfBps6E5PtHUYMbpCfZ0ljkT/KP/AJAhUTobGw6HJs+atM4haEoY yRmIlRyVTEJwOOYUM6g0k+6Dg9MOR7CYSTLSSR8v8jsP1q6rbnkj4nIEFSJ3IGhAMJYQHJVOLD5A 4hHRi0QkypY3z9w2YUtCcQsY3UY6bD8VpYFLh1ps4xgGDZUq85FYSjRspGYGA9wKhBRQVJhMVofm lcrHFfcY4EMYT/dujAeraGDrNk2LyGSrVvyUgOG5IUsxGUEciIUzKgQ2A0XEdchhAcRWE1xyloAX 3GPWGND83isC1qclUlLC4xdWHFVhQt1BcEMvGVWYNiSleLGriflA3XJhKtCgMwQdH53/AOftJ6Qf M/L5howzOqMTmbVJmpaDGDoWCuKbipdIMgtThqvkK8QdQ/T2I3Q+qdQUBYaicZacv7AMlhDP9zBC JiXV5FRyMS2ko9ebEZSCasyrpGr6hAy8CBjErPSxMwqYDg/7ivkKKDDxRCcn2KcFxGWEe5iMDHTB xyXjmKj1sUDCtcE14PLEQjLxvmhxM9GUNGUxZqVgq+FWxy3uochlxGScSJj2kZnEEKOJZYVyP8YG BPQxhFJyRkPAYpjKRAwaCs8ql41XthfdQ4PAQpCkKQqRMQ9JyEYZhZhK2zHgbDDqHgPVGyGUGMMR TK1LRNNiw1wga0AMxY+8lowSCMQiMIRHGIfn/tZmUn1OIfnWRhlzCMFT1OcY5DssJp1AA4l1mAST 8FHKzvAwHMYTEdejL1UZFixMg/MWLiKYDkWJkKJVWWC6xE/rrBYFLX5hJJ+GjYJMHWMIyxRHTI4Y KL0dMhUOa6zDrvF1zyTFbd1TGu6fHyYrYhYY6GKkbAJVSeIARFaNWqszKB32ndaE5/jc2/8AmP8A /9oACAEDAAEFAP8AS32FWPfa0D2qaLu4P5NlqoLLWeBRAoEKRXatq7FsX+PZdiMxdlWAQAwpmOJR 3VIa0FHDD+I5wrsSVEUQL0x0K5gqEVIEhqhR52zHDAJa3JrFWDYSKwYfFt/xEUQCATECwLAsCRa8 x04hj1IJj1gjYUgq5JobK/F2P8QOqiAQCAQCBYqwLEAjqCDV14Q1GWVAjYo4mo2oyWoR8S45CxYs AgECxVi4EzK6rDHUYKgEV5LoFFgmwuQ2QSxmjeeXwScRrMxSTMYZRFEAiiYxEqdpVokhKK6wX628 JxzFVUFpzLAZcpxaPUQCUIQpt0t8AkAWWQGfJQMlViiKpMVYEyVIrLWlQ1zTuYFY5HgEnaYx6RLk AlgE2UGWUGdozi3LTcmv3ScB3ySclFzG6xEigQYit6a1JIXEUgm0HBwZTwedhVIetY+wJZaxlgJl gmz09hToSRNG5T71z4hfpWsAwFWBegEURVimc5WSprIYcVJQDmdfMNDiMrAMGjkx2myQROUJGA5V 6bBZX7lrEtxlakQCIsYdBFxA0XMACk/OsdLBhz0i2qwzkNiWduWhZaoxsEgwAEACWgCaGeHtb5H5 qFEE6wNiF8kGDMHQcSAo5NacFTGHIVFXLVFCHdY1haMBHEsbE2TkgZhzM4DWEzVXjT7bD0sYxDmB jGawNkmKCYogGQnzYgLT1l6+mpQ9OcRyBFcMtlQMdSI5IjPL2yLGyR0mMx0ldfcdQAPbdyJatYFU RTM5ZV6qIIvyQEs/UaqjtWHA1GHCxYy9AZ3rBGvzLCDLTiW2Q9TOWICCoYI4OR7RibFYUgeoKFig RQYsEHQULgOcGggJYgIRihS4MGXo4htIjODHaWP0uPqmeqKmWrWOuDr57PubFizugRYhyVMErEPz qPR1yKrCsVgwsWAgwWusaxXjwtiO/Sy0CMeRVRGXEWd3Eqra+0AAe22zggOWbof90OCIIkaVtgg5 B6FLCp5Bg46i2M2YXljdLLY7BmZQIrQqCGQwKWbS1P6+t7l7ZI+TewRfkDFM+YESzEfBitAxBNnK POcssxLLOjtkms4BIJOYLCsDBhqLna2HxX7b7O2jGJG+VZzAYhgMUxWjQHMDkRoHhaM/RrcG26Bi 0T5/7OvUeiZVg44nxal9rY/7PZbZ21uYvPmikB3GDVnGcytoG6BoGnPIDdec5w2YLWTugiywmZzA xBcYiuDGXIx0yVNdVl7aOouuljcm9lyc0URfSzKQcckBKsRghuJ54heK+QLOrWEEW5At9VlmD3Ww HObsgpjD/MOwnSJZG+WpQLDrUhTsXAL7mzWVIw4WAFCUi/LHQdRX6othRrGIjPyQOwLEmMeQGMtj BXlXXiEZmMT5Qgzn00KeNdv/ABp7ty5RnOVuzFtBnMKekVkywKMti8rlViGOK8hrP8+HpUqUHzI6 K2Iw6o2Y4ieojXuaUaA5DjWtlhc+9dqEkU2AkMpcxCSgY8rWIVRkD/qrAyf8rRxZeoU+qxeoOQwh +WcxgeOlTk11ZjkVBmLH4JRTNmrjKziN6XJ5IhyEPROjPORcVNHHVWyuOJYyrkxXStLHRDxK0RRe ih2LN8O+oOqU4O0hV0HQelm+bEzlkJguQVYtkUk9xtdjDVYW1tUVBEWNYAPj4E2KBYE12B2NdlBc 5SnuVPrWKuvXY9n9VWj6NobW1lpAcCdyZ/ikAj+tTn2AAf8Ay7//2gAIAQEAAQUA/wBf8zdZR4f8 t+5J+W/ck/LfuSflv3JPy37kn5b9yT8t+5J+W/ck/LfuSflv3JPy37kn5b9yT8t+5J+W/ck/LfuS flv3JPy37kn5b9yT8t+5J+W/ck/LfuSflv3JPy37kn5b9yT8t+5J+W/ck/LfuSflv3JPy37kn5b9 yT8t+5J+W/ck/LfuSflv3JPy37kn5b9yT8t+5J+W/ck/LfuSflv3JPy37kn5b9yT8t+5J+W/ck/L fuSflv3JPy37kn5b9yT8t+5J+W/ck/LfuSflv3JPy37kn5b9yT8t+5J+W/ck/LfuSflv3JPy37kn 5b9yezz/ANB/jpW9h1fBbV8q8BrVRvC6DC/7eQza1LdWz/QPP/Qf4qVvY2h4Xk9XjNXWGMDAclRj DzyGpXuUXVPTZ/P8/wDQf4YBM1fG7Gw2loV6oGpaHNPM2VsYgWtQEdnVlJyB53xpdT0/n+f+g/wq aXtfx/iKub6tFQGvXQHqe2FmCK3bXuJaSKuK1DLCxZaAV8x4vtN/O8/9B/gAEmrx7meP0l7lGFts wtl1TNC7munNVdbGy1rqkASol1DFqyFdmIvrDrteIfnr+I2LW3NC3Ub+X5/6D8cDJ09UJFQ4QGlU BqCo5e022zuLVTr83e231LUmWKMy1VqHABYrnYvrxsbgJsvsc0V2XDe8cq1e1KLXBBBgBM4N/D8/ 9B+Pp19y2pOi1Fwxa5GFlys9jxP+KjVXrdeC6qizkjnt1INiylJf5DXUNcWNx7hNSCcUMUnn/Udt fc8V1q8JtWI3h1qWlRXLdDVuQ+E2y48bfUGp4S/UVgylTMH4/n/oPx9BfTQAGqdkqQt/XRu3TrkU 0aZy9loe0pWiVcbVParl9lNc2tnm+C7MZjM45JXMrrCsN1hLWJdUs2NezxdhWvxl6DV0XVE0hx39 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 yMtShTclqZKl0ciX8tH1N588m+DyK62grudfPKytehN2v0xnJHIlGpYv8hslfsJv9XJRkoqalMIx iCVqXcSsvXwJO4nhCe6cnmeR23blNBxcyXczXO7Wi3/JTkgStdPqOou2BQvt3ySJPBvaSS17pFan fbqhPlFCuFcsoVu7ElsoyRsSykudSEQTiimxBXdkbHbwSiWj7bo6Fan3IoUNcklt6/V1JW+SpK/F oVaFXUTyt8nmJcEEToQyjOGQymeiILJ/jlVrelYPM7rvTJOSMOqP43IrVHGRonHWGQyLapKX0Qkt qZG99ite7BMXgdChO5Dwh41O6yq3W6yJKpffd+f+xey4y3dHBPDwfQQskEYQymeSUTEPoVRQtSLb PV5G99EeZcukiF1Ue2HnknCGThONGQuCuFCdVhKO56W2sa4xnXgluZE+KCbGh9KkkceFE1w0HB3p UesbPCUQyjItWhOtzrcy67l4tcHa9tBp6Mhif8SUShPYkk8sZIb1GiJ98F1WEkyTb6ojC665TAla oH/rtq9G8vfauuHbd6E7blNB2vaqHyh9NB2v0K+TE1o6ota1ipKJ0O7in/nCUJrVVw0w6E/MrqWy vyqylG9M1NVUcPQhqvJF25Gx3In5HdbVCuX28ncnE1O35EcjXU6jT/JyRhBNvqsJO0iIXU7r6pbE sl6bLO7rPYh2tDoKeEPoigsG98FFCcHPJ3LFXW+oo1Jp6H/0a8sEtWS34VVJC2Z50PM8iOB2v/kj Twab0O17DIJ2w7V+xqu3kSlpbiVEraFE7mO57+I+cEP3PMoKdHVdMIPIlFFMkQdltrZ90d93yHVE W+/wK5RVE/MSaqmJ6cDu2WonFOdjWGNJqOZJb7r3vsvIoiiSfPw0NSie1Y0Uf3d//9oACAEBAQY/ AP6/5/X0ZGGrpeW1p6cxeMo6ciCOYr7hq9Y9C+4avWPQvuGr1j0L7hq9Y9C+4avWPQvuGr1j0L7h q9Y9C+4avWPQvuGr1j0L7hq9Y9C+4avWPQvuGr1j0L7hq9Y9C+4avWPQvuGr1j0L7hq9Y9C+4avW PQvuGr1j0L7hq9Y9C+4avWPQvuGr1j0L7hq9Y9C+4avWPQvuGr1j0L7hq9Y9C+4avWPQvuGr1j0L 7hq9Y9C+4avWPQvuGr1j0L7hq9Y9C+4avWPQvuGr1j0L7hq9Y9C+4avWPQvuGr1j0L7hq9Y9C+4a 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"
+ width="480"
+ height="456"
+ transform="matrix(0.0667,0,0,0.0739,-4.8828e-4,-0.3735)"
+ id="image50"
+ style="overflow:visible" /></g></g><use
+ id="use52"
+ style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-miterlimit:10;overflow:visible"
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ xlink:href="#a" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/image-select-erase-rubber.png b/silx/resources/gui/icons/image-select-erase-rubber.png
new file mode 100755
index 0000000..175eb11
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-erase-rubber.png
Binary files differ
diff --git a/silx/resources/gui/icons/image-select-erase-rubber.svg b/silx/resources/gui/icons/image-select-erase-rubber.svg
new file mode 100644
index 0000000..0c091a2
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-erase-rubber.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <polygon id="b" points="21.065 26.312 0.489 22.273 10.937 12.341 31.512 16.375"/>
+ </defs>
+ <clipPath id="a">
+ <use overflow="visible" xlink:href="#b"/>
+ </clipPath>
+ <g clip-path="url(#a)">
+ <image transform="matrix(.0953 0 0 .1337 -.2744 -11.418)" width="480" height="456" overflow="visible" xlink:href="data:image/jpeg;base64,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 vis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/ev is/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evi s/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evis/evisr+bfGLbJ3D2H8kA mcGH/A9v9/O4ew/jojOdPsexeaeza9EbR1HXY7JTZN3Ss1LP53b/AH87h7D+N2/tr7L63ZdahVUA OFaGviMsZ3HUp26HUo/83t/v53D2H8QAk9s7WHKKivY9hjlwKa8hvUBZuBwrHv2n6V383t/v53D2 H8OjVtuOj2lKhUmY/oUrX5q/TS2MjIqrYIbEeFQyb2quxRs0Pr2/zO3+/ncPYfwtbXa1+36iI17K sfFaLUtqkNYuDSqvY5NygDGbKwWccB3nSW6sgg/y+3+/ncPYfwACTRpM00dQc6sLbbhWspLg2N6d AatFf1L2tRQAjSxVcmrCMzEWqHG92ws2t2q+6ze7fbqN/J7f7+dw9h/A0tbkQvTXHpmov6nJ7bdi 7pRhKa7BZdaUrVaFsLIkWlgXFoL5zsFgNi9Elu5YSLG2Bt6HCv8Akdv9/O4ew/PWvN6UwoXilhRd d7FWgOFp10D0qDe3p1649AWsQQAlrPY1ixwwFuyeeza5Lq7E6jSkrU1lPrU7Wq9NmDEpseaulWo2 O0sIyMrVavMDSXF2uyfwO3+/ncPYfn0UzZUpJ10V2qXnXRWLVrp/7BA5Cusa5sTYublwVGtdmtxN y+ysbG3tNOoDAwo2PSOFRi1OtUdba1UddftWumtc2sErBaU12PX+u1sdjsK1C7t1tSWFMXIFYAmC mww02CFSPx9v9/O4ew/PoDpT5WrLKlXJqkLV10Zpq1OXqW2G20kLVrNyFlyibGylY2byzAMzNOMw SSuYqhZ/2Dm0uXoqOwj9ssKr2jbpmtotWtOqlde6KzUSizuWjY4GvY5p0OIXXjUjNurWRsUGo/h7 f7+dw9h+fQHSoA3VhWt0yitpnk1Teps3Mtb4VVTjdX5KksZEW+42Fl9Wx1ABYZygnHocAYnIBgS6 6PkGraRL7ObitKzu9zWpdnYayIMAL02dccq6wQcAmkKLgS2zVzrIwfwdv9/O4ew/PojygEBlxZVW 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 btl119gMrWqo71vpc2SJ6jzt22tGxd3mikb29bt2SjfsqG5vtsAOwLOzfy+3+/ncPYfw67HrZO67 Cy3uezYCSfsJJ/4Ht/v53D2H/N9v9/O4ew/5vt/v53D2H/N9v9/O4ew/l9t7btd02avjPdLbR2Lu J7fgzi0II/l9v9/O4ew/l/GLLarKtBatjb4vr/H9EbXbCuvRb8j4v/L7f7+dw9h/K7D8a2O+Jr/A u7a1ifCO+Vt+id49DV+I921O2n4L3kl//wCfdzsHfexXdkv/AJPb/fzcRrNP9M+Tz9M+Tz9M+Tz9 M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M +Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tz9M+Tyv4n8tqH6z8zn6z8zn6z8zn6z8zn6z8zn6z8zln xH5Zaf0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP 0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PP0z5PNP4f8AJK9z/n//2gAIAQIC Bj8A/wBKln4il3IeX1m86GWQ3bsi9iNvql4FDvN2NfxRL4wiZgkn6eCNyY7I9clxdxPLj/UmYSyJ cYrEkP6Nx8D4/wAYlmVuIvxFKVVDiBX8keynuz8XnsTLs9chRHsXZZkPrOj3asJTlmztNkXzwwPk lke3+S8aEKxKE1nqXFyXjr+UJrwhL5JeeKYIaW5P6GxZR5Liacoa+p84M8jOxmWz6jbzjE8MYJwr ksuX9elLzHihCbwWrJc1JVfX7F1HQl0irLkKiW5fDLwpqrT26U4G+KuXzdE+hLGOHlXMuPziSw9q WJLkFiKWwySTgnfCsPd5F9qJLXqW5fDE8PjDOHlyekpEvwWRe9qQqfAnRVsTBch9a57Nf+SElC2J yPZkv4E++GGZExJZFy1y5OBt9KKeqXzRcewhE1TRDpcsRiXd9KSxyf8AygjekkoZBcgsXpCy2E1k 6LAvGC5bDHy6OBDX9py7IseVS5ncvcyJUp0h0yLOqeGMFhsbebI3HyehO441pGC/3pcnVV8dFEKq G251p2VkQTXweyzWZ3JV6Pjyf4v9CH8FztWapYbUYxPtRtf20jfKkbnek6CfEh3PZfJc7qsYWtsb rBtKonrxJRGwuSO5DyId+LLZMn7oTWTyFBlSVVC5DeN0/Sk7Eo9XqPiz2R6vUlENXPU9GQ9D1ZfS smxai/69Jkj4jTI72Fy4n/z5/D3LZST/ACVPaLrMTWZ7LPUeDyTRMjtgnBNWqTue60PR5Mj7DTht IlaZi5JW5DTy5WILCkawRRSRv1PZEPNZF8nmWyZPHNHtHwJr+R6vKl8EqsCeSIG8EdDtyp5IefGn kjamdHXsyVRLuQR260kbVgnKXHSl6UbxKl8couqw8c0yHxIWON+g6/GOHmWEKVcgcdHOxKfRjHYu TR9OzIfVla0l2I3IViEX+jms0si6Jdki4mS+vasYYJZLyQ9hKCMl9NchYPWSP9i//9oACAEDAgY/ AP8ASpbhEcFHdjfs3HcS5cvbj3z+ru/gbbhbGd2JQ1u0Wfsj0f7uP9PqWNvUuvgW5blnuREwLlx0 Pb2S3J4uU/p4707kLMiJLJ0vdifG3HVfV2eGxlSeDy0Jf47pliOv9zyujNLUbRcU9drufHSmtyV5 NmQ/3Lqsjp30JqxpqSeCgS5q25K16bSE9H0LEuyJmskDqkJa8bdKEJLUvhkhFyYksTz10G1T1Raj q1ydieHJcuhBBH3wy6cuby4s/EhXGpcC7Fj04XerwMaZa45E988ck0b3wKS2So+G7GshrdETM5En rELerSww/wBRadHyQsUITPyzPbvSOXH25IygzwMa2rKI142wungno3yVjI8o78XFLXMseQpy5Wxw stWRRYfZk5QP/uNbo8HJN5nmlyKNodWQj4wQRp0IQ12P1OS7zTyLnx1zLPIiUmXdWOl6KPnDA0sl SU7H4ucLZO4/B6vVEMnYfB6ErC1ggfLZYYJgUEZSWyJoqpdz1fwce5JY9tzPoyiVnN8DSLoiC/6E 75CnUjAnucfNFvxdIWpdSj8XBmQ8MlyJOfD/ANlhai6yO6FfIUELAkQJvSnsiGSqOMtsDwZEoUap 4ZHyeugktTv0fJ6v4Ny9JWOGSPm9o++GFnyJkbzguLpQyzIdWTsTWGLir+zg/wAfBf2J8vOCWT8H gdIwxSHSUSs63runmj2434v9KyL/ACclMftQ+1sHl0aOXxjkgmmZJNGh1syUiGSjjy8sb3eB8F/F UT3RG9hPHKxsTetfBFGji9+P9cDS/cOf5SMT2sJkfPVZOY+Kz43RnWUQxcUrN3fYX+NdkvjA51E9 mSv5D47qi5LNEiZOKSG8yzLvK+D24/K2pNFaExeqFxX8cC5IkfB5q6EyVlyuPi9SCDzRPca1VJWT GlmqWGm9IL1sSvtTit2I/wCTyQ283gaGn+1nsiR8HpkSJ/JYlHHmvkfF5rIuSsnkRNh97EUjQl/y LUg70W3G9H9sT2zuQ1KLKz0PZU9X8ELPievKz0HxZts0TmTRJ5Niayik09XVclqNw75G/J5shfue OVoXExrdUV6pK0kUaSyon3G9iKNF7NakN5UUq7vS1+RL6GUMiS905uPsJrakdzj5E96cuPJxcikE qiZKeY7TBCX48buj5P48k9NjGfoTuJkLNEa0TomeSKL2tsQlnm2WXrLPxR+T+OrKOQ1sfrRo760T WhD1IMsj2jM9uSjitaJt/BL690NRmMTgh5MaPJDUMuSlZCSTS1bFwWSIalEcVC+lgb4xc9uTlrKi 5cvsLjxUJEf7Gf/aAAgBAQEGPwCW5MtCAMpG7ABzZeu+jvfbXrvo7321676O99teu+jvfbXrvo73 21676O99teu+jvfbXrvo7321676O99teu+jvfbXrvo7321676O99teu+jvfbXrvo7321676O99te u+jvfbXrvo7321676O99teu+jvfbXrvo7321676O99teu+jvfbXrvo7321676O99teu+jvfbXrvo 7321676O99teu+jvfbXrvo7321676O99teu+jvfbXrvo7321676O99teu+jvfbXrvo7321676O99 teu+jvfbXrvo7321676O99teu+jvfbXrvo7321676O99teu+jvfbXrvo7321676O99teu+jvfbXr vo7321676O99teu+jvfbXrvo7321676O99teu+jvfbXrvo7321676O99teu+jvfbXrvo7321676O 99teu+jvfbXrvo7321HbhzrzmRGI+VvBySwvt4cz5W54T+aorH/AeW83b8Qw5nytzwn8w0Q5QlPu x7EDufqWTCAPYAj8uJj7FpkKZH8/y3m7fiGHM+VueE/lxqeMUJsX6yrMEIu5KBjcLUYs2SmAO+xI 7UYkMQfz3Lebt+IYcz5W54T+VYIbm+2ngox2Yj2KMIx7SiGC1FnTCoXesUQKPUL5sYgRnduP57lv N2/EMOZ8rc8J/KNEIbm6NXsQjGDDrTxiBLqAWo8F2LufojOSZOKEKW3uNWsTwKO3MW/O8t5u34hh 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 RNmEfmWRlEd02da4huKjISTCpOSlLcoTYISei94I7kpBgKBEQoCnP5DlvN2/EMOZ8rc8J/FbCMnz qql+CKBQKI4YFhZA5hVPUVKNoyqE+eSrda7g3TOxGSBBrkqoFGRoeK+W7xj/AFKBKqzJoSaJWqRc r/aLDHS9OH5LlvN2/EMOZ8rc8J/ICJJ1DJdavVAv2oEG9xg3FS1JnQk9RmhtyP8A8iqUSTRO7Ogd fdXy5mo45hMD7EWNEZJnTOf1V1Un8ty3m7fiGHM+VueE/kHCunKeJRhK4qgDdOSKdaG3tl2uVRXQ luViU8SJvYAp5UjkMAMgogBmzTvVVP5vlvN2/EMOZ8rc8J/KaoFiuKMTJgeCc3/wXlvN2/EMOZ8r c8J/xzlvN2/EMOZ8rc8J/wAc5bzdvxDDmfK3PCf8c5bzdvxDDmfK3PCfzn/i8oBLd0mXeOkNG9Vv 7MYw1csWn3qGRD6YnMqX/wDR0AbEHJBPfYHSZNwfCxTEMfzfLebt+IYcz5W54T+c5ue1yn/mn5Om W3q0nTIsWGmTqOzyMDGGzz23u7u2K/KEttyJdinzcIvyg5LfgZgd3Wdw0WobPzZjntmMjpc6CKjs W3sx5faMNyPNym8AX+We6PYuQ5nRGG5zHLRnuaBpBk5Dt+b5bzdvxDDmfK3PCfze7PZ3Y7Y2SAdT VftkF83Y52G3MU1Rb+a3Jw//AKEYy3qbhDd7t76PLf8AnR+QS526M/xrd5HY5qEJbu7Hc+aGBGkM 3voE89Fw7Gn7r/vzURPnISEBpi7UHD31t7G9uR3DuR1Ax7W4n81y3m7fiGG/twDzntzjEcSYkBeg n8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3 /Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Neg n8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/Negn8W3/NEbXKbu2DfTuQj/AGmv+Df/ AO2P3F/wb/8A2x+4v+Df/wC2P3F/wb//AGx+4v8Ag3/+2P3F/wAG/wD9sfuIHd5PdmRYy3IH+816 Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxb f816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816 Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf816Cfxbf81sbk+RmIQ3ISkdUKASBP7v/oD/2Q==">
+ </image>
+ </g>
+ <path d="m5.724 19.576c1.59-0.385 3.401-0.499 5.101-0.614 1.997-0.153 4.067-0.21 6.1-0.21 1.958 0 5.936 0.133 5.936 0.133 9e-3 0 9e-3 0 0-2e-3 0 0-0.132-0.016-0.168-0.016l-16.969 0.709z" fill="#fff"/>
+ <path d="m6.8 21.601c5.011-1.024 10.784-0.789 16.06-0.616 2.205 0.072 4.05-1.01 4.05-2.1v-2e-3c0-0.879-1.224-1.85-2.974-2.024-0.056-6e-3 -0.111-0.011-0.168-0.017-5.103-0.512-7.278 3.535-2.152 4.05 0.056 6e-3 0.111 0.011 0.167 0.017-0.991-0.675-1.982-1.35-2.974-2.025v2e-3c1.351-0.699 2.7-1.4 4.051-2.1-5.935-0.195-12.585-0.386-18.213 0.766-4.801 0.98-2.712 5.044 2.153 4.049z" fill="#fff"/>
+ <path d="m17.025 15.811c-5e-3 -0.01-2e-3 -0.021 8e-3 -0.027l6.697-3.973c0.01-6e-3 0.022-3e-3 0.027 7e-3l2.194 3.7c5e-3 0.01 2e-3 0.021-8e-3 0.027l-4.282 2.539c-0.01 6e-3 -0.026 0.01-0.037 0.011l-3.201 0.042c-0.011 0-0.024-8e-3 -0.029-0.018l-1.369-2.308zm-0.085-0.209c5e-3 9e-3 0.018 0.012 0.027 6e-3l6.695-3.972c0.01-6e-3 0.013-0.018 8e-3 -0.027l-6.575-11.088c-5e-3 -0.01-0.018-0.013-0.027-7e-3l-6.698 3.973c-0.01 6e-3 -0.013 0.019-8e-3 0.027l6.578 11.088z" fill="#414042"/>
+ <path d="m17.025 15.811c-5e-3 -0.01-2e-3 -0.021 8e-3 -0.027l6.697-3.973c0.01-6e-3 0.022-3e-3 0.027 7e-3l2.194 3.7c5e-3 0.01 2e-3 0.021-8e-3 0.027l-4.282 2.539c-0.01 6e-3 -0.026 0.01-0.037 0.011l-3.201 0.042c-0.011 0-0.024-8e-3 -0.029-0.018l-1.369-2.308zm-0.085-0.209c5e-3 9e-3 0.018 0.012 0.027 6e-3l6.695-3.972c0.01-6e-3 0.013-0.018 8e-3 -0.027l-6.575-11.088c-5e-3 -0.01-0.018-0.013-0.027-7e-3l-6.698 3.973c-0.01 6e-3 -0.013 0.019-8e-3 0.027l6.578 11.088z" fill="none" stroke="#fff" stroke-miterlimit="10" stroke-width=".4"/>
+</svg>
diff --git a/silx/resources/gui/icons/image-select-erase.png b/silx/resources/gui/icons/image-select-erase.png
new file mode 100755
index 0000000..d5d1a5b
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-erase.png
Binary files differ
diff --git a/silx/resources/gui/icons/image-select-erase.svg b/silx/resources/gui/icons/image-select-erase.svg
new file mode 100644
index 0000000..5cf5261
--- /dev/null
+++ b/silx/resources/gui/icons/image-select-erase.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <path d="m9.085 25.873" fill="none" stroke="#00A14B" stroke-miterlimit="10" stroke-width="1.5"/>
+ <defs>
+ <rect id="a" x="2.848" y="5.846" width="20.208" height="20.309"/>
+ </defs>
+ <use fill="#FFFFFF" overflow="visible" xlink:href="#a"/>
+ <clipPath id="b">
+ <use overflow="visible" xlink:href="#a"/>
+ </clipPath>
+ <g transform="translate(2.3842e-7 1.4901e-8)" clip-path="url(#b)">
+ <image transform="matrix(.0667 0 0 .0739 -2.897 -.1597)" width="480" height="456" overflow="visible" xlink:href="data:image/jpeg;base64,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 9mdzz7M7nn2Z3PPszuefZnc8+zO559mdzz7M7nn2Z3PPszuefZnc8+zO559mdzz7M7nn2Z3PPszu efZnc8+zO559mdzz7M7nn2Z3PPszuefZnc8+zO559mdzzT7Z7x0b/J/9Knk/+lTyf/Sp5P8A6TPJ /wDSp5P/AKVN30rv71Cn7M7nn2Z3PPszuefZnc8+zO559mdzz7M7nn2Z3PPszuefZnc8+zO559md zz7M7nn2Z3PPszuefZnc8+zO559mdzz7M7nn2Z3PPszuefZnc8+zO559mdzz7M7nn2Z3PO3NW/T9 D/5//9oACAECAgY/AP6VVwQkdTv8VUoyYs+eTo2cPqSiV8UqcjXP6FH7tl1rYp8O59xpXdfYlOMe e5ExjwJUK6tRQaSt1JkjNSeMeDIVSxVR8B8hQ/8Asytv2oqtzhw0uCJyybfJ5ZvybqUoRl+JQhjx 6euiOJJIRBfY6EtVek3/AE08cn7EyLJe3qqefTWsI7kirTScbr05dRbvy1pumS5D0qfTZ19Odksp YSVCm6t9kMhlNFmqTffLvpGvUohQ/p5K8b6aV0QniTrHfdPTasW65Fr6PSNJWttlmU/PWdK+k8n8 kLLJ/c/wEiEiZcyXIXGrW6qFyStLap9/QoeOSlHll9T4ngmLkOGeKvo9ZJWlSxaD/XSNqx+eyeu+ Tyyu7CfRboZQrpVEqpUnZDG/SpZFORIbZJjBNmIh6VRRn0tH1KNJVnpT1YRHIo+Z+R48vRLotsXR QhnWT30qU0qt7nWBpOCtZPLrYrrK0njk64soytUTi2mRbNfmWPYj1lohfoR1H1RDI6DK2K1xZKt1 K1PLH7eRMlX0lbW7bY2+2jX+I0WZKI6HniRkoKVR1TJVmdmSrMnSTo9V7iXX0vfRNfM8sTxy5LSj zxcdf9zxdiVZkP7WUszxy+186JNbKUZcqhC9OVdHixpiyxs+SHdckqjV+4s8a9ep4uuL/IgjnG2r klap6y7jeyfQ8sbE8ni6plEeSp1I4ekZFNsrZQhc7Y0lbmuuqfK0p6Eo6MoS+R+hT0IaI18lzrBO sFETkoFFEiFbfDv6S1jZKHSGTBLsSqQMjj0eqOhSu+dJ1lX1mBRB4/D1I0sWE8kQMbbv69yuypOk IqVvwhSifEll38LYl60Kuf7t/9oACAEDAgY/AP6V9Tg+hfNkvx+ZFslx8VLoRh+JLct8nVImq6ci yV59jyx+JjguIqr8FmdfcopTuhR/HTmXUo/h6++kFpZzJUotJx+ZbSx4uj7ksuinrM+b9Kq0gsXI mX67O8i9GCltYaJx5LP2dhNer8vSopOjKkIqQMguzwzcp8v04R7OBpWdd1EWgnOpGKXYmV7aS+Bp FtkyJyp9Od0uovP9yJsiSciJJyoiMVGK2Si8M5FFGeOTmLPfC0jqRstUponzEFaFW6ETUlC/9Mpg uUK6PSUVIs2qehPcnfJLdCGNLoLiX+Z9/wAisva1pGieLsLLnn32xpaMV+etNs5c6OBZLm4/xMXe mlVpQY5166NcNTtbZXZGsslIx0T6kHjkUbOGijSKvfDHl1ptpV6WkUYzJOtCOpBTTumQzzxE2Tjs ZGtDuY483eyC5Pl20S6iS2QiDOfYh1Rkp5JQz6WfUiqKOdWRqslwxZLlTsqpJX2sUEsnuU2T00fV sfcZccckqjIyKa01qfS2iJEn+1tbfErXudEiFvh6d0UfjkiMkUvp20a2XsQxJVlmOPN377G3wS7c aKLC9KVdEMpQh6X0WScrmNr/AJ/5F9OC+meu3x7D0S7SLbBD0hlN8lCV9P6FShiovkhpUmi2Nvg8 v/oa6o9hdqEC2TpDJ0nZHXSCUS7FiUz+Jf8AJGOPbVt2RCpiz/qxPudmNEoj0mRpNzzScO/vpI0y h4pVP/X+RQ/2of8Axpq0PF+6IdmQd8SULJciZKJW6CIkqLLqSSj9e55Y26dNfGyRKUvqyXfhEvnZ 54+5J45XVmTwSrMeL90NEfM8epXglWZPKJRKlC64319raRp/mTyVMs+rgeXQnJ7WiiSZGShkP8SJ oJolfMlWFli+bCyxu+DxdV3FS5EaOaOxGkdTyx+elCOp4rGRJ/SuWLFUWJ4Y253+WKKogTZGrHL+ 0qJ9GJvRqwslr5LglUfYmGdlVlETkQqY+jVJlcUNK3GiIGhpkaeLSoeL07nbSOpCwbm0EKPJqpDr lyyuSRT7Vb1H7aI+RPBKFKvz0IYjuiTsUV6o8WLPNU4nnRzfoX9eYISqhKB0IdGilSzcXElIuo0s X8jz/louMeWWPJ4SzoSm/hGnyS2zxxULSccUn10r/dv/2gAIAQEBBj8A/wBe1/wZ/iampL8eWQzj KIB+a9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+K K9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq +KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9 Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+K K9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK9Dq+KK0PzoQOnH8iOcQlUj5bPcP NPIfuGAcoNBgd6dwOCdnHBNOJieP+ge3+UOZ2e4eaeQ/bCMA5KEtSWUYhDsiUhiQiwA4pzIn5JmL jAos0ZYFS0pXiW/f+3+UOZ2e4eaeQ/agy7MN5QjpRzT3tVAZCZFdoB8aouzDcuyx4ISI62Ts29HX 04vONyMR+/8Ab/KHM7PcPNPIfs+yKb0NScXbemjGMYjcgMuYjFGU6IhniMVSizGTssuVxvTTDAog doWY7lLW0R2Cajd++9v8oczs9w808h+xYB0DO25QjYXQEaIRAzFGWpTcCjG8UBEAPuTykTizptOX W6u8lWLNvVKSHwRie0D80Zwj2DuwTNVPKJAO/wDd+3+UOZ2e4eaeQ/YAC2JTAV3qMmoLqEIixBJ4 LLEPI2QB72JUjKsVlg1aMF9yTkjeaBNpyI3lVk5OKahAxVnB3LMzFGTfFGUmrgs0NMZxi1EdLVhE g2YMyMoV4Jjcfufb/KHM7PcPNPIfrsgMblElSMxU2CJnjgjKQbMaPuUyawFkNKBobr7h7Ut5V2GK EY0CYMBvXZqRgjKZEeorLA5pINLtD5KtSVmlMBAjtHfgmks8Kg3VYlUgW3sVm1a8Fm0DlOINllmP iFUt1qpTxLpj+w9v8oczs9w808h+uBgKocUIYAOVM/wjbrUyawBo6OmawCGlBgDRlnA7WJT5zGO5 fahcLNOTDcF2LJs3bO5MNQl7RdXqblf7p3Z05qVuAREmJlclOB2JXdTnqZSSOyCHdSGnpdkOxoE0 g29GA3XXagZzH8ij2A7WZSgImMo/yCqM8P7x/unAquyFWioVZ+pNIN+n7f5Q5nZ7h5p5D9cn4IEX UP8AIVX2zaVVHRh/JDJTNQlDVNTxQkZnJuRhCjWCOpP4BERIWQScp3ris8u8f6JzTrVK8Vv4rgmH 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 acPwox1I6n45zSzfe7/aMnHBTOr7RKeg+nLQ0WkPty0Q2mXEq8V+T+X+d+Fqka2jrCQykCUtQWoU dDT9qnp6WXSjENIkDROYVJxX5GhL27UiPyNYa5IiaEDK11938r8bU0dN2zSDBz+79v8AKHM7Pzfy fxvw5amjq6hlCYlAOGG+S9BPxaf1r0E/Fp/WvQT8Wn9a9BPxaf1r0E/Fp/WvQT8Wn9a9BPxaf1r0 E/Fp/WvQT8Wn9a9BPxaf1r0E/Fp/WvQT8Wn9a9BPxaf1r0E/Fp/WvQT8Wn9a9BPxaf1r0E/Fp/Wv QT8Wn9a9BPxaf1r0E/Fp/WvQT8Wn9a9BPxaf1r0E/Fp/WvQT8Wn9a9BPxaf1ofkfifiamlrAECYl pkseuRVtb56KtrfPRVtb56KtrfPRVtb56KtrfPRX2PzNHV1tJxLKTpCo6iF6Cfi0/rXoJ+LT+teg n4tP616Cfi0/rXoJ+LT+tegn4tP616Cfi0/rXoJ+LT+tegn4tP616Cfi0/rXoJ+LT+tegn4tP616 Cfi0/rXoJ+LT+tegn4tP616Cfi0/rXoJ+LT+tegn4tP616Cfi0/rXoJ+LT+tegn4tP616Cfi0/rX oJ+LT+tegn4tP616Cfi0/rXoJ+LT+tfhfjfkwOnraWmIzgWLFzu/8Af/2Q==">
+ </image>
+ </g>
+ <use fill="none" overflow="visible" stroke="#FFFFFF" stroke-miterlimit="10" stroke-width="1.5" xlink:href="#a"/>
+ <image transform="matrix(.24 0 0 .24 15.032 15.717)" width="84" height="84" opacity=".75" overflow="visible" xlink:href="data:image/png;base64,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 AAAAAElFTkSuQmCC">
+ </image>
+ <path d="m30.146 28.578l-3.846-3.828 3.827-3.845c0.614-0.618 0.611-1.614-5e-3 -2.229-0.616-0.613-1.615-0.611-2.229 5e-3l-3.828 3.846-3.844-3.825c-0.617-0.614-1.615-0.613-2.229 4e-3 -0.613 0.616-0.612 1.616 5e-3 2.23l3.845 3.825-3.828 3.847c-0.613 0.615-0.61 1.613 6e-3 2.229 0.617 0.613 1.615 0.611 2.229-4e-3l3.828-3.847 3.847 3.827c0.616 0.615 1.615 0.611 2.229-4e-3 0.613-0.618 0.61-1.616-7e-3 -2.231z" fill="#ED1C24"/>
+ <path d="m30.146 28.578l-3.846-3.828 3.827-3.845c0.614-0.618 0.611-1.614-5e-3 -2.229-0.616-0.613-1.615-0.611-2.229 5e-3l-3.828 3.846-3.844-3.825c-0.617-0.614-1.615-0.613-2.229 4e-3 -0.613 0.616-0.612 1.616 5e-3 2.23l3.845 3.825-3.828 3.847c-0.613 0.615-0.61 1.613 6e-3 2.229 0.617 0.613 1.615 0.611 2.229-4e-3l3.828-3.847 3.847 3.827c0.616 0.615 1.615 0.611 2.229-4e-3 0.613-0.618 0.61-1.616-7e-3 -2.231z" fill="none" stroke="#ED1C24" stroke-miterlimit="10"/>
+</svg>
diff --git a/silx/resources/gui/icons/image.png b/silx/resources/gui/icons/image.png
new file mode 100755
index 0000000..484caa0
--- /dev/null
+++ b/silx/resources/gui/icons/image.png
Binary files differ
diff --git a/silx/resources/gui/icons/image.svg b/silx/resources/gui/icons/image.svg
new file mode 100644
index 0000000..5789160
--- /dev/null
+++ b/silx/resources/gui/icons/image.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<path d="m18.462 31.115" stroke="#fff" stroke-miterlimit="10" stroke-width=".51"/>
+<image transform="matrix(.0576 0 0 .0638 2.1826 1.4443)" width="480" height="456" overflow="visible" xlink:href="data:image/jpeg;base64,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 Xedc6u6nXRlzSU/M+m8td/RgZfYX4z2fjDgABKLWLFutYplmvrM6JnOKVnfypo+13DijegRmbSCL NdA1nnGrRFypfS9KVLS7evUbF3FvS2iu1D366S2JoqMlWaL034revybOwj0YqSsqtynBth8YRZGu mSdScNXnLkttvOhCxHnYW6ca8vdqz2y54r1njG9H2wEPRX4z2fjDgAHXos05asJu8w8VZrzmqMoJ oLFd3Ox7I52y2oI87VbVle1lMfK2e5tV3darOTXSqzlVXwmzmvI1cvUZkSanlWV587OF7Mv8oxT2 TpRlbh3FxqraZOX0wnn0K0krBCJw2+T1qmkJHJK4txztPlmvujkYFmtX2PbgJZfjPZ+MOAAS0c2+ 87rKcmy3IdislLfyNVzi5XU2HVpDVrW5WZ29nRpG7n6PK9yNDP61hzay6cvTpaj0rqvVuaMzQoWa LaTY5PbVCdMyeP4RQ+11Oxs1GzS4IuShOFlK5KDI1tnnsVLtfPlKSOK+VSfO2p1npSS+9svjs70/ mNfo+3A5oX4z2fjDgAAAFqxSs35eYviYewi7NSHW843LxKVI6NS/G3aN/LVpWeqKJdT3eWMTfxEt T2sXUq7k2COvFhq0tGXlqlzt7XJ2J3qsdDmara7IzNZUuzUbPs4LbU6+aCZK0+dPhJ8iiUO8exLZ 0bGclvWTeRszUvGev8hp2e2ATevxns/GHAAAAC/T2SUe2mSxokxa9XcZJLNYmxG7FxnOhTde49nA 9JkSpR18jUrWzSvQz6PMvvZ22Gm/Mvw2xhcQrZlh1O+aDLwr9dTbPrHNnOC8/VX3LOWTf7NWZp5u rE2de5TFxkZzOKsQO07POPJjFwZrdflXYuNh2a3fY9uAtF+M9n4w4AABcOXr0ZR8tdiu85F0Iq1h qHztXv599NMHpZOtfSx9ZaaOdpIxVwJRl6C6zszUxa6mN6PKstPspX5dfjaefSJ0EqmTednWho9X YmIvxorPR4rqxyeXKe7ExMymKhaVWpza7StxVxFkrKVZiy1pSRqz9z4L9H2cRMo5be3AOL8Z7Pxh wACW5lbCZnEuJhjPnQIy5yj312zrGwjqXtyYyFcxyG0ptPzNTzbYtfZyNfE3+02bcSi9jvgS1MTZ G/Ttv4yriOSazCzyc/PasKGuOzCMZJm6OdDVm0K/J9xnZs4lDlitWauWXDRfX7NrZVajyrWa2meN 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 B8Ld+RNd0+n9ef8Arn5B8Ld+RNd0+n9ef+ufkHwt35E13T6f15/vNrvUtk+y39PsjjLX5rDmtvu0 tk+03QTBqho+c55YqXd+8QMN2LOOmoI6VZVBpf8AefkHwt35E13T6f15/vO69773/wC1fY3O7Duu 5sP7TRHzxME2iv8A/P3O87c9/vEe+Hb3BJ4x9sYmDyw1aSv/AI7ZgY70dk912N2Q7UJyjpjLpGC3 I757sdwb/epiLRk0TD/rBBjnYI7W8dgjc/8AjzKbbcBI94jICPaEQdQH7z8g+Fu/Imu6fT+vP91t neBO0JR9oBcxftN4lXufeeseVf8Ah956x5V/4feeseVQ3dvuveY7m3IShIEUILg3Ut3d7r3qW5Mm UpEipPjX/h956x5Vux7t3XvEd8wI2pSIYSaj1/d/kHwt35E1Hd793WG/uQjpjKYLiLuy+37XUfKv t+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ft dR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUf Kvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7 ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37X UfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hy r7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyre7r3bu0NrY7wDHe24u0wRpL+L/Xv//Z">
+</image>
+</svg>
diff --git a/silx/resources/gui/icons/item-0dim.png b/silx/resources/gui/icons/item-0dim.png
new file mode 100644
index 0000000..e0f75bf
--- /dev/null
+++ b/silx/resources/gui/icons/item-0dim.png
Binary files differ
diff --git a/silx/resources/gui/icons/item-0dim.svg b/silx/resources/gui/icons/item-0dim.svg
new file mode 100644
index 0000000..9a86c3a
--- /dev/null
+++ b/silx/resources/gui/icons/item-0dim.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <path d="m20.984 16c0 2.7539-2.2305 4.9844-4.9844 4.9844s-4.9844-2.2305-4.9844-4.9844 2.2305-4.9844 4.9844-4.9844 4.9844 2.2305 4.9844 4.9844z" fill="#0034ff"/>
+</svg>
diff --git a/silx/resources/gui/icons/item-1dim.png b/silx/resources/gui/icons/item-1dim.png
new file mode 100644
index 0000000..49622bc
--- /dev/null
+++ b/silx/resources/gui/icons/item-1dim.png
Binary files differ
diff --git a/silx/resources/gui/icons/item-1dim.svg b/silx/resources/gui/icons/item-1dim.svg
new file mode 100644
index 0000000..a422e31
--- /dev/null
+++ b/silx/resources/gui/icons/item-1dim.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <path transform="scale(.66667)" d="m4.7051 29.947c1.4414-1.6055 9.2402-12.574 15.721-7.9395 7.8984 5.6426 11.443 23.842 23.449-0.21094" fill="none" stroke="#0034ff" stroke-linecap="round" stroke-width="5"/>
+</svg>
diff --git a/silx/resources/gui/icons/item-2dim.png b/silx/resources/gui/icons/item-2dim.png
new file mode 100644
index 0000000..6dafb6b
--- /dev/null
+++ b/silx/resources/gui/icons/item-2dim.png
Binary files differ
diff --git a/silx/resources/gui/icons/item-2dim.svg b/silx/resources/gui/icons/item-2dim.svg
new file mode 100644
index 0000000..8e80fd0
--- /dev/null
+++ b/silx/resources/gui/icons/item-2dim.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <path d="m6.5703 6.5703h18.859v18.859h-18.859z" fill="#0034ff"/>
+</svg>
diff --git a/silx/resources/gui/icons/item-3dim.png b/silx/resources/gui/icons/item-3dim.png
new file mode 100644
index 0000000..b9ec4f5
--- /dev/null
+++ b/silx/resources/gui/icons/item-3dim.png
Binary files differ
diff --git a/silx/resources/gui/icons/item-3dim.svg b/silx/resources/gui/icons/item-3dim.svg
new file mode 100644
index 0000000..9c3c23d
--- /dev/null
+++ b/silx/resources/gui/icons/item-3dim.svg
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <g fill-rule="evenodd">
+ <path d="m2.4219 7.9062l13.625 4.543 13.531-4.5117-13.625-4.543z" fill="#00f"/>
+ <path d="m16.047 12.449v16.156l13.531-4.5117v-16.156z" fill="#0063ff"/>
+ <path d="m2.4219 7.9062l13.625 4.543v16.156l-13.625-4.543z" fill="#0034ff"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/item-ndim.png b/silx/resources/gui/icons/item-ndim.png
new file mode 100644
index 0000000..65dd21c
--- /dev/null
+++ b/silx/resources/gui/icons/item-ndim.png
Binary files differ
diff --git a/silx/resources/gui/icons/item-ndim.svg b/silx/resources/gui/icons/item-ndim.svg
new file mode 100644
index 0000000..7de2aed
--- /dev/null
+++ b/silx/resources/gui/icons/item-ndim.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <g fill-rule="evenodd">
+ <path d="m16.031 9.7188l6.8398 2.2812 6.793-2.2656-6.8398-2.2812z" fill="#00f"/>
+ <path d="m22.871 12v8.1094l6.793-2.2656v-8.1094z" fill="#0063ff"/>
+ <path d="m16.031 9.7188l6.8398 2.2812v8.1094l-6.8398-2.2812z" fill="#0034ff"/>
+ <path d="m2.3359 9.7188l6.8398 2.2812 6.793-2.2656-6.8398-2.2812z" fill="#00f"/>
+ <path d="m9.1758 12v8.1094l6.793-2.2656v-8.1094z" fill="#0063ff"/>
+ <path d="m2.3359 9.7188l6.8398 2.2812v8.1094l-6.8398-2.2812z" fill="#0034ff"/>
+ <path d="m9.1406 20.043l6.8398 2.2773 6.793-2.2617-6.8398-2.2812z" fill="#00f"/>
+ <path d="m15.98 22.32v8.1133l6.7891-2.2656v-8.1094z" fill="#0063ff"/>
+ <path d="m9.1406 20.043l6.8398 2.2773v8.1133l-6.8398-2.2812z" fill="#0034ff"/>
+ <path d="m9.1406 11.938l6.8398 2.2773 6.793-2.2617-6.8398-2.2812z" fill="#00f"/>
+ <path d="m15.98 14.215v8.1133l6.7891-2.2656v-8.1094z" fill="#0063ff"/>
+ <path d="m9.1406 11.938l6.8398 2.2773v8.1133l-6.8398-2.2812z" fill="#0034ff"/>
+ <path d="m9.1406 3.832l6.8398 2.2812 6.793-2.2656-6.8398-2.2812z" fill="#00f"/>
+ <path d="m15.98 6.1133v8.1094l6.7891-2.2617v-8.1133z" fill="#0063ff"/>
+ <path d="m9.1406 3.832l6.8398 2.2812v8.1094l-6.8398-2.2812z" fill="#0034ff"/>
+ <path d="m16.031 14.242l6.8398 2.2812 6.793-2.2656-6.8398-2.2773z" fill="#00f"/>
+ <path d="m22.871 16.523v8.1094l6.793-2.2617v-8.1094z" fill="#0063ff"/>
+ <path d="m16.031 14.242l6.8398 2.2812v8.1094l-6.8398-2.2773z" fill="#0034ff"/>
+ <path d="m2.3359 14.242l6.8398 2.2812 6.793-2.2656-6.8398-2.2773z" fill="#00f"/>
+ <path d="m9.1758 16.523v8.1094l6.793-2.2617v-8.1094z" fill="#0063ff"/>
+ <path d="m2.3359 14.242l6.8398 2.2812v8.1094l-6.8398-2.2773z" fill="#0034ff"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/item-object.png b/silx/resources/gui/icons/item-object.png
new file mode 100644
index 0000000..f8e3283
--- /dev/null
+++ b/silx/resources/gui/icons/item-object.png
Binary files differ
diff --git a/silx/resources/gui/icons/item-object.svg b/silx/resources/gui/icons/item-object.svg
new file mode 100644
index 0000000..69d1267
--- /dev/null
+++ b/silx/resources/gui/icons/item-object.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+ <g fill="#0034ff">
+ <path d="m13.617 8.7812l0.67969-4.0391 4.0039 0.039062 0.47656 3.9609z"/>
+ <path d="m9.2266 12.59l-2.375-3.3359 2.8555-2.8008 3.1406 2.4609z"/>
+ <path d="m8.7852 18.41l-4.043-0.67969 0.042968-4 3.957-0.48047z"/>
+ <path d="m12.594 22.801l-3.3398 2.375-2.8008-2.8555 2.4609-3.1406z"/>
+ <path d="m18.383 23.227l-0.67969 4.0391-4-0.039063-0.48047-3.9609z"/>
+ <path d="m22.773 19.418l2.375 3.3359-2.8555 2.8008-3.1406-2.4609z"/>
+ <path d="m23.219 13.598l4.0391 0.67969-0.039062 4-3.9609 0.48047z"/>
+ <path d="m19.41 9.207l3.3359-2.375 2.8008 2.8555-2.4609 3.1406z"/>
+ <path d="m16 7.9609c-4.4375 0-8.0391 3.6016-8.0391 8.0391s3.6016 8.0391 8.0391 8.0391 8.0391-3.6016 8.0391-8.0391-3.6016-8.0391-8.0391-8.0391zm0 5.168c1.5859 0 2.8711 1.2852 2.8711 2.8711s-1.2852 2.8672-2.8711 2.8672-2.8711-1.2812-2.8711-2.8672 1.2852-2.8711 2.8711-2.8711z"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/last.png b/silx/resources/gui/icons/last.png
new file mode 100644
index 0000000..4418006
--- /dev/null
+++ b/silx/resources/gui/icons/last.png
Binary files differ
diff --git a/silx/resources/gui/icons/last.svg b/silx/resources/gui/icons/last.svg
new file mode 100644
index 0000000..598c48d
--- /dev/null
+++ b/silx/resources/gui/icons/last.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="b" x1="11.913" x2="27.737" y1="10.398" y2="16.471" gradientTransform="translate(-.81925)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#002839" offset="0"/>
+ <stop stop-color="#00f" stop-opacity=".2585" offset="1"/>
+ </linearGradient>
+ <linearGradient id="a" x1="11.913" x2="27.737" y1="10.398" y2="16.471" gradientTransform="translate(-.81925)" gradientUnits="userSpaceOnUse">
+ <stop offset="0"/>
+ <stop stop-color="#00f" stop-opacity=".30612" offset="1"/>
+ </linearGradient>
+ </defs>
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g>
+ <path d="m6.2357 4.9951c6.6141 3.9114 12.473 7.571 18.396 11.252l-18.307 10.806z" fill="url(#b)" stroke="url(#a)" stroke-linejoin="round" stroke-width=".4"/>
+ <path d="m25.151 6.2992v9.9456 9.9456" fill="none" stroke="#00006a"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/math-average.png b/silx/resources/gui/icons/math-average.png
new file mode 100755
index 0000000..675cd62
--- /dev/null
+++ b/silx/resources/gui/icons/math-average.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-average.svg b/silx/resources/gui/icons/math-average.svg
new file mode 100644
index 0000000..418f1eb
--- /dev/null
+++ b/silx/resources/gui/icons/math-average.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<g fill="#643814" stroke="#000" stroke-miterlimit="10" stroke-width="2.3">
+ <line x1="8.767" x2="17.544" y1="11.924" y2="20.866"/>
+ <line x1="25.387" x2="8.613" y1="12.079" y2="28.547"/>
+</g>
+<line x1="7.333" x2="26.423" y1="8.667" y2="8.667" fill="none" stroke="#F7941E" stroke-miterlimit="10" stroke-width="2.2"/>
+</svg>
diff --git a/silx/resources/gui/icons/math-derive.png b/silx/resources/gui/icons/math-derive.png
new file mode 100755
index 0000000..2a31042
--- /dev/null
+++ b/silx/resources/gui/icons/math-derive.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-derive.svg b/silx/resources/gui/icons/math-derive.svg
new file mode 100644
index 0000000..65d41a3
--- /dev/null
+++ b/silx/resources/gui/icons/math-derive.svg
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+ <path d="m9.085 25.873" fill="none" stroke="#00A14B" stroke-miterlimit="10" stroke-width="1.5"/>
+ <path d="m6.655 25.043v-10.306h-1.189v-2.4h1.188v-0.548c0-1.644 0.306-3.288 1.063-4.332 0.648-0.887 1.53-1.226 2.287-1.226 0.594 0 1.062 0.13 1.422 0.313l-0.162 2.479c-0.234-0.13-0.54-0.235-0.937-0.235-1.098 0-1.476 1.331-1.476 2.896v0.652h1.926v2.4h-1.907v10.306h-2.215z"/>
+ <path d="m15.385 7.17c-0.486 2.375-1.261 5.062-1.945 6.68l-1.35 0.183c0.468-1.905 0.937-4.514 1.153-6.627l2.142-0.236z"/>
+ <path d="m18.32 12.025c-0.627 1.467-1.111 3.604-1.111 6.457 0 2.807 0.496 4.928 1.111 6.41h-1.166c-0.594-1.227-1.254-3.348-1.254-6.426 0.011-3.093 0.66-5.198 1.254-6.441h1.166z"/>
+ <path d="m20.686 15.246l0.527 1.292c0.154 0.399 0.297 0.797 0.439 1.164h0.023c0.143-0.414 0.275-0.813 0.418-1.195l0.473-1.26h1.814l-1.77 3.715 1.793 4.082h-1.893l-0.539-1.402c-0.154-0.383-0.287-0.781-0.418-1.18h-0.033c-0.133 0.414-0.275 0.797-0.408 1.18l-0.506 1.402h-1.836l1.826-3.97-1.783-3.827h1.873z"/>
+ <path d="m24.875 24.893c0.605-1.467 1.111-3.619 1.111-6.441s-0.494-4.943-1.111-6.426h1.166c0.584 1.228 1.256 3.316 1.256 6.426-0.012 3.109-0.672 5.198-1.256 6.441h-1.166z"/>
+</svg>
diff --git a/silx/resources/gui/icons/math-energy.png b/silx/resources/gui/icons/math-energy.png
new file mode 100755
index 0000000..341f483
--- /dev/null
+++ b/silx/resources/gui/icons/math-energy.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-energy.svg b/silx/resources/gui/icons/math-energy.svg
new file mode 100644
index 0000000..58b2aec
--- /dev/null
+++ b/silx/resources/gui/icons/math-energy.svg
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<linearGradient id="a" x1="6.3496" x2="28.184" y1="16.621" y2="16.621" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#fff" offset="0"/>
+ <stop stop-color="#FDFDFD" stop-opacity=".971" offset=".2903"/>
+ <stop stop-color="#F5F5F5" stop-opacity=".957" offset=".4299"/>
+ <stop stop-color="#E8E8E8" stop-opacity=".9463" offset=".5375"/>
+ <stop stop-color="#D6D6D6" stop-opacity=".9371" offset=".6286"/>
+ <stop stop-color="#BEBEBE" stop-opacity=".9291" offset=".7093"/>
+ <stop stop-color="#A0A0A0" stop-opacity=".9217" offset=".7826"/>
+ <stop stop-color="#7D7D7D" stop-opacity=".915" offset=".8505"/>
+ <stop stop-color="#545454" stop-opacity=".9086" offset=".9139"/>
+ <stop stop-color="#272727" stop-opacity=".9028" offset=".9717"/>
+ <stop stop-color="#0E0E0E" stop-opacity=".9" offset="1"/>
+</linearGradient>
+<rect x="6.85" y="6.205" width="20.834" height="20.833" fill="none" stroke="url(#a)" stroke-miterlimit="10"/>
+<line x1="20.104" x2="5.141" y1="6.204" y2="6.204" fill="none" stroke="#F7941E" stroke-miterlimit="10" stroke-width="2.8"/>
+<line x1="6.872" x2="6.872" y1="6.204" y2="27.037" fill="none" stroke="#F7941E" stroke-miterlimit="10" stroke-width="2.8"/>
+<line x1="5.141" x2="20.104" y1="27.037" y2="27.037" fill="none" stroke="#F7941E" stroke-miterlimit="10" stroke-width="2.8"/>
+<line x1="7.712" x2="15.85" y1="16.246" y2="16.246" fill="none" stroke="#F7941E" stroke-miterlimit="10" stroke-width="2.8"/>
+</svg>
diff --git a/silx/resources/gui/icons/math-fit.png b/silx/resources/gui/icons/math-fit.png
new file mode 100755
index 0000000..c4fcd30
--- /dev/null
+++ b/silx/resources/gui/icons/math-fit.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-fit.svg b/silx/resources/gui/icons/math-fit.svg
new file mode 100644
index 0000000..f307b17
--- /dev/null
+++ b/silx/resources/gui/icons/math-fit.svg
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata16"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs14" /><path
+ d="m 5.389,25.291 c 1.58,-0.508 1.812,-2.553 2.157,-3.945 0.386,-1.556 1.273,-1.214 2.263,-2.038 0.688,-0.573 0.899,-1.425 0.95,-2.313 0.042,-0.741 -0.152,-3.181 0.782,-3.454 0.318,-0.092 0.664,-0.102 0.965,-0.255 0.843,-0.43 1.344,-1.121 1.679,-2.019 0.255,-0.686 0.463,-1.369 0.655,-2.074 0.03,-0.11 1.031,-3.262 1.374,-2.735 1.012,1.557 1.44,3.84 1.949,5.601 0.467,1.616 0.819,3.259 1.312,4.869 0.223,0.728 0.394,1.828 1.124,2.255 1.383,0.811 1.77,-1.7 1.924,-2.377 0.246,-1.075 0.345,-1.811 0.732,-0.343 0.3,1.136 0.448,2.319 0.637,3.477 0.226,1.388 0.626,3.463 1.515,4.559 0.089,0.11 0.305,0.171 0.438,0.116 0.787,-0.324 0.642,-2.325 1.354,-0.873 0.313,0.641 0.516,1.625 1.247,1.912 0.54,0.213 0.772,-0.658 0.238,-0.867 -0.869,-0.342 -0.671,-3.279 -2.23,-2.851 -0.671,0.185 -0.841,1.305 -0.97,1.82 0.32,-1.277 -0.408,-2.326 -0.656,-3.659 -0.226,-1.215 -0.218,-5.231 -1.676,-5.757 -0.453,-0.164 -0.721,0.077 -0.967,0.44 -0.239,0.353 -0.314,0.894 -0.416,1.295 -0.056,0.224 -0.622,3.16 -1.157,1.405 -1.157,-3.8 -1.675,-8.486 -3.87,-11.864 -1.414,-2.176 -2.873,3.723 -2.96,4.045 -0.374,1.378 -0.894,2.683 -2.477,3.011 -0.307,0.063 -0.67,0.193 -0.897,0.421 -1.402,1.402 0.693,4.751 -1.486,5.647 -0.974,0.4 -1.453,0.299 -1.934,1.379 -0.503,1.128 -0.444,3.855 -1.834,4.303 -0.554,0.179 -0.319,1.048 0.235,0.869 z"
+ inkscape:connector-curvature="0"
+ id="path4"
+ style="fill:#ed1c24" /><path
+ d="m 8.904,16.8 h 4.941 v 1.5 h -3.106 v 1.847 h 2.903 v 1.487 h -2.903 v 3.25 H 8.904 V 16.8 z"
+ inkscape:connector-curvature="0"
+ id="path6" /><path
+ d="m 17.063,16.8 v 8.083 H 15.228 V 16.8 h 1.835 z"
+ inkscape:connector-curvature="0"
+ id="path8" /><path
+ d="M 20.207,18.336 H 18.036 V 16.8 h 6.213 v 1.536 h -2.207 v 6.548 h -1.835 v -6.548 z"
+ inkscape:connector-curvature="0"
+ id="path10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/math-normalize.png b/silx/resources/gui/icons/math-normalize.png
new file mode 100755
index 0000000..14db904
--- /dev/null
+++ b/silx/resources/gui/icons/math-normalize.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-normalize.svg b/silx/resources/gui/icons/math-normalize.svg
new file mode 100644
index 0000000..c878a70
--- /dev/null
+++ b/silx/resources/gui/icons/math-normalize.svg
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata20"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs18" /><line
+ x1="8.1370001"
+ x2="25.667999"
+ y1="16.749001"
+ y2="16.749001"
+ fill="#F7941E"
+ stroke="#F7941E"
+ stroke-miterlimit="10"
+ stroke-width="2"
+ id="line4"
+ style="fill:#f7941e;stroke:#f7941e;stroke-width:2;stroke-miterlimit:10" /><path
+ d="M 12.09,29.497 V 19.84 h 2.565 l 3.188,4.141 c 0.825,1.075 1.54,2.192 2.107,3.238 h 0.037 C 19.841,25.93 19.785,24.683 19.785,23.207 V 19.84 h 2.09 v 9.657 H 19.547 L 16.322,25.256 C 15.534,24.195 14.71,23.007 14.105,21.918 l -0.055,0.014 c 0.091,1.247 0.11,2.522 0.11,4.112 v 3.453 h -2.07 z"
+ inkscape:connector-curvature="0"
+ id="path6" /><path
+ d="m 16.552,7.344 c -0.432,0.783 -0.762,1.87 -0.762,3.354 0,1.458 0.337,2.538 0.762,3.329 h -0.607 c -0.385,-0.659 -0.816,-1.73 -0.816,-3.329 0.007,-1.607 0.432,-2.687 0.816,-3.354 h 0.607 z"
+ inkscape:connector-curvature="0"
+ id="path8" /><path
+ d="m 19.319,7.916 0.587,1.137 c 0.162,0.321 0.304,0.618 0.445,0.927 h 0.03 c 0.142,-0.333 0.283,-0.643 0.425,-0.952 l 0.546,-1.112 h 1.356 l -1.649,2.892 1.68,3.127 h -1.406 l -0.607,-1.199 c -0.162,-0.321 -0.304,-0.643 -0.445,-0.977 h -0.02 c -0.142,0.346 -0.283,0.643 -0.445,0.977 l -0.566,1.199 h -1.376 l 1.71,-3.065 -1.649,-2.954 h 1.384 z"
+ inkscape:connector-curvature="0"
+ id="path10" /><path
+ d="m 24.166,14.026 c 0.425,-0.783 0.756,-1.878 0.756,-3.345 0,-1.467 -0.331,-2.546 -0.756,-3.337 h 0.601 c 0.392,0.659 0.823,1.73 0.823,3.345 -0.007,1.607 -0.432,2.669 -0.823,3.337 h -0.601 z"
+ inkscape:connector-curvature="0"
+ id="path12" /><polygon
+ points="9.052,4.063 9.052,12.68 8.367,12.68 8.367,14.091 11.862,14.091 11.862,12.68 11.18,12.68 11.18,4.063 11.862,4.063 11.862,2.651 8.367,2.651 8.367,4.063 "
+ id="polygon14" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/math-peak-reset.png b/silx/resources/gui/icons/math-peak-reset.png
new file mode 100755
index 0000000..ec0932b
--- /dev/null
+++ b/silx/resources/gui/icons/math-peak-reset.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-peak-reset.svg b/silx/resources/gui/icons/math-peak-reset.svg
new file mode 100644
index 0000000..e35c13b
--- /dev/null
+++ b/silx/resources/gui/icons/math-peak-reset.svg
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3119"
+ xml:space="preserve"><metadata
+ id="metadata3143"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3141"><filter
+ x="-0.13669565"
+ y="-0.15212902"
+ width="1.2733912"
+ height="1.3042581"
+ color-interpolation-filters="sRGB"
+ id="filter6093"><feGaussianBlur
+ id="feGaussianBlur6095"
+ stdDeviation="0.85968749" /></filter></defs><path
+ d="m 5.389,25.291 c 1.58,-0.508 1.812,-2.553 2.157,-3.945 0.386,-1.556 1.273,-1.214 2.263,-2.038 0.688,-0.573 0.899,-1.425 0.95,-2.313 0.042,-0.741 -0.152,-3.181 0.782,-3.454 0.318,-0.092 0.664,-0.102 0.965,-0.255 0.843,-0.43 1.344,-1.121 1.679,-2.019 0.255,-0.686 0.463,-1.369 0.655,-2.074 0.03,-0.11 1.031,-3.262 1.374,-2.735 1.012,1.557 1.44,3.84 1.949,5.601 0.467,1.616 0.819,3.259 1.312,4.869 0.223,0.728 0.394,1.828 1.124,2.255 1.383,0.811 1.77,-1.7 1.924,-2.377 0.246,-1.075 0.345,-1.811 0.732,-0.343 0.3,1.136 0.448,2.319 0.637,3.477 0.226,1.388 0.626,3.463 1.515,4.559 0.089,0.11 0.305,0.171 0.438,0.116 0.787,-0.324 0.642,-2.325 1.354,-0.873 0.313,0.641 0.516,1.625 1.247,1.912 0.54,0.213 0.772,-0.658 0.238,-0.867 -0.869,-0.342 -0.671,-3.279 -2.23,-2.851 -0.671,0.185 -0.841,1.305 -0.97,1.82 0.32,-1.277 -0.408,-2.326 -0.656,-3.659 -0.226,-1.215 -0.218,-5.231 -1.676,-5.757 -0.453,-0.164 -0.721,0.077 -0.967,0.44 -0.239,0.353 -0.314,0.894 -0.416,1.295 -0.056,0.224 -0.622,3.16 -1.157,1.405 -1.157,-3.8 -1.675,-8.486 -3.87,-11.864 -1.414,-2.176 -2.873,3.723 -2.96,4.045 -0.374,1.378 -0.894,2.683 -2.477,3.011 -0.307,0.063 -0.67,0.193 -0.897,0.421 -1.402,1.402 0.693,4.751 -1.486,5.647 -0.974,0.4 -1.453,0.299 -1.934,1.379 -0.503,1.128 -0.444,3.855 -1.834,4.303 -0.554,0.179 -0.319,1.048 0.235,0.869 z"
+ id="path3121" /><g
+ id="g3123"
+ style="fill:#00a651;stroke:#00a651;stroke-width:1.10000002;stroke-miterlimit:10"><line
+ x1="16.027"
+ x2="16.016001"
+ y1="23.438"
+ y2="10.753"
+ id="line3125" /><polygon
+ points="13.807,23.451 18.248,23.438 16.045,27.269 "
+ id="polygon3127" /><polygon
+ points="18.236,10.247 13.795,10.228 16.022,6.413 "
+ id="polygon3129" /></g><path
+ d="m 9.7696852,14.337521 -1.28125,1.40625 5.9999998,5.34375 -6.1249998,5.28125 1.25,1.4375 6.2812498,-5.4375 6.1875,5.53125 1.25,-1.40625 -5.96875,-5.375 6.09375,-5.25 -1.25,-1.4375 -6.28125,5.40625 -6.1562498,-5.5 z"
+ id="line3135-6"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.89999998;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter6093);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><g
+ id="g3133"
+ style="fill:none;stroke:#ed1c24;stroke-width:1.89999998;stroke-miterlimit:10"><line
+ x1="9.2329998"
+ x2="22.822001"
+ y1="14.099"
+ y2="26.26"
+ id="line3135" /><line
+ x1="22.948999"
+ x2="9.1049995"
+ y1="14.211"
+ y2="26.146999"
+ id="line3137" /></g></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/math-peak-search.png b/silx/resources/gui/icons/math-peak-search.png
new file mode 100755
index 0000000..28db259
--- /dev/null
+++ b/silx/resources/gui/icons/math-peak-search.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-peak-search.svg b/silx/resources/gui/icons/math-peak-search.svg
new file mode 100644
index 0000000..47164ac
--- /dev/null
+++ b/silx/resources/gui/icons/math-peak-search.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3093"
+ xml:space="preserve"><metadata
+ id="metadata3117"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3115"><filter
+ color-interpolation-filters="sRGB"
+ id="filter5562"><feGaussianBlur
+ id="feGaussianBlur5564"
+ stdDeviation="1.2128746" /></filter></defs><path
+ d="m 4.356,26.781 c 0.66,-0.935 1.841,-0.809 2.729,-1.399 0.703,-0.467 0.856,-1.623 0.992,-2.349 0.218,-1.165 -0.362,-4.839 1.218,-5.27 1.004,-0.274 1.677,-0.422 2.422,-1.176 1.721,-1.742 1.883,-4.988 2.669,-7.182 0.504,-1.407 1.142,-1.524 1.711,-0.079 0.35,0.886 0.697,1.771 1.017,2.668 0.689,1.934 1.256,3.931 1.737,5.926 0.45,1.865 0.957,3.707 1.576,5.523 0.279,0.821 0.38,1.479 1.177,1.893 1.154,0.598 1.675,-0.925 1.896,-1.673 0.278,-0.937 0.439,-1.908 0.69,-2.854 0.455,-1.711 0.864,0.714 1.019,1.371 0.442,1.884 0.466,3.932 1.071,5.769 0.181,0.549 1.05,0.314 0.867,-0.238 -0.398,-1.209 -0.782,-9.396 -2.967,-8.609 -1.242,0.448 -1.363,3.699 -1.672,4.738 -0.364,1.226 -1.034,-0.032 -1.215,-0.635 -0.366,-1.225 -0.775,-2.429 -1.108,-3.664 -0.629,-2.33 -1.193,-4.659 -1.927,-6.96 -0.276,-0.867 -1.45,-6 -3.046,-5.583 -2.015,0.528 -2.388,4.501 -2.846,6.112 -0.615,2.163 -1.571,3.309 -3.726,3.896 -0.864,0.236 -1.143,0.979 -1.28,1.771 -0.3,1.735 0.738,5.357 -1.488,6.215 -1.107,0.426 -1.578,0.317 -2.295,1.332 -0.334,0.478 0.447,0.927 0.779,0.457 z"
+ id="path3095" /><g
+ transform="translate(1.6271186,0.13559322)"
+ id="g6629"
+ style="filter:url(#filter5562)"><path
+ d="m 2.1425431,16.187422 c -0.417,0.236 -1.12,0.115 -1.55699999,-0.271 -0.442,-0.39 -0.455,-0.906 -0.039,-1.147 l 7.32999999,-4.184 c 0.422,-0.242 1.121,-0.119 1.56,0.27 0.44,0.392 0.457,0.901 0.035,1.146 l -7.329,4.186 z"
+ id="path3101-3"
+ style="fill:#000000;stroke:#00a651;stroke-width:0.1;stroke-miterlimit:10" /><path
+ d="m 14.176377,2.8135593 c -1.840801,-0.221807 -3.710615,0.0891 -5.2499999,0.96875 -1.53907,0.881724 -2.455231,2.258419 -2.5625,3.75 -0.107269,1.4915809 0.571478,3.0356967 1.9375,4.2499997 2.7388449,2.425517 7.2029939,2.980654 10.2812499,1.21875 1.539106,-0.879247 2.454634,-2.258711 2.5625,-3.7499997 0.107866,-1.4912883 -0.5729,-3.035478 -1.9375,-4.25 -1.3708,-1.214169 -3.190449,-1.965693 -5.03125,-2.1875 z m -0.15625,1.5625 c 1.561699,0.187693 3.0903,0.778169 4.1875,1.75 1.0904,0.9704781 1.507134,2.0372883 1.4375,3 -0.06963,0.9627117 -0.622606,1.8827477 -1.8125,2.5624997 -2.379744,1.362096 -6.340095,0.909234 -8.5312499,-1.03125 -1.091978,-0.9706963 -1.506731,-2.0685806 -1.4375,-3.0312497 0.06923,-0.962669 0.62157,-1.848974 1.8125,-2.53125 1.1906149,-0.680351 2.7820509,-0.906443 4.3437499,-0.71875 z"
+ id="path3103-6"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+ d="m 30.571543,31.718422 c 0.247,0.361 0.019,0.865 -0.506,1.109 -0.531,0.246 -1.174,0.141 -1.42,-0.221 l -4.346,-6.416 c -0.255,-0.369 -0.025,-0.869 0.502,-1.111 0.533,-0.244 1.163,-0.146 1.422,0.227 l 4.348,6.412 z"
+ id="path3109-6"
+ style="fill:#000000;stroke:#00a651;stroke-width:0.1;stroke-miterlimit:10" /><path
+ d="m 21.551377,15.594809 c -0.874914,0.08975 -1.739271,0.308145 -2.5625,0.6875 -1.644381,0.761544 -2.826791,2.026822 -3.34375,3.46875 -0.516959,1.441929 -0.342017,3.054671 0.59375,4.4375 l 0,0.03125 c 1.880796,2.76166 5.959716,3.614814 9.25,2.09375 1.646103,-0.760464 2.826654,-2.026732 3.34375,-3.46875 0.517096,-1.442017 0.345253,-3.056476 -0.59375,-4.4375 -1.404856,-2.074744 -4.062758,-3.08175 -6.6875,-2.8125 z m 0.15625,1.5 c 2.128008,-0.198468 4.257606,0.644495 5.28125,2.15625 0.683997,1.005977 0.772904,2.071268 0.40625,3.09375 -0.366654,1.022483 -1.205353,1.981214 -2.53125,2.59375 -2.649716,1.224937 -6.001796,0.45384 -7.375,-1.5625 -0.682233,-1.00817 -0.804291,-2.101928 -0.4375,-3.125 0.366791,-1.023071 1.237881,-1.980293 2.5625,-2.59375 0.663271,-0.305644 1.384414,-0.496344 2.09375,-0.5625 z"
+ id="path3111-2"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /></g><g
+ id="g3099"
+ style="stroke:#00a651;stroke-miterlimit:10"><path
+ d="M 3.222,15.385 C 2.805,15.621 2.102,15.5 1.665,15.114 1.223,14.724 1.21,14.208 1.626,13.967 l 7.33,-4.184 c 0.422,-0.242 1.121,-0.119 1.56,0.27 0.44,0.392 0.457,0.901 0.035,1.146 l -7.329,4.186 z"
+ id="path3101"
+ style="fill:#00a651;stroke-width:0.1" /><path
+ d="M 19.291,11.538 C 16.562,13.1 12.355,12.592 9.89,10.409 7.432,8.224 7.649,5.19 10.379,3.626 c 2.73,-1.56 6.936,-1.054 9.404,1.132 2.455,2.185 2.237,5.221 -0.492,6.78 z"
+ id="path3103"
+ style="fill:none;stroke-width:1.5" /></g><g
+ id="g3107"
+ style="stroke:#00a651;stroke-miterlimit:10"><path
+ d="m 31.651,30.916 c 0.247,0.361 0.019,0.865 -0.506,1.109 -0.531,0.246 -1.174,0.141 -1.42,-0.221 l -4.346,-6.416 c -0.255,-0.369 -0.025,-0.869 0.502,-1.111 0.533,-0.244 1.163,-0.146 1.422,0.227 l 4.348,6.412 z"
+ id="path3109"
+ style="fill:#00a651;stroke-width:0.1" /><path
+ d="m 28.693,18.014 c 1.623,2.387 0.53,5.436 -2.442,6.809 -2.97,1.373 -6.686,0.547 -8.313,-1.842 -1.618,-2.391 -0.526,-5.438 2.443,-6.813 2.973,-1.37 6.693,-0.545 8.312,1.846 z"
+ id="path3111"
+ style="fill:none;stroke-width:1.5" /></g></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/math-peak.png b/silx/resources/gui/icons/math-peak.png
new file mode 100755
index 0000000..604776d
--- /dev/null
+++ b/silx/resources/gui/icons/math-peak.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-peak.svg b/silx/resources/gui/icons/math-peak.svg
new file mode 100644
index 0000000..eb78383
--- /dev/null
+++ b/silx/resources/gui/icons/math-peak.svg
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata16"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs14" /><path
+ d="m 5.389,25.291 c 1.58,-0.508 1.812,-2.553 2.157,-3.945 0.386,-1.556 1.273,-1.214 2.263,-2.038 0.688,-0.573 0.899,-1.425 0.95,-2.313 0.042,-0.741 -0.152,-3.181 0.782,-3.454 0.318,-0.092 0.664,-0.102 0.965,-0.255 0.843,-0.43 1.344,-1.121 1.679,-2.019 0.255,-0.686 0.463,-1.369 0.655,-2.074 0.03,-0.11 1.031,-3.262 1.374,-2.735 1.012,1.557 1.44,3.84 1.949,5.601 0.467,1.616 0.819,3.259 1.312,4.869 0.223,0.728 0.394,1.828 1.124,2.255 1.383,0.811 1.77,-1.7 1.924,-2.377 0.246,-1.075 0.345,-1.811 0.732,-0.343 0.3,1.136 0.448,2.319 0.637,3.477 0.226,1.388 0.626,3.463 1.515,4.559 0.089,0.11 0.305,0.171 0.438,0.116 0.787,-0.324 0.642,-2.325 1.354,-0.873 0.313,0.641 0.516,1.625 1.247,1.912 0.54,0.213 0.772,-0.658 0.238,-0.867 -0.869,-0.342 -0.671,-3.279 -2.23,-2.851 -0.671,0.185 -0.841,1.305 -0.97,1.82 0.32,-1.277 -0.408,-2.326 -0.656,-3.659 -0.226,-1.215 -0.218,-5.231 -1.676,-5.757 -0.453,-0.164 -0.721,0.077 -0.967,0.44 -0.239,0.353 -0.314,0.894 -0.416,1.295 -0.056,0.224 -0.622,3.16 -1.157,1.405 -1.157,-3.8 -1.675,-8.486 -3.87,-11.864 -1.414,-2.176 -2.873,3.723 -2.96,4.045 -0.374,1.378 -0.894,2.683 -2.477,3.011 -0.307,0.063 -0.67,0.193 -0.897,0.421 -1.402,1.402 0.693,4.751 -1.486,5.647 -0.974,0.4 -1.453,0.299 -1.934,1.379 -0.503,1.128 -0.444,3.855 -1.834,4.303 -0.554,0.179 -0.319,1.048 0.235,0.869 z"
+ inkscape:connector-curvature="0"
+ id="path4" /><line
+ x1="16.027"
+ x2="16.016001"
+ y1="21.652"
+ y2="10.477"
+ fill="none"
+ stroke="#00A651"
+ stroke-miterlimit="10"
+ stroke-width="1.5"
+ id="line6"
+ style="fill:none;stroke:#00a651;stroke-width:1.5;stroke-miterlimit:10" /><polygon
+ points="13.807,21.666 18.248,21.652 16.045,25.029 "
+ id="polygon8"
+ style="fill:#009444;stroke:#00a651;stroke-width:1.5;stroke-miterlimit:10" /><polygon
+ points="18.236,10.031 13.795,10.014 16.022,6.652 "
+ id="polygon10"
+ style="fill:#00a651;stroke:#00a651;stroke-width:1.5;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/math-sigma.png b/silx/resources/gui/icons/math-sigma.png
new file mode 100755
index 0000000..ecbd054
--- /dev/null
+++ b/silx/resources/gui/icons/math-sigma.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-sigma.svg b/silx/resources/gui/icons/math-sigma.svg
new file mode 100644
index 0000000..9b7e022
--- /dev/null
+++ b/silx/resources/gui/icons/math-sigma.svg
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata39"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs37" /><linearGradient
+ x1="7"
+ y1="16.334"
+ x2="26.5"
+ y2="16.334"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop5"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" /><stop
+ id="stop7"
+ style="stop-color:#fdfdfd;stop-opacity:0.9623"
+ offset="0.37689999" /><stop
+ id="stop9"
+ style="stop-color:#f6f6f6;stop-opacity:0.94870001"
+ offset="0.51270002" /><stop
+ id="stop11"
+ style="stop-color:#ebebeb;stop-opacity:0.93910003"
+ offset="0.60939997" /><stop
+ id="stop13"
+ style="stop-color:#dadada;stop-opacity:0.93120003"
+ offset="0.68769997" /><stop
+ id="stop15"
+ style="stop-color:#c4c4c4;stop-opacity:0.92449999"
+ offset="0.75480002" /><stop
+ id="stop17"
+ style="stop-color:#a8a8a8;stop-opacity:0.91860002"
+ offset="0.81419998" /><stop
+ id="stop19"
+ style="stop-color:#888888;stop-opacity:0.91320002"
+ offset="0.86790001" /><stop
+ id="stop21"
+ style="stop-color:#626262;stop-opacity:0.90829998"
+ offset="0.91720003" /><stop
+ id="stop23"
+ style="stop-color:#393939;stop-opacity:0.90390003"
+ offset="0.9612" /><stop
+ id="stop25"
+ style="stop-color:#0e0e0e;stop-opacity:0.89999998"
+ offset="1" /></linearGradient><rect
+ width="18.5"
+ height="18.499001"
+ x="7.5"
+ y="7.0840001"
+ id="rect27"
+ style="fill:none;stroke:url(#a);stroke-miterlimit:10" /><line
+ x1="19.367001"
+ x2="6.0799999"
+ y1="7.0840001"
+ y2="7.0840001"
+ fill="none"
+ stroke="#F7941E"
+ stroke-miterlimit="10"
+ stroke-width="2.8"
+ id="line29"
+ style="fill:none;stroke:#f7941e;stroke-width:2.79999995;stroke-miterlimit:10" /><polyline
+ points="7.3 7.418 14.349 14.71 7.3 25.159"
+ fill="none"
+ stroke="#F7941E"
+ stroke-miterlimit="10"
+ stroke-width="2.8"
+ id="polyline31"
+ style="fill:none;stroke:#f7941e;stroke-width:2.79999995;stroke-miterlimit:10" /><line
+ x1="6.1859999"
+ x2="19.473"
+ y1="25.583"
+ y2="25.583"
+ fill="none"
+ stroke="#F7941E"
+ stroke-miterlimit="10"
+ stroke-width="2.8"
+ id="line33"
+ style="fill:none;stroke:#f7941e;stroke-width:2.79999995;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/math-smooth.png b/silx/resources/gui/icons/math-smooth.png
new file mode 100755
index 0000000..06eda41
--- /dev/null
+++ b/silx/resources/gui/icons/math-smooth.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-smooth.svg b/silx/resources/gui/icons/math-smooth.svg
new file mode 100644
index 0000000..388bb63
--- /dev/null
+++ b/silx/resources/gui/icons/math-smooth.svg
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata12"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs10" /><path
+ d="m 4.418,32.184 c 0.2,-1.021 0.117,-1.992 0.491,-2.975 0.402,-1.06 0.737,-2.134 1.026,-3.229 -0.278,0.073 -0.557,0.147 -0.835,0.22 0.596,0.553 1.127,1.153 1.709,1.721 0.282,0.274 0.714,0.132 0.835,-0.221 0.512,-1.481 0.99,-2.95 1.544,-4.419 -0.304,0.04 -0.609,0.08 -0.914,0.119 0.563,0.816 0.943,1.702 1.556,2.484 0.304,0.388 0.811,0.018 0.854,-0.354 0.467,-4.027 2.292,-7.606 2.975,-11.567 h -0.964 c 0.947,2.809 2.17,5.516 3.31,8.252 0.162,0.391 0.884,0.555 0.964,0 0.525,-3.624 1.333,-7.173 1.74,-10.826 0.334,-2.994 0.411,-6.013 0.8,-9.002 -0.311,0.084 -0.621,0.168 -0.932,0.252 0.628,1.238 0.684,2.911 0.908,4.259 0.312,1.862 0.695,3.725 1.131,5.56 0.126,0.528 0.795,0.422 0.965,0 1.127,-2.805 1.088,-5.958 1.494,-8.904 h -0.964 c 1.152,6.973 0.797,14.117 1.969,21.087 0.083,0.489 0.866,0.469 0.965,0 0.64,-3.043 1.899,-6.224 1.979,-9.339 -0.327,0.044 -0.654,0.088 -0.982,0.133 0.449,3.083 0.943,6.189 1.532,9.249 0.304,1.582 0.607,3.018 0.567,4.64 -0.024,0.99 0.01,1.907 0.276,2.858 0.174,0.62 1.139,0.356 0.965,-0.266 -0.379,-1.349 -0.22,-2.722 -0.225,-4.102 -0.004,-1.153 -0.379,-2.28 -0.62,-3.396 -0.655,-3.034 -1.084,-6.178 -1.531,-9.249 -0.084,-0.577 -0.969,-0.409 -0.982,0.133 -0.077,3.006 -1.326,6.135 -1.944,9.074 h 0.965 c -1.173,-6.969 -0.816,-14.114 -1.97,-21.087 -0.078,-0.474 -0.897,-0.485 -0.964,0 -0.405,2.938 -0.374,6.116 -1.495,8.904 h 0.965 C 21.098,10.16 20.695,8.099 20.351,6.038 20.138,4.76 20.036,3.307 19.441,2.135 19.19,1.64 18.567,1.947 18.509,2.387 c -0.361,2.781 -0.481,5.589 -0.737,8.38 -0.346,3.774 -1.225,7.443 -1.766,11.182 h 0.964 c -1.131,-2.719 -2.371,-5.469 -3.31,-8.252 -0.144,-0.428 -0.874,-0.524 -0.964,0 -0.698,4.047 -2.533,7.719 -3.011,11.833 0.285,-0.118 0.569,-0.235 0.854,-0.354 C 9.986,24.47 9.647,23.63 9.139,22.895 8.883,22.523 8.381,22.6 8.225,23.014 7.669,24.486 7.194,25.948 6.681,27.433 6.959,27.36 7.238,27.286 7.516,27.212 6.934,26.645 6.403,26.044 5.807,25.491 5.536,25.24 5.071,25.337 4.972,25.712 c -0.29,1.098 -0.639,2.162 -1.027,3.229 -0.403,1.107 -0.268,1.837 -0.49,2.976 -0.124,0.631 0.839,0.899 0.963,0.267 z"
+ inkscape:connector-curvature="0"
+ id="path4" /><path
+ d="m 4.684,31.103 c 2.359,-0.676 3.119,-2.497 3.404,-4.851 0.184,-1.516 -0.359,-5.724 1.418,-6.241 1.085,-0.316 2.144,-0.343 3.2,-0.805 2.411,-1.056 3.432,-4.736 4.18,-6.97 0.803,-2.399 1.699,-4.674 2.307,-7.13 C 19.31,4.633 19.447,4.167 19.591,3.701 19.683,3.396 19.806,3.104 19.96,2.825 19.446,2.46 19.317,2.491 19.574,2.918 c 0.383,1.057 0.544,2.221 0.758,3.32 0.531,2.725 1.413,5.188 2.235,7.844 1.28,4.137 2.059,8.395 3.272,12.548 0.6,2.052 0.949,5.032 3.668,4.78 1.146,-0.106 1.156,-1.907 0,-1.801 C 27.376,29.807 25.951,19.581 25.518,17.927 24.663,14.668 23.287,11.498 22.552,8.226 22.369,7.411 21.064,-1.957 18.573,1.67 c -1.098,1.599 -1.262,3.777 -1.785,5.604 -0.834,2.914 -1.991,6.316 -3.551,8.903 -1.502,2.491 -4.539,1.265 -6.162,3.438 -1.916,2.564 1.174,8.592 -2.873,9.75 -1.111,0.321 -0.637,2.057 0.482,1.738 z"
+ inkscape:connector-curvature="0"
+ id="path6"
+ style="fill:#ed1c24" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/math-substract.png b/silx/resources/gui/icons/math-substract.png
new file mode 100755
index 0000000..cf7627c
--- /dev/null
+++ b/silx/resources/gui/icons/math-substract.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-substract.svg b/silx/resources/gui/icons/math-substract.svg
new file mode 100644
index 0000000..498d36d
--- /dev/null
+++ b/silx/resources/gui/icons/math-substract.svg
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata25"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs23" /><linearGradient
+ x1="4.5137"
+ y1="16.049999"
+ x2="28.514"
+ y2="16.049999"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop5"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" /><stop
+ id="stop7"
+ style="stop-color:#f4f4f4;stop-opacity:0.991"
+ offset="0.0905" /><stop
+ id="stop9"
+ style="stop-color:#d6d6d6;stop-opacity:0.97490001"
+ offset="0.25080001" /><stop
+ id="stop11"
+ style="stop-color:#a5a5a5;stop-opacity:0.95380002"
+ offset="0.4623" /><stop
+ id="stop13"
+ style="stop-color:#616161;stop-opacity:0.92830002"
+ offset="0.71689999" /><stop
+ id="stop15"
+ style="stop-color:#0e0e0e;stop-opacity:0.89999998"
+ offset="1" /></linearGradient><rect
+ width="23"
+ height="23"
+ x="5.0139999"
+ y="4.5500002"
+ id="rect17"
+ style="fill:none;stroke:url(#a);stroke-miterlimit:10" /><path
+ d="m 6.165,7.499 h 10.208 c 0,0 3.043,-0.055 3.093,3.311 0.056,3.367 -2.821,3.583 -2.821,3.583 H 6.165 m 0,10.211 h 10.48 c 0,0 3.964,-0.49 4.02,-5.432 0.051,-4.94 -4.02,-4.779 -4.02,-4.779 M 6.708,6.373 v 19.355"
+ inkscape:connector-curvature="0"
+ id="path19"
+ style="fill:none;stroke:#f7941e;stroke-width:2.79999995;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/math-swap-sign.png b/silx/resources/gui/icons/math-swap-sign.png
new file mode 100755
index 0000000..8e67e81
--- /dev/null
+++ b/silx/resources/gui/icons/math-swap-sign.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-swap-sign.svg b/silx/resources/gui/icons/math-swap-sign.svg
new file mode 100644
index 0000000..5d80c1f
--- /dev/null
+++ b/silx/resources/gui/icons/math-swap-sign.svg
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata26"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs24" /><path
+ d="m 10.411,24.871 0.289,0.776 c 0.097,0.26 0.174,0.519 0.231,0.732 h 0.02 c 0.067,-0.224 0.145,-0.491 0.222,-0.732 l 0.28,-0.776 h 1.273 l -1.07,2.143 1.089,2.223 H 11.366 L 11.048,28.416 C 10.962,28.193 10.884,27.97 10.817,27.747 h -0.019 c -0.058,0.223 -0.145,0.446 -0.212,0.669 l -0.289,0.821 H 9.032 l 1.051,-2.169 -1.042,-2.196 h 1.37 z"
+ inkscape:connector-curvature="0"
+ id="path4" /><path
+ d="m 18.296,20.802 c -0.559,0.812 -1.021,1.973 -1.021,3.642 0,1.616 0.463,2.768 1.021,3.606 H 17.39 C 16.85,27.38 16.281,26.157 16.281,24.435 16.32,22.694 16.85,21.48 17.39,20.802 h 0.906 z"
+ inkscape:connector-curvature="0"
+ id="path6" /><path
+ d="m 21.649,25.116 v 1.199 h -2.738 v -1.199 h 2.738 z"
+ inkscape:connector-curvature="0"
+ id="path8" /><path
+ d="M 24.091,22.728 H 24.07 l -1.212,0.582 -0.242,-1.052 1.642,-0.786 h 1.267 v 6.636 h -1.433 v -5.38 z"
+ inkscape:connector-curvature="0"
+ id="path10" /><path
+ d="m 27.021,28.05 c 0.56,-0.821 1.022,-2.018 1.022,-3.642 0,-1.625 -0.463,-2.785 -1.022,-3.606 h 0.906 c 0.54,0.651 1.109,1.839 1.109,3.606 -0.039,1.767 -0.569,2.945 -1.109,3.642 h -0.906 z"
+ inkscape:connector-curvature="0"
+ id="path12" /><line
+ x1="1.224"
+ x2="27.546"
+ y1="12.123"
+ y2="12.123"
+ fill="none"
+ stroke="#000"
+ stroke-miterlimit="10"
+ stroke-width=".8"
+ id="line14"
+ style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-miterlimit:10" /><path
+ d="M 2.491,11.448"
+ inkscape:connector-curvature="0"
+ id="path16"
+ style="fill:none;stroke:#00a651;stroke-miterlimit:10" /><path
+ d="m 26.441,10.765 c 0,0 -2.07,0.308 -3.128,0 -1.057,-0.309 -2.687,-2.774 -2.995,-3.436 -0.308,-0.662 -1.938,-3.083 -3.876,0 -1.938,3.083 -4.405,-2.828 -4.405,-2.828 0,0 -2.51,-6.07 -4.314,0.229 -1.806,6.299 -4.935,6.21 -4.935,6.21"
+ inkscape:connector-curvature="0"
+ id="path18"
+ style="fill:none;stroke:#00a651;stroke-width:1.10000002;stroke-miterlimit:10" /><path
+ d="m 26.441,13.33 c 0,0 -2.07,-0.309 -3.127,0 -1.057,0.308 -2.688,2.774 -2.995,3.435 -0.308,0.662 -1.938,3.083 -3.876,0 -1.938,-3.083 -4.406,2.828 -4.406,2.828 0,0 -2.51,6.07 -4.314,-0.229 -1.807,-6.299 -4.936,-6.21 -4.936,-6.21"
+ inkscape:connector-curvature="0"
+ id="path20"
+ style="fill:none;stroke:#ed1c24;stroke-width:1.10000002;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/math-ymin-to-zero.png b/silx/resources/gui/icons/math-ymin-to-zero.png
new file mode 100755
index 0000000..3366e35
--- /dev/null
+++ b/silx/resources/gui/icons/math-ymin-to-zero.png
Binary files differ
diff --git a/silx/resources/gui/icons/math-ymin-to-zero.svg b/silx/resources/gui/icons/math-ymin-to-zero.svg
new file mode 100644
index 0000000..084b879
--- /dev/null
+++ b/silx/resources/gui/icons/math-ymin-to-zero.svg
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata16"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs14" /><line
+ x1="4.9790001"
+ x2="31.028"
+ y1="17.829"
+ y2="17.829"
+ fill="none"
+ stroke="#000"
+ stroke-miterlimit="10"
+ id="line4"
+ style="fill:none;stroke:#000000;stroke-miterlimit:10" /><path
+ d="M 2.491,11.448"
+ inkscape:connector-curvature="0"
+ id="path6"
+ style="fill:none;stroke:#00a651;stroke-miterlimit:10" /><path
+ d="m 4.703,18.357 c 0,0 -0.047,-1.082 1.587,-4.552 1.634,-3.469 3.268,-3.283 3.268,-3.283 0,0 1.541,-0.374 2.661,3.035 1.12,3.409 2.334,2.007 3.642,0 1.308,-2.007 2.334,-1.96 2.334,-1.96 0,0 1.027,-0.654 3.035,2.567 2.008,3.22 5.369,-2.591 6.068,-3.653"
+ inkscape:connector-curvature="0"
+ id="path8"
+ style="fill:none;stroke:#00a651;stroke-width:1.5;stroke-miterlimit:10" /><path
+ d="m 8.361,23.684 c 0,2.371 -0.934,3.42 -2.088,3.42 -1.56,0 -2.087,-1.659 -2.087,-3.359 0,-1.902 0.659,-3.419 2.142,-3.419 1.649,-0.001 2.033,1.779 2.033,3.358 z m -2.724,0.031 c -0.022,1.547 0.187,2.248 0.67,2.248 0.45,0 0.604,-0.732 0.604,-2.248 0,-1.416 -0.143,-2.25 -0.604,-2.25 -0.451,0 -0.682,0.713 -0.67,2.25 z"
+ inkscape:connector-curvature="0"
+ id="path10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/median-filter.png b/silx/resources/gui/icons/median-filter.png
new file mode 100644
index 0000000..ef47103
--- /dev/null
+++ b/silx/resources/gui/icons/median-filter.png
Binary files differ
diff --git a/silx/resources/gui/icons/median-filter.svg b/silx/resources/gui/icons/median-filter.svg
new file mode 100644
index 0000000..179a36b
--- /dev/null
+++ b/silx/resources/gui/icons/median-filter.svg
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="32"
+ height="32"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.5 r10040"
+ sodipodi:docname="median-filter.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="7.9195959"
+ inkscape:cx="5.3998064"
+ inkscape:cy="0.5973639"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showborder="true"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1098"
+ inkscape:window-x="0"
+ inkscape:window-y="31"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1020.3622)">
+ <g
+ transform="scale(0.99689828,1.0031114)"
+ style="font-size:13.08228397px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ id="text2985">
+ <path
+ sodipodi:type="inkscape:offset"
+ inkscape:radius="0"
+ inkscape:original="M 16.28125 1025.7188 L 16.28125 1027.9062 C 16.100583 1027.667 15.907224 1027.4874 15.6875 1027.375 C 15.470213 1027.2599 15.220701 1027.2188 14.9375 1027.2188 C 14.432127 1027.2188 14.012206 1027.4096 13.6875 1027.8125 C 13.362792 1028.2129 13.1875 1028.7427 13.1875 1029.375 C 13.1875 1030.0074 13.362792 1030.5033 13.6875 1030.9062 C 14.012206 1031.3067 14.432127 1031.5312 14.9375 1031.5312 C 15.223142 1031.5312 15.470213 1031.4561 15.6875 1031.3438 C 15.904783 1031.2315 16.100583 1031.0542 16.28125 1030.8125 L 16.28125 1031.4062 L 17.59375 1031.4062 L 17.59375 1025.7188 L 16.28125 1025.7188 z M 18.875 1025.7188 L 18.875 1026.7812 L 20.1875 1026.7812 L 20.1875 1025.7188 L 18.875 1025.7188 z M 1 1025.9375 L 1 1031.4062 L 2.34375 1031.4062 L 2.34375 1027.4062 L 3.59375 1030.375 L 4.5 1030.375 L 5.75 1027.4062 L 5.75 1031.4062 L 7.09375 1031.4062 L 7.09375 1025.9375 L 5.28125 1025.9375 L 4.03125 1028.875 L 2.78125 1025.9375 L 1 1025.9375 z M 10.375 1027.2188 C 9.6669902 1027.2187 9.1240221 1027.398 8.71875 1027.7812 C 8.3159174 1028.1646 8.0937497 1028.7061 8.09375 1029.375 C 8.0937497 1030.0562 8.3085932 1030.5903 8.71875 1030.9688 C 9.1313463 1031.3448 9.6953106 1031.5312 10.4375 1031.5312 C 10.747556 1031.5312 11.064938 1031.4985 11.375 1031.4375 C 11.685055 1031.3789 12.002437 1031.2734 12.3125 1031.1562 L 12.3125 1030.1562 C 12.00732 1030.3223 11.696773 1030.4482 11.40625 1030.5312 C 11.118161 1030.6121 10.838376 1030.6562 10.5625 1030.6562 C 10.2207 1030.6562 9.9716775 1030.5601 9.78125 1030.4062 C 9.5908185 1030.2524 9.469237 1030.0265 9.4375 1029.7188 L 12.5 1029.7188 L 12.5 1029.3438 C 12.499996 1028.6943 12.325679 1028.1695 11.9375 1027.7812 C 11.551754 1027.3931 11.019528 1027.2188 10.375 1027.2188 z M 23.1875 1027.2188 C 22.904294 1027.2188 22.626952 1027.2442 22.34375 1027.2812 C 22.060546 1027.3153 21.780761 1027.3383 21.5 1027.4062 L 21.5 1028.4062 C 21.707519 1028.2939 21.9458 1028.2123 22.1875 1028.1562 C 22.429198 1028.1002 22.687986 1028.0938 22.96875 1028.0938 C 23.315427 1028.0938 23.555173 1028.1208 23.71875 1028.2188 C 23.882322 1028.3139 23.968747 1028.48 23.96875 1028.6875 L 23.96875 1028.7812 L 23.1875 1028.7812 C 22.47949 1028.7812 21.95703 1028.9004 21.625 1029.125 C 21.29541 1029.3497 21.15625 1029.7065 21.15625 1030.1875 C 21.15625 1030.583 21.267578 1030.9072 21.53125 1031.1562 C 21.797362 1031.4028 22.137694 1031.5312 22.5625 1031.5312 C 22.877439 1031.5313 23.155271 1031.4561 23.375 1031.3438 C 23.594724 1031.2291 23.792966 1031.0615 23.96875 1030.8125 L 23.96875 1031.4062 L 25.28125 1031.4062 L 25.28125 1029.0625 C 25.281246 1028.4057 25.110836 1027.9468 24.78125 1027.6562 C 24.454098 1027.3633 23.927243 1027.2188 23.1875 1027.2188 z M 29.1875 1027.2188 C 28.918942 1027.2187 28.690915 1027.2603 28.46875 1027.375 C 28.24658 1027.4874 28.041502 1027.667 27.84375 1027.9062 L 27.84375 1027.3125 L 26.53125 1027.3125 L 26.53125 1031.4062 L 27.84375 1031.4062 L 27.84375 1029.4062 C 27.843748 1029.0328 27.906248 1028.7413 28.0625 1028.5312 C 28.218748 1028.3188 28.44531 1028.1875 28.71875 1028.1875 C 28.831052 1028.1875 28.91211 1028.2323 29 1028.2812 C 29.087888 1028.3276 29.16748 1028.3837 29.21875 1028.4688 C 29.25781 1028.5322 29.29785 1028.647 29.3125 1028.7812 C 29.32963 1028.9155 29.312496 1029.146 29.3125 1029.5 L 29.3125 1031 L 29.3125 1031.4062 L 30.65625 1031.4062 L 30.65625 1028.9062 C 30.656245 1028.352 30.527827 1027.9468 30.28125 1027.6562 C 30.037105 1027.3657 29.661129 1027.2188 29.1875 1027.2188 z M 18.875 1027.3125 L 18.875 1031.4062 L 20.1875 1031.4062 L 20.1875 1027.3125 L 18.875 1027.3125 z M 10.375 1028.0938 C 10.609372 1028.0938 10.793454 1028.1587 10.9375 1028.3125 C 11.083976 1028.4639 11.156247 1028.6572 11.15625 1028.9062 L 9.46875 1028.9062 C 9.5078108 1028.6377 9.5913067 1028.4541 9.75 1028.3125 C 9.9086892 1028.1684 10.121091 1028.0938 10.375 1028.0938 z M 15.40625 1028.1562 C 15.687009 1028.1562 15.916012 1028.2637 16.0625 1028.4688 C 16.211418 1028.6739 16.281247 1028.9844 16.28125 1029.375 C 16.281247 1029.7657 16.211422 1030.0449 16.0625 1030.25 C 15.916012 1030.4551 15.687009 1030.5625 15.40625 1030.5625 C 15.127928 1030.5625 14.930174 1030.4551 14.78125 1030.25 C 14.634764 1030.0449 14.562498 1029.7657 14.5625 1029.375 C 14.562498 1028.9844 14.634764 1028.6738 14.78125 1028.4688 C 14.930174 1028.2636 15.127928 1028.1562 15.40625 1028.1562 z M 23.28125 1029.5625 L 23.96875 1029.5625 L 23.96875 1029.7188 C 23.968747 1029.9848 23.887204 1030.1968 23.71875 1030.375 C 23.55029 1030.5507 23.340329 1030.6562 23.09375 1030.6562 C 22.895994 1030.6562 22.737302 1030.593 22.625 1030.5 C 22.515135 1030.4048 22.468748 1030.291 22.46875 1030.125 C 22.468748 1029.9443 22.519529 1029.8118 22.65625 1029.7188 C 22.795408 1029.6256 23.007811 1029.5625 23.28125 1029.5625 z M 6.0625 1035.0938 L 6.0625 1036.1562 L 7.375 1036.1562 L 7.375 1035.0938 L 6.0625 1035.0938 z M 8.65625 1035.0938 L 8.65625 1040.7812 L 9.96875 1040.7812 L 9.96875 1035.0938 L 8.65625 1035.0938 z M 1 1035.3125 L 1 1040.7812 L 2.40625 1040.7812 L 2.40625 1038.4688 L 4.65625 1038.4688 L 4.65625 1037.4062 L 2.40625 1037.4062 L 2.40625 1036.375 L 4.8125 1036.375 L 4.8125 1035.3125 L 1 1035.3125 z M 11.34375 1035.5312 L 11.34375 1036.6875 L 10.6875 1036.6875 L 10.6875 1037.625 L 11.34375 1037.625 L 11.34375 1039.375 C 11.343749 1039.8926 11.441406 1040.2514 11.65625 1040.4688 C 11.873534 1040.6836 12.263671 1040.7812 12.78125 1040.7812 L 13.90625 1040.7812 L 13.90625 1039.8438 L 13.21875 1039.8438 C 12.994138 1039.8438 12.85693 1039.816 12.78125 1039.75 C 12.705565 1039.6816 12.656248 1039.5654 12.65625 1039.375 L 12.65625 1037.625 L 14 1037.625 L 14 1036.6875 L 12.65625 1036.6875 L 12.65625 1035.5312 L 11.34375 1035.5312 z M 16.78125 1036.5938 C 16.07324 1036.5938 15.530272 1036.773 15.125 1037.1562 C 14.722168 1037.5395 14.5 1038.0811 14.5 1038.75 C 14.5 1039.4312 14.714843 1039.9653 15.125 1040.3438 C 15.537596 1040.7198 16.101561 1040.9062 16.84375 1040.9062 C 17.153806 1040.9062 17.471188 1040.8735 17.78125 1040.8125 C 18.091305 1040.7539 18.408687 1040.6484 18.71875 1040.5312 L 18.71875 1039.5312 C 18.41357 1039.6973 18.103024 1039.8232 17.8125 1039.9062 C 17.524411 1039.9871 17.244626 1040.0312 16.96875 1040.0312 C 16.626951 1040.0312 16.377928 1039.9351 16.1875 1039.7812 C 15.997069 1039.6274 15.87549 1039.4015 15.84375 1039.0938 L 18.90625 1039.0938 L 18.90625 1038.7188 C 18.906245 1038.0694 18.700679 1037.5445 18.3125 1037.1562 C 17.926754 1036.768 17.425778 1036.5938 16.78125 1036.5938 z M 22.5625 1036.5938 C 22.257321 1036.5938 22.000973 1036.6568 21.78125 1036.7812 C 21.563962 1036.9034 21.387205 1037.1065 21.21875 1037.375 L 21.21875 1036.6875 L 19.90625 1036.6875 L 19.90625 1040.7812 L 21.21875 1040.7812 L 21.21875 1038.9062 C 21.218748 1038.5035 21.288084 1038.1835 21.46875 1037.9688 C 21.651853 1037.7514 21.913083 1037.6562 22.25 1037.6562 C 22.364743 1037.6562 22.481442 1037.6605 22.59375 1037.6875 C 22.708493 1037.7116 22.82275 1037.7585 22.9375 1037.8125 L 22.9375 1036.625 C 22.83984 1036.613 22.77002 1036.5938 22.71875 1036.5938 C 22.667478 1036.5837 22.60644 1036.5938 22.5625 1036.5938 z M 6.0625 1036.6875 L 6.0625 1040.7812 L 7.375 1040.7812 L 7.375 1036.6875 L 6.0625 1036.6875 z M 16.78125 1037.4688 C 17.015622 1037.4688 17.199704 1037.5337 17.34375 1037.6875 C 17.490226 1037.8389 17.562497 1038.0322 17.5625 1038.2812 L 15.84375 1038.2812 C 15.882811 1038.0127 15.997557 1037.8291 16.15625 1037.6875 C 16.31494 1037.5434 16.527341 1037.4688 16.78125 1037.4688 z "
+ style="font-size:7.5px;font-weight:bold"
+ id="path3029"
+ d="m 16.28125,1025.7188 0,2.1874 c -0.180667,-0.2392 -0.374026,-0.4188 -0.59375,-0.5312 -0.217287,-0.1151 -0.466799,-0.1562 -0.75,-0.1562 -0.505373,0 -0.925294,0.1908 -1.25,0.5937 -0.324708,0.4004 -0.5,0.9302 -0.5,1.5625 0,0.6324 0.175292,1.1283 0.5,1.5312 0.324706,0.4005 0.744627,0.625 1.25,0.625 0.285642,0 0.532713,-0.075 0.75,-0.1874 0.217283,-0.1123 0.413083,-0.2896 0.59375,-0.5313 l 0,0.5937 1.3125,0 0,-5.6874 -1.3125,0 z m 2.59375,0 0,1.0624 1.3125,0 0,-1.0624 -1.3125,0 z M 1,1025.9375 l 0,5.4687 1.34375,0 0,-4 1.25,2.9688 0.90625,0 1.25,-2.9688 0,4 1.34375,0 0,-5.4687 -1.8125,0 -1.25,2.9375 -1.25,-2.9375 -1.78125,0 z m 9.375,1.2813 c -0.7080098,-1e-4 -1.2509779,0.1792 -1.65625,0.5624 -0.4028326,0.3834 -0.6250003,0.9249 -0.625,1.5938 -3e-7,0.6812 0.2148432,1.2153 0.625,1.5938 0.4125963,0.376 0.9765606,0.5624 1.71875,0.5624 0.310056,0 0.627438,-0.033 0.9375,-0.094 0.310055,-0.059 0.627437,-0.1641 0.9375,-0.2813 l 0,-1 c -0.30518,0.1661 -0.615727,0.292 -0.90625,0.375 -0.288089,0.081 -0.567874,0.125 -0.84375,0.125 -0.3418,0 -0.5908225,-0.096 -0.78125,-0.25 -0.1904315,-0.1538 -0.312013,-0.3797 -0.34375,-0.6874 l 3.0625,0 0,-0.375 c -4e-6,-0.6495 -0.174321,-1.1743 -0.5625,-1.5626 -0.385746,-0.3881 -0.917972,-0.5624 -1.5625,-0.5624 z m 12.8125,0 c -0.283206,0 -0.560548,0.025 -0.84375,0.062 -0.283204,0.034 -0.562989,0.057 -0.84375,0.125 l 0,1 c 0.207519,-0.1123 0.4458,-0.1939 0.6875,-0.25 0.241698,-0.056 0.500486,-0.062 0.78125,-0.062 0.346677,0 0.586423,0.027 0.75,0.125 0.163572,0.095 0.249997,0.2612 0.25,0.4687 l 0,0.094 -0.78125,0 c -0.70801,0 -1.23047,0.1192 -1.5625,0.3438 -0.32959,0.2247 -0.46875,0.5815 -0.46875,1.0625 0,0.3955 0.111328,0.7197 0.375,0.9687 0.266112,0.2466 0.606444,0.375 1.03125,0.375 0.314939,1e-4 0.592771,-0.075 0.8125,-0.1874 0.219724,-0.1147 0.417966,-0.2823 0.59375,-0.5313 l 0,0.5937 1.3125,0 0,-2.3437 c -4e-6,-0.6568 -0.170414,-1.1157 -0.5,-1.4063 -0.327152,-0.2929 -0.854007,-0.4374 -1.59375,-0.4374 z m 6,0 c -0.268558,-1e-4 -0.496585,0.041 -0.71875,0.1562 -0.22217,0.1124 -0.427248,0.292 -0.625,0.5312 l 0,-0.5937 -1.3125,0 0,4.0937 1.3125,0 0,-2 c -2e-6,-0.3734 0.0625,-0.6649 0.21875,-0.875 0.156248,-0.2124 0.38281,-0.3437 0.65625,-0.3437 0.112302,0 0.19336,0.045 0.28125,0.094 0.08789,0.046 0.16748,0.1025 0.21875,0.1876 0.03906,0.063 0.0791,0.1782 0.09375,0.3124 0.01713,0.1343 -4e-6,0.3648 0,0.7188 l 0,1.5 0,0.4062 1.34375,0 0,-2.5 c -5e-6,-0.5542 -0.128423,-0.9594 -0.375,-1.25 -0.244145,-0.2905 -0.620121,-0.4374 -1.09375,-0.4374 z m -10.3125,0.094 0,4.0937 1.3125,0 0,-4.0937 -1.3125,0 z m -8.5,0.7813 c 0.234372,0 0.418454,0.065 0.5625,0.2187 0.146476,0.1514 0.218747,0.3447 0.21875,0.5937 l -1.6875,0 c 0.039061,-0.2685 0.1225567,-0.4521 0.28125,-0.5937 0.1586892,-0.1441 0.371091,-0.2187 0.625,-0.2187 z m 5.03125,0.062 c 0.280759,0 0.509762,0.1075 0.65625,0.3126 0.148918,0.2051 0.218747,0.5156 0.21875,0.9062 -3e-6,0.3907 -0.06983,0.6699 -0.21875,0.875 -0.146488,0.2051 -0.375491,0.3125 -0.65625,0.3125 -0.278322,0 -0.476076,-0.1074 -0.625,-0.3125 -0.146486,-0.2051 -0.218752,-0.4843 -0.21875,-0.875 -2e-6,-0.3906 0.07226,-0.7012 0.21875,-0.9062 0.148924,-0.2052 0.346678,-0.3126 0.625,-0.3126 z m 7.875,1.4063 0.6875,0 0,0.1563 c -3e-6,0.266 -0.08155,0.478 -0.25,0.6562 -0.16846,0.1757 -0.378421,0.2812 -0.625,0.2812 -0.197756,0 -0.356448,-0.063 -0.46875,-0.1562 -0.109865,-0.095 -0.156252,-0.209 -0.15625,-0.375 -2e-6,-0.1807 0.05078,-0.3132 0.1875,-0.4062 0.139158,-0.093 0.351561,-0.1563 0.625,-0.1563 z m -17.21875,5.5313 0,1.0624 1.3125,0 0,-1.0624 -1.3125,0 z m 2.59375,0 0,5.6874 1.3125,0 0,-5.6874 -1.3125,0 z M 1,1035.3125 l 0,5.4687 1.40625,0 0,-2.3124 2.25,0 0,-1.0626 -2.25,0 0,-1.0312 2.40625,0 0,-1.0625 -3.8125,0 z m 10.34375,0.2187 0,1.1563 -0.65625,0 0,0.9375 0.65625,0 0,1.75 c -10e-7,0.5176 0.09766,0.8764 0.3125,1.0938 0.217284,0.2148 0.607421,0.3124 1.125,0.3124 l 1.125,0 0,-0.9374 -0.6875,0 c -0.224612,0 -0.36182,-0.028 -0.4375,-0.094 -0.07569,-0.068 -0.125002,-0.1846 -0.125,-0.375 l 0,-1.75 1.34375,0 0,-0.9375 -1.34375,0 0,-1.1563 -1.3125,0 z m 5.4375,1.0626 c -0.70801,0 -1.250978,0.1792 -1.65625,0.5624 -0.402832,0.3833 -0.625,0.9249 -0.625,1.5938 0,0.6812 0.214843,1.2153 0.625,1.5938 0.412596,0.376 0.976561,0.5624 1.71875,0.5624 0.310056,0 0.627438,-0.033 0.9375,-0.094 0.310055,-0.059 0.627437,-0.1641 0.9375,-0.2813 l 0,-1 c -0.30518,0.1661 -0.615726,0.292 -0.90625,0.375 -0.288089,0.081 -0.567874,0.125 -0.84375,0.125 -0.341799,0 -0.590822,-0.096 -0.78125,-0.25 -0.190431,-0.1538 -0.31201,-0.3797 -0.34375,-0.6874 l 3.0625,0 0,-0.375 c -5e-6,-0.6494 -0.205571,-1.1743 -0.59375,-1.5626 -0.385746,-0.3882 -0.886722,-0.5624 -1.53125,-0.5624 z m 5.78125,0 c -0.305179,0 -0.561527,0.063 -0.78125,0.1874 -0.217288,0.1222 -0.394045,0.3253 -0.5625,0.5938 l 0,-0.6875 -1.3125,0 0,4.0937 1.3125,0 0,-1.875 c -2e-6,-0.4027 0.06933,-0.7227 0.25,-0.9374 0.183103,-0.2174 0.444333,-0.3126 0.78125,-0.3126 0.114743,0 0.231442,0 0.34375,0.031 0.114743,0.024 0.229,0.071 0.34375,0.125 l 0,-1.1875 c -0.09766,-0.012 -0.16748,-0.031 -0.21875,-0.031 -0.05127,-0.01 -0.11231,0 -0.15625,0 z m -16.5,0.094 0,4.0937 1.3125,0 0,-4.0937 -1.3125,0 z m 10.71875,0.7813 c 0.234372,0 0.418454,0.065 0.5625,0.2187 0.146476,0.1514 0.218747,0.3447 0.21875,0.5937 l -1.71875,0 c 0.03906,-0.2685 0.153807,-0.4521 0.3125,-0.5937 0.15869,-0.1441 0.371091,-0.2187 0.625,-0.2187 z" />
+ </g>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/next.png b/silx/resources/gui/icons/next.png
new file mode 100644
index 0000000..1137720
--- /dev/null
+++ b/silx/resources/gui/icons/next.png
Binary files differ
diff --git a/silx/resources/gui/icons/next.svg b/silx/resources/gui/icons/next.svg
new file mode 100644
index 0000000..09cc561
--- /dev/null
+++ b/silx/resources/gui/icons/next.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="b" x1="11.913" x2="27.737" y1="10.398" y2="16.471" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#002839" offset="0"/>
+ <stop stop-color="#00f" stop-opacity=".2585" offset="1"/>
+ </linearGradient>
+ <linearGradient id="a" x1="11.913" x2="27.737" y1="10.398" y2="16.471" gradientUnits="userSpaceOnUse">
+ <stop offset="0"/>
+ <stop stop-color="#00f" stop-opacity=".30612" offset="1"/>
+ </linearGradient>
+ </defs>
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path d="m7.055 4.9951c6.6141 3.9114 12.473 7.571 18.396 11.252l-18.307 10.806z" fill="url(#b)" stroke="url(#a)" stroke-linejoin="round" stroke-width=".4"/>
+</svg>
diff --git a/silx/resources/gui/icons/normal.png b/silx/resources/gui/icons/normal.png
new file mode 100755
index 0000000..dd80045
--- /dev/null
+++ b/silx/resources/gui/icons/normal.png
Binary files differ
diff --git a/silx/resources/gui/icons/normal.svg b/silx/resources/gui/icons/normal.svg
new file mode 100644
index 0000000..8bc4e66
--- /dev/null
+++ b/silx/resources/gui/icons/normal.svg
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata10"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs8"><filter
+ x="-0.18998802"
+ y="-0.11593667"
+ width="1.379976"
+ height="1.2318733"
+ color-interpolation-filters="sRGB"
+ id="filter4582"><feGaussianBlur
+ id="feGaussianBlur4584"
+ stdDeviation="1.239375" /></filter></defs><path
+ d="m 8.9854343,3.2658713 c 0,7.6682957 0,14.7273767 0,21.4687487 1.5624997,-1.562499 3.1249997,-3.124999 4.6874997,-4.687499 1.286105,2.960737 2.595998,5.911189 3.875,8.874999 1.679854,-0.586234 3.057686,-1.123669 4.5625,-1.687499 -1.355248,-2.924576 -2.785698,-5.815806 -4.1875,-8.71875 2.239583,0 4.479167,0 6.71875,0 C 19.271285,13.204637 13.579202,7.8489993 8.9854343,3.2658713 z"
+ id="path3222-6"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter4582);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+ d="m 9.8419543,4.1474217 0,19.0835623 4.3693007,-4.3693 3.983775,9.124129 3.598247,-1.349344 -4.305047,-8.931362 6.296934,0 z"
+ id="path3222"
+ style="fill:#000000;stroke:#ffffff;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/pixel-intensities.png b/silx/resources/gui/icons/pixel-intensities.png
new file mode 100644
index 0000000..eebb873
--- /dev/null
+++ b/silx/resources/gui/icons/pixel-intensities.png
Binary files differ
diff --git a/silx/resources/gui/icons/pixel-intensities.svg b/silx/resources/gui/icons/pixel-intensities.svg
new file mode 100644
index 0000000..1948634
--- /dev/null
+++ b/silx/resources/gui/icons/pixel-intensities.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <defs>
+ <linearGradient id="a" x1="73.425" x2="507.42" y1="868.27" y2="868.27" gradientTransform="matrix(.066589 0 0 .065952 -2.0502 -37.163)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#b32222" offset="0"/>
+ <stop stop-color="#2e7231" stop-opacity=".86275" offset=".5"/>
+ <stop stop-color="#323aac" stop-opacity=".72549" offset="1"/>
+ </linearGradient>
+ </defs>
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path d="m3.1803 33.222c0.4672-17.948 5.0836-5.422 10.04-10.721 0 0 2.7506-2.9654 3.7783-4.8302 1.0278-1.8648 2.1592-12.576 8.139-10.4 5.9331 2.1586 6.2601 25.874 6.2601 25.874z" fill="none" stroke="url(#a)" stroke-width="1.679"/>
+ <g transform="matrix(.084762 0 0 .051812 -1.5175 -37.163)" font-family="Sans" font-size="399.31px" line-height="125%">
+ <path d="m83.123 927.19c5.7378 9e-5 10.954 1.3042 15.649 3.9122 4.6946 2.543 8.4112 5.8684 11.15 9.9761 2.8037 4.1079 4.9228 8.4439 6.3573 13.008 1.4996 4.5643 2.2494 9.0307 2.2495 13.399-9e-5 6.1292-1.3694 12.128-4.1078 17.996-2.6734 5.8031-6.1618 10.824-10.465 15.062-4.3035 4.1731-9.2264 7.531-14.769 10.074-5.4772 2.5429-10.954 3.8144-16.431 3.8144-4.5643 0-9.1285-0.7173-13.693-2.1517-0.52166 0.652-0.78247 1.4996-0.78244 2.5429v18.974c-3.2e-5 7.5636 0.32598 12.389 0.97805 14.475 0.26078 0.9128 1.8909 1.6626 4.8903 2.2495 3.0645 0.5868 5.5423 0.8802 7.4332 0.8803 0.39118 0.5216 0.58678 1.467 0.58683 2.8363 0.06516 1.3692-0.13045 2.3147-0.58683 2.8364-13.367-0.6521-20.344-0.9781-20.93-0.9781-2.2821 0-4.4991 0.033-6.6508 0.098-2.0865 0.1304-4.4991 0.2934-7.2376 0.489-2.7386 0.1956-5.0207 0.326-6.8464 0.3913-0.45643-0.5217-0.68464-1.4672-0.68464-2.8364 0.0652-1.3693 0.29341-2.3147 0.68464-2.8363 1.8909-1e-4 4.336-0.2935 7.3354-0.8803 3.0646-0.5869 4.7272-1.3367 4.9881-2.2495 0.52161-1.6301 0.84763-6.4552 0.97805-14.475v-80.005c-1.7e-5 -5.2162-0.32604-8.6068-0.97805-10.172-0.39124-0.97798-1.6301-1.7604-3.7166-2.3473-2.0865-0.58676-3.847-0.91278-5.2815-0.97805-1.3693-0.13034-2.6081-0.19554-3.7166-0.19561-0.26082-0.26074-0.42383-1.0432-0.48903-2.3473-2e-6 -1.304 0.16301-2.2168 0.48903-2.7386 11.15-1.4996 20.474-4.2381 27.972-8.2156 0.45639 9e-5 0.91282 0.39131 1.3693 1.1737 0.5216 0.78253 0.78241 1.4346 0.78244 1.9561-3.3e-5 0.0653-0.22824 1.2716-0.68464 3.6188-0.45646 2.2822-0.68467 3.7493-0.68464 4.4012-3.2e-5 0.5217 0.13038 0.78252 0.39122 0.78244 0.13038 8e-5 0.32598-0.13033 0.58683-0.39122 3.0645-2.6081 6.9115-5.1184 11.541-7.531 4.6946-2.4124 8.8024-3.6187 12.323-3.6188m-8.4113 11.541c-3.7818 8e-5 -7.4658 0.91293-11.052 2.7386-3.5862 1.7606-5.3793 3.3906-5.3793 4.8903v46.947c-3.2e-5 4.5643 1.9561 8.0853 5.8683 10.563 3.9774 2.4777 8.0852 3.7166 12.323 3.7166 5.151 0 9.7153-1.6627 13.693-4.9881 4.0426-3.3253 7.0419-7.4332 8.9981-12.323 1.956-4.9554 2.9341-10.139 2.9342-15.551-8e-5 -11.215-2.6408-20.017-7.9222-26.407-5.2163-6.3899-11.704-9.5848-19.463-9.5849"/>
+ <path d="m145.62 903.81c-1.8909-1.8908-2.8364-4.2055-2.8364-6.9442-1e-5 -2.7384 0.94544-5.0532 2.8364-6.9442 1.8909-1.8908 4.2056-2.8362 6.9442-2.8364 2.7385 1.2e-4 5.0532 0.94557 6.9442 2.8364 1.8909 1.891 2.8363 4.2058 2.8364 6.9442-4e-5 2.7387-0.94549 5.0534-2.8364 6.9442-1.8909 1.891-4.2057 2.8365-6.9442 2.8364-2.7386 1.1e-4 -5.0533-0.94534-6.9442-2.8364m15.942 45.479v40.883c-4e-5 7.5636 0.32598 12.389 0.97805 14.475 0.26078 0.9129 1.8909 1.6627 4.8903 2.2496 3.0645 0.5868 5.5423 0.8802 7.4332 0.8802 0.39118 0.5216 0.58679 1.4671 0.58684 2.8364 0.0651 1.3692-0.13046 2.3147-0.58684 2.8363-13.367-0.652-20.344-0.978-20.93-0.978-2.2822 0-4.4991 0.065-6.6508 0.1956-2.0865 0.065-4.4991 0.1956-7.2376 0.3912-2.7386 0.1956-5.0207 0.326-6.8464 0.3912-0.45643-0.5216-0.68465-1.4671-0.68464-2.8363 0.0652-1.3693 0.29341-2.3148 0.68464-2.8364 1.8909 0 4.336-0.2934 7.3354-0.8802 3.0646-0.5869 4.7272-1.3367 4.9881-2.2496 0.52161-1.63 0.84763-6.4551 0.97805-14.475v-36.384c-2e-5 -5.2162-0.32603-8.6068-0.97805-10.172-0.39124-0.97798-1.6301-1.7604-3.7166-2.3473-2.0865-0.58676-3.847-0.91278-5.2815-0.97805-1.3693-0.13034-2.6082-0.19554-3.7166-0.19561-0.26082-0.26074-0.42383-1.0432-0.48903-2.3473-1e-5 -1.304 0.163-2.2168 0.48903-2.7386 11.15-1.4996 20.474-4.2381 27.972-8.2156 0.45639 9e-5 0.91282 0.39131 1.3693 1.1737 0.52159 0.78253 0.7824 1.4346 0.78244 1.9561-0.91288 6.39-1.3693 10.693-1.3693 12.91v6.4551"/>
+ <path d="m202.93 929.73c5.9987 8e-5 12.584-0.32594 19.757-0.97805 0.13036 0.65211 0.19556 1.6302 0.19561 2.9342-5e-5 1.3042-0.19566 2.217-0.58684 2.7386-5.2163 8e-5 -7.8244 1.1085-7.8244 3.3254-3e-5 0.4565 0.32598 1.2389 0.97806 2.3473l12.91 20.539c1.0432-1.6952 2.9015-4.4012 5.5749-8.1178 2.7385-3.7165 4.7924-6.7485 6.1617-9.0959 1.4344-2.3473 2.1517-4.1078 2.1517-5.2815-6e-5 -0.91277-0.55429-1.63-1.6627-2.1517-1.0433-0.58676-2.1518-0.94538-3.3254-1.0759-1.1737-0.19553-2.4452-0.32594-3.8144-0.39122-1.3693-0.0651-2.0866-0.0977-2.1517-0.0978-0.19566-0.13033-0.32607-1.0106-0.39122-2.6407-5e-5 -1.63 0.13035-2.6407 0.39122-3.032 1.8908 0.0653 4.0752 0.19569 6.553 0.39122 2.4777 0.19569 4.6946 0.3587 6.6508 0.48902 2.0212 0.0653 4.2056 0.0979 6.553 0.0978 5.8682 8e-5 11.085-0.32594 15.649-0.97805 0.13032 0.52171 0.16292 1.5976 0.0978 3.2276-9e-5 1.6302-0.0979 2.4452-0.29342 2.4451-8.1505 0.4565-13.171 1.891-15.062 4.3034-1.6302 2.2822-4.1079 5.7706-7.4332 10.465-3.3254 4.6295-6.064 8.4113-8.2156 11.345-2.0866 2.9342-3.3906 4.7273-3.9122 5.3793l23.473 34.819c3.2601 4.6947 8.2808 7.042 15.062 7.042 0.13032 0 0.19552 0.4238 0.19561 1.2715 0.0651 0.8476 0.0651 1.7279 0 2.6407-0.0653 0.9129-0.1957 1.4997-0.39122 1.7605-1.6954-0.065-3.7167-0.1956-6.0639-0.3912-2.3474-0.1956-4.4665-0.326-6.3573-0.3912-1.8258-0.1304-3.8145-0.1956-5.9661-0.1956-2.4778 0-4.8251 0.065-7.042 0.1956-2.217 0.065-4.7599 0.1956-7.6288 0.3912-2.8038 0.1956-5.1511 0.326-7.042 0.3912-0.26087-0.652-0.39128-1.7605-0.39122-3.3254 0.0651-1.5648 0.26076-2.3473 0.58683-2.3473 1.8908-0.1304 3.7165-0.489 5.4771-1.0758 1.8256-0.5869 2.7385-1.4019 2.7386-2.4452-6e-5 -0.2608-0.13047-0.652-0.39122-1.1736-6.7812-11.085-11.932-19.235-15.453-24.451-0.71729 1.0433-2.7386 4.01-6.0639 8.9003-3.2602 4.8251-5.9336 8.9003-8.02 12.226-0.78248 1.2389-1.1737 2.4777-1.1737 3.7166-3e-5 0.7824 0.26079 1.4671 0.78244 2.0539 0.5216 0.5216 1.3692 0.9454 2.5429 1.2715 1.2388 0.2608 2.1843 0.4564 2.8364 0.5868 0.71721 0.065 1.8909 0.163 3.521 0.2934 0.45639 0.065 0.81501 0.098 1.0759 0.098 0.13037 0 0.22818 0.4238 0.29342 1.2715 0.0652 0.7824 0.0652 1.6301 0 2.5429-0.0652 0.9129-0.22825 1.5323-0.48903 1.8583-1.8257-0.065-3.8796-0.1956-6.1617-0.3912-2.2822-0.1956-4.3687-0.326-6.2595-0.3912-1.8257-0.1304-3.8796-0.1956-6.1617-0.1956-2.2169 0-4.2708 0.065-6.1617 0.1956-1.8257 0.065-3.8796 0.1956-6.1617 0.3912s-4.3034 0.326-6.0639 0.3912c-0.19561-0.7824-0.26082-1.7931-0.19561-3.0319 0.1304-1.3041 0.32601-2.1844 0.58683-2.6408 0.26081-0.065 1.0432-0.1956 2.3473-0.3912s2.1517-0.326 2.5429-0.3912c0.45642-0.065 1.2715-0.1956 2.4451-0.3913 1.2389-0.2608 2.1191-0.489 2.6408-0.6846 0.58682-0.2608 1.3693-0.5868 2.3473-0.978 0.97804-0.3913 1.7605-0.7825 2.3473-1.1737 0.65202-0.4564 1.3366-0.978 2.0539-1.5649 0.71722-0.652 1.3366-1.3367 1.8583-2.0539 12.128-17.475 18.518-26.668 19.17-27.581l-22.73-33.89c-0.97807-1.4996-2.8038-2.5755-5.4771-3.2276-2.6082-0.71716-5.1511-1.0758-7.6288-1.0759-0.13041 8e-5 -0.22821-0.39114-0.29341-1.1737-1e-5 -0.78236 0.0326-1.63 0.0978-2.5429 0.0652-0.91276 0.19561-1.5648 0.39122-1.9561 7.1724 0.65211 13.628 0.97813 19.365 0.97805"/>
+ <path d="m319.89 820.39c2.832 2e-4 14.258-0.48808 34.277-1.4648 0.68351 0.78144 0.97648 2.1975 0.87891 4.248-8e-5 2.051-0.29305 3.467-0.87891 4.248-2.9298 1.9e-4 -6.9337 0.43964-12.012 1.3184-5.0782 0.87909-7.8126 2.0021-8.2031 3.3691-0.97663 3.1252-1.4649 10.352-1.4648 21.68v125.1c-6e-5 11.328 0.48822 18.555 1.4648 21.68 0.39056 1.3672 3.1249 2.4902 8.2031 3.3691 5.078 0.879 9.082 1.3184 12.012 1.3184 0.58586 0.7813 0.87883 2.1973 0.87891 4.248 0.0976 2.0508-0.1954 3.4668-0.87891 4.2481-20.02-0.9766-31.445-1.4649-34.277-1.4649-3.0274 0-14.551 0.4883-34.57 1.4649-0.68361-0.7813-1.0254-2.1973-1.0254-4.2481 0.0976-2.0507 0.43944-3.4667 1.0254-4.248 2.9297 0 6.9336-0.4394 12.012-1.3184 5.0781-0.8789 7.8125-2.0019 8.2031-3.3691 0.97653-3.125 1.4648-10.352 1.4648-21.68v-125.1c-3e-5 -11.328-0.48831-18.555-1.4648-21.68-0.39066-1.367-3.125-2.49-8.2031-3.3691-5.0781-0.87872-9.082-1.3182-12.012-1.3184-0.58595-0.78106-0.92775-2.1971-1.0254-4.248-2e-5 -2.0506 0.34178-3.4666 1.0254-4.248 20.019 0.97676 31.543 1.465 34.57 1.4648"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/plot-grid.png b/silx/resources/gui/icons/plot-grid.png
new file mode 100755
index 0000000..38884c4
--- /dev/null
+++ b/silx/resources/gui/icons/plot-grid.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-grid.svg b/silx/resources/gui/icons/plot-grid.svg
new file mode 100644
index 0000000..435c99a
--- /dev/null
+++ b/silx/resources/gui/icons/plot-grid.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<line x1="8.15" x2="8.15" y1="4.79" y2="28.24" fill="none" stroke="#00A14B" stroke-miterlimit="10" stroke-width="1.5"/>
+ <path d="m15.651 26.156" fill="none" stroke="#00A651" stroke-miterlimit="10" stroke-width="1.5"/>
+<line x1="16" x2="16" y1="4.79" y2="28.24" fill="none" stroke="#00A14B" stroke-miterlimit="10" stroke-width="1.5"/>
+<line x1="23.511" x2="23.511" y1="4.79" y2="28.24" fill="none" stroke="#00A14B" stroke-miterlimit="10" stroke-width="1.5"/>
+<g fill="none" stroke="#00A14B" stroke-miterlimit="10" stroke-width="1.5">
+ <line x1="27.556" x2="4.105" y1="8.835" y2="8.835"/>
+ <line x1="27.556" x2="4.105" y1="16.685" y2="16.686"/>
+ <line x1="27.556" x2="4.105" y1="24.195" y2="24.195"/>
+</g>
+</svg>
diff --git a/silx/resources/gui/icons/plot-roi-above.png b/silx/resources/gui/icons/plot-roi-above.png
new file mode 100644
index 0000000..e994668
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi-above.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-roi-above.svg b/silx/resources/gui/icons/plot-roi-above.svg
new file mode 100644
index 0000000..faf6f69
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi-above.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata>
+<path d="m5.27 24.857c1.462-0.169 1.631-3.713 2.25-4.838 0.45-0.787 0.787-0.619 1.519-0.844s0.9-0.506 1.125-1.294c0.281-1.181 0.169-2.362 0.225-3.6 0.112-1.744 1.744-0.731 2.7-1.969 1.069-1.35 1.294-3.656 1.913-5.231 0.281-0.675 0.675-1.8 1.35-1.237 0.337 0.337 0.675 1.519 0.899 1.969 0.619 1.575 1.125 3.318 1.576 4.95 0.393 1.631 0.787 3.263 1.35 4.837 0.225 0.731 0.338 1.406 1.125 1.182 0.675-0.169 0.899-4.063 1.574-4.063 0.899 0 1.406 5.582 1.688 6.257 0.563 1.182 1.078 4.186 1.353 2.9 0.882-4.121 2.028 1.4 2.647 1.345" fill="#a7a9ac" stroke="#000" stroke-miterlimit="10" stroke-width="1.2"/>
+<path d="m1.029 25.321h21.412v-20.954h8.5303" fill-opacity="0" stroke="#f7941e" stroke-width="1px"/><rect x="22.372" y="4.4097" width="8.5303" height="21.412" fill="#f7931e" fill-opacity=".4"/></svg>
diff --git a/silx/resources/gui/icons/plot-roi-below.png b/silx/resources/gui/icons/plot-roi-below.png
new file mode 100644
index 0000000..5a92476
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi-below.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-roi-below.svg b/silx/resources/gui/icons/plot-roi-below.svg
new file mode 100644
index 0000000..363dca2
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi-below.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata>
+<path d="m5.27 24.857c1.462-0.169 1.631-3.713 2.25-4.838 0.45-0.787 0.787-0.619 1.519-0.844s0.9-0.506 1.125-1.294c0.281-1.181 0.169-2.362 0.225-3.6 0.112-1.744 1.744-0.731 2.7-1.969 1.069-1.35 1.294-3.656 1.913-5.231 0.281-0.675 0.675-1.8 1.35-1.237 0.337 0.337 0.675 1.519 0.899 1.969 0.619 1.575 1.125 3.318 1.576 4.95 0.393 1.631 0.787 3.263 1.35 4.837 0.225 0.731 0.338 1.406 1.125 1.182 0.675-0.169 0.899-4.063 1.574-4.063 0.899 0 1.406 5.582 1.688 6.257 0.563 1.182 1.078 4.186 1.353 2.9 0.882-4.121 2.028 1.4 2.647 1.345" fill="#a7a9ac" stroke="#000" stroke-miterlimit="10" stroke-width="1.2"/>
+<path d="m30.971 25.321h-21.412v-20.954h-8.5303" fill-opacity="0" stroke="#f7941e" stroke-width="1px"/><rect transform="scale(-1,1)" x="-9.6281" y="4.4097" width="8.5303" height="21.412" fill="#f7931e" fill-opacity=".4"/></svg>
diff --git a/silx/resources/gui/icons/plot-roi-between.png b/silx/resources/gui/icons/plot-roi-between.png
new file mode 100644
index 0000000..5daadbd
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi-between.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-roi-between.svg b/silx/resources/gui/icons/plot-roi-between.svg
new file mode 100644
index 0000000..42d5dfe
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi-between.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata>
+<path d="m5.27 24.857c1.462-0.169 1.631-3.713 2.25-4.838 0.45-0.787 0.787-0.619 1.519-0.844s0.9-0.506 1.125-1.294c0.281-1.181 0.169-2.362 0.225-3.6 0.112-1.744 1.744-0.731 2.7-1.969 1.069-1.35 1.294-3.656 1.913-5.231 0.281-0.675 0.675-1.8 1.35-1.237 0.337 0.337 0.675 1.519 0.899 1.969 0.619 1.575 1.125 3.318 1.576 4.95 0.393 1.631 0.787 3.263 1.35 4.837 0.225 0.731 0.338 1.406 1.125 1.182 0.675-0.169 0.899-4.063 1.574-4.063 0.899 0 1.406 5.582 1.688 6.257 0.563 1.182 1.078 4.186 1.353 2.9 0.882-4.121 2.028 1.4 2.647 1.345" fill="#a7a9ac" stroke="#000" stroke-miterlimit="10" stroke-width="1.2"/>
+<rect transform="scale(-1)" x="-22.5" y="-25.821" width="13" height="21.412" fill="#f7931e" fill-opacity=".4"/><path d="m30.971 25.321h-8.5303v-20.954h-12.881v20.954h-8.5303" fill-opacity="0" stroke="#f7941e" stroke-width="1px"/></svg>
diff --git a/silx/resources/gui/icons/plot-roi-reset.png b/silx/resources/gui/icons/plot-roi-reset.png
new file mode 100755
index 0000000..4bf6129
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi-reset.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-roi-reset.svg b/silx/resources/gui/icons/plot-roi-reset.svg
new file mode 100644
index 0000000..8d041c5
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi-reset.svg
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3309"
+ xml:space="preserve"><metadata
+ id="metadata3331"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3329"><filter
+ x="-0.14283186"
+ y="-0.14518739"
+ width="1.2856637"
+ height="1.2903748"
+ color-interpolation-filters="sRGB"
+ id="filter5023"><feGaussianBlur
+ id="feGaussianBlur5025"
+ stdDeviation="1.2609376" /></filter></defs><path
+ d="M 22.807,17.744 C 22.02,17.969 21.081,17.736 20.857,17.006 20.294,15.429 19.9,13.798 19.507,12.167 19.056,10.536 18.55,8.792 17.931,7.217 17.705,6.767 16.863,4.704 16.525,4.366 15.851,3.803 15.962,5.81 15.68,6.485 c -0.619,1.575 -1.117,3.731 -2.186,5.082 -0.957,1.237 -2.314,0.375 -2.426,2.119 -0.057,1.237 -0.758,2.17 -1.039,3.35 v 8.571 h 12.777 v -7.863 z"
+ id="path3311"
+ style="fill:#a7a9ac" /><path
+ d="m 5.389,25.229 c 1.708,-0.537 1.918,-2.888 2.278,-4.363 0.386,-1.586 1.375,-1.263 2.348,-2.098 0.678,-0.582 0.898,-1.396 0.969,-2.284 0.063,-0.779 0.081,-1.548 0.085,-2.33 0.013,-2.141 0.784,-1.382 1.778,-1.905 0.839,-0.441 1.34,-1.112 1.686,-2.007 0.574,-1.485 0.863,-3.048 1.376,-4.552 0.617,-1.808 1.159,-0.028 1.492,0.791 0.468,1.155 0.808,2.366 1.158,3.56 0.599,2.042 1.023,4.128 1.629,6.169 0.226,0.76 0.399,1.967 1.168,2.417 1.522,0.893 1.89,-2.108 2.041,-2.796 0.111,-0.509 0.223,-1.024 0.429,-1.505 -0.134,0.312 0.268,1.145 0.358,1.515 0.271,1.118 0.422,2.269 0.601,3.404 0.247,1.579 0.629,3.881 1.618,5.138 0.134,0.171 0.374,0.144 0.545,0.07 0.898,-0.382 0.599,-2.526 1.461,-0.604 0.269,0.6 0.481,1.527 1.171,1.773 0.547,0.196 0.781,-0.674 0.238,-0.867 -0.831,-0.298 -0.735,-3.522 -2.242,-3.107 -0.778,0.214 -0.935,1.33 -1.087,1.967 0.32,-1.342 -0.453,-2.465 -0.71,-3.835 -0.275,-1.478 -0.17,-5.41 -1.672,-6.29 -1.451,-0.85 -1.849,3.332 -2.032,3.947 -0.624,-0.295 -0.964,-0.784 -1.019,-1.466 -0.179,-0.575 -0.343,-1.154 -0.494,-1.736 -0.318,-1.171 -0.565,-2.359 -0.883,-3.53 -0.537,-1.983 -1.024,-4.517 -2.137,-6.281 -1.597,-2.535 -2.773,1.821 -3.061,2.927 -0.283,1.084 -0.56,2.115 -1.059,3.128 -0.581,1.179 -1.765,0.985 -2.661,1.55 -0.985,0.621 -0.595,2.794 -0.617,3.685 -0.061,2.502 -2.243,2.114 -3.047,3.946 -0.503,1.146 -0.497,4.244 -1.949,4.701 -0.55,0.174 -0.314,1.043 0.241,0.868 z"
+ id="path3313" /><line
+ x1="9.3400002"
+ x2="9.3400002"
+ y1="5.7129998"
+ y2="25.607"
+ fill="none"
+ stroke="#00A14B"
+ stroke-miterlimit="10"
+ stroke-width="1.5"
+ id="line3315"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><line
+ x1="23.322001"
+ x2="23.322001"
+ y1="5.7129998"
+ y2="25.607"
+ fill="none"
+ stroke="#00A651"
+ stroke-miterlimit="10"
+ stroke-width="1.5"
+ id="line3317"
+ style="fill:none;stroke:#00a651;stroke-width:1.5;stroke-miterlimit:10" /><path
+ d="m 7.2674788,8.497352 -1.34375,1.34375 9.0625002,9.062502 -9.2500002,8.90625 1.34375,1.34375 9.2500002,-8.90625 9.09375,9.09375 1.34375,-1.34375 -9.0625,-9.0625 9.21875,-8.906252 -1.3125,-1.375 -9.25,8.937502 -9.0937502,-9.093752 z"
+ id="line3323-5"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.89999998;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5023);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><g
+ id="g3321"
+ style="fill:none;stroke:#ed1c24;stroke-width:1.89999998;stroke-miterlimit:10"><line
+ x1="6.776"
+ x2="26.271999"
+ y1="7.994"
+ y2="27.495001"
+ id="line3323" /><line
+ x1="26.455"
+ x2="6.5929999"
+ y1="8.1730003"
+ y2="27.313999"
+ id="line3325" /></g></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/plot-roi.png b/silx/resources/gui/icons/plot-roi.png
new file mode 100755
index 0000000..b34ff7c
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-roi.svg b/silx/resources/gui/icons/plot-roi.svg
new file mode 100644
index 0000000..d73d4c5
--- /dev/null
+++ b/silx/resources/gui/icons/plot-roi.svg
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata18"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs16" /><path
+ d="M 21.778,18.118 C 20.991,18.343 20.326,17.736 20.101,17.006 19.538,15.43 19.144,13.799 18.751,12.168 18.3,10.537 17.794,8.793 17.175,7.218 16.95,6.768 16.612,5.587 16.274,5.249 15.6,4.686 15.206,5.812 14.924,6.486 c -0.619,1.575 -0.844,3.881 -1.912,5.231 -0.957,1.237 -2.588,0.225 -2.7,1.969 -0.056,1.237 -0.273,2.386 -0.555,3.565 v 8.355 h 12.02 v -7.488 z"
+ inkscape:connector-curvature="0"
+ id="path4"
+ style="fill:#a7a9ac" /><path
+ d="m 5.27,24.857 c 1.462,-0.169 1.631,-3.713 2.25,-4.838 0.45,-0.787 0.787,-0.619 1.519,-0.844 0.732,-0.225 0.9,-0.506 1.125,-1.294 0.281,-1.181 0.169,-2.362 0.225,-3.6 0.112,-1.744 1.744,-0.731 2.7,-1.969 1.069,-1.35 1.294,-3.656 1.913,-5.231 0.281,-0.675 0.675,-1.8 1.35,-1.237 0.337,0.337 0.675,1.519 0.899,1.969 0.619,1.575 1.125,3.318 1.576,4.95 0.393,1.631 0.787,3.263 1.35,4.837 0.225,0.731 0.338,1.406 1.125,1.182 0.675,-0.169 0.899,-4.063 1.574,-4.063 0.899,0 1.406,5.582 1.688,6.257 0.563,1.182 1.078,4.186 1.353,2.9 0.882,-4.121 2.028,1.4 2.647,1.345"
+ inkscape:connector-curvature="0"
+ id="path6"
+ style="fill:none;stroke:#000000;stroke-width:1.20000005;stroke-miterlimit:10" /><line
+ x1="9.1499996"
+ x2="9.1499996"
+ y1="7.2129998"
+ y2="25.607"
+ fill="none"
+ stroke="#00A14B"
+ stroke-miterlimit="10"
+ stroke-width="1.5"
+ id="line8"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><line
+ x1="22.482"
+ x2="22.482"
+ y1="7.2129998"
+ y2="25.607"
+ fill="none"
+ stroke="#00A651"
+ stroke-miterlimit="10"
+ stroke-width="1.5"
+ id="line10"
+ style="fill:none;stroke:#00a651;stroke-width:1.5;stroke-miterlimit:10" /><path
+ d="M 9.758,25.607"
+ inkscape:connector-curvature="0"
+ id="path12"
+ style="fill:none;stroke:#000000;stroke-width:1.20000005;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/plot-toggle-points.png b/silx/resources/gui/icons/plot-toggle-points.png
new file mode 100755
index 0000000..33b579a
--- /dev/null
+++ b/silx/resources/gui/icons/plot-toggle-points.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-toggle-points.svg b/silx/resources/gui/icons/plot-toggle-points.svg
new file mode 100644
index 0000000..3f9a9b6
--- /dev/null
+++ b/silx/resources/gui/icons/plot-toggle-points.svg
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata20"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs18" /><line
+ x1="8.1499996"
+ x2="8.1499996"
+ y1="7.2129998"
+ y2="26.156"
+ fill="none"
+ stroke="#00A14B"
+ stroke-miterlimit="10"
+ stroke-width="1.5"
+ id="line4"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><g
+ id="g6"
+ style="fill:none;stroke:#00a651;stroke-width:1.5;stroke-miterlimit:10"><line
+ x1="15.651"
+ x2="15.651"
+ y1="7.2129998"
+ y2="14.25"
+ id="line8" /><rect
+ width="4.5640001"
+ height="4.7909999"
+ x="13.369"
+ y="14.542"
+ id="rect10" /><line
+ x1="15.651"
+ x2="15.651"
+ y1="19.118999"
+ y2="26.156"
+ id="line12" /></g><rect
+ width="4.5630002"
+ height="4.7909999"
+ x="23.077999"
+ y="14.542"
+ id="rect14"
+ style="fill:#00a651;stroke:#00a651;stroke-width:1.5;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/plot-widget.png b/silx/resources/gui/icons/plot-widget.png
new file mode 100755
index 0000000..c0495a5
--- /dev/null
+++ b/silx/resources/gui/icons/plot-widget.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-widget.svg b/silx/resources/gui/icons/plot-widget.svg
new file mode 100644
index 0000000..ab5d537
--- /dev/null
+++ b/silx/resources/gui/icons/plot-widget.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+ <path d="m19.316 30.985l-0.536-0.755c-0.222-0.291-0.361-0.509-0.528-0.749h-0.019c-0.123 0.24-0.272 0.458-0.457 0.749l-0.492 0.755h-1.532l1.716-2.11-1.655-2.062h1.541l0.519 0.761c0.176 0.255 0.309 0.458 0.449 0.694h0.018c0.142-0.267 0.255-0.452 0.404-0.694l0.502-0.761h1.531l-1.671 2.037 1.76 2.135h-1.55z"/>
+<rect x="7.443" y="3.907" width="22.104" height="21.774" fill="#E6E7E8" stroke="#00A14B" stroke-miterlimit="10" stroke-width=".5"/>
+<line x1="12.121" x2="12.121" y1="24.228" y2="25.445" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5"/>
+<line x1="16.481" x2="16.481" y1="24.228" y2="25.445" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5"/>
+<line x1="20.675" x2="20.675" y1="24.226" y2="25.443" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5"/>
+<line x1="25.106" x2="25.106" y1="24.229" y2="25.446" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5"/>
+<g fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5">
+ <line x1="8.689" x2="7.513" y1="8.26" y2="8.264"/>
+ <line x1="8.705" x2="7.529" y1="12.62" y2="12.624"/>
+ <line x1="8.722" x2="7.545" y1="16.814" y2="16.818"/>
+ <line x1="8.734" x2="7.558" y1="21.246" y2="21.249"/>
+</g>
+ <path d="m3.114 16.572v-1.71l-1.879-2.466h1.533l0.609 1.002c0.186 0.304 0.308 0.526 0.458 0.799h0.017c0.133-0.26 0.274-0.503 0.448-0.799l0.6-1.003 1.507-2e-3 -1.954 2.437 1e-3 1.741-1.34 1e-3z"/>
+ <path d="m8.894 22.083c1.279-0.466 1.521-1.852 1.816-3.051 0.472-1.914 2.476-1.43 2.608-3.744 0.026-0.451-0.108-2.314 0.439-2.495 0.349-0.115 0.718-0.137 1.046-0.329 0.636-0.373 1.043-1.117 1.274-1.787 0.216-0.625 0.394-1.25 0.563-1.89-6e-3 0.024 0.46-1.912 0.784-1.102 0.575 1.446 1.029 2.918 1.45 4.416 0.276 0.985 0.626 5.058 2.067 5.165 1.46 0.107 1.508-1.37 1.775-2.526 0.11-0.474-0.442-1.211-0.105-0.205 0.149 0.446 0.224 0.926 0.314 1.386 0.162 0.831 0.262 1.673 0.434 2.503 0.158 0.763 0.541 2.86 1.448 3.114 0.34 0.095 0.62-0.116 0.738-0.419 0.411-1.056 0.119-0.812 0.579 0.213 0.165 0.368 0.341 0.793 0.723 0.978 0.693 0.335 1.302-0.7 0.605-1.037-0.676-0.326-0.62-1.838-1.458-2.27-1.072-0.552-1.386 1.231-1.606 1.797 0.246-0.14 0.492-0.279 0.738-0.419-0.401-0.112-0.95-4.248-1.045-4.779-0.127-0.715-0.328-2.714-1.429-2.714-1.126 0-1.239 2.197-1.42 2.9 0.032-0.126-0.555-1.494-0.614-1.694-0.227-0.762-0.401-1.541-0.589-2.313-0.363-1.501-0.869-2.986-1.45-4.416-0.433-1.066-1.004-2.122-2.16-1.197-0.551 0.44-0.767 1.692-0.938 2.299-0.458 1.627-0.732 2.734-2.437 3.297-0.57 0.188-0.711 0.708-0.844 1.218-0.421 1.625 0.561 2.907-1.508 3.708-1.621 0.627-0.637 3.695-2.12 4.235-0.719 0.263-0.407 1.424 0.322 1.158z"/>
+</svg>
diff --git a/silx/resources/gui/icons/plot-window-image.png b/silx/resources/gui/icons/plot-window-image.png
new file mode 100755
index 0000000..a95edb5
--- /dev/null
+++ b/silx/resources/gui/icons/plot-window-image.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-window-image.svg b/silx/resources/gui/icons/plot-window-image.svg
new file mode 100644
index 0000000..c3dc0a8
--- /dev/null
+++ b/silx/resources/gui/icons/plot-window-image.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata>
+<g transform="translate(.27119 .40678)"><g transform="translate(-.91869 -2.2683)"><rect x="1.745" y="6.35" width="29.805" height="23.023" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".21"/><rect x="1.745" y="6.35" width="29.805" height="23.023" fill="#e6e7e8"/><rect x="1.745" y="6.466" width="29.805" height="3.083" fill="#FFF" stroke="#000" stroke-miterlimit="10" stroke-width=".2"/></g></g>
+<rect x="1.7627" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="4.5008" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="7.239" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="9.9771" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="12.715" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="15.453" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><image x="7.8457" y="9.4196" width="16.309" height="17.161" overflow="visible" xlink:href="data:image/jpeg;base64,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 Xedc6u6nXRlzSU/M+m8td/RgZfYX4z2fjDgABKLWLFutYplmvrM6JnOKVnfypo+13DijegRmbSCL NdA1nnGrRFypfS9KVLS7evUbF3FvS2iu1D366S2JoqMlWaL034revybOwj0YqSsqtynBth8YRZGu mSdScNXnLkttvOhCxHnYW6ca8vdqz2y54r1njG9H2wEPRX4z2fjDgAHXos05asJu8w8VZrzmqMoJ oLFd3Ox7I52y2oI87VbVle1lMfK2e5tV3darOTXSqzlVXwmzmvI1cvUZkSanlWV587OF7Mv8oxT2 TpRlbh3FxqraZOX0wnn0K0krBCJw2+T1qmkJHJK4txztPlmvujkYFmtX2PbgJZfjPZ+MOAAS0c2+ 87rKcmy3IdislLfyNVzi5XU2HVpDVrW5WZ29nRpG7n6PK9yNDP61hzay6cvTpaj0rqvVuaMzQoWa LaTY5PbVCdMyeP4RQ+11Oxs1GzS4IuShOFlK5KDI1tnnsVLtfPlKSOK+VSfO2p1npSS+9svjs70/ mNfo+3A5oX4z2fjDgAAAFqxSs35eYviYewi7NSHW843LxKVI6NS/G3aN/LVpWeqKJdT3eWMTfxEt T2sXUq7k2COvFhq0tGXlqlzt7XJ2J3qsdDmara7IzNZUuzUbPs4LbU6+aCZK0+dPhJ8iiUO8exLZ 0bGclvWTeRszUvGev8hp2e2ATevxns/GHAAAAC/T2SUe2mSxokxa9XcZJLNYmxG7FxnOhTde49nA 9JkSpR18jUrWzSvQz6PMvvZ22Gm/Mvw2xhcQrZlh1O+aDLwr9dTbPrHNnOC8/VX3LOWTf7NWZp5u rE2de5TFxkZzOKsQO07POPJjFwZrdflXYuNh2a3fY9uAtF+M9n4w4AABcOXr0ZR8tdiu85F0Iq1h qHztXv599NMHpZOtfSx9ZaaOdpIxVwJRl6C6zszUxa6mN6PKstPspX5dfjaefSJ0EqmTednWho9X YmIvxorPR4rqxyeXKe7ExMymKhaVWpza7StxVxFkrKVZiy1pSRqz9z4L9H2cRMo5be3AOL8Z7Pxh wACW5lbCZnEuJhjPnQIy5yj312zrGwjqXtyYyFcxyG0ptPzNTzbYtfZyNfE3+02bcSi9jvgS1MTZ G/Ttv4yriOSazCzyc/PasKGuOzCMZJm6OdDVm0K/J9xnZs4lDlitWauWXDRfX7NrZVajyrWa2meN VuZHqfR0wMmT24B1fjPZ+MAC0LftzjLzZ945ZJ6ufe2K1uqpJ9WzzR3vYJXTu4e1ktmc0cx3ltYz UpvY+n3DTz+jlW96xtPRJrlN1iXfN6fKGtNSSHx6m5mtZLmbaW2elZrGjOUb9Suad7H2F42UZQtG pcU067uyabJVXJURaWyqXBO6dTA3/O6vpoAZ8ftwDq/Gez8r1W6bF98+1XemMXOrvRKb+c7R6pw4 i2omaLSgVp6GY6d97Ns9ytSZUsWeW759+emhib2ScfZwtVu8sGTw1qc5k8q9nP0LdxdKi0dHmVa7 G71M1hPN0ajGfpUk1feZQs5+OiTnWv2caSWizXrJ8qVfSzayHb/drYV6jloAJn9uAdX5H13jDnpo UdOvmRbVsykl6JSZ9Z9fg5ldgqWiSjWplw5eqTWjtTPVF7lDUx+9vlW5x7L8DSmU+Xciy60aruLW v4em3LFNzuZqq70GXItJnSl6wl0JyS2KtRXbr3mm52vzugzOsza1HhOkM7QxvQWuQf6vsdVHJxbo RCOAAOe3AOr8Z7Pxhxm75688NlVqs+Flfjp9GUmy7xkVca0rk+cCEjreR7xLSVt4Wu5WmnM++lLP brW6HF1ClbWVWV/p3MhYruzrVSzyVnsZQfPp6WVobXfmaM5tjLkqKVZW86durCvLVe2xGRZoT7x2 Jepepvl0rW9rIWGHCAc4AB7cA6vxns/GHBqjp6BtLT0+YutozJZi9Ds3zutbN6L3VEafG8TitChP hOduaxxr3Fdrq8rXZZlI0q3HytDN1Ks90W5uZ2V6HGuzbNO8SsS5KDqzNVNFy79TtW0359qHHpbB HRUup0QrX8JerTq16jNOldivF/WZjcXmiATiAAAB7cA6vxns/GHAAHb/AJqdI+sPP3L4dGxj3+Iy EhUnna+YjScu/NcuLIpa5er3c8aWXt4bU0LtG8k3pdCNsHQy7ermo6tZy8jk69R+Y9+rHQ+0zPv5 5kWQXudG3maOaCZ94tvuQops51jJ19kDfS9tcm5ELrq8MeUA4gAAAAAHtwDq/Gez8YcAAAAJwOlu VLtTT0/NbXcm5TsJbzq+plaU+1qejUVrl/I1s3OYPosYeGlk3V5pc73NTLra2bpnZu4+hPltDlyp SzdvJ0qXsxve7kEtz8hQuVdMkXsRm7a+umxTVOi6iurVMZS108rhGIAswAAAAAAAPbgHV+M9n4w4 AAAAAAAAWqp3np+ZL74H6/mNtU0KNuh3P3TybkW16tiKcxoyg3dS3laeZuZenTdM6zQez7DMzTzk c+7UvPElDmn0dLV8zeln0MJ+TfTpNzW39G1ypQl2SwhnAOcAAAAAAAAAAAA9uAdX4z2fjDgAAAAA AAAAB3gBfod6vpVY5TLo3vM3V77B2Pffy6OXs+S5t9Df8h2dPeV81L46cM1vPV2tPDotH2GDmVzr 7Oac26EKQdegEQA5wAAAAAAAAAAAAAAAAAD24B1fjPZ+MOAAAAAAAAAAAAAAAAAAWHUTqNUA4Bw7 wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9uAdX4z2fjDgAAAAAAAAAAAAAAAAAAAAAAAAAAX5Bn DlBw7wAAAAAAAAAAAAAAAAAAAAAAAAAAPbgHV+M9n4w4AAAAAAAAAAAAAAAAAAAAAAAAE/UhYnUD tTYqAc8l6xQeYAOAAAAAAAAAAAAAAAAAAAAAAAAe3AO+4q7AGObAGObAGObAGObAGObAGObAGObA GObAGObAGObAGObAGObAGObAGObAGObAGObAGObAGObAGObAGObAGObAGObAGObAGObAGObAGObA GObAGObAGObAFEvAf//aAAgBAgABBQD/AIp7Qoa52neHNVpJ/kswEe/MZjMnAMDSt+Q/js0cw9hP UnoDEJMTMyYrgmZHs4N/CMaMSYx6MclELFVVZmcoS3JryCdmsz/sHR6N98HjYRr5jazAfFPYYxj9 hHVK8xQAAZn2HstbkV1mIrqRAzYlFjoarOYBE2U4v8RuwxoVzOAmRDAfYJxltXWpSq8YekLzW2mR q9hGFpWxSpHw8SxeIMIhhmZmCBYFmQI4DQJOMcZjELFbrU/St8xAHDKVb4AGYMLLTmGNCYSScRes wBCwELEwCAH2Ex4yiLgFMSoZiEiWqbIylT7wGTgCMcAsTDGhGZhVBOYvU5ycTjCJ/gmFgAzmZYxi RKGIi2FSl4MRxLVDVe6Bk8QoJjnMJhMLZnImMAxHSBoCTAeohEyZgmFRDgR3xDYZSwInIg1vAxK+ 7WOrGMYTDLrwpLZXELjIMQZgwIwiZxORE5wkGMQI2TChJqUgwrEBleZYvuqOKu0JhM2LiqB3LDOG DGARV6qckDqexehjKckQ5jKxhDCFutTBgCJ1iysywDu/aoyWbozexlJndAw1okIJHQNYTlgFgGCD 1hg6gPCYTHLRrDFUMa1xD0gaVsJWAZaxA9qdh6wpMQ5hhEsbCjCqCGLdWHRc4Z+wHIEdevIicwYx IhAaVpgqOjewN1os6u3I+1cTBhHQn2GWNAeSuJWMAHkbG+RGzGBKg4M5GF1jKhh6RG+ZVBgwIMGF YymVZBPuochyBCYTGY5sbpX/AFJzLm4prmWgwNgq5MKgwsyzkDGZYwInImcMxB07J2hgYuc0jMYY 93nxjMTMwt1btAALNwr1363AkI3EqwdbExFeA8obBGUQvK3AjVEGkdG6QmKTknMVMylMRjk+0nEJ hh7GlkbGbx8lTcWOCLlKmizMJEsrKxLICHhGJgWEIQUOQMCEAhlxD0gaUEEleCe40/z/AI/ww6MM gt1YZly8WqsDIcOCprethYvIrGVWIcgnFiqnU18gFwC2CpyCxEPAwoRNX+2z/X3DD2wRhP8AFy4Z G5LdWHWp2qssXI5coC1bdLFYMC1YYVqVPFTElgxDEbELZjLiV5M16jz2D7RGXEIh9n+SJiOuQnyM y9b6eY1yZbVgrXzCqVLICK1AndYhWVnqy8gyGdRMgitcyrXJKKEFjcm9v9gVhEHtIjDMdOQr6grg vT1UchwwXQZ6rA0PY+YvSKcw4MZDMTSTkRgC2w+6h6ssK5hQzHtxMdSuCRkAdCuJzgjQ9qdVcEex TCoYBiIUzNJOKO2B7oigEFBCkKRkmIRCwE6ENkFXJZuxjK2yGhiNgkAx1i9JWMkajErqqsDhVssL H3ks4wOrTEIjCERh0fMTss7F/sw6OOtTAAjIdcEGL8yjM7ialPzGWWcVJJ+CCQRe0D8iRMdSOjrE EsSY6oSRYkWVnoy5HEg0oTF1TBShDFUZr4zE/EBxA2QCMkRlgXqyx68GtYyQ14auszw5IbWPIIKl F6xrsEnJ+ODg8xOQgQGOAIcGKqgLxLWJWIGVVFrAG1skkn+LyP8A5l//2gAIAQMAAQUA+Ln+a+wq l77GmCJRewb+S7hA97PAs4jJEZcTWv5j+PbZxFjlyogHTEIjrFqs5BbSFckzI/iXNllEUQCATEFY gSBBO7BHdPO7MKEBjYrG1QPFLlLVb4zdj/3URRAJiBYFgWKkVMnusLYcEgmFJsVHBLBtZxB2fEsP ykdVEAgEAgECxVgWIBkjpZXlu7ndZj14m1QpHdsDTsBVWxH+I7CY+ZYsUQCBYqwYEBMSi1pwKhlE K5JqCraMy0dLlwxJlNpSxWDD4BOI9kBLSwfMgiCAQCBZXWzyrSzEorrDuQbGTHGIgWWvmWAyxCZs qQWE+USjdrVK7EsX3icCyyA5Kdh6lFiiKpMVcTGFrArUOcNccK85ZdUUDumYtUsuRRLMTZUMGAhr Uw1tNElX96yzMdslFMPYqRRBEYiKMkKBFYCEHiQQa3UFq6or1JG2JZaxjjMcCbI6MckKCCCJr38L AQR7lrYVm6oMxRiBYq9MRYqwHEL4iBs0vmW8TYcCChWU6xjUsI6NHBjkiXNmN0IachHM0Liy+5ec njK0OQMxAIQPYuIDATMcR/6VS0ZU5xReoQMDGMseuWshlgE2hgEwdoIjgcdAHvPcs/sMAg5nWA4h eKYIg6VqSF+aN0SokqOszwd6VIIIJsJhKxwJYcTYbI/yROyO7A+Wr09rHAtbArbqG6PzKqThQYoi jJAxEOFTLWYBTTxGXiXIM17RwdVYW1kR4zkSx+l7dRB1hTIIwdesJX7bQxDViBVikAkkALmKPYk7 T2DVH+ywYms4DsAQVJhIB5OI17x3BlktsxLGyeyZxEYGOVM1bOdXuXIGQgEYUQYMGTFGPYvSUjLW zWYCHqCoQ134nysLFxCxWG0GO0d5sHM7fYhWEKRaoE8vBC+5dYFXvQIDyitkiAxRksJUYeoBKNXb mOJnjAWEN2Y+I5wWfpdbiO/IqIyjHQHnxhJtaqnul9rMFFjlmaJ1RexTBEh6hTgo2RYIrERLQwsE 7wrC+YXxHbpZZiWPmAIygkEYIauMpE8r0cM5y/t2G69rZ6VnovYkEUxTD0KtxnIMCeJ5TvDhzOWI 79GtyLHzFryCMHJIHIBbQZZ2o3d0e1mCguXmcOwxKzMxDAYDFaHqA05YhOQGxOUNkssj3gjmSWBD jssXMVYlgMsUSoNZZsjCexjgPaXCRoxyE/vnEVsENOUDRXhbrznONZDb0NwBtcwNCSDgsqvidGBU gt2otlh0NAVTafL+wjIsXhY4KswyK4ykEZZc9A+QHyEs6l8Rn6Ld1e3Ess6d4cljlutaYy/UAmZD QORCcipBZdTSAXtWpScn27FYZV5QAqWSY5ADi2ByHRslXtBRi/Na7PlfkCWYhckHtGMVYIxxYiMu PYBkBsTy+osQAqE5PuEZF2VZbWEFxBLqAGVxzQSxecNmYzLYmeJwRLoi9K24F+jAdMlS2GCsQXwR kgjWsMq0ATXWla22l/fuoFkbUsU2UuD140nq5IYE92vU1Ach/Zv62LlKjkWZDMA6qYwijIycKCV1 qTZZXXGVa1Z2b4WJs1DCdJd2Vt0XowPFn/t2rkgg8WsGYjYLLC3QE8vBO8XSXhVTXSouRZZabD8N lDBtchtmoiuoRwQWOQM8EboxGbFgboSeS0uy3a1itrafdxeAL2KpJJPx3QOo1SDbrEh+SHTQup0z O4tZ0oXjfo5OvppWQ5E7xoSSf4pqrMAAH/mH/9oACAEBAAEFAGtrQ+IoniKJ4iieIoniKJ4iieIo niKJ4iieIoniKJ4iieIoniKJ4iieIoniKJ4iieIoniKJ4iieIoniKJ4iieIoniKJ4iieIoniKJ4i ieIoniKJ4iieIoniKJ4iieIoniKJ4iieIoniKJ4iieIoniKJ4iieIoniKJ4iieIoniKJ4iieIoni KJ4iieIoniKJ4iieIoniKILK2H7N+rfyRW5hVh/wPo/8T/Zv1b+MlVjnU8i2b5r+QatQr16Flnl9 Ni7vp9TXbVZS/wDO9H/if7N+rfxACTp+S3Wjy7T1krHdklxlAEBCEsCs8/8ALy6/zvR/4n+zfq38 LGZRo33nT8rooNGv3q1V0rO7VAlLhnsYz5AOAzahdfNvLW1Lv5vo/wDE/wBm/Vv4KqWPl3lwI1qK aqqERyhDutaUE1PyFlhnIoCUsjrWV4NNmmu5N/TbWs/mej/xP9m/Vv4GtpNbKNStJVWlWuh5U669 6tXFLDSwe03WKpNSLY1hZwoCV5sHE2BidvWquFnk6A/9b5eardeytv5Po/8AE/2b9W+PqUd41STV p5WVoHsA72xcJKq+5ewbFxQ8K6q3JexVUFWWx6mjsiCzZrC37gEstseV1Wuadetl8x1DTb7K6nsa 3y7YrQgghSYKLDGosX+D6P8AxP8AZv1b4+pUESoEAIaiqd24r7k00tU7122lrsJqq+XvUTKx7FxZ vhJbt2Xl2Yh05FeYLBp5bQbX3tEEDyXvdg+S6dDiqmt6AS1/k77sT0zcg/6zaU2VlW2aEHsAJndv OJHxPR/4n+zfq3xqRmzXXKg5HM98isrhXay02WlreFWojrLbP9pdEBvXG1uFgzvZCuAQSeJxgiCs Zqt7pe9axNd3Vm8tFhPp/ZdqvK7VbU0hmwVVDdNHf7NHiE2vL9qp6fLmaJphY2uFVtZWF+nWQylT 8H0f+J/s36t8bWGbdfpXnlSxDl3a1rWdlTjVr6jnu1u7y5jWhazE2tkubHERQiOcTJyATCQJ2lzK CxNKYehmUi5glK18drzBddH277SFOUwxtoLK1PdOUOBrsZsJkFRN6nifg+j/AMT/AGb9W+NpjNus VWVkLrEBNVwi6tFiprai97OavaHCSx1rFl7OXdcJW9jsvGcCC2MlmadIzdGJMpznVrryzBGfaDGz zhljE7MZuoJaxQlavt1y24MNa5Fa6zlLVDS2t6zsKLKj2/A9H/if7N+rfG8u/wDvWqc6V5Coc01l 75aPnBt+VG/1tsokstdn5OY64ikVk2hQWtxg4JAPZHwByANZ66liE8wRtlTRQi2u9pJL1iG8VxUL RWEFZIv0lIQmtlRXltII2tfuzfWa3+B6P/E/2b9W+NqIK5WG4r0lfVUOF74KqO2GdipwSqqoA5Q9 HFebCUUXPiFsnoCMAO4jWARbJTaytXfgbOwbBzChmZoSqhWFYqQtKq1EyqgFMbNCEOttLHZvMdbr pd5TbcbfJ9lI6Mje96P/ABP9m/VvigEykEIhIRX+atgFDHC5EB+QiMQAWJUtxBUiHkrFiJxJhfrk Ze5BGszHsEFk17MxbMIXAgclrNhTBYBKQXNQ4zmFlQYnBxYgYbCFWSsMq1KJwE7tSfO9FGrIx73o /wDE/wBm/VviKhaV1BRWONVJDJnDJmJiKYGxMs8KZny4x89mS2yQIXXi1mQbQI1wJa6ZseJp2NE0 kU9yiiuw8XsMZiRzACdTVgBbAooQ22NTwCgEOol6BhTlbeBBnEzaQOm/rmm/3fR/4n+zfq3w0qLR EAi1M8qUmqhyjv1YHpV2g4OelVbBSMIhBFjjk9nJ9hnNb7QjbLGF2MTXteV6PVKEQdIWwMZD1FRg 5KmBJVViBgoqBaU28H8Ujxb65bcVPfCwWAkrZ8vMQ39W+dfMqeSn3fR/4n+zfq3wq68lEMSk4XjU ldvy05JJyZWcK6HAQIiEKLmBJuAcFrXd6aEdrWTiZXrc5XqqsCqJkQmNB1ZrOMa4sepgXMSvJawL EUsyWKIrqZWyAo4Bs16nFutZUVfM7wGwVlq+7MGu2bPLar0t9M6jTf8AJLdUe30f+J/s36t8GuvM qqJldQUOwRSjWKg+asdAOo6shXLZDLjjZcqy3ZOKENhGEBVSdmzuqqKnvlXFIXxFJIa4Amw4WwNK yFl5yKjyCrErllgWVVsxFRxVR1FAiVdUpAi14FidL6yjuA4r2rKgmzQ4NiCV2CMxE2MMvmOuKdj2 ej/xP9m/VvgVV8jXXk11gT/H97dl+IpTqoxD25ANQUnvAXe1mjMc6+jdabLe6CqOPSb5ZhqhE1yD ZZUgEsYmVvg235apw0yRLS01x1ULGZmKUgFFAiRMZLKALwWSyUkMlrAC5cwDi71ho1PU12CJdch8 XmW2qy+bjPt9H/if7N+re/VQ7iqoLKlBKiWEIlQCgku9YwB0jZVl+Z1qtuI1AIKUrVlFdj7lRqHE pbYzWrmOvKVDFfdYK4Ut0jDjY4QxURLFQENQGAoIiU4gAABEFiid/BaxIFrSqoqU13MSoqNtbAA/ JWB5A5PHM7gThDVLNcmecV2J7fSH4n+zfq3vVLzcYwtRLVKOQEduVltnSuvqsByVDM1VFevXQxa4 oc2IWiKLlNCJY7s0rpPeuoRA1bS5FEOwAUC2C6uWUKKwp4kFZXY9bLYrKb6xDsCd8TOZMVLGiVAF ABK1yauAinoB0sUY2KzUxLCcCGr6nOIygxVjJN7TXYq2KHotnpD8T/Zv1b3terJprACgytOj28Tz MweQPEA9F7NXStsHBWmrQGgKoC65z8/Axqzg2ICna9iVvs35FJAdLTlDyl1aslaQ15lRCsacw6qz uuMHIRWeK7wMpilJVVyNdFkRbli2KA5BmyMgEmV45jEDdemVmRGXr555ebEnpD8T/Zv1b3VGW1kO UHyjrLLAqAGxmYEqITFQmeW+XvtW2a9devvUIi6aNWnQtwzbrUd4bqeTuLCtdYZdizuq77BbFoZ4 +uqLUjBaWlzMUofiWOJf0FLc68TiJ3YMNAM7pgErJZaWjIVlQYSq68S3ZXC3Fhf/AFfoxIBziJYI LhlWYghoc5sAdfMNc6+16Q/E/wBm/VvdpXJ1UCqOzmFnBrpsuoCL7EQCeW6Dbdutq1alNtPKrzBc X5PEKYmsAMWLXXYwjMUnehQ/LZL91TASZef9Vf8A8KhkJ1F4C2swWWgNXpn/AFwQQQARFERTBWrK KThFIjVq6WrZQ7WMwfqCxMFQwmvXhK0EXiInYyK0vQLPP1HP0h+J/s36t7gGTSoyvY9hJChRbezR VgXArrLGrRLJ5N3dKnDTY2tfXrs202dixiAjOtdW5W4rde7e6vu0tayXjL1qvDePzUEqNo5rT/8A PURFPXZQEIoKsvCU28GXYBhcRSCBOarBsosXcbK23NE2Biviw49L0BDKUYJ0esGKxQps1Kq3VtEy SGxG6TaPyedWcn9Ifif7N+re5WOuuMvzM5LUCzNFXMAJldJY6wqrniq8jdVYPUIpK3vttwoECM1T bAd7uDPRc5Ka4rN2yBZkMKHPebY57FaYNyqVobKIcBTCvMFTW1RBNuspndgTushUuris7nw9hNeq TE1eMFFma6GWVumGsFcucEOMwtiYzHr5BahWAFAXGC2ItuZu47rdu7270h+J/s36t7iDC66MYSqD unLGtFZgJ34SFzBfkNccE2ONfXUtqtQK9huld1oTWZWXeVDTQQrbl/d62srWMUQoHIuoIe5Pna/I lTDvmRkZexDibCEhXZTWwsSynMKlYrYliqYhKivYiXDFZBgCkd3LlYOGxGPyntTqMZhEeoEh7ki7 GZynmNvHUPb6Q/E/2b9W9oGSB1RuKalAc2KRLCALHEqqFsagqadNXR6EqNaZKAheYAtvLHy6h9kF q6EDtY5HF/ML806qBavl4bKqi67kHXGBegyuBeyh1NfGKwnTF1KzTsw2I1YYNQQcMpCrmtVMXWtz TeQ9bgw2KFv+YMwIL8yCCUAEBzCMwCMsKdRYUnnO3imekPxP9m/Vvan9qhlqaS8rrJhRs7NTA9yc MhVldga77eBJYJ1At4l7CZrU8zoDhd5m5bZo1wiXa3JtwAHXMvPFdq9mmpQXqodeV6ZFy8LqzlGX IxGRljWZWscbkvBiupgAMahWjazCAEGnmsauu6MtuuUdSLW62kg8uAp4mDoQfYMYKxq5chxvO7bM 9Ifif7N+re1P7UUjCvxg2MTxkOwbC7vh0cEqAtaMSxMDLipX2b7VorV9XuqdE8Gc8/MEyKzx4Wty s1FGNniy7C4OgmNa6gMWsdBsp1qGKyOliHPPEYB53Fbw0XrA9iSvZbFW1k1bOu0NWu4FJAVMi5YH am13BjkGFwSDwQWKYD1BgMHYRLUBXzug1bc9Ifif7N+re1Thq92vAuV4nVv9cV1rgyxsqQRc2PyU BVBBRmGvV3CadQCkKtdX9TlNh2+W+zFeqhu2L9fuy5DzfA5a9fGh0M2lzW7qV1LCEBBjYloHLiAG oLiu1lKqjjwteG1kUqiMK9VJUCAADLlYtfVmHva4qM8KqjdDGVWATarivYQrEEWIAbVyHVp6h1ed E9Ifif7N+re7X1Wty1YtOKmrNdbZeyxWlfI1q/CVUWWONUJL+PHT124bueFXFa3XndW2RuWjj5Nr nF6cltZqrWAu2VACYytiZGxplDxdBTaJkMGq5Tw7KFOI9KXKnfLKbQwRg87hTErZIKAQtprZzkWk 5JzMxhkI7I9Q+ZVJgUGcFw1CGGgANlDugW6p6H0h+J/s36t7tNhVkjqDMrGQmV67YCECisvZWyJZ eNi2ynTuF1NpVrMcFORr657s2AWtWb9mhFrSwZXerOaGUPVbyAjqMOAwblSWpYRL+LV3K0UAhtcE AcJWjBrPLbHbvXpsrOYi8h/UbAAlNwdLWyQwPsAllfIITWKn+VXwVYH2ES5Mru2CvVPb6Q/E/wBm /VvdHSaczZae4USmrkH+WV1WXNZQKqdWhFRC1VjbIaXfK+wf9OhQdu+1AK9wFWorDSvsI5LtUCxb qCr0XZWm0MoAItrKl6xYlZbXts1arlam6mUbBBq2UaGuuwdyympiG2aE2aq7bdK1MEHs2UBC2tRY 1yEVKcAEzEKyyoMFFlZCFgpZYtsyDL3wPO9v/XPSH4n+zfq3u1Uva2vpLVWtQKpTWpuVVNVNtkFY rmz/APm17AEsGS+XW8cqtnLaflGv3Gu4yNqhQxXw9tFgMUZV0nmNC8O7yaLg0pfI4hgyFTsa4uSu x9dq3SxTo1OW0rUlJVDWVsHcwDE26EtSjYGvYLcizDC9A5orXkpGOkHZ/hhDAxU8gwPIFbHE37+F e+zNsT0h+J/s36t7vl2uKqnGVUyvrNlcGpvlc5UIr0654wgNWHwzlRTZaq1eW2NZrlQRvVgoireu pcM67hgy9L6hYrVmu16hKtjDU3K0asMChU7Woty1WNrvW8VyIa0clW1mS+l06GWYI3qGD697EMSQ crLtgo2rsd5AwwpgxCsZIQfZyBHeKJt3d6+03K6ekPxP9m/Vvc09M2MighDP6vV27OM67fIx6VHK kENQcoFHN6+9rasmaVkHUbFXNHVqbbdfB09gEVPyFiTeoKihl5X6oaV3Oj6u0GjVq4FfE3atewjG zSspZWCcWigY2EbTsqvS1Xfo/wA0tpQxU5KahG1w6mm3XOtso6qwimDrCIUjJiWgg3XF3vYJXY3J 56P/ABP9m/VvbWvJ614Svtzh7R81ZmwfmX5WJDGg9OJddZsoF+dlYJQw5atndtr2h1Zcr5hRxegs Vas0W62zxKkOttXKbevXS2rfyWzWquWyqzWbU2BhSlwC8ZdrV2qDZqW1FXVWE2eNiVbL61xsDBn4 hByCgTgZaCrLw5W6OSll+u1V1bBbIGBEYTY6BR18xt41+z0f+J/s36t7dCvneR1rGZeONjAFEE2h H6AHC0nBB430MUvoTmbayJsZS+3IOpeCynK7OuLq1pbXe2tLAU8O+ptjLjlNiiu2tkfXtotDovAx tKpwLGUqVccZuaTONPaNdxaF8jfFZXT3GAsvJiDCqnUqMXVkgsKq6beYdBYF0UyaLqorsItwMPWb P9F6zzG0td7PR/4n+zfq3t09fuqT/Ws9NkfLX1Soxk51/wBqqjkVgiX/ACtb0GjYAHXI3td2lDiy usmi3Su5B68zzXXdU0djrwqslupbqHW22xxLjc02uldlmtYpBCYJ2Nbv69a9lHeAgsTPMdXkurvF wWIm4oep6yqagGVGYvSZ6MOl1eH7nlE6RWBGMx6wY6cItuJtHFIGBtNy2PZ6P/E/2b9W9mlqvbZa o7mvqKxiWKbKa2zB8rq3Q/JZW3ErLMW1VWc11LTW9bCyvYq5IU7u9lDDWtsrOtsC1L6UddzXs17d XZW2uq7Iu1zS1N3Etgjf0RaKNxddlsES448yXguretlBsODaDL9NbDX3oDVM67aqiadvFk6BevsP YwgypYAhWxEsBh6ywdMibtuamOK7Tmz2ej/xP9m/Vh1lGgwFahQqh66Tg/8Ash+UfK5GRX1myvFj 2VuSFJByUsKkjQ2MzkGXdrCjWsF4evmNXeau5XWxNulLq7Km17qrVtWq0zYazWmvtJZWbOM3tSu1 NHZDFHKm097Xr7LauwL1sUtFMyBMTdrxddQ1bat4srQrMztjLGBEB6WDELlTXd0ssAW69ASTYd68 VUn2+j/xP9m/VtFFe9k51UkkUNLUNVwOQhGNqoLK25JWemyHYVuCO6YmliVu6pVZ1UtTZrXhlvqS 1WPg7+eWvq75dDzBqyzch5l3inQ3gl4tKs1qvXbdbrW13iysv8u/rGp9XaW6ougm7RW1mtsmphsg lXJirmFOm1XlLGudKrbKX19hbVV8xW65BjpOOAOkuyDXaJu7pMUOzE4HmV3N/b6P/E/2b9W1rO7t 1bAy2Kaba263J3tdLgxTg2sWrqbiwJDNkhkNbIcr3hRsh1q+V6wrDlbpvVaLa96hXSmwoa7QrbaL jR2Q6WqjrveXhJp71oCWnlvqttHl22VfvGMJVlbSZGCW4uLd1ZgDX4musZiLiGWDMsoXC1pGR9d6 NhLQrwGdDDHnmOwak7+14oidu1sLWjuXb2+j/wAT/Zv1aeW7OQ6d4iEg1uJsVmtltDBHBGwjIyPy VbOlwNgVjFbIqbiz4BRxhXDprXtVYzBh5hWyNRd3ldbhlvLal9e13lbOGF9VlNtGwlq94rBw1N6X CxA4MVgQWLR6w67KMraDEhSAQRjMbEsSOpVlC2JZqtW1e1graYrCMY88xPO1MqQs2NhaRde9p9z0 f+J/s36tKLDXZq35GxQVgbEUhgyNS1dmISHUE1vygfpYOLocHlhyWEFzUtVbk7ANb621zr2UF9Vb HXsRwZu4eny7YwweWYdW1LFNRcHc+cVFAlbFSrklRGE3K2LVWFLkw0UGdkODDLlytdprZHzLtVbQ ve0GuziQQwvcKHY2WhRh/kS+1rLPd9H/AIn+zfq3s0bXMq3qnqtVQVs4nkjqWKOlsuXvERyQj5jD mtZzLADEPIWKSKrCZezPVq391bW5m3SGmvdwmRYndpW1W0rLW6tFhAwHFuztV91cg5CrkIrEwzaT lWwYHStJFbTtAWMsZci+oiU2uJU/INWrq6mo1XMp8w2AIq9B0Hmexwo970f+J/s36t7Naw1XCut4 lSCNq1tLNa+lu6Ngs1rqol/WxDC+GSwYsJVhcCKLClw42K9ViMlgK2qVfV2QwQ1MH0qLINQLNujE UrzpVUVfmIQcdjVMtdy+uVaupMFR0jLkXUspXmrUbIuFdoysPYwj4zdVwlWwymrZDje2VzZtAKtj 2WgTZ2UpW+97n970f+J/s36t7fLbxajICgURkBSqsMhpHK6pQ1dOFuor4mtllaEqdRMtT1o2HEqc Ovg6nO1pmsqAF11ZYrExU6by5qU/7KwMovsuQshq60MENWDF7MQiX18hYhVipSU7NdkrtUzMY9Cg 5bJ+V7XrsG7dz45IQCVDFmzvV1C657W9/wBH/if7N+re3VvNFtWwliVv8psWa7/M6Ai2lDXSpKtX 02U4yoR6pcgmtUQddZXXNusyyxjZWcioQCbK5qcogpPOmo9JacJcuHYkPVcCKrFZRDMEzaTB1bQS +mlgpD1213JxFiPLGKjd2CgUZncCceJvdKqrNwgFix+B6P8AxP8AZv1b3K7bKzR5rdXE8yRxXvIr p5jQ4dhbXqkEWnA2xxmsymt1U17GOWmzGygZYdJtjNTgk0nNdJyBLeq7AK2aOwhNRwwlg+WylXS6 ooyOa5r3gFWBBh7L6Q6n/VZTs9Le4JtZsq11VzX8qmu8RYAYICs8y2hY/wAL0f8Aif7N+re8lhQr sBp3qTT2hS+pYoezsvWvFI4QfNXsqvdrlbNdsOvUWAFbk42aTHGu2YsYTb1U7161qei3ktb8g+Cp E3qspghkbidW/wCY4wTHPTYpBlNlWa0paeY7NXe62wOe9sm2vUOG7J3igbe+ioTk/C9H/if7N+rf AyYrsp1bMEOHRguXb/ZqnlXcAC6fNQ5MoPIMMTdqK3DlW9GyjMhBDLL0513DKUWMjU2AMeo49bKw VtTgQ6sFfkNXY71D0jsSb3VRZ/sdA7LwCOqgzbsSulNtKw+7c5a6xvi+j/xP9m/VvhauyVai/wCR 7Y1i50HBGyArbDDNfR9GzKHqNtAU2usSgFdG8WV5BBAm7Xwap5WWmtaLFYQ447VbMrNwdLuDa+13 brYti32d3N/c52V4ZV7bUPN9iuiu+97n+P6P/E/2b9W+EOk1tzAbaWW7Kg+V7Kuu23KXEFKnyunY FsXJFgyuwOmrcoldgpvBBBww3agay/B1t5DVvUWBgwtBUWW4W+8bNgSwxCdd6vMFAuvd5fsK9te8 laVeY1l9vzMuWdnP8D0f+J/s36t8TJ9nlm0ambYNgY5lVwD1PmU2gqSGG+nB+97uxb1sr0dwNCy5 tORv2it6dliNezrRYCXvRB5tvh1ovVWG7WDbvq617q1C/asuP8X0f+J/s36t8YEgpu3IG37mAscN reYMH1NkCLYCN7Yorpvva2xNu9B46/Oj5jWdbd89pVLbXtfV2moYeaUtW3mOzk+Y7JV3Zz/K9H/i f7N+rfw6t7YqH/cbeLti68+3JH/Bej/xP9m/Vv8Am/R/4n+zfq3/ADfo/wDE/wBm/Vv5b+SeZV61 nkHmlext6mxp7GDCrD+Z6P8AxP8AZv1b+XZt+XhE2NTXq3X17vUXd+W6NreYal+r/L9H/if7N+rf yaDULhu+gZ430BPG+gJX5j6Eqst8x9CXWeN9ATa2/RDa38r0f+J73knlXmNn2l6bn2l6bn2l6bn2 l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l 6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6 bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6b n2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bn2l6bmt5N5Xqa//ADv/2gAIAQICBj8A /hU6lKFPuRdv9W+ENS+iKNPk0pyiSHr9RCNdKjjXXsUdIqxqkL8kxQ37PDUjCJwmH9JHOrJa/S6I TamdjQ0rj5J0PldCKXpvueNlYF5qU/Zk2RU/USnP0C7wOdLX9xuKv8H983iNW/Gasovlu8EyZ9sJ X/b12SVwqaZJI5w/uUwkpqtCq9RTv6WuWN3kdr3Ha9vSoLLONMtChMFUTbimtdyGozwQsK5JZIhr ZZqY1woVNRv/ABzQUq8IxcbGop1tG2TBTJphUoaYQ8jtnXNL2yq1av8ABKwjgqTsQUzamv4Ihe2b yXo3O2rJU3XO6XyWpqsFBqNyGRtj3wnJycFdcrfpTbbV74JCSWokN9MsPCmGmXXBW++R53Gp5PW4 T4wrgnhQlY0OHxjHoVzTshplq6DbPJC6sSdTthJSvQqjddil3l3wT3IKmq9ThEWkcELY8V/2IF0x lYSisLqSjqK5Y0yLNXBDncRc1rMIck4Th1RKpcRcibGRceDra/wcohkL15EUwjZ6EkckM8rSVRop +rdYQ6XLTrgk8Iytvj0vyQf7Ekboh6kbPQh/qRDquCbaMnRo8rdVqSK5Ku53woRcUf3KC7i9LsSR wdSLthX278Hj+4lOz2ZT2PK3XdCa2FetyUSvsRkhkogQl6bTK6ErTY8rV8lqjxIjsQ1Fy/JKozyW jHa9HhXNBRYN54y9UeLJPK3c8bqwJ8E8lCqyakOjxqUUDtXOWCV6EokgkhojpOeUQ6kobe43nnPX CjIwoVy6YQhNqJKuSux0zxsU9FE5oIdSSXtg/wAFfRlFVJpGZ5YIIeEtpEboSWxQr9NTCURFRf5C qPxJf0E5aktnyohO1yQlLZCJkl/Ta/zl/9oACAEDAgY/AP4VFvyZVwuLSfJz3qKy9ynu+fqpZC+K ZMdyqfQmZfDRC/B4XfqX5+ooVZphTU1qQo9ibZT5FP7jUcHi1HX6aMaETGXQoyqNSY8rfyS2aFPW Y+6F6M5G0iI9zxmr9Zrk1n0tCcakpVKXIj9y5Sj4tP1Ehr0KVJ8YIuxkpg4wVyemorlv6XA420E1 xmoTeyiIW5Drdh5XaHTGpU1SFbfP2PKxys84SyftkoQMsardcqkv7Et+wnrgm68JE3UWyxphDqaw QqojZ540WEckLJTcRDZD2J1Go6lVT+gm7kpPjUosKvBtYTgvITW+Zjb0zSUOp5RoKaCJWwrkpkob 5GUyf+d2ttV2ywV32Je2izyTqyeUW/6o/wBToxWvYawqymDawqUORNbTlZyyizSyRW9cE+KYRseV m5q00NXNv3NcWRkvvfOVpOOok2QnHU+Lh8lXXJGFNimxfayhDUEXPR5K4QTjDElvXIvEqiltSCN3 lSPFlz4Q3aP/AOsH0Ifx6lGVNIwh5K0NS3m34v2y+S1WpT8Et+w8svYkfXCVuRcSmVKVzo0JL+Jy w3+rYoeTdOBRp6PRnjdoTa6EXIoTmqUcotstUu5xB4PVa98ksd2C6YTmklEPCHph0weEL43fhkOk Ywf+9+36V/cufLeRW9BrBdfR6Eoh4RjBLIIfy/qTDgh0F3OrtSyNvY83yJ9RofSuHbLBTCMZw7sh 4zuiGSWWazcixYt8Db22LrcFcvcRDoQR6Eld8IQqGq8rdP8AghqHg8FZbWTzurd/Qj/GmLXI09GK 5HktGOx76dzsTutTqiTsRhKIbwTWjKOCdSeHjEldeSpIrXoUUCSrdBL3yTweNyOjJROj3OjIe5DE U7o8lqtS61z0KlTxffFpjTxlFDoXfuNa0Q7nsiXljk8W2crqdOBXKk4RdseVuqIuVVuhLdfcoJi7 FRyp4HGjwk67EXYzbRMXk55NrbUQqW5+GUUroT4sc84+xLHimq74ewo1RDwdu+xDNUVXxt1Ig8ud Cvpu5bnYVxHJGHmtMImh0eDtJwoJpxOqZ4V7itT6vkomyXSNF6kMdBOBE8EkrYgROzIeqFGwm1rs Rba3Ir/3P1bIVUPx+XUl/QO17lIJVSIlDlQuRw0uDxVujFbd9ybLlXk87353bcI0WEv6aXba/YhU /nH/2gAIAQEBBj8Aac4xORIC97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0 gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IL3sPSC 97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IL3 sPSC97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IL3sPSC97D0gvew 9IL3sPSC97D0gvew9IL3sPSC97D0gvew9IIyjOJiLkEEBd0+n9ef7qkSqgj/AEH8g+Fu/Imu6fT+ vP8AbtGJPQgZdiPNDUdUsytMdq2LBe7jVGezSWSMNwNIfv8A8g+Fu/Imu6fT+vP9qwDlDc3exDmm EY9m/Mo6SBEUotMWJTzublPGVBcCy7JBicF/7iAaUR2hmM/3/wCQfC3fkTXdPp/Xn+zogwYZoGch KaLyMYiy9lGuZWmIAfBajXJaRGuKYsOSZ6FGE46hbxIyjXalUH99+QfC3fkTXdPp/Xn+yaIco7m4 HOAWoxAkylMgACyO2P6Jo+dLFe0mXawWmMdXNAzDZrVpcDkqUOBCMtTtgpRnFhIMxzRasDY/vfyD 4W78ia7p9P68/wBi8qRTxFqLUD2hVCRoSHKlVojJaNsVNyhPdm7VAAWnbAIP8lZ2uy80iPNNY5IF qlPA9IWDIwmHH9k8dxo5FMN2XtWu1HRDOBj+6/IPhbvyJrun0/rz/YapWFkIgIx5OUduVoI7TtEB 3CGzCj2RnuFyck0Rph/uKYdohGe4Gew4CUgtIr0KzdKJDya5FgiIY4lUfxLIC5KZ9R6KIyjFonjp iKrW2qP/ABTEMqKgVR+x/IPhbvyJrun0/rz/AGERjcrUcaBREfO3MUdsedKrpnec8V7Xek8sBkno NsF0IxiZHlVSluAxBNAVpAJlkEJTHWiRYIiO0/MKoaAyxTC2SqERCLDMrtF00uxEYrTOsDYobUaP c8lp3JmUhnQIjbs90IyxwR9ntiLfyNHTiVRyRA0kjCxKMN0GJGBotUOrhQKyt+p+QfC3fkTXdPp/ Xn+vEc0+ChL+IKEibCi9tuG/mqO5uUhG3NDSGjmhEAyLYIy3AxOCAjdVuiSKYIxjSOLIwjbEoABW 8ap1rmnKcFGtTmh2iJ4EL2re0matJe0EIxeulCW4wMcAtc+hlVgFqidX/EIwlEEYOiDEmGElqmEw CcpyKI6KFMbj9L8g+Fu/Imu6fT+vP9cJhchDbiLVJyUIxFAXJ6FGDNCPnHPktO3FwRfBDVUsjOdB g6EduoFynYA5rVI9nAJolgmv/koAiprLpTgeNVGrlZPLqCdVsmCYWxTs5QBOCAHnSoCiJ+cDUIs0 GwFSjOZ86wOSJPBtLqo7JXYDp5ogUAXNawL3/S/IPhbvyJrun0/rz/YF8ApnGSjXt/5Wo0k1OlDW aspSn7vAFeziHiBXJadoVN1qn2pnNHUehc0CzAVCzkqjUcBkmAtdNYclbgyGCBlJzkgbrECNQmBq 9c0NydICrZlUKEY1zTyYHNNB5dAR1QLc1pNYnzU0VzTkUzUgen9L8g+Fu/Imu6fT+vP9dzYBQ6CZ KZPmxNFKZ/jZapGkbdKlqqAWRANBkqDSMURCslVNH+qEXqUYxpICpVO1LNEmhKZ73QATCp/sqlyq DxrUShpNk6MoiyO5uWBTRLR5poEyJuSjGAfcNkJd4lqP+0WTRDRwVQCE8eyVp3qHPAp4sUQRTJER 80og+L9H8g+Fu/Imu6fT+vP9eMjeQdRmLyLIx61pFsU0aRK0RDBFhQYqp7IKdHFUouzfMqQkelrL TGpwQiqYJzUomRZ6tw58AQelAmy0gtDFNEUVAUzPuH+ip5xuU8qpgua7YcosHjiF2JERNlUpqKpZ k8e1yRjMEEYHw/yD4W78ia7p9P68/wBaihmyjkKrWbnBSljIpgnOKIQGF1zTRxuUzYJ5ZuyDjSJf 1VKc1qkbpooh+kpo8aKqZnCchOaRC0w60wqcSnNkFzQkfFwaxTSqDinIsnFFZc0d2I/7I3bEeH+Q fC3fkTXdPp/Xn+s5UJshHG6Y+JPkmQyCPNU/iuSACdF6BQ0g9k1J5rniq15JiaKluDAErtUCquyE Q6NVUlskwHCl1W6D9JUW4c0QUYGxsqW4VRKNGjKo8L8g+Fu/Imu6fT+vP9SqsqCmJR2yPN4Ap0EQ f4rUKk2CfUdRuMEY4hVQAwuqWjdGUyIxFYxz6U5PiCpRZrILtF1QeATGTIueFU54ajQIHn5y7Uwi 0qdC1QkJDHg8biyc0OI4UFEQKNiiCKix8L8g+Fu/Imu6fT+vP9Nzwc05KRlc2COq5sqoZMEIonJG R86TaRmgBWRuVF7lA4Yo5YBGMPHLJGIaUs1No6nFzgmknFlXwLprsmPgVWkVKGrqTNZVF0OyFQAA 3DJwGfJaoEyjiMkJDC6NHOS1kXsEwsqSITTJfknjKQPiRntn2kBfPwPyD4W78ia7p9P68/0nPCyJ RlIsMlROzLkAEEVEn/bRaineuCr1LVORD2AuvZxGk3JQo5uSU6MmWnEcHNFpxTmgTu+Q4Eg1XMcK rTG6cqiqrKvgGUbYxTx85aJjVEdaDFjlwbgQaujp82VRx/IPhbvyJrun0/rz/RdMOHIJnZrBCDue BQAxjVN1pzSI/wAIzvEUj0Jhc4LmvaTDQ54rTCNbUTyuuRX/ABiVrzRlgnKpZSe4KawTQDAcCyqr rTC2ac18ByUNK/ytTgnJV6lROLPXhZPCXiXai4zCqCqGqEsuP5B8Ld+RNd0+n9ef6GpqBBFgwHAu VrJq1An4DmhG500QDOBfmmAYDDALSTXFlZ3xUSA9XCaPnNZOwc4r2cLCjqtWRcdlMTR6BdmgOCY8 CcDdBx2UNJ7JVK8GCr4FFQryoab5p28ZVb5iie7WKyTDHi44WXkQ1Cj34/kHwt35E13T6f15+GAh CKbBSAz4VtGi0RtinTrVlQIEVkaFdsvMhzyQALRGAxWqJqjW1QFomCJiuqyEommIzTWGSpR8V2Q5 zXaFclqjRBOmRJJMlWoVbINUZZrU7K7qnCn9Fl0qpdUYKpQHGtQjKPmy/ogTda8zZB+DjhRSgRU2 6VLbmGIPD8g+Fu/Imu6fT+vPwwetEr+5T51RGSPNdPgHcDxhG80SZHU7OcQr+NM9lqJYYDNFhRPJ OPGUAzvZkxockdVEWxsu0HOaeJsnKKMck2BXs5XFiqqnGyrF1WJBXnEeIphuhdmTqocZpiW4MiD0 LkB4DqvD28B2o36OH5B8Ld+RNd0+n9efhBAIhaR4yiyMj5oVLBOeFUBEdkVkeSG2ItGK1xpyTyuU Tc4rVKwCM5Dsiqd2iEYxj48EYyDSGSEhezpx5y7V8EZSqWQlgUyOlF7ogKMxcFA+DQpzVUCqEDCR iclfUu1FpJwKJ04xuqUoi5ZVPCgVlWiMTYhThg7hfkHwt35E13T6f15+HqN8Fy4PItAXQ29ukRds VVMnKANnR29sM1Sc1W91EEY3QjEaRnimihOZvZGMS8T4lomKGjogiwoVrkWcIC20P6phEB04Unuy j0p0ycCiB60W4t4Dq67VShJulBMQ67JOlVPAD+QTm+KdnVlRE8CyhPGy/IPhbvyJrun0/rz8FkBm tOAutMKlapmuS0xoE5XMpohytUvOwGC0zAjLNPEuCid6YjS2KnOBaGAKYF6BHs+N8EdvcJf+JRAJ 5OmNDal1pagxKD+aEwQFpBF8k6jyKZFauBo8SiBQZFVQkONSs0BAAkodqI5N/wDdNIh8hx5Ix/iV Vc0Yz8RWkvSxXZKomThEqEcl+QfC3fkzXdPp/Xn4T5IRjcpo3OKc2wTmwXZCcldpNqYp9SaBMpZY I7m6dc53FtKGh4zF3sVrJtiogUaiJ80Ylez2y5kWBOSeXakbkr2YoXZaT52KlA4IgIgqUTRSgcLL nwIKIemC0mrpwFpIbmmEiKKki3WvPbxJ9ToaiqBUTkDxhCJjoOaAd1ROcUODFNgqCuBQZOqqZ5Oi cBQL8g+Fu/Jmu6fT+vPwelUtimF0DKjoA2QAFEYgVTgqpYhPqVZdnJAm3NaYsZqVGqnc6MV2YGUv 9zUAWRswW3LJHciKsvayqTJ3RkbhEiylOVcVKWZRRGBTGidVTxTlAqiZrcHjQp75roTnizUWklx/ FEO6r4DJxQq7hNJOFuf+k8PyD4W78ia7p9P68/AAQGCYLXPCyt41XqQ0FwiXZuBkTRUDquCDxBCL XwZMTgtM6bcT5uaMYsNIspzFYEsY5hFqAGgUNoYs6gMxVF0SKYhSIwuq3NUSU+DqqcKtFSqJR2z4 uLhf4TlVC1bZcZLRMaZc01k1yui3SibGKdADx+HWyO2DWZty4fkHwt35E13T6f15+AOGqQeIsFk2 CZ7p3cZLVgniaJm6HWmwC1SRNhYJpFmXYe2CEmeRrVGA8aGzC5v41IDC5WsdSgBcBiojBk5siLBS liVpmGkKcAedUOhFVstUDTEIiQbmgRa6r4FExCBiUNcWmMbIEy1QOacEFURk97oOMETjmqeEaKYm X0lhw/IPhbvyJrun0/rz8AJ5Joqq82q06KCrowFgg+ODoGVA90Zixs60iqAAbTfJ0IigJAKj3fu4 BkaTndPC4FSjuSqVKeDOhzui4RN6kMjqoUGqyfB6oc6pxQ5rRMOMChLAlR6ODhV8aeNcwuyTCSoB IZ2K7QIVDbAqoTSLHmnEgg1lUVC0yDgiiYnsnBU60QUxdAiNTkqUPhmTMJ14fkHwt35E13T6f15+ ADkmlQoGJqg8uy9SgQKNddkasJeNSsIPggYEkjNPIdkIgeIIydg60xpEm5R3MQGHMrbka7ky/iCI nZlLTUOwQ1UMgzoAWV2WjMuhKOCcHpCiBioDILkiWqFplfBCMz1qnAHB6rVErXtlpZLRuBpc1Zea ECAQ3UmkOpOJEIQkbZpxwY+IpjUZpzQIOHBQANOSMYkaisJDN1UMnNOmyrIJky9qBWH9uH5B8Ld+ RNd0+n9efhCUS0gtUv8A8oONMAtABcvInospAUjdaY2xKOgWpVVvmVpHZjeqjWgNStAsFHdngGiM gg2S5lbZ5FGJuEY5I78h53moo5KIlZ0I5BMbpitQtgy1msM0K34MruMlkyeVDmEW7W3H+SoXITEJ wFWxTg+I4LTM0NinwR1BslbgUQfNaiJbxquCsmZWCYLI5rcif9pRX5B8Ld+RNd0+n9efhNgVpeh/ yomXZDO3QjKZ00pEUugdsHmcFXxqTMGwWuVWtkg4M5XZA4mggLBA7w824RhkbKUpZYog5ll7eQvS PQq2N0YO0Sa9CjtxsOBenNV84IPwdGJRjIdk2XtNoPE1MUBUHIrtcHCquwaH+Jshu7EgJ4gUBQ29 +Gk21YcK3TB3GIXZ/rZNjG6JdMOLIxl4e5In+JHD8g+Fu/Imu6fT+vPwxuyqxoM0SRSw6E71yRBo cAtIKMrQdulREBWRYlHGZuUZAVCBIcFnOTqMx0KR5LSKbcazP+FpiGERQItmhOJ7QxQPAi6pSQQ/ 3C4Vb5cHiiCFpmOybLUL3DIuNUcCFQuBcJjRUquScURjIdrAobW+H2yWE08TQ2ITBO/ZxXaBEJYq lSVqN1XixTXCcKoTHgckNkGsi54fkHwt35E13T6f15+FpgHKGsvL+ioWTmpRkCychgcTkg1hZEjA uFGeYQOaEIsA4c9C6MUWrKKj/ulUlHmjKQcoEUjJaeT8LLWBVao03B/VZSFwq8aedgvZ7gqLFVFF qj2TmE8Trj0VQMSYHEHFCtVSiZdqLkWR25A6DQAmyd6GyIKqCSMBgquGsFdU8HlxYmicXNgiTfh+ QfC3fkTXdPp/Xn4QlIdqSBHEPa6pbgYnJezP8TToVEI4lHVQKT2IZRMgxTozsylCYqLFaSe1FwmW aMZBEOwBQ3Nu+LYpvNkLxKaxTrknxXst4sBaTIEGhsmZxmu0BVCVZwxAwQO32syn4GcQ60yNQn1d SJBcoUY4lXfw3GCOYTkpx5sbKR4fkHwt35E13T6f15+CJy80VTZIgo8I80TlRBFRmKVMSjE+Jcwt LtkVGRrGBaQ/yhEUCoiGuqGxaSG/tUIqQMU5x4OAvaAf+pGEqDALXAtIWK0ToVoN1ROSmID4FGE3 nt/1CeNQmNCtJDOvaQH/AFk2yQlHG4V0XWoUIyQD1VFIkOcVr23McQgHriPDLURjE9kXKJ5KRzPD 8g+Fu/Imu6fT+vPwIxzKEcuIIXNRzRjgSCgRZFbkcQXHSokInNSGOantyHnI7ZvG3RxMyKHFab6V q/8A5yNsihEngYyDgo0dxQ5IdSaYHTkh/KGEsQql+ab+qpYIuO1miIVgTUZdCE4yundSF4laCWi7 KhcHFGnCgbg4saFkI+c617Z0k4BCO7WOaeJ8E9CPSVp4/kHwt35E13T6f15+BE4RqnQ5qPNAhAoE WUZDoKpwkM6hS28Lx6CnRKhLAn+hQ3BeN+hAYEIC6MCvaRLxBaQKEohwcCmqYGz4ckIGxsU4KMZC uBRLVj5ws/NOA6YhaoNGSECwnHJA45cDOBYioXstwaXNMnTEObohmzTiH/ZjJ17Hcq3my5JohyUH ueJahRiA+4blaZ0kMUAViCcQU0Zao5FVockx4E5J0Y4R4/kHwt35E13T6f15+BCZvKpXNDpQlkUR iyZSGLUTf/ThA8k2ahP/APU+NCY86N+hMSs4lNEMYmiGq4pILSD2DWJ/wmJ6U4xUpxsfOZDak7jE owlV8UZMZbL0IuEABqjmnGK1RbWEYnzSWkBgUJBULFahTcjYhaJmsaF6FBMbLVtRGsVJ6F7OYaca cCXYioUZzoDbNaoyfp8HUA6Eo0KrfjVf5THxKXPhM8+P5B8Ld+RNd0+n9efGMiGgDUpxaK6UyIyr 1Lnw6VOODuEY83TgsRZEC4t0hVxoQtGMT/Rc0JYhf8dz+60HxHIrQfOH9QgCUQbFPEGhcHMK7SFC MVo3A4K9tsh9v+UckCaRNQhKJviju7XnYjNDZ3AYiwfNagQOSBGK9sLnzgotJyFSjYou5da9s6Zj EJphyMVXxLRIvKP9lpNjY+FyTjg2PAog4IRzsiTgFI5nj+QfC3fkTXdPp/XmmUdzdDA2CAjQKQTZ UK6URgpDAFA8BMY0KcXH9kKo1oUR/GVQtcayGHJAGyzBRNsYnmnPnCkguyWlHzSht7o0yx5oSumk LWXtIR1EXiBhmhONEYmoyTiJlsmo/wCK0xDFrKgujuiLkDtI7M3Eo+a+SYU5qUZEFwjGQo61RqDi qnwIzIcG6Ex2Q9FzFwqeCE8Q6syqU+C1UWqXiRGMqDwPyD4W78ia7p9P680NVRGqYYBwmuQulcpW K5jgNyIpYpseHQq3XZkwNQE0qkLV/KNQgXoUJR8yRpyVT4kYkdCErA0kBlmhOMqFOG1Colihs71M HKcHoWuJIwLI7MnEZVAKiR5pubsiC1UHoP4yFEJx8aINdS9rtUODZpj54uEAhuuY8wjAknbwdUqr 3Tvwc3C/7JNHktcH04pwa4jw9RqE5LckNvbL5p5F+AgDa/gfkHwt35E13T6f15oHA0K8S1Cglbhz jUJjdMUYNdNLC65cHNpK9rLUBe4T4FGBsKjoXs5EEGwTjtRNwUJxNCjNu0htE0PmlNKyG7EO1+a0 ana2aImH5I7uzcV5hDame1/dPIokedGqlsyxt0qqIkHCO5sSZ8E8rhESFM0MAgGvim4kZoNfELQf EtcbYhdk9rEKvghqkp3Z8lzTZIlGRx8D8g+Fu/Imu6fT+vPhpkahMLioVbjgN2Hmm4GCB4e0wN1z HCmFuDog2NVqjeP9V7WIJ/3jJENqDUdCIPYJYjIpjZPAtpqEJ9a0my1wJa6jMFwUQ9CtQsC4Wp7Y IjBa4vqBoOSE443GKofEnKomlVGEY2Wk3CZvAcXTlMVr2rhadwMUD/E+AI5BMRROiSa4BObZeD+Q fC3fkTXdPp/XnwEh40Kr2oHZlfpV1plYr/ibHgYmqMT4k/DlL+/FjZao2lSQWAfALUMVW4oVQVVT 2TSQQY0wTtUKWyTzAV1WLo7m1Y3iu0D0MotHtIh9G4D1qpcqllbhqjlVAxoMUD4LpuD2Oa0yrA4o G8SnHCU+aCMjgESTj4X5B8Ld+RNd0+n9efHSLxt0IQnQ2IKJ2zqicFywRjKxRi/QeDjzhZNjw/sq 3F1S6a5CZNjFXstLvqoQr0yRlHHBaJ0IsiMCpE9mcagoOWOKAEnTJ0ITLQsFIRPZDFkJPgnFQrcC VQXWiVxZMeNkyfBaSaJnWmQotEvNwKYlxgtIrI04OtAPal4f5B8Ld+RNd0+n9efGMsHr0J26E1gm L9IVC8cCmmGyktQLhMb81r274oG2aqtcfNN02OaINjw1xHSiDitcLhDX41RORXkuzIsgSVo0hs8U FbgZRoRV0QSScUHFOSeEqZKvAg9CP9EJR84JpUmExvxdMauE4TxuLrIrTGpzQas2wRluVOAy4HPB GUy+Xh/kHwt35E13T6f15+Bpke1FCURXFBsboglw3A6i4yWqMWr/AETp9NcQtUS8XZMbFULJ3dlQ O1CV2g6JAZ1QvktMhU2IomJoUAnKJAsgeaA4MipFmLrTgUGNfA5jgNyFxdP5shgU3F8UQA5KIiDJ rrSOyDinJJfnwNXCIBeWQRlI/ofkHwt35E13T6f15+AJ4YhAwkCDx0806mTcCiGIIXajTFHQHi7o c0DfMJw4zCkCKu6qC66U+aECLG6APiX+eEhyVC8iahQmLtVB1RFEyLRKBjgcUJDxpxwdVRWmVUZR 7J5I7Zk4wXaLEXTRkJHILmgB50rIvcpyEDgtROCMdvG5Tkuf0fyD4W78ia7p9P68/B7MiExqE5FV qNEDqZdiVFEPZVsjprE3CiWTtVHJESOFOJIwRKhPHHiQjSoK9nYHPNaTwKIlitOSpUG4QyKfjzCu xXaNM17SM2kMkxldaoF+hCcsqoyHmig4VVQvZw82P6f5B8Ld+RNd0+n9ef6FeGl+xOhHNDJ24ZyK 0nAv1oFERuonL+yrjwMTiiMkds9ITYjiJEdmSaNMinNxQ8WQkMFWxWjDBaJ+JU4mS0TKcGMY4lDb 2e2wqyAmDBkYwpCIqc0Wx4VLBGG2XkcU/wCn+QfC3fkTXdPp/Xn+kC6FbsUE6BFjRMUzKzOKKJdi KFdPAlqSQkBarIGJY4gp1RENUVCB/kFqvE0kE2fEgovgmxwQIPaimPnDgwoEST0pwWAsQtJkWXMJ 2RBLE2CJiHKuwyVZfq/kHwt35E13T6f15/pxjK1ghVV61TN+FFGQtipNY1CbJOtTViozWuB7YqEP 9woRxNaSsEYnFNjG3Qq3F+F6omIfNEEaVq/ugY11XCdFCEfNie0c0DwEgHGKeXnYBGUvEP2H5B8L d+RNd0+n9ef6jEsVdOCol7hA0RAwXMK9CqIg2ZSibg0TFDcHmblJdKfBFixyWq8oo4IEGuCd2wkF RdipyRMjpIu9ERFgIm+aAJon3KwNjkiIF8gKoz3JaYZIkCi0sSV2wwWnZpEYp5F/2P5B8Ld+RNd0 +n9ef6+k+JO9UUYvUIEYVQ4ahXUnTWyQ2p+cBTmq3RexRETUGicB8084kajQpwaYhEkowBZ08qcN ADA4pgHVaDL9t+QfC3fkTXdPp/Xn+u4oUzumdlqBLqInZMT2TUKhUvakWo6MnYYJhKyfUgTuOQKg ox2e1PNGcy5KzGSMdyNcEdMyBgmMn5p5Fz+7/IPhbvyJrun0/rz/AGmkScDNMCB1p9yRl4FD/oX5 B8Ld+RNd0+n9ef8Arn5B8Ld+RNd0+n9ef+ufkHwt35E13T6f15/vNrvUtk+y39PsjjLX5rDmtvu0 tk+03QTBqho+c55YqXd+8QMN2LOOmoI6VZVBpf8AefkHwt35E13T6f15/vO69773/wC1fY3O7Duu 5sP7TRHzxME2iv8A/P3O87c9/vEe+Hb3BJ4x9sYmDyw1aSv/AI7ZgY70dk912N2Q7UJyjpjLpGC3 I757sdwb/epiLRk0TD/rBBjnYI7W8dgjc/8AjzKbbcBI94jICPaEQdQH7z8g+Fu/Imu6fT+vP91t neBO0JR9oBcxftN4lXufeeseVf8Ah956x5V/4feeseVQ3dvuveY7m3IShIEUILg3Ut3d7r3qW5Mm UpEipPjX/h956x5Vux7t3XvEd8wI2pSIYSaj1/d/kHwt35E1Hd793WG/uQjpjKYLiLuy+37XUfKv t+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ft dR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUf Kvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7 ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37X UfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hy r7ftdR8q+37XUfKvt+11Hyr7ftdR8q+37XUfKvt+11Hyre7r3bu0NrY7wDHe24u0wRpL+L/Xv//Z"/></svg>
diff --git a/silx/resources/gui/icons/plot-window.png b/silx/resources/gui/icons/plot-window.png
new file mode 100755
index 0000000..ea7eb3b
--- /dev/null
+++ b/silx/resources/gui/icons/plot-window.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-window.svg b/silx/resources/gui/icons/plot-window.svg
new file mode 100644
index 0000000..61ee6f6
--- /dev/null
+++ b/silx/resources/gui/icons/plot-window.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata>
+<g transform="translate(.27119 .40678)"><g transform="translate(-.91869 -2.2683)"><rect x="1.745" y="6.35" width="29.805" height="23.023" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".21"/><rect x="1.745" y="6.35" width="29.805" height="23.023" fill="#e6e7e8"/><rect x="1.745" y="6.466" width="29.805" height="3.083" fill="#FFF" stroke="#000" stroke-miterlimit="10" stroke-width=".2"/></g><g transform="matrix(.77205 0 0 .77205 2.9938 4.6274)"><rect x="5.443" y="5.907" width="22.104" height="21.774" fill="#FFF" stroke="#00a14b" stroke-miterlimit="10" stroke-width=".5"/><line x1="10.121" x2="10.121" y1="26.228" y2="27.445" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5"/><line x1="14.481" x2="14.481" y1="26.228" y2="27.445" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5"/><line x1="18.675" x2="18.675" y1="26.226" y2="27.443" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5"/><line x1="23.106" x2="23.106" y1="26.229" y2="27.446" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5"/><g transform="translate(-2,2)" fill="none" stroke="#000" stroke-miterlimit="10" stroke-width=".5">
+ <line x1="8.689" x2="7.513" y1="8.26" y2="8.264"/>
+ <line x1="8.705" x2="7.529" y1="12.62" y2="12.624"/>
+ <line x1="8.722" x2="7.545" y1="16.814" y2="16.818"/>
+ <line x1="8.734" x2="7.558" y1="21.246" y2="21.249"/>
+</g><g transform="translate(-2,2)">
+ <path d="m8.894 22.083c1.279-0.466 1.521-1.852 1.816-3.051 0.472-1.914 2.476-1.43 2.608-3.744 0.026-0.451-0.108-2.314 0.439-2.495 0.349-0.115 0.718-0.137 1.046-0.329 0.636-0.373 1.043-1.117 1.274-1.787 0.216-0.625 0.394-1.25 0.563-1.89-6e-3 0.024 0.46-1.912 0.784-1.102 0.575 1.446 1.029 2.918 1.45 4.416 0.276 0.985 0.626 5.058 2.067 5.165 1.46 0.107 1.508-1.37 1.775-2.526 0.11-0.474-0.442-1.211-0.105-0.205 0.149 0.446 0.224 0.926 0.314 1.386 0.162 0.831 0.262 1.673 0.434 2.503 0.158 0.763 0.541 2.86 1.448 3.114 0.34 0.095 0.62-0.116 0.738-0.419 0.411-1.056 0.119-0.812 0.579 0.213 0.165 0.368 0.341 0.793 0.723 0.978 0.693 0.335 1.302-0.7 0.605-1.037-0.676-0.326-0.62-1.838-1.458-2.27-1.072-0.552-1.386 1.231-1.606 1.797 0.246-0.14 0.492-0.279 0.738-0.419-0.401-0.112-0.95-4.248-1.045-4.779-0.127-0.715-0.328-2.714-1.429-2.714-1.126 0-1.239 2.197-1.42 2.9 0.032-0.126-0.555-1.494-0.614-1.694-0.227-0.762-0.401-1.541-0.589-2.313-0.363-1.501-0.869-2.986-1.45-4.416-0.433-1.066-1.004-2.122-2.16-1.197-0.551 0.44-0.767 1.692-0.938 2.299-0.458 1.627-0.732 2.734-2.437 3.297-0.57 0.188-0.711 0.708-0.844 1.218-0.421 1.625 0.561 2.907-1.508 3.708-1.621 0.627-0.637 3.695-2.12 4.235-0.719 0.263-0.407 1.424 0.322 1.158z"/>
+</g></g></g>
+<rect x="1.7627" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="4.5008" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="7.239" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="9.9771" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="12.715" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/><rect x="15.453" y="5.1525" width="2.0339" height="2.0339" fill="#c8c8c8"/></svg>
diff --git a/silx/resources/gui/icons/plot-xauto.png b/silx/resources/gui/icons/plot-xauto.png
new file mode 100755
index 0000000..2c79723
--- /dev/null
+++ b/silx/resources/gui/icons/plot-xauto.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-xauto.svg b/silx/resources/gui/icons/plot-xauto.svg
new file mode 100644
index 0000000..3debd34
--- /dev/null
+++ b/silx/resources/gui/icons/plot-xauto.svg
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata16"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs14" /><line
+ x1="25.941999"
+ x2="7"
+ y1="22.684999"
+ y2="22.684999"
+ fill="none"
+ stroke="#00A14B"
+ stroke-miterlimit="10"
+ stroke-width="1.5"
+ id="line4"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><polygon
+ points="25.47,24.417 25.463,20.953 28.467,22.68 "
+ id="polygon6"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><polygon
+ points="6.988,24.417 3.993,22.676 7,20.953 "
+ id="polygon8"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><path
+ d="m 18.474,19.135 -1.3,-1.83 C 16.642,16.6 16.301,16.075 15.897,15.49 h -0.043 c -0.298,0.585 -0.66,1.11 -1.107,1.815 l -1.193,1.83 H 9.847 L 14,14.02 9.996,9.025 h 3.728 l 1.257,1.845 c 0.426,0.615 0.745,1.11 1.086,1.68 h 0.043 c 0.341,-0.645 0.618,-1.095 0.979,-1.68 l 1.215,-1.845 h 3.706 l -4.047,4.935 4.26,5.175 h -3.749 z"
+ inkscape:connector-curvature="0"
+ id="path10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/plot-xlog.png b/silx/resources/gui/icons/plot-xlog.png
new file mode 100755
index 0000000..1e0a843
--- /dev/null
+++ b/silx/resources/gui/icons/plot-xlog.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-xlog.svg b/silx/resources/gui/icons/plot-xlog.svg
new file mode 100644
index 0000000..692062f
--- /dev/null
+++ b/silx/resources/gui/icons/plot-xlog.svg
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata20"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs18" /><line
+ x1="25.941999"
+ x2="7"
+ y1="22.684999"
+ y2="22.684999"
+ fill="none"
+ stroke="#00A14B"
+ stroke-miterlimit="10"
+ stroke-width="1.5"
+ id="line4"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><polygon
+ points="25.47,24.417 25.463,20.953 28.467,22.68 "
+ id="polygon6"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><polygon
+ points="6.988,24.417 3.993,22.676 7,20.953 "
+ id="polygon8"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10" /><path
+ d="M 7.395,7.535 H 9.36 v 8.444 h 2.595 v 1.666 H 7.395 V 7.535 z"
+ inkscape:connector-curvature="0"
+ id="path10" /><path
+ d="m 18.195,13.954 c 0,3.06 -1.696,3.81 -2.805,3.81 -1.755,0 -2.805,-1.379 -2.805,-3.765 0,-2.64 1.38,-3.81 2.834,-3.81 1.726,0 2.776,1.455 2.776,3.765 z m -3.66,0 c 0,1.26 0.195,2.31 0.9,2.31 0.63,0 0.795,-1.23 0.795,-2.31 0,-1.005 -0.165,-2.28 -0.825,-2.28 -0.72,0 -0.87,1.275 -0.87,2.28 z"
+ inkscape:connector-curvature="0"
+ id="path12" /><path
+ d="m 24.719,10.31 c -0.029,0.66 -0.074,1.44 -0.074,2.325 v 4.185 c 0,1.576 -0.285,2.445 -0.885,3.015 -0.541,0.51 -1.305,0.811 -2.385,0.811 -0.676,0 -1.305,-0.121 -1.83,-0.346 l 0.359,-1.515 c 0.375,0.165 0.84,0.315 1.41,0.315 0.99,0 1.381,-0.66 1.381,-1.785 v -0.45 H 22.664 C 22.41,17.329 21.9,17.6 21.344,17.6 c -1.648,0 -2.295,-1.8 -2.295,-3.555 0,-2.445 1.111,-3.855 2.477,-3.855 0.584,0 1.064,0.3 1.35,0.855 h 0.029 L 23.01,10.31 h 1.709 z m -2.024,2.669 c 0,-0.195 -0.031,-0.39 -0.076,-0.54 -0.09,-0.315 -0.299,-0.6 -0.629,-0.6 -0.705,0 -0.99,0.96 -0.99,2.16 0,1.365 0.389,2.055 0.945,2.055 0.254,0 0.51,-0.135 0.66,-0.525 0.059,-0.165 0.09,-0.39 0.09,-0.585 v -1.965 z"
+ inkscape:connector-curvature="0"
+ id="path14" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/plot-yauto.png b/silx/resources/gui/icons/plot-yauto.png
new file mode 100755
index 0000000..e5e34f0
--- /dev/null
+++ b/silx/resources/gui/icons/plot-yauto.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-yauto.svg b/silx/resources/gui/icons/plot-yauto.svg
new file mode 100644
index 0000000..34ab240
--- /dev/null
+++ b/silx/resources/gui/icons/plot-yauto.svg
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata18"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs16" /><g
+ id="g4"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10"><line
+ x1="8.7320004"
+ x2="8.7320004"
+ y1="6.0489998"
+ y2="24.990999"
+ id="line6" /><polygon
+ points="10.464,6.521 7,6.528 8.727,3.524 "
+ id="polygon8" /><polygon
+ points="10.464,25.003 8.723,27.998 7,24.991 "
+ id="polygon10" /></g><path
+ d="m 17.778,21.167 v -4.14 l -4.537,-5.97 h 3.706 l 1.471,2.43 c 0.447,0.735 0.744,1.275 1.107,1.935 h 0.042 c 0.319,-0.63 0.661,-1.215 1.087,-1.935 l 1.447,-2.43 h 3.643 l -4.729,5.895 v 4.215 h -3.237 z"
+ inkscape:connector-curvature="0"
+ id="path12" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/plot-ydown.png b/silx/resources/gui/icons/plot-ydown.png
new file mode 100755
index 0000000..f857097
--- /dev/null
+++ b/silx/resources/gui/icons/plot-ydown.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-ydown.svg b/silx/resources/gui/icons/plot-ydown.svg
new file mode 100644
index 0000000..276021c
--- /dev/null
+++ b/silx/resources/gui/icons/plot-ydown.svg
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata14"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs12" /><path
+ d="M 9.872,22.665 V 9.224 m 1.732,13.939 -3.464,0.007 1.737,2.997 1.727,-3.004 z"
+ inkscape:connector-curvature="0"
+ id="path4"
+ style="fill:none;stroke:#00a14b;stroke-width:2;stroke-miterlimit:10" /><path
+ d="M 20.232,22.168 V 16.829 L 14.486,9.363 h 3.777 l 2.186,3.287 c 0.62,0.95 1.078,1.672 1.564,2.545 h 0.054 c 0.458,-0.817 0.972,-1.615 1.591,-2.545 l 2.186,-3.287 h 3.75 l -6.043,7.409 v 5.396 h -3.319 z"
+ inkscape:connector-curvature="0"
+ id="path6" /><path
+ d="m 7.638,12.205 c 0,1.882 -0.738,3.061 -2.134,3.061 -1.351,0 -2.071,-1.224 -2.08,-3.006 0,-1.819 0.774,-3.043 2.143,-3.043 1.414,-0.001 2.071,1.26 2.071,2.988 z m -3.097,0.054 c -0.009,1.422 0.387,2.161 1,2.161 0.648,0 0.99,-0.792 0.99,-2.197 0,-1.359 -0.324,-2.161 -0.99,-2.161 -0.595,0.001 -1.009,0.73 -1,2.197 z"
+ inkscape:connector-curvature="0"
+ id="path8" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/plot-ylog.png b/silx/resources/gui/icons/plot-ylog.png
new file mode 100755
index 0000000..a705f40
--- /dev/null
+++ b/silx/resources/gui/icons/plot-ylog.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-ylog.svg b/silx/resources/gui/icons/plot-ylog.svg
new file mode 100644
index 0000000..8380464
--- /dev/null
+++ b/silx/resources/gui/icons/plot-ylog.svg
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata22"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs20" /><g
+ id="g4"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10"><line
+ x1="7.3540001"
+ x2="7.3109999"
+ y1="26.356001"
+ y2="7.414"
+ id="line6" /><polygon
+ points="5.621,25.888 9.085,25.873 7.365,28.881 "
+ id="polygon8" /><polygon
+ points="5.579,7.406 7.313,4.407 9.042,7.41 "
+ id="polygon10" /></g><path
+ d="m 10.882,11.535 h 1.965 v 8.444 h 2.595 v 1.665 h -4.56 V 11.535 z"
+ inkscape:connector-curvature="0"
+ id="path12" /><path
+ d="m 21.682,17.955 c 0,3.06 -1.695,3.81 -2.805,3.81 -1.756,0 -2.805,-1.38 -2.805,-3.765 0,-2.64 1.379,-3.81 2.834,-3.81 1.726,0 2.776,1.455 2.776,3.765 z m -3.661,0 c 0,1.26 0.195,2.31 0.9,2.31 0.63,0 0.795,-1.229 0.795,-2.31 0,-1.005 -0.165,-2.28 -0.825,-2.28 -0.719,0 -0.87,1.275 -0.87,2.28 z"
+ inkscape:connector-curvature="0"
+ id="path14" /><path
+ d="m 28.206,14.31 c -0.029,0.66 -0.075,1.44 -0.075,2.325 v 4.185 c 0,1.575 -0.284,2.445 -0.885,3.015 -0.54,0.51 -1.305,0.811 -2.385,0.811 -0.675,0 -1.305,-0.12 -1.83,-0.346 l 0.36,-1.514 c 0.375,0.164 0.84,0.314 1.41,0.314 0.989,0 1.38,-0.66 1.38,-1.785 v -0.449 h -0.03 c -0.255,0.465 -0.765,0.734 -1.32,0.734 -1.649,0 -2.295,-1.8 -2.295,-3.555 0,-2.445 1.11,-3.855 2.476,-3.855 0.585,0 1.064,0.3 1.35,0.855 h 0.03 l 0.104,-0.735 h 1.71 z m -2.024,2.669 c 0,-0.195 -0.03,-0.39 -0.075,-0.54 -0.09,-0.315 -0.3,-0.6 -0.63,-0.6 -0.705,0 -0.99,0.96 -0.99,2.16 0,1.365 0.39,2.055 0.945,2.055 0.255,0 0.51,-0.135 0.66,-0.525 0.06,-0.164 0.09,-0.39 0.09,-0.584 v -1.966 z"
+ inkscape:connector-curvature="0"
+ id="path16" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/plot-yup.png b/silx/resources/gui/icons/plot-yup.png
new file mode 100755
index 0000000..bfef167
--- /dev/null
+++ b/silx/resources/gui/icons/plot-yup.png
Binary files differ
diff --git a/silx/resources/gui/icons/plot-yup.svg b/silx/resources/gui/icons/plot-yup.svg
new file mode 100644
index 0000000..402afec
--- /dev/null
+++ b/silx/resources/gui/icons/plot-yup.svg
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata16"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs14" /><line
+ x1="10.669"
+ x2="10.669"
+ y1="9.7259998"
+ y2="23.167"
+ fill="none"
+ stroke="#00A14B"
+ stroke-miterlimit="10"
+ stroke-width="2"
+ id="line4"
+ style="fill:none;stroke:#00a14b;stroke-width:2;stroke-miterlimit:10" /><polygon
+ points="12.401,9.221 8.938,9.228 10.664,6.224 "
+ id="polygon6"
+ style="fill:none;stroke:#00a14b;stroke-width:2;stroke-miterlimit:10" /><path
+ d="m 21.029,23.168 v -5.339 l -5.746,-7.466 h 3.777 l 2.186,3.287 c 0.62,0.95 1.078,1.672 1.564,2.545 h 0.054 c 0.458,-0.817 0.972,-1.615 1.591,-2.545 l 2.186,-3.287 h 3.75 l -6.043,7.409 v 5.396 h -3.319 z"
+ inkscape:connector-curvature="0"
+ id="path8" /><path
+ d="m 8.435,20.205 c 0,1.883 -0.738,3.061 -2.134,3.061 -1.351,0 -2.071,-1.223 -2.08,-3.006 0,-1.818 0.774,-3.043 2.143,-3.043 1.414,0 2.071,1.26 2.071,2.988 z M 5.338,20.26 c -0.009,1.422 0.387,2.16 1,2.16 0.648,0 0.99,-0.791 0.99,-2.196 0,-1.359 -0.324,-2.161 -0.99,-2.161 -0.595,0 -1.009,0.729 -1,2.197 z"
+ inkscape:connector-curvature="0"
+ id="path10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/previous.png b/silx/resources/gui/icons/previous.png
new file mode 100644
index 0000000..9f436ce
--- /dev/null
+++ b/silx/resources/gui/icons/previous.png
Binary files differ
diff --git a/silx/resources/gui/icons/previous.svg b/silx/resources/gui/icons/previous.svg
new file mode 100644
index 0000000..75372e2
--- /dev/null
+++ b/silx/resources/gui/icons/previous.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <linearGradient id="b" x1="11.913" x2="27.737" y1="10.398" y2="16.471" gradientTransform="matrix(-1 0 0 1 32.506 0)" gradientUnits="userSpaceOnUse">
+ <stop stop-color="#002839" offset="0"/>
+ <stop stop-color="#00f" stop-opacity=".2585" offset="1"/>
+ </linearGradient>
+ <linearGradient id="a" x1="11.913" x2="27.737" y1="10.398" y2="16.471" gradientTransform="matrix(-1 0 0 1 32.506 0)" gradientUnits="userSpaceOnUse">
+ <stop offset="0"/>
+ <stop stop-color="#00f" stop-opacity=".30612" offset="1"/>
+ </linearGradient>
+ </defs>
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path d="m25.451 4.9951c-6.6141 3.9114-12.473 7.571-18.396 11.252l18.307 10.806z" fill="url(#b)" stroke="url(#a)" stroke-linejoin="round" stroke-width=".4"/>
+</svg>
diff --git a/silx/resources/gui/icons/process-working.mng b/silx/resources/gui/icons/process-working.mng
new file mode 100644
index 0000000..842ea5a
--- /dev/null
+++ b/silx/resources/gui/icons/process-working.mng
Binary files differ
diff --git a/silx/resources/gui/icons/profile-clear.png b/silx/resources/gui/icons/profile-clear.png
new file mode 100644
index 0000000..5f2159d
--- /dev/null
+++ b/silx/resources/gui/icons/profile-clear.png
Binary files differ
diff --git a/silx/resources/gui/icons/profile-clear.svg b/silx/resources/gui/icons/profile-clear.svg
new file mode 100644
index 0000000..09f1f94
--- /dev/null
+++ b/silx/resources/gui/icons/profile-clear.svg
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3423"
+ xml:space="preserve"><metadata
+ id="metadata3431"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3429"><filter
+ x="-0.14179821"
+ y="-0.14627124"
+ width="1.2835964"
+ height="1.2925425"
+ color-interpolation-filters="sRGB"
+ id="filter7174"><feGaussianBlur
+ stdDeviation="0.9522046"
+ id="feGaussianBlur7176" /></filter></defs><line
+ x1="4.1233144"
+ x2="27.305519"
+ y1="17.429787"
+ y2="15.176897"
+ stroke-miterlimit="10"
+ id="line3425"
+ style="fill:#f7941e;stroke:#f7941e;stroke-width:3;stroke-miterlimit:10" /><g
+ transform="translate(-0.28742515,-0.28742515)"
+ id="g4379"><path
+ d="m 26.957244,11.637296 c -0.39375,0.002 -0.79775,0.17675 -1.09375,0.46875 l -5.375,5.250001 -5.437499,-5.218751 c -0.602,-0.58 -1.55925,-0.583 -2.15625,0 -0.598,0.584001 -0.602,1.547001 0,2.125001 l 5.4375,5.218748 -5.375,5.25 c -0.599,0.583 -0.605,1.51675 0,2.09375 0.601,0.577 1.5905,0.586 2.1875,0 l 5.374999,-5.25 5.4375,5.1875 c 0.605,0.578 1.55825,0.584 2.15625,0 0.596,-0.58 0.598,-1.51475 0,-2.09375 l -5.4375,-5.21875 5.375,-5.249998 c 0.594,-0.584 0.602,-1.547999 0,-2.125001 -0.301,-0.29 -0.7,-0.4395 -1.09375,-0.4375 z"
+ transform="matrix(0.68043931,0,0,0.68043931,2.0968612,3.5974984)"
+ id="path3107-3"
+ style="filter:url(#filter7174)" /><path
+ d="m 20.137161,10.881026 c -0.267923,0.0014 -0.54282,0.099 -0.744231,0.297692 l -3.657361,3.572306 -3.699889,-3.529778 c -0.409624,-0.394655 -1.060975,-0.396697 -1.467197,0 -0.406902,0.397376 -0.409624,1.031375 0,1.424669 l 3.699889,3.551043 -3.657361,3.572306 c -0.407583,0.396696 -0.411666,1.05332 0,1.445934 0.408944,0.392613 1.082238,0.377474 1.488461,-0.02126 l 3.657361,-3.572306 3.699889,3.551042 c 0.411665,0.393294 1.060294,0.397377 1.467197,0 0.405542,-0.394654 0.406903,-1.051959 0,-1.445933 l -3.699889,-3.551043 3.657361,-3.572306 c 0.404181,-0.397377 0.409625,-1.032056 0,-1.42467 -0.204812,-0.197327 -0.476307,-0.299053 -0.74423,-0.297692 z"
+ id="path3107"
+ style="fill:#ff0000;stroke:#ff4042;stroke-width:0.2041318;stroke-miterlimit:10;stroke-opacity:1" /></g></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/profile1D.png b/silx/resources/gui/icons/profile1D.png
new file mode 100644
index 0000000..65991fe
--- /dev/null
+++ b/silx/resources/gui/icons/profile1D.png
Binary files differ
diff --git a/silx/resources/gui/icons/profile1D.svg b/silx/resources/gui/icons/profile1D.svg
new file mode 100644
index 0000000..4465df5
--- /dev/null
+++ b/silx/resources/gui/icons/profile1D.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(-35.201 -492.37)">
+ <flowRoot fill="#000000" font-family="Sans" font-size="40px" letter-spacing="0px" word-spacing="0px" style="line-height:125%" xml:space="preserve"><flowRegion><rect x="299.51" y="378.09" width="73.741" height="62.629"/></flowRegion><flowPara/></flowRoot>
+ <rect x="38.265" y="494.84" width="27.563" height="26.906" ry="0" color="#000000" fill="#fff" stroke="#000" stroke-miterlimit="2" stroke-width="1.0776"/>
+ <path d="m64.793 513.73-25.771-0.0252" fill="none" stroke="#f7941e" stroke-linecap="round" stroke-miterlimit="0" stroke-opacity=".81569" stroke-width="1.3908"/>
+ <rect x="38.145" y="494.84" width="27.563" height="26.906" ry="0" color="#000000" fill="none" stroke="#000" stroke-miterlimit="2" stroke-width="1.0776"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/profile2D.png b/silx/resources/gui/icons/profile2D.png
new file mode 100644
index 0000000..8478931
--- /dev/null
+++ b/silx/resources/gui/icons/profile2D.png
Binary files differ
diff --git a/silx/resources/gui/icons/profile2D.svg b/silx/resources/gui/icons/profile2D.svg
new file mode 100644
index 0000000..089108f
--- /dev/null
+++ b/silx/resources/gui/icons/profile2D.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(-35.201 -492.37)">
+ <path d="m36.808 505.45v17.66h17.686v-0.0531h0.58775l10.366-10.692-0.05335-0.0265-0.05335-17.633h-0.26716l0.05335-0.0531h-17.739l8.7e-5 -1.7e-4 -10.633 10.692z" fill="#fff"/>
+ <rect transform="matrix(1 0 -.69678 .71728 0 0)" x="545.71" y="714.56" width="17.72" height="14.863" fill="#fff" stroke="#000" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1598"/>
+ <rect x="47.726" y="494.85" width="17.72" height="17.64" ry="0" fill="#fff" stroke="#000" stroke-miterlimit="2" stroke-width=".98223"/>
+ <rect transform="matrix(1 0 -.70784 .70637 0 0)" x="543.37" y="700.5" width="17.72" height="15.092" fill="none" stroke="#000" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1687"/>
+ <rect transform="matrix(1 0 -.69678 .71728 0 0)" x="540.83" y="707.56" width="17.72" height="14.863" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.1598"/>
+ <rect x="36.897" y="505.63" width="17.72" height="17.64" ry="0" fill="none" stroke="#000" stroke-miterlimit="2" stroke-width=".98223"/>
+ <flowRoot fill="#000000" font-family="Sans" font-size="40px" letter-spacing="0px" word-spacing="0px" style="line-height:125%" xml:space="preserve"><flowRegion><rect x="299.51" y="378.09" width="73.741" height="62.629"/></flowRegion><flowPara/></flowRoot>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/remove.png b/silx/resources/gui/icons/remove.png
new file mode 100755
index 0000000..235338c
--- /dev/null
+++ b/silx/resources/gui/icons/remove.png
Binary files differ
diff --git a/silx/resources/gui/icons/remove.svg b/silx/resources/gui/icons/remove.svg
new file mode 100644
index 0000000..3ce7ff8
--- /dev/null
+++ b/silx/resources/gui/icons/remove.svg
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata28"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs26" /><radialGradient
+ cx="22.443001"
+ cy="21.502001"
+ r="0"
+ id="b"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop5"
+ style="stop-color:#00aeef;stop-opacity:0.60000002"
+ offset="0" /><stop
+ id="stop7"
+ style="stop-color:#517180;stop-opacity:0.53170002"
+ offset="0.6832" /><stop
+ id="stop9"
+ style="stop-color:#414042;stop-opacity:0.5"
+ offset="1" /></radialGradient><path
+ d="M 22.443,21.502"
+ inkscape:connector-curvature="0"
+ id="path11"
+ style="fill:url(#b)" /><linearGradient
+ x1="22.414"
+ y1="21.502001"
+ x2="22.473"
+ y2="21.502001"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop14"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" /><stop
+ id="stop16"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1" /></linearGradient><path
+ d="m 22.443,24.002 c 0.038,0 0.038,-5 0,-5 -0.038,0 -0.038,5 0,5 z"
+ inkscape:connector-curvature="0"
+ id="path18"
+ style="fill:url(#a)" /><path
+ d="m 8.293,10.899 c 5.462,5.68 10.925,11.36 16.387,17.04 -0.814,-0.847 0.851,-4.115 0,-5 -5.462,-5.68 -10.924,-11.36 -16.387,-17.04 0.814,0.847 -0.851,4.116 0,5 z"
+ inkscape:connector-curvature="0"
+ id="path20"
+ style="fill:#ed1c24" /><path
+ d="M 24.452,5.675 C 19.018,11.333 13.583,16.992 8.148,22.65 c -0.851,0.886 0.814,4.152 0,5 5.435,-5.658 10.869,-11.317 16.304,-16.976 0.851,-0.884 -0.814,-4.152 0,-4.999 z"
+ inkscape:connector-curvature="0"
+ id="path22"
+ style="fill:#ed1c24" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/rudder.png b/silx/resources/gui/icons/rudder.png
new file mode 100755
index 0000000..ad45338
--- /dev/null
+++ b/silx/resources/gui/icons/rudder.png
Binary files differ
diff --git a/silx/resources/gui/icons/rudder.svg b/silx/resources/gui/icons/rudder.svg
new file mode 100644
index 0000000..83cf9a9
--- /dev/null
+++ b/silx/resources/gui/icons/rudder.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata10"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs8" /><path
+ d="M 16.398,2.854 V 29.337 M 29.642,16.096 H 3.158 M 7.021,25.443 25.779,6.749 M 25.747,25.476 7.052,6.717 m 9.332,0.678 c -4.804,0 -8.701,3.895 -8.701,8.701 0,4.806 3.896,8.703 8.701,8.703 4.807,0 8.702,-3.897 8.702,-8.703 0,-4.806 -3.895,-8.701 -8.702,-8.701 z"
+ inkscape:connector-curvature="0"
+ id="path4"
+ style="fill:none;stroke:#00a651;stroke-width:1.89999998;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/selected.png b/silx/resources/gui/icons/selected.png
new file mode 100755
index 0000000..451d7c7
--- /dev/null
+++ b/silx/resources/gui/icons/selected.png
Binary files differ
diff --git a/silx/resources/gui/icons/selected.svg b/silx/resources/gui/icons/selected.svg
new file mode 100644
index 0000000..7f12860
--- /dev/null
+++ b/silx/resources/gui/icons/selected.svg
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3255"
+ xml:space="preserve"><metadata
+ id="metadata3267"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3265"><filter
+ x="-0.1568312"
+ y="-0.13310958"
+ width="1.3136624"
+ height="1.2662193"
+ color-interpolation-filters="sRGB"
+ id="filter4492"><feGaussianBlur
+ id="feGaussianBlur4494"
+ stdDeviation="1.292605" /></filter></defs><rect
+ width="19.802"
+ height="19.799999"
+ x="6.5999999"
+ y="6.5019999"
+ id="rect3257"
+ style="fill:none;stroke:#000000;stroke-miterlimit:10" /><path
+ d="m 8.1240038,17.76283 c 4.1369992,0.876 6.7039992,5.926 8.5199992,9.279 -0.6,-1.106 0.144,-3.692 0,-5 -0.036,-0.327 -0.072,-0.654 -0.108,-0.982 v 5 c 0.322,-4.015 2.883,-7.747 5.092,-10.997 1.146,-1.687999 3.936,-5.9909991 6.068,-6.3259991 0.292,-0.046 -0.219,-4.966 0,-5.0000004 -1.679,0.2640004 -3.304,2.9040004 -4.336,4.1140004 -2.09,2.4490001 -3.723,5.2160001 -5.227,8.0529991 -1.823,3.438 -1.907,7.337 -1.49,11.139 v -5 c -1.815,-3.353 -4.382,-8.402999 -8.5199992,-9.278999 0.303,0.063 -0.373,4.918999 0.001,4.998999 z"
+ id="path3261-9"
+ style="fill:#000000;filter:url(#filter4492)" /><path
+ d="m 7.489,16.747 c 4.137,0.876 6.704,5.926 8.52,9.279 -0.6,-1.106 0.144,-3.692 0,-5 -0.036,-0.327 -0.072,-0.654 -0.108,-0.982 v 5 c 0.322,-4.015 2.883,-7.747 5.092,-10.997 1.146,-1.688 3.936,-5.991 6.068,-6.326 0.292,-0.046 -0.219,-4.966 0,-5 -1.679,0.264 -3.304,2.904 -4.336,4.114 -2.09,2.449 -3.723,5.216 -5.227,8.053 -1.823,3.438 -1.907,7.337 -1.49,11.139 v -5 c -1.815,-3.353 -4.382,-8.403 -8.52,-9.279 0.303,0.063 -0.373,4.919 10e-4,4.999 z"
+ id="path3261"
+ style="fill:#00a651" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/shape-circle-solid.png b/silx/resources/gui/icons/shape-circle-solid.png
new file mode 100755
index 0000000..f43d736
--- /dev/null
+++ b/silx/resources/gui/icons/shape-circle-solid.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-circle-solid.svg b/silx/resources/gui/icons/shape-circle-solid.svg
new file mode 100644
index 0000000..600170f
--- /dev/null
+++ b/silx/resources/gui/icons/shape-circle-solid.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<circle cx="16.473" cy="16.329" r="9.953" fill="#F7941E"/>
+</svg>
diff --git a/silx/resources/gui/icons/shape-circle.png b/silx/resources/gui/icons/shape-circle.png
new file mode 100755
index 0000000..3d21824
--- /dev/null
+++ b/silx/resources/gui/icons/shape-circle.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-circle.svg b/silx/resources/gui/icons/shape-circle.svg
new file mode 100644
index 0000000..45a2a0d
--- /dev/null
+++ b/silx/resources/gui/icons/shape-circle.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<circle cx="16.473" cy="16.329" r="9.953" fill="none" stroke="#F7941E" stroke-miterlimit="10" stroke-width="2.5"/>
+</svg>
diff --git a/silx/resources/gui/icons/shape-diagonal.png b/silx/resources/gui/icons/shape-diagonal.png
new file mode 100755
index 0000000..f71bcb0
--- /dev/null
+++ b/silx/resources/gui/icons/shape-diagonal.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-diagonal.svg b/silx/resources/gui/icons/shape-diagonal.svg
new file mode 100644
index 0000000..4580c06
--- /dev/null
+++ b/silx/resources/gui/icons/shape-diagonal.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<line x1="8.45" x2="24.895" y1="8.727" y2="25.221" fill="#F7941E" stroke="#F7941E" stroke-miterlimit="10" stroke-width="3"/>
+</svg>
diff --git a/silx/resources/gui/icons/shape-ellipse-solid.png b/silx/resources/gui/icons/shape-ellipse-solid.png
new file mode 100755
index 0000000..31bcb4c
--- /dev/null
+++ b/silx/resources/gui/icons/shape-ellipse-solid.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-ellipse-solid.svg b/silx/resources/gui/icons/shape-ellipse-solid.svg
new file mode 100644
index 0000000..b740a23
--- /dev/null
+++ b/silx/resources/gui/icons/shape-ellipse-solid.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<ellipse cx="16.295" cy="17.16" rx="12.776" ry="7.818" fill="#F7941E"/>
+</svg>
diff --git a/silx/resources/gui/icons/shape-ellipse.png b/silx/resources/gui/icons/shape-ellipse.png
new file mode 100755
index 0000000..e1cff68
--- /dev/null
+++ b/silx/resources/gui/icons/shape-ellipse.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-ellipse.svg b/silx/resources/gui/icons/shape-ellipse.svg
new file mode 100644
index 0000000..5318ea0
--- /dev/null
+++ b/silx/resources/gui/icons/shape-ellipse.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+<ellipse cx="16.295" cy="17.16" rx="12.776" ry="7.818" fill="none" stroke="#F7941E" stroke-miterlimit="10" stroke-width="2.5"/>
+</svg>
diff --git a/silx/resources/gui/icons/shape-horizontal.png b/silx/resources/gui/icons/shape-horizontal.png
new file mode 100755
index 0000000..0ea55e2
--- /dev/null
+++ b/silx/resources/gui/icons/shape-horizontal.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-horizontal.svg b/silx/resources/gui/icons/shape-horizontal.svg
new file mode 100644
index 0000000..053a590
--- /dev/null
+++ b/silx/resources/gui/icons/shape-horizontal.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
+<svg enable-background="new 0 0 32 32" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
+ <rect x="5.387" y="14.5" width="22.665" height="3" fill="#F7941E"/>
+</svg>
diff --git a/silx/resources/gui/icons/shape-polygon.png b/silx/resources/gui/icons/shape-polygon.png
new file mode 100755
index 0000000..efbb449
--- /dev/null
+++ b/silx/resources/gui/icons/shape-polygon.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-polygon.svg b/silx/resources/gui/icons/shape-polygon.svg
new file mode 100644
index 0000000..0aa07a1
--- /dev/null
+++ b/silx/resources/gui/icons/shape-polygon.svg
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata10"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs8" /><polygon
+ points="17.425,14.594 26.908,19.767 20.964,27.766 8.163,26.214 11.774,22.113 5.596,13.013 14.631,4.408 "
+ id="polygon4"
+ style="fill:none;stroke:#f7941e;stroke-width:2.5;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/shape-rectangle.png b/silx/resources/gui/icons/shape-rectangle.png
new file mode 100755
index 0000000..c523c72
--- /dev/null
+++ b/silx/resources/gui/icons/shape-rectangle.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-rectangle.svg b/silx/resources/gui/icons/shape-rectangle.svg
new file mode 100644
index 0000000..1405c9f
--- /dev/null
+++ b/silx/resources/gui/icons/shape-rectangle.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata10"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs8" /><rect
+ width="21.139999"
+ height="12.56"
+ x="6.3400002"
+ y="11.485"
+ id="rect4"
+ style="fill:none;stroke:#f7941e;stroke-width:3;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/shape-square.png b/silx/resources/gui/icons/shape-square.png
new file mode 100755
index 0000000..667b758
--- /dev/null
+++ b/silx/resources/gui/icons/shape-square.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-square.svg b/silx/resources/gui/icons/shape-square.svg
new file mode 100644
index 0000000..469f0fb
--- /dev/null
+++ b/silx/resources/gui/icons/shape-square.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata10"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs8" /><rect
+ width="18.5"
+ height="18.5"
+ x="7.099"
+ y="7.0830002"
+ id="rect4"
+ style="fill:none;stroke:#f7941e;stroke-width:2.5;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/shape-vertical.png b/silx/resources/gui/icons/shape-vertical.png
new file mode 100755
index 0000000..384c4ae
--- /dev/null
+++ b/silx/resources/gui/icons/shape-vertical.png
Binary files differ
diff --git a/silx/resources/gui/icons/shape-vertical.svg b/silx/resources/gui/icons/shape-vertical.svg
new file mode 100644
index 0000000..5fbce1e
--- /dev/null
+++ b/silx/resources/gui/icons/shape-vertical.svg
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata10"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs8" /><line
+ x1="16.261"
+ x2="16.261"
+ y1="7.6680002"
+ y2="27.667999"
+ fill="none"
+ stroke="#F7941E"
+ stroke-miterlimit="10"
+ stroke-width="3"
+ id="line4"
+ style="fill:none;stroke:#f7941e;stroke-width:3;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/silx.png b/silx/resources/gui/icons/silx.png
new file mode 100755
index 0000000..9d7ffc9
--- /dev/null
+++ b/silx/resources/gui/icons/silx.png
Binary files differ
diff --git a/silx/resources/gui/icons/silx.svg b/silx/resources/gui/icons/silx.svg
new file mode 100644
index 0000000..25381ce
--- /dev/null
+++ b/silx/resources/gui/icons/silx.svg
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="32" height="32" enable-background="new 0 0 46.401 46.401" version="1.1" viewBox="0 0 31.999999 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><metadata><rdf:RDF><cc:Work rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><dc:title/></cc:Work></rdf:RDF></metadata>
+<g transform="matrix(.6896 0 0 .6896 -.020788 -.30571)">
+ <polygon points="29.495 28.237 38.689 29.693 39.026 32.153 33.188 36.185 32.301 35.732 31.56 35.929" fill="#5a5b5d"/>
+ <path d="m29.222 26.766c0.057-0.121-2.232-0.209-2.232-0.209l-4.19 3.048 4.559 7.404 4.322-1.051-2.459-9.192z" fill="#808285"/>
+ <path d="m24.472 1.89s-4.283 2.305-4.828 2.497c-0.546 0.189-4.033 3.568-3.404 3.791 0.628 0.223 3.772 1.429 3.772 1.429l6.402-3.714-0.684-2.37-1.258-1.633" fill="#dcddde"/>
+ <path d="m16.067 8.177-1.303 1.925s-0.701 2.221-1.167 3.446c-0.452 1.187-1.11 2.632-1.11 2.632l3.899 3.088s6.086-2.344 5.914-2.23c-0.171 0.114-2.287-7.432-2.287-7.432l-3.946-1.429z" fill="#f8f8f9"/>
+ <path d="m13.61 15.472" fill="#939598"/>
+ <polygon points="9.931 19.558 8.219 24.074 7.666 28 12.923 33.159 15.439 27.157 11.453 23.67" fill="#dcddde"/>
+ <path d="m7.666 28s-0.799 1.539-0.794 2.701c0 1.164 0.396 3.087 0.396 3.087l0.917 2.641 7.346-1.992-2.376-1.278-5.489-5.159z" fill="#d1d3d4"/>
+ <path d="m18.127 39.503 2.523 0.67 5.38 4.701s-8.99 0.824-9.364 0.41c-0.371-0.41 0.659-2.008 0.088-2.408-0.571-0.402 1.373-3.373 1.373-3.373z" fill="#58595b"/>
+ <path d="m15.439 27.157s-2.625 5.788-2.516 6.001c0.218 0.431 2.607 1.278 2.607 1.278l8.371-5.678-2.844-11.251-3.067 1.22s-3.294 5.58-3.122 5.347c0.171-0.234 0.571 3.083 0.571 3.083z" fill="#d1d3d4"/>
+ <path d="m21.058 17.507 0.35-0.081 1.83-0.731s1.176 1.715 1.119 1.887c-0.059 0.171 2.766 1.713 2.766 1.713s-0.021 6.005-0.251 6.261c-0.228 0.258-2.969 2.203-2.969 2.203l-2.845-11.252z" fill="#808285"/>
+ <path d="m20.299 40.275s6.674-1.889 6.847-2.002c0.171-0.119 8.016 2.002 8.016 2.002l-1.33 0.883h-1.07l-2.747 2.402-3.984 1.314-5.732-4.599z" fill="#333334"/>
+ <polygon points="27.35 38.281 27.239 37.009 32.301 35.732 38.019 37.826 35.162 40.275" fill="#515254"/>
+ <path d="m32.647 35.91 6.379-3.757s0.555 2.034 0.566 2.376c7e-3 0.348-1.573 3.297-1.573 3.297l-5.372-1.916z" fill="#464547"/>
+ <polygon points="26.871 21.247 30.071 21.783 32.189 28.826 29.575 28.531 29.104 26.766 26.871 26.556" fill="#9fa1a4"/>
+ <path d="m30.071 21.783 0.207-0.131 5.299-3.419 2.685 5.348s-0.294 4.035-0.01 3.918c0.282-0.112 0.437 2.194 0.437 2.194l-6.5-0.867-2.118-7.043z" fill="#464547"/>
+ <path d="m26.031 5.748" fill="#939598"/>
+ <polygon points="32.49 12.237 32.989 14.524 26.241 12.581 26.241 5.893 27.498 6.494 29.285 8.156 30.071 8.177 30.887 8.967 31.56 10.979" fill="#6d6e71"/>
+ <polygon points="26.974 21.783 30.071 21.783 35.578 18.233 32.989 14.524 29.575 15.381 24.156 18.583 26.708 21.247" fill="#5a5b5d"/>
+ <path d="m26.241 5.893s-6.516 4-6.229 3.714c0.025-0.022 1.757 7.32 2.287 7.432 0.458 0.096 0.458 0.096 0.458 0.096l1.599 1.448 1.436-4.059 0.449-1.943v-6.688z" fill="#939598"/>
+ <path d="m8.185 36.429 7.579-2.156 2.364 5.23-1.465 2.957 0.264 0.75-0.259 2.074-2.654-1.322-1.545-1.313-1.486-1.943s-1.011-0.891-1.028-1.203c-0.022-0.31-1.77-3.074-1.77-3.074z" fill="#808285"/>
+ <polygon points="12.487 16.18 10.696 17.753 9.931 19.558 11.453 23.67 15.439 27.157 14.869 24.074 17.991 18.727 16.386 19.268" fill="#ededee"/>
+ <polygon points="32.989 14.524 26.241 12.581 25.792 14.524 24.356 18.583 29.575 15.381" fill="#464547"/>
+ <path d="m22.303 28.826" fill="#a7a9ac"/>
+ <polygon points="33.832 41.158 31.022 42.675 32.148 39.503 39.094 35.732 38.019 37.826"/>
+ <polygon points="27.35 38.281 27.35 38.281 20.649 40.173 18.127 39.503 15.763 34.273 22.682 29.605 27.757 37.009" fill="#515254"/>
+ <path d="m11.114 33.878" fill="#939598"/>
+ <path d="m18.264 25.999c0 0.965-0.465 1.451-1.394 1.457l-4.407-9e-3c-0.978 0.012-1.469 0.259-1.475 0.742 0.012 0.458 0.507 0.685 1.484 0.678h1.421c2.914 0.013 4.377 1.237 4.389 3.674 0 2.371-1.46 3.563-4.38 3.574h-4.353c-0.959-5e-3 -1.439-0.478-1.439-1.419 6e-3 -0.959 0.482-1.434 1.43-1.42l4.362-0.027c0.977-6e-3 1.466-0.254 1.466-0.742 0-0.496-0.495-0.74-1.484-0.734h-1.42c-2.902-6e-3 -4.353-1.2-4.353-3.583v-0.045c0-2.389 1.451-3.587 4.353-3.593h4.353c0.958 5e-3 1.441 0.488 1.447 1.447z" fill="#f7941e" stroke="#FFF" stroke-miterlimit="10" stroke-width=".3"/>
+ <path d="m20.37 24.288c0.923 6e-3 1.394 0.497 1.411 1.471v8.955c-0.011 0.986-0.476 1.488-1.394 1.508-0.923-0.025-1.385-0.527-1.385-1.508v-8.946c-6e-3 -0.987 0.45-1.48 1.368-1.48z" fill="#f7941e" stroke="#FFF" stroke-miterlimit="10" stroke-width=".3"/>
+ <circle cx="20.29" cy="20.567" r="1.689" d="m 21.979001,20.566999 c 0,0.932809 -0.756191,1.689 -1.689,1.689 -0.932809,0 -1.689,-0.756191 -1.689,-1.689 0,-0.932809 0.756191,-1.689 1.689,-1.689 0.932809,0 1.689,0.756191 1.689,1.689 z" fill="#f7941e" stroke="#FFF" stroke-miterlimit="10" stroke-width=".3"/>
+ <path d="m27.838 24.594c0.559-1e-3 0.979 0.115 1.263 0.351 0.283 0.236 1.279 1.245 2.986 3.026 1.727-1.82 2.731-2.847 3.014-3.081 0.282-0.233 0.702-0.352 1.261-0.353 0.545-1e-3 0.964 0.119 1.257 0.36 0.28 0.229 0.421 0.574 0.422 1.035v0.063c1e-3 0.515-0.295 0.997-0.887 1.445l-2.841 2.923 2.865 2.88c0.587 0.477 0.882 0.938 0.883 1.379 0 0.031-4e-3 0.064-0.011 0.1v0.119c1e-3 0.43-0.134 0.756-0.405 0.98-0.307 0.25-0.732 0.369-1.277 0.357-0.572 8e-3 -1.003-0.117-1.293-0.373-0.291-0.258-1.269-1.258-2.935-3.004-1.692 1.783-2.681 2.801-2.966 3.053s-0.715 0.379-1.287 0.381h-0.042c-0.523 2e-3 -0.932-0.117-1.226-0.352-0.28-0.223-0.42-0.551-0.421-0.98v-0.117c-7e-3 -0.037-0.01-0.07-0.01-0.1-1e-3 -0.443 0.291-0.9 0.876-1.375l2.978-2.903-2.98-2.908c-0.595-0.447-0.892-0.928-0.894-1.442v-0.063c-1e-3 -0.46 0.138-0.806 0.417-1.036 0.29-0.242 0.709-0.364 1.253-0.365z" fill="#f7941e" stroke="#FFF" stroke-miterlimit="10" stroke-width=".3"/>
+ <path d="m25.549 35.16c0 0.551-0.45 1-1 1h-0.845c-0.55 0-1-0.449-1-1v-19.883c0-0.55 0.45-1 1-1h0.845c0.55 0 1 0.45 1 1v19.883z" fill="#f7941e"/>
+ <path d="m25.549 35.16c0 0.551-0.45 1-1 1h-0.845c-0.55 0-1-0.449-1-1v-19.883c0-0.55 0.45-1 1-1h0.845c0.55 0 1 0.45 1 1v19.883z" fill="none" stroke="#FFF" stroke-miterlimit="10" stroke-width=".3"/>
+</g>
+</svg>
diff --git a/silx/resources/gui/icons/sliders-off.png b/silx/resources/gui/icons/sliders-off.png
new file mode 100755
index 0000000..463f4ec
--- /dev/null
+++ b/silx/resources/gui/icons/sliders-off.png
Binary files differ
diff --git a/silx/resources/gui/icons/sliders-off.svg b/silx/resources/gui/icons/sliders-off.svg
new file mode 100644
index 0000000..2799274
--- /dev/null
+++ b/silx/resources/gui/icons/sliders-off.svg
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata52"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs50" /><g
+ id="g4"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10"><line
+ x1="5.098"
+ x2="9.5120001"
+ y1="9.0349998"
+ y2="9.0349998"
+ id="line6" /><line
+ x1="13.449"
+ x2="19.752001"
+ y1="9.0349998"
+ y2="9.0349998"
+ id="line8" /><rect
+ width="3.5639999"
+ height="2.7550001"
+ x="9.5179996"
+ y="7.658"
+ id="rect10" /><rect
+ width="3.563"
+ height="2.7550001"
+ x="20.006001"
+ y="7.658"
+ id="rect12" /><line
+ x1="23.246"
+ x2="27.66"
+ y1="9.0349998"
+ y2="9.0349998"
+ id="line14" /><line
+ x1="5.098"
+ x2="7.6560001"
+ y1="15.613"
+ y2="15.644"
+ id="line16" /><rect
+ width="3.5639999"
+ height="2.7539999"
+ x="7.0879998"
+ y="14.236"
+ id="rect18" /><rect
+ width="3.5639999"
+ height="2.7539999"
+ x="21.625"
+ y="14.236"
+ id="rect20" /><line
+ x1="11.092"
+ x2="21.625"
+ y1="15.612"
+ y2="15.639"
+ id="line22" /><path
+ d="M 24.611,15.639"
+ inkscape:connector-curvature="0"
+ id="path24" /><line
+ x1="5.098"
+ x2="8.4490004"
+ y1="22.191"
+ y2="22.191"
+ id="line26" /><line
+ x1="11.829"
+ x2="18.131001"
+ y1="22.191"
+ y2="22.191"
+ id="line28" /><rect
+ width="3.5639999"
+ height="2.7550001"
+ x="7.8979998"
+ y="20.813"
+ id="rect30" /><rect
+ width="3.5639999"
+ height="2.7550001"
+ x="18.385"
+ y="20.813"
+ id="rect32" /><line
+ x1="22.437"
+ x2="27.66"
+ y1="22.191"
+ y2="22.191"
+ id="line34" /><path
+ d="M 25.416,15.639"
+ inkscape:connector-curvature="0"
+ id="path36" /><path
+ d="M 23.208,15.639"
+ inkscape:connector-curvature="0"
+ id="path38" /><line
+ x1="24.611"
+ x2="27.542999"
+ y1="15.639"
+ y2="15.649"
+ id="line40" /></g><g
+ id="g42"
+ style="fill:none;stroke:#ed1c24;stroke-width:1.79999995;stroke-miterlimit:10"><line
+ x1="8.1260004"
+ x2="24.591999"
+ y1="7.2610002"
+ y2="24.037001"
+ id="line44" /><line
+ x1="24.746"
+ x2="7.9720001"
+ y1="7.4159999"
+ y2="23.882999"
+ id="line46" /></g></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/sliders-on.png b/silx/resources/gui/icons/sliders-on.png
new file mode 100755
index 0000000..e720d15
--- /dev/null
+++ b/silx/resources/gui/icons/sliders-on.png
Binary files differ
diff --git a/silx/resources/gui/icons/sliders-on.svg b/silx/resources/gui/icons/sliders-on.svg
new file mode 100644
index 0000000..ba31951
--- /dev/null
+++ b/silx/resources/gui/icons/sliders-on.svg
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata46"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs44" /><g
+ id="g4"
+ style="fill:none;stroke:#00a14b;stroke-width:1.5;stroke-miterlimit:10"><line
+ x1="4.7480001"
+ x2="9.5120001"
+ y1="9.0349998"
+ y2="9.0349998"
+ id="line6" /><line
+ x1="13.449"
+ x2="19.752001"
+ y1="9.0349998"
+ y2="9.0349998"
+ id="line8" /><rect
+ width="3.5639999"
+ height="2.7550001"
+ x="9.5179996"
+ y="7.658"
+ id="rect10" /><rect
+ width="3.563"
+ height="2.7550001"
+ x="20.006001"
+ y="7.658"
+ id="rect12" /><line
+ x1="23.246"
+ x2="27.66"
+ y1="9.0349998"
+ y2="9.0349998"
+ id="line14" /><line
+ x1="5.098"
+ x2="8.4490004"
+ y1="22.191"
+ y2="22.191"
+ id="line16" /><line
+ x1="11.829"
+ x2="18.131001"
+ y1="22.191"
+ y2="22.191"
+ id="line18" /><rect
+ width="3.5639999"
+ height="2.7550001"
+ x="7.8979998"
+ y="20.813"
+ id="rect20" /><rect
+ width="3.5639999"
+ height="2.7550001"
+ x="18.385"
+ y="20.813"
+ id="rect22" /><line
+ x1="22.437"
+ x2="27.66"
+ y1="22.191"
+ y2="22.191"
+ id="line24" /><line
+ x1="4.7480001"
+ x2="7.6560001"
+ y1="15.659"
+ y2="15.644"
+ id="line26" /><rect
+ width="3.5639999"
+ height="2.7539999"
+ x="7.0879998"
+ y="14.236"
+ id="rect28" /><rect
+ width="3.5639999"
+ height="2.7539999"
+ x="21.625"
+ y="14.236"
+ id="rect30" /><line
+ x1="11.092"
+ x2="21.625"
+ y1="15.612"
+ y2="15.639"
+ id="line32" /><path
+ d="M 24.611,15.639"
+ inkscape:connector-curvature="0"
+ id="path34" /><path
+ d="M 25.416,15.639"
+ inkscape:connector-curvature="0"
+ id="path36" /><path
+ d="M 23.208,15.639"
+ inkscape:connector-curvature="0"
+ id="path38" /><line
+ x1="24.729"
+ x2="27.66"
+ y1="15.649"
+ y2="15.659"
+ id="line40" /></g></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/spec.png b/silx/resources/gui/icons/spec.png
new file mode 100755
index 0000000..876ab1b
--- /dev/null
+++ b/silx/resources/gui/icons/spec.png
Binary files differ
diff --git a/silx/resources/gui/icons/spec.svg b/silx/resources/gui/icons/spec.svg
new file mode 100644
index 0000000..cc17c67
--- /dev/null
+++ b/silx/resources/gui/icons/spec.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata26"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs24" /><path
+ d="M 18.462,31.115"
+ inkscape:connector-curvature="0"
+ id="path4"
+ style="stroke:#ffffff;stroke-width:0.50999999;stroke-miterlimit:10" /><rect
+ width="28.273001"
+ height="21.511999"
+ x="2.3959999"
+ y="4.5700002"
+ id="rect6"
+ style="fill:none;stroke:#000000;stroke-width:0.20999999;stroke-miterlimit:10" /><rect
+ width="28.273001"
+ height="21.511999"
+ x="2.3959999"
+ y="4.5700002"
+ id="rect8"
+ style="fill:#e6e7e8" /><g
+ id="g10"
+ style="stroke:#000000;stroke-width:0.2;stroke-miterlimit:10"><path
+ d="m 3.264,19.466 c 0.511,0.324 1.277,0.606 2.082,0.606 1.009,0 1.571,-0.521 1.571,-1.296 0,-0.719 -0.434,-1.141 -1.532,-1.577 C 3.967,16.635 3.06,15.804 3.06,14.438 c 0,-1.549 1.175,-2.732 3.04,-2.732 0.933,0 1.622,0.226 2.069,0.479 L 7.786,13.579 C 7.479,13.396 6.879,13.128 6.075,13.128 c -0.996,0 -1.43,0.592 -1.43,1.141 0,0.732 0.498,1.07 1.647,1.563 1.494,0.62 2.222,1.451 2.222,2.817 0,1.521 -1.047,2.845 -3.27,2.845 -0.907,0 -1.852,-0.281 -2.325,-0.592 l 0.345,-1.436 z"
+ inkscape:connector-curvature="0"
+ id="path12" /><path
+ d="m 9.929,11.988 c 0.562,-0.113 1.341,-0.197 2.401,-0.197 1.15,0 1.993,0.268 2.542,0.775 0.511,0.464 0.843,1.211 0.843,2.098 0,0.901 -0.255,1.648 -0.741,2.155 -0.626,0.69 -1.609,1.015 -2.72,1.015 -0.294,0 -0.562,-0.015 -0.767,-0.057 v 3.577 H 9.929 v -9.366 z m 1.558,4.422 c 0.191,0.056 0.447,0.07 0.767,0.07 1.175,0 1.89,-0.634 1.89,-1.747 0,-1.056 -0.664,-1.62 -1.75,-1.62 -0.434,0 -0.741,0.042 -0.907,0.084 v 3.213 z"
+ inkscape:connector-curvature="0"
+ id="path14" /><path
+ d="m 21.881,17.143 h -3.243 v 2.788 h 3.627 v 1.423 h -5.198 v -9.493 h 5.007 v 1.423 h -3.436 v 2.45 h 3.243 v 1.409 z"
+ inkscape:connector-curvature="0"
+ id="path16" /><path
+ d="m 29.811,21.072 c -0.37,0.211 -1.188,0.422 -2.222,0.422 -2.733,0 -4.394,-1.887 -4.394,-4.774 0,-3.126 1.967,-5.014 4.598,-5.014 1.034,0 1.775,0.239 2.095,0.422 l -0.345,1.38 c -0.409,-0.197 -0.971,-0.366 -1.687,-0.366 -1.749,0 -3.014,1.211 -3.014,3.493 0,2.084 1.111,3.422 3.001,3.422 0.639,0 1.303,-0.141 1.712,-0.352 l 0.256,1.367 z"
+ inkscape:connector-curvature="0"
+ id="path18" /></g><rect
+ width="28.273001"
+ height="2.881"
+ x="2.3959999"
+ y="4.678"
+ id="rect20"
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.2;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/test-png.png b/silx/resources/gui/icons/test-png.png
new file mode 100644
index 0000000..7aa66d6
--- /dev/null
+++ b/silx/resources/gui/icons/test-png.png
Binary files differ
diff --git a/silx/resources/gui/icons/test-svg.svg b/silx/resources/gui/icons/test-svg.svg
new file mode 100644
index 0000000..417d0ce
--- /dev/null
+++ b/silx/resources/gui/icons/test-svg.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(0 -1036.4)">
+ <path transform="translate(-1.5964 1036.4)" d="m14.268 7.9188c0 2.5803-2.0917 4.672-4.672 4.672-2.5802 0-4.672-2.0917-4.672-4.672 0-2.5802 2.0917-4.672 4.672-4.672s4.672 2.0917 4.672 4.672z" color="#000000" fill="#F00"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/view-1d.png b/silx/resources/gui/icons/view-1d.png
new file mode 100644
index 0000000..b420a5c
--- /dev/null
+++ b/silx/resources/gui/icons/view-1d.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-1d.svg b/silx/resources/gui/icons/view-1d.svg
new file mode 100644
index 0000000..3632f45
--- /dev/null
+++ b/silx/resources/gui/icons/view-1d.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g transform="translate(1.1932 -1.149)">
+ <path d="m28.765 3.4301v26.581h-26.863v-26.581" fill="#f7941e" fill-opacity=".81569"/>
+ <path d="m28.76 30.013h-26.951v-26.583" fill="none" stroke="#000" stroke-miterlimit="2" stroke-width="1.3"/>
+ </g>
+ <path d="m29.956 16.168c-2.7537-0.0701-5.2366 4.4566-7.5238 3.9365-7.6475-1.7392-8.9368-19.912-19.399-3.7641-0.048098 0.07424-0.33967-0.06041-0.52072-0.05101" fill="none" stroke="#000" stroke-miterlimit="2" stroke-width="1.5627"/>
+</svg>
diff --git a/silx/resources/gui/icons/view-2d-stack.png b/silx/resources/gui/icons/view-2d-stack.png
new file mode 100644
index 0000000..6571a23
--- /dev/null
+++ b/silx/resources/gui/icons/view-2d-stack.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-2d-stack.svg b/silx/resources/gui/icons/view-2d-stack.svg
new file mode 100644
index 0000000..ca81b16
--- /dev/null
+++ b/silx/resources/gui/icons/view-2d-stack.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <rect x="10.867" y="2.9322" width="18" height="18" ry="0" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="6.9153" y="6.8983" width="18" height="18" ry="0" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="2.9631" y="10.864" width="18" height="18" ry="0" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+</svg>
diff --git a/silx/resources/gui/icons/view-2d.png b/silx/resources/gui/icons/view-2d.png
new file mode 100644
index 0000000..3704867
--- /dev/null
+++ b/silx/resources/gui/icons/view-2d.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-2d.svg b/silx/resources/gui/icons/view-2d.svg
new file mode 100644
index 0000000..aba32c7
--- /dev/null
+++ b/silx/resources/gui/icons/view-2d.svg
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <rect x="2.8314" y="2.8314" width="26.026" height="26.026" ry="0" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+</svg>
diff --git a/silx/resources/gui/icons/view-3d.png b/silx/resources/gui/icons/view-3d.png
new file mode 100644
index 0000000..4a38b19
--- /dev/null
+++ b/silx/resources/gui/icons/view-3d.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-3d.svg b/silx/resources/gui/icons/view-3d.svg
new file mode 100644
index 0000000..3a00254
--- /dev/null
+++ b/silx/resources/gui/icons/view-3d.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <rect transform="matrix(1 0 -.69517 .71885 0 0)" x="31.3" y="26.522" width="16.142" height="13.571" fill="none" stroke="#000" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.6512"/>
+ <rect x="12.767" y="2.935" width="15.819" height="16.09" ry="0" fill="none" stroke="#000" stroke-miterlimit="2" stroke-width="1.3837"/>
+ <rect transform="matrix(1 0 -.70625 .70796 0 0)" x="15.432" y="4.0219" width="16.142" height="13.779" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-linecap="square" stroke-miterlimit="0" stroke-width="1.6639"/>
+ <rect x="2.9112" y="12.74" width="16.142" height="16.142" ry="0" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <path d="m28.899 18.96 0.0111-15.906-9.4388 9.4342-0.0111 16.222z" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-linejoin="bevel" stroke-miterlimit="0" stroke-width="1.4"/>
+</svg>
diff --git a/silx/resources/gui/icons/view-fullscreen.png b/silx/resources/gui/icons/view-fullscreen.png
new file mode 100755
index 0000000..7c891c7
--- /dev/null
+++ b/silx/resources/gui/icons/view-fullscreen.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-fullscreen.svg b/silx/resources/gui/icons/view-fullscreen.svg
new file mode 100644
index 0000000..3164a0c
--- /dev/null
+++ b/silx/resources/gui/icons/view-fullscreen.svg
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg3005"
+ xml:space="preserve"><metadata
+ id="metadata3035"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs3033"><filter
+ x="-0.11942703"
+ y="-0.18130475"
+ width="1.2388541"
+ height="1.3626095"
+ color-interpolation-filters="sRGB"
+ id="filter3804"><feGaussianBlur
+ id="feGaussianBlur3806"
+ stdDeviation="1.05051" /></filter></defs><rect
+ width="27.627001"
+ height="20.344"
+ x="2.688"
+ y="5.8280001"
+ id="rect3011"
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.69999999;stroke-miterlimit:10" /><rect
+ width="26.986"
+ height="2.681"
+ x="3.0090001"
+ y="5.8280001"
+ id="rect3013"
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.2;stroke-miterlimit:10" /><g
+ transform="translate(0.04793944,-3.4995793)"
+ id="g6066"
+ style="fill:#000000;filter:url(#filter3804)"><polygon
+ points="10.365,24.588 9.183,23.109 13.122,19.823 12.04,18.469 8.102,21.758 6.92,20.279 6.145,24.518 "
+ transform="translate(-0.06551334,4.603172)"
+ id="polygon3017-1"
+ style="fill:#000000" /><polygon
+ points="22.924,10.866 24.206,12.38 20.324,15.808 21.498,17.193 25.38,13.763 26.657,15.271 27.256,10.894 "
+ transform="translate(-0.06551334,4.603172)"
+ id="polygon3021-2"
+ style="fill:#000000" /><polygon
+ points="6.718,15.227 8.002,13.709 11.862,17.123 13.036,15.735 9.178,12.323 10.463,10.808 6.145,10.85 "
+ transform="translate(-0.06551334,4.603172)"
+ id="polygon3025-7"
+ style="fill:#000000" /><polygon
+ points="26.391,20.21 25.248,21.758 21.257,18.677 20.215,20.09 24.206,23.168 23.063,24.714 27.256,24.415 "
+ transform="translate(-0.06551334,4.603172)"
+ id="polygon3029-0"
+ style="fill:#000000" /></g><polygon
+ points="9.183,23.109 13.122,19.823 12.04,18.469 8.102,21.758 6.92,20.279 6.145,24.518 10.365,24.588 "
+ id="polygon3017"
+ style="fill:#ed1c24" /><polygon
+ points="24.206,12.38 20.324,15.808 21.498,17.193 25.38,13.763 26.657,15.271 27.256,10.894 22.924,10.866 "
+ id="polygon3021"
+ style="fill:#ed1c24" /><polygon
+ points="8.002,13.709 11.862,17.123 13.036,15.735 9.178,12.323 10.463,10.808 6.145,10.85 6.718,15.227 "
+ id="polygon3025"
+ style="fill:#ed1c24" /><polygon
+ points="25.248,21.758 21.257,18.677 20.215,20.09 24.206,23.168 23.063,24.714 27.256,24.415 26.391,20.21 "
+ id="polygon3029"
+ style="fill:#ed1c24" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/view-hdf5.png b/silx/resources/gui/icons/view-hdf5.png
new file mode 100644
index 0000000..efdf7c7
--- /dev/null
+++ b/silx/resources/gui/icons/view-hdf5.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-hdf5.svg b/silx/resources/gui/icons/view-hdf5.svg
new file mode 100644
index 0000000..e542ef0
--- /dev/null
+++ b/silx/resources/gui/icons/view-hdf5.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path transform="translate(9.9117 -.3238)" d="m18.888 16.324a12.8 12.8 0 1 1 -25.6 0 12.8 12.8 0 1 1 25.6 0z" color="#000000" fill="#f6941d" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <text x="6.1552963" y="21.15884" fill="#000000" font-family="Sans" font-size="13.838px" letter-spacing="0px" word-spacing="0px" style="line-height:125%" xml:space="preserve"><tspan x="6.1552963" y="21.15884" font-weight="bold">h5</tspan></text>
+</svg>
diff --git a/silx/resources/gui/icons/view-nexus.png b/silx/resources/gui/icons/view-nexus.png
new file mode 100644
index 0000000..ab36b1a
--- /dev/null
+++ b/silx/resources/gui/icons/view-nexus.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-nexus.svg b/silx/resources/gui/icons/view-nexus.svg
new file mode 100644
index 0000000..6a1aa09
--- /dev/null
+++ b/silx/resources/gui/icons/view-nexus.svg
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="32"
+ height="32"
+ id="svg3001"
+ inkscape:version="0.48.5 r10040"
+ sodipodi:docname="view-hdf5.svg">
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1161"
+ id="namedview8"
+ showgrid="false"
+ inkscape:zoom="20.85965"
+ inkscape:cx="18.004605"
+ inkscape:cy="9.8354269"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3001" />
+ <defs
+ id="defs3019" />
+ <metadata
+ id="metadata3003">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <path
+ d="m 18.888141,16.323803 a 12.799831,12.799831 0 1 1 -25.5996631,0 12.799831,12.799831 0 1 1 25.5996631,0 z"
+ transform="translate(9.9116907,-0.32380295)"
+ id="path2987"
+ style="color:#000000;fill:#f6941d;fill-opacity:0.81568627;fill-rule:nonzero;stroke:#000000;stroke-width:1.39999998;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:2;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <text
+ x="6.0864153"
+ y="20.080931"
+ id="text3757"
+ xml:space="preserve"
+ style="font-size:13.09981823px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+ sodipodi:linespacing="125%"
+ transform="scale(0.95955357,1.0421513)"><tspan
+ x="6.0864153"
+ y="20.080931"
+ id="tspan3759"
+ style="font-weight:bold;-inkscape-font-specification:Sans Bold">NX</tspan></text>
+</svg>
diff --git a/silx/resources/gui/icons/view-nofullscreen.png b/silx/resources/gui/icons/view-nofullscreen.png
new file mode 100755
index 0000000..d61625e
--- /dev/null
+++ b/silx/resources/gui/icons/view-nofullscreen.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-nofullscreen.svg b/silx/resources/gui/icons/view-nofullscreen.svg
new file mode 100644
index 0000000..c5b2c24
--- /dev/null
+++ b/silx/resources/gui/icons/view-nofullscreen.svg
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg4275"
+ xml:space="preserve"><metadata
+ id="metadata4303"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+ id="defs4301"><filter
+ x="-0.33807367"
+ y="-0.42624661"
+ width="1.6761473"
+ height="1.8524932"
+ color-interpolation-filters="sRGB"
+ id="filter3943"><feGaussianBlur
+ id="feGaussianBlur3945"
+ stdDeviation="1.16241" /></filter><filter
+ x="-0.3533161"
+ y="-0.42546651"
+ width="1.7066323"
+ height="1.850933"
+ color-interpolation-filters="sRGB"
+ id="filter3947"><feGaussianBlur
+ id="feGaussianBlur3949"
+ stdDeviation="1.16241" /></filter><filter
+ x="-0.34981617"
+ y="-0.42520714"
+ width="1.6996324"
+ height="1.8504143"
+ color-interpolation-filters="sRGB"
+ id="filter3951"><feGaussianBlur
+ id="feGaussianBlur3953"
+ stdDeviation="1.16241" /></filter><filter
+ x="-0.34548408"
+ y="-0.41976887"
+ width="1.6909682"
+ height="1.8395379"
+ color-interpolation-filters="sRGB"
+ id="filter3955"><feGaussianBlur
+ id="feGaussianBlur3957"
+ stdDeviation="1.16241" /></filter></defs><g
+ id="g3959"><polygon
+ points="28.095,10.325 26.996,8.802 22.393,12.264 21.201,10.608 20.02,15.224 24.684,15.448 23.488,13.785 "
+ transform="translate(0.11748671,0.92428829)"
+ id="polygon4281-7"
+ style="fill:#000000;filter:url(#filter3955)" /><polygon
+ points="26.968,24.394 28.044,22.933 23.491,19.431 24.671,17.833 20.069,17.94 21.237,22.488 22.416,20.892 "
+ transform="translate(0.11748671,0.92428829)"
+ id="polygon4287-5"
+ style="fill:#000000;filter:url(#filter3951)" /><polygon
+ points="5.118,22.968 6.202,24.392 10.702,20.813 11.887,22.369 13.014,17.835 8.434,17.838 9.618,19.391 "
+ transform="translate(0.11748671,0.92428829)"
+ id="polygon4291-3"
+ style="fill:#000000;filter:url(#filter3947)" /><polygon
+ points="5.971,8.852 4.94,10.418 9.675,13.685 8.543,15.397 13.192,14.976 11.837,10.404 10.709,12.119 "
+ transform="translate(0.11748671,0.92428829)"
+ id="polygon4295-5"
+ style="fill:#000000;filter:url(#filter3943)" /></g><path
+ d="M 18.462,31.115"
+ id="path4277"
+ style="stroke:#ffffff;stroke-width:0.50999999;stroke-miterlimit:10" /><polygon
+ points="24.684,15.448 23.488,13.785 28.095,10.325 26.996,8.802 22.393,12.264 21.201,10.608 20.02,15.224 "
+ id="polygon4281"
+ style="fill:#ed1c24" /><rect
+ width="26.216"
+ height="2.7049999"
+ x="3.4130001"
+ y="5.1230001"
+ id="rect4283"
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.2;stroke-miterlimit:10" /><polygon
+ points="21.237,22.488 22.416,20.892 26.968,24.394 28.044,22.933 23.491,19.431 24.671,17.833 20.069,17.94 "
+ id="polygon4287"
+ style="fill:#ed1c24" /><polygon
+ points="8.434,17.838 9.618,19.391 5.118,22.968 6.202,24.392 10.702,20.813 11.887,22.369 13.014,17.835 "
+ id="polygon4291"
+ style="fill:#ed1c24" /><polygon
+ points="11.837,10.404 10.709,12.119 5.971,8.852 4.94,10.418 9.675,13.685 8.543,15.397 13.192,14.976 "
+ id="polygon4295"
+ style="fill:#ed1c24" /><rect
+ width="26.580999"
+ height="19.924999"
+ x="3.0480001"
+ y="5.1230001"
+ id="rect4297"
+ style="fill:none;stroke:#000000;stroke-width:0.89999998;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/view-raw.png b/silx/resources/gui/icons/view-raw.png
new file mode 100644
index 0000000..a0fb23d
--- /dev/null
+++ b/silx/resources/gui/icons/view-raw.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-raw.svg b/silx/resources/gui/icons/view-raw.svg
new file mode 100644
index 0000000..b7ddb98
--- /dev/null
+++ b/silx/resources/gui/icons/view-raw.svg
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <rect x="3.2544" y="21.322" width="7.7285" height="7.7285" ry="0" color="#000000" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="3.2544" y="13.051" width="7.7285" height="7.7285" ry="0" color="#000000" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="3.2544" y="4.9832" width="7.7285" height="7.7285" ry="0" color="#000000" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="11.017" y="21.322" width="7.7285" height="7.7285" ry="0" color="#000000" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="11.017" y="13.051" width="7.7285" height="7.7285" ry="0" color="#000000" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="11.017" y="4.9832" width="7.7285" height="7.7285" ry="0" color="#000000" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="19.22" y="21.322" width="7.7285" height="7.7285" ry="0" color="#000000" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="19.22" y="13.051" width="7.7285" height="7.7285" ry="0" color="#000000" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <rect x="19.22" y="4.9832" width="7.7285" height="7.7285" ry="0" color="#000000" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+</svg>
diff --git a/silx/resources/gui/icons/view-refresh.png b/silx/resources/gui/icons/view-refresh.png
new file mode 100755
index 0000000..1a8c064
--- /dev/null
+++ b/silx/resources/gui/icons/view-refresh.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-refresh.svg b/silx/resources/gui/icons/view-refresh.svg
new file mode 100644
index 0000000..f426a03
--- /dev/null
+++ b/silx/resources/gui/icons/view-refresh.svg
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata16"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs14" /><path
+ d="M 27.433,12.199 C 22.826,3.239 11.787,3.033 8.074,12.794 5.616,12.082 4.388,11.727 1.93,11.014 c 5.262,-12.507 22.627,-12.86 26.917,0.597 -0.567,0.234 -0.85,0.353 -1.414,0.588 z"
+ inkscape:connector-curvature="0"
+ id="path4"
+ style="fill:#00a651;stroke:#00a651;stroke-miterlimit:10" /><path
+ d="m 5.083,19.917 c 4.676,8.426 15.219,8.544 18.909,-0.728 2.47,0.721 3.708,1.075 6.2,1.762 C 25.04,33.107 8.285,33.617 3.602,20.786 4.196,20.425 4.493,20.25 5.083,19.917 z"
+ inkscape:connector-curvature="0"
+ id="path6"
+ style="fill:#f7941e;stroke:#f7941e;stroke-miterlimit:10" /><polygon
+ points="5.909,21.146 1.634,23.639 2.355,13.137 5.812,16.029 9.457,19.078 "
+ id="polygon8"
+ style="fill:#f7941e;stroke:#f7941e;stroke-miterlimit:10" /><polygon
+ points="26.533,9.5 30.686,6.475 29.58,18.389 25.758,14.432 21.852,10.77 "
+ id="polygon10"
+ style="fill:#00a651;stroke:#00a651;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/view-text.png b/silx/resources/gui/icons/view-text.png
new file mode 100644
index 0000000..5bfde30
--- /dev/null
+++ b/silx/resources/gui/icons/view-text.png
Binary files differ
diff --git a/silx/resources/gui/icons/view-text.svg b/silx/resources/gui/icons/view-text.svg
new file mode 100644
index 0000000..24b8662
--- /dev/null
+++ b/silx/resources/gui/icons/view-text.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <metadata>
+ <rdf:RDF>
+ <cc:Work rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+ <dc:title/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <rect x="3.4068" y="7.339" width="25.219" height="16.007" ry="0" fill="#f7941e" fill-opacity=".81569" stroke="#000" stroke-miterlimit="2" stroke-width="1.4"/>
+ <g transform="matrix(.89445 0 0 .89445 1.3024 .77355)">
+ <path d="m8.9353 15.017v-3.1925h0.96935v8.1973h-0.96935v-0.88506c-0.20371 0.35121-0.46185 0.61287-0.77443 0.78496-0.30907 0.16858-0.68136 0.25287-1.1169 0.25287-0.71297 0-1.2942-0.28448-1.7438-0.85345-0.44604-0.56896-0.66906-1.317-0.66906-2.2443-6e-7 -0.9272 0.22302-1.6753 0.66906-2.2443 0.44955-0.56896 1.0308-0.85344 1.7438-0.85345 0.4355 7e-6 0.80779 0.08605 1.1169 0.25814 0.31258 0.16859 0.57072 0.42849 0.77443 0.77969m-3.3032 2.0599c-1.6e-6 0.71297 0.14575 1.2732 0.43726 1.6806 0.29502 0.4039 0.69891 0.60584 1.2117 0.60584 0.51277 1e-6 0.91666-0.20195 1.2117-0.60584 0.29501-0.40741 0.44252-0.96759 0.44253-1.6806-4.9e-6 -0.71296-0.14751-1.2714-0.44253-1.6753-0.29502-0.4074-0.69892-0.61111-1.2117-0.61111-0.51277 6e-6 -0.91667 0.20371-1.2117 0.61111-0.29151 0.4039-0.43726 0.96233-0.43726 1.6753"/>
+ <path d="m14.583 17.056c-0.78321 3e-6 -1.3258 0.08956-1.6279 0.26868-0.30204 0.17912-0.45307 0.48468-0.45306 0.91667-1e-6 0.34419 0.11239 0.61814 0.33716 0.82184 0.22829 0.20019 0.53735 0.30029 0.9272 0.30029 0.53735 1e-6 0.96759-0.18965 1.2907-0.56896 0.32662-0.38282 0.48994-0.89032 0.48994-1.5225v-0.216h-0.96408m1.9334-0.40038v3.3664h-0.96935v-0.89559c-0.22127 0.35824-0.49697 0.6234-0.82711 0.7955-0.33014 0.16858-0.73404 0.25287-1.2117 0.25287-0.60409 0-1.0853-0.16858-1.4435-0.50575-0.35473-0.34068-0.53209-0.7955-0.53209-1.3645 0-0.66379 0.22126-1.1643 0.66379-1.5014 0.44604-0.33716 1.1098-0.50574 1.9914-0.50575h1.3592v-0.09483c-5e-6 -0.44604-0.14751-0.79022-0.44253-1.0326-0.29151-0.24584-0.70243-0.36877-1.2328-0.36877-0.33717 5e-6 -0.66555 0.04039-0.98515 0.12117-0.31961 0.08078-0.62692 0.20195-0.92194 0.36351v-0.89559c0.35472-0.13697 0.69891-0.23882 1.0326-0.30556 0.33365-0.07024 0.65852-0.10536 0.97462-0.10536 0.85344 7e-6 1.4909 0.22127 1.9124 0.66379 0.42145 0.44253 0.63218 1.1134 0.63218 2.0125"/>
+ <path d="m19.477 12.447v1.6753h1.9966v0.75335h-1.9966v3.2031c-2e-6 0.48116 0.06497 0.79023 0.19492 0.9272 0.13346 0.13697 0.40214 0.20546 0.80603 0.20546h0.99569v0.8113h-0.99569c-0.74809 0-1.2644-0.13873-1.5489-0.41619-0.28448-0.28097-0.42672-0.79023-0.42672-1.5278v-3.2031h-0.71121v-0.75335h0.71121v-1.6753h0.97462"/>
+ <path d="m25.435 17.056c-0.78321 3e-6 -1.3258 0.08956-1.6279 0.26868-0.30204 0.17912-0.45307 0.48468-0.45306 0.91667-2e-6 0.34419 0.11239 0.61814 0.33716 0.82184 0.22829 0.20019 0.53735 0.30029 0.9272 0.30029 0.53735 1e-6 0.96759-0.18965 1.2907-0.56896 0.32662-0.38282 0.48994-0.89032 0.48994-1.5225v-0.216h-0.96408m1.9334-0.40038v3.3664h-0.96935v-0.89559c-0.22127 0.35824-0.49697 0.6234-0.82711 0.7955-0.33014 0.16858-0.73404 0.25287-1.2117 0.25287-0.60409 0-1.0853-0.16858-1.4435-0.50575-0.35473-0.34068-0.53209-0.7955-0.53209-1.3645-1e-6 -0.66379 0.22126-1.1643 0.66379-1.5014 0.44604-0.33716 1.1098-0.50574 1.9914-0.50575h1.3592v-0.09483c-4e-6 -0.44604-0.14751-0.79022-0.44253-1.0326-0.29151-0.24584-0.70243-0.36877-1.2328-0.36877-0.33717 5e-6 -0.66555 0.04039-0.98515 0.12117-0.31961 0.08078-0.62692 0.20195-0.92194 0.36351v-0.89559c0.35472-0.13697 0.69891-0.23882 1.0326-0.30556 0.33365-0.07024 0.65852-0.10536 0.97462-0.10536 0.85344 7e-6 1.4909 0.22127 1.9124 0.66379 0.42145 0.44253 0.63218 1.1134 0.63218 2.0125"/>
+ </g>
+</svg>
diff --git a/silx/resources/gui/icons/window-new.png b/silx/resources/gui/icons/window-new.png
new file mode 100755
index 0000000..d26703b
--- /dev/null
+++ b/silx/resources/gui/icons/window-new.png
Binary files differ
diff --git a/silx/resources/gui/icons/window-new.svg b/silx/resources/gui/icons/window-new.svg
new file mode 100644
index 0000000..cdcf9f1
--- /dev/null
+++ b/silx/resources/gui/icons/window-new.svg
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata24"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><path
+ d="M 24.653,7.496 C 13.689,7.389 14.58,18.149 14.387,18.47 c 0,0 0.193,-7.139 10.267,-6.713 V 7.496 z"
+ id="path6"
+ style="fill:#f7941e;stroke:#f7941e;stroke-width:0.1;stroke-miterlimit:10" /><path
+ d="m 24.653,5.819 c 0,-0.17 0.122,-0.243 0.271,-0.16 l 6.169,3.403 c 0.149,0.083 0.157,0.23 0.018,0.328 l -6.204,4.348 c -0.14,0.098 -0.254,0.038 -0.254,-0.132 V 5.819 z"
+ id="path10"
+ style="fill:#f7941e;fill-opacity:1;stroke:#f7941e;stroke-miterlimit:10" /><defs
+ id="defs12"><polygon
+ points="2.505,29.804 0.69,7.484 16.967,6.267 12.083,13.194 23.478,18.148 29.488,13.594 29.488,28.585 "
+ id="b" /><clipPath
+ id="a-3"><use
+ id="use16-6"
+ style="overflow:visible"
+ x="0"
+ y="0"
+ width="32"
+ height="32"
+ xlink:href="#b" /></clipPath></defs><path
+ d="M 6.21875,8.75 C 5.2556622,8.75 4.4375,9.5384524 4.4375,10.5 l 0,14.125 c 0,0.963088 0.8197024,1.75 1.78125,1.75 l 19.5625,0 c 0.456817,0 0.872767,-0.208524 1.1875,-0.5 0.394494,-0.391361 0.545811,-0.733107 0.59375,-1.25 l 0,-9.625 -2.5,2.03125 c -0.0096,2.28115 0.03017,4.564259 -0.03125,6.84375 l -18.09375,0 0,-12.625 6.5625,0 1.6875,-2.5 z"
+ id="path20-5"
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#f7941e;fill-opacity:1;stroke:none;stroke-width:2.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/zoom-in.png b/silx/resources/gui/icons/zoom-in.png
new file mode 100755
index 0000000..a133948
--- /dev/null
+++ b/silx/resources/gui/icons/zoom-in.png
Binary files differ
diff --git a/silx/resources/gui/icons/zoom-in.svg b/silx/resources/gui/icons/zoom-in.svg
new file mode 100644
index 0000000..11e9487
--- /dev/null
+++ b/silx/resources/gui/icons/zoom-in.svg
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata50"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs48" /><linearGradient
+ x1="19.886999"
+ y1="23.759001"
+ x2="22.374001"
+ y2="20.443001"
+ id="d"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop5"
+ style="stop-color:#280e19;stop-opacity:1"
+ offset="0" /><stop
+ id="stop7"
+ style="stop-color:#382229;stop-opacity:1"
+ offset="0.1053" /><stop
+ id="stop9"
+ style="stop-color:#f9edf5;stop-opacity:1"
+ offset="0.98390001" /></linearGradient><polygon
+ points="27.606,24.356 25.103,27.571 14.723,19.758 17.174,16.502 "
+ id="polygon11"
+ style="fill:url(#d);stroke:#808285;stroke-width:0.1;stroke-miterlimit:10" /><circle
+ cx="10.483"
+ cy="14.302"
+ r="7"
+ id="circle13"
+ style="fill:none;stroke:#776569;stroke-miterlimit:10" /><radialGradient
+ cx="12.253"
+ cy="10.413"
+ r="9.1342001"
+ id="c"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop16"
+ style="stop-color:#00aeef;stop-opacity:0.60000002"
+ offset="0" /><stop
+ id="stop18"
+ style="stop-color:#9bd1ea;stop-opacity:0.53170002"
+ offset="0.6832" /><stop
+ id="stop20"
+ style="stop-color:#e6e7e8;stop-opacity:0.5"
+ offset="1" /></radialGradient><linearGradient
+ x1="3.4521"
+ y1="14.302"
+ x2="17.514"
+ y2="14.302"
+ id="b"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop23"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" /><stop
+ id="stop25"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1" /></linearGradient><path
+ d="m 17.014,14.301 c 0,3.594 -3.038,6.507 -6.517,6.507 -3.479,0 -6.544,-2.913 -6.544,-6.507 0,-3.594 3.065,-6.507 6.544,-6.507 3.479,0 6.517,2.914 6.517,6.507 z"
+ inkscape:connector-curvature="0"
+ id="path27"
+ style="fill:url(#c);stroke:url(#b);stroke-miterlimit:10" /><radialGradient
+ cx="21.443001"
+ cy="23.502001"
+ r="0"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop30"
+ style="stop-color:#00aeef;stop-opacity:0.60000002"
+ offset="0" /><stop
+ id="stop32"
+ style="stop-color:#517180;stop-opacity:0.53170002"
+ offset="0.6832" /><stop
+ id="stop34"
+ style="stop-color:#414042;stop-opacity:0.5"
+ offset="1" /></radialGradient><path
+ d="M 21.443,23.502"
+ inkscape:connector-curvature="0"
+ id="path36"
+ style="fill:url(#a)" /><path
+ d="m 9.177,9.151 c 0,0 4.405,-1.127 6.307,3.42"
+ inkscape:connector-curvature="0"
+ id="path38"
+ style="fill:none;stroke:#ffffff;stroke-miterlimit:10" /><g
+ id="g40"
+ style="fill:#00a651;stroke:#00a651;stroke-miterlimit:10"><rect
+ width="1.239"
+ height="8.3789997"
+ x="24.483"
+ y="7.2249999"
+ id="rect42" /><rect
+ width="8.3800001"
+ height="1.237"
+ x="20.913"
+ y="10.796"
+ id="rect44" /></g></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/zoom-original.png b/silx/resources/gui/icons/zoom-original.png
new file mode 100755
index 0000000..5d78149
--- /dev/null
+++ b/silx/resources/gui/icons/zoom-original.png
Binary files differ
diff --git a/silx/resources/gui/icons/zoom-original.svg b/silx/resources/gui/icons/zoom-original.svg
new file mode 100644
index 0000000..da0eb75
--- /dev/null
+++ b/silx/resources/gui/icons/zoom-original.svg
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata50"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs48" /><linearGradient
+ x1="20.888"
+ y1="23.759001"
+ x2="23.375"
+ y2="20.443001"
+ id="d"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop5"
+ style="stop-color:#280e19;stop-opacity:1"
+ offset="0" /><stop
+ id="stop7"
+ style="stop-color:#382229;stop-opacity:1"
+ offset="0.1053" /><stop
+ id="stop9"
+ style="stop-color:#f9edf5;stop-opacity:1"
+ offset="0.98390001" /></linearGradient><polygon
+ points="28.606,24.356 26.103,27.571 15.723,19.758 18.174,16.502 "
+ id="polygon11"
+ style="fill:url(#d);stroke:#808285;stroke-width:0.1;stroke-miterlimit:10" /><circle
+ cx="11.483"
+ cy="14.302"
+ r="7"
+ id="circle13"
+ style="fill:none;stroke:#776569;stroke-miterlimit:10" /><radialGradient
+ cx="13.253"
+ cy="10.413"
+ r="9.1342001"
+ id="c"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop16"
+ style="stop-color:#00aeef;stop-opacity:0.60000002"
+ offset="0" /><stop
+ id="stop18"
+ style="stop-color:#9bd1ea;stop-opacity:0.53170002"
+ offset="0.6832" /><stop
+ id="stop20"
+ style="stop-color:#e6e7e8;stop-opacity:0.5"
+ offset="1" /></radialGradient><linearGradient
+ x1="4.4520998"
+ y1="14.302"
+ x2="18.514"
+ y2="14.302"
+ id="b"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop23"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" /><stop
+ id="stop25"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1" /></linearGradient><path
+ d="m 18.014,14.301 c 0,3.594 -3.038,6.507 -6.517,6.507 -3.479,0 -6.544,-2.913 -6.544,-6.507 0,-3.594 3.065,-6.507 6.544,-6.507 3.479,0 6.517,2.914 6.517,6.507 z"
+ inkscape:connector-curvature="0"
+ id="path27"
+ style="fill:url(#c);stroke:url(#b);stroke-miterlimit:10" /><radialGradient
+ cx="22.443001"
+ cy="23.502001"
+ r="0"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop30"
+ style="stop-color:#00aeef;stop-opacity:0.60000002"
+ offset="0" /><stop
+ id="stop32"
+ style="stop-color:#517180;stop-opacity:0.53170002"
+ offset="0.6832" /><stop
+ id="stop34"
+ style="stop-color:#414042;stop-opacity:0.5"
+ offset="1" /></radialGradient><path
+ d="M 22.443,23.502"
+ inkscape:connector-curvature="0"
+ id="path36"
+ style="fill:url(#a)" /><path
+ d="m 10.177,9.151 c 0,0 4.405,-1.127 6.307,3.42"
+ inkscape:connector-curvature="0"
+ id="path38"
+ style="fill:none;stroke:#ffffff;stroke-miterlimit:10" /><g
+ id="g40"
+ style="fill:#ed1c24;stroke:#ed1c24;stroke-width:2.5;stroke-miterlimit:10"><line
+ x1="7.257"
+ x2="25.712"
+ y1="24.906"
+ y2="6.5180001"
+ id="line42" /><line
+ x1="7.3920002"
+ x2="25.575001"
+ y1="6.3709998"
+ y2="25.052999"
+ id="line44" /></g></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/zoom-out.png b/silx/resources/gui/icons/zoom-out.png
new file mode 100755
index 0000000..3110fa8
--- /dev/null
+++ b/silx/resources/gui/icons/zoom-out.png
Binary files differ
diff --git a/silx/resources/gui/icons/zoom-out.svg b/silx/resources/gui/icons/zoom-out.svg
new file mode 100644
index 0000000..d2f82e2
--- /dev/null
+++ b/silx/resources/gui/icons/zoom-out.svg
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata46"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs44" /><linearGradient
+ x1="19.886999"
+ y1="22.759001"
+ x2="22.374001"
+ y2="19.443001"
+ id="d"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop5"
+ style="stop-color:#280e19;stop-opacity:1"
+ offset="0" /><stop
+ id="stop7"
+ style="stop-color:#382229;stop-opacity:1"
+ offset="0.1053" /><stop
+ id="stop9"
+ style="stop-color:#f9edf5;stop-opacity:1"
+ offset="0.98390001" /></linearGradient><polygon
+ points="27.606,23.356 25.103,26.571 14.723,18.758 17.174,15.502 "
+ id="polygon11"
+ style="fill:url(#d);stroke:#808285;stroke-width:0.1;stroke-miterlimit:10" /><circle
+ cx="10.483"
+ cy="13.302"
+ r="7"
+ id="circle13"
+ style="fill:none;stroke:#776569;stroke-miterlimit:10" /><radialGradient
+ cx="12.253"
+ cy="9.4125996"
+ r="9.1342001"
+ id="c"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop16"
+ style="stop-color:#00aeef;stop-opacity:0.60000002"
+ offset="0" /><stop
+ id="stop18"
+ style="stop-color:#9bd1ea;stop-opacity:0.53170002"
+ offset="0.6832" /><stop
+ id="stop20"
+ style="stop-color:#e6e7e8;stop-opacity:0.5"
+ offset="1" /></radialGradient><linearGradient
+ x1="3.4521"
+ y1="13.302"
+ x2="17.514"
+ y2="13.302"
+ id="b"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop23"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" /><stop
+ id="stop25"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1" /></linearGradient><path
+ d="m 17.014,13.301 c 0,3.594 -3.038,6.507 -6.517,6.507 -3.479,0 -6.544,-2.914 -6.544,-6.507 0,-3.593 3.065,-6.507 6.544,-6.507 3.479,0 6.517,2.914 6.517,6.507 z"
+ inkscape:connector-curvature="0"
+ id="path27"
+ style="fill:url(#c);stroke:url(#b);stroke-miterlimit:10" /><radialGradient
+ cx="21.443001"
+ cy="22.502001"
+ r="0"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop30"
+ style="stop-color:#00aeef;stop-opacity:0.60000002"
+ offset="0" /><stop
+ id="stop32"
+ style="stop-color:#517180;stop-opacity:0.53170002"
+ offset="0.6832" /><stop
+ id="stop34"
+ style="stop-color:#414042;stop-opacity:0.5"
+ offset="1" /></radialGradient><path
+ d="M 21.443,22.502"
+ inkscape:connector-curvature="0"
+ id="path36"
+ style="fill:url(#a)" /><path
+ d="m 9.177,8.151 c 0,0 4.405,-1.127 6.307,3.42"
+ inkscape:connector-curvature="0"
+ id="path38"
+ style="fill:none;stroke:#ffffff;stroke-miterlimit:10" /><rect
+ width="7.3769999"
+ height="0.98799998"
+ x="20.304001"
+ y="7.802"
+ id="rect40"
+ style="fill:#ed1c24;stroke:#ed1c24;stroke-width:2;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/gui/icons/zoom.png b/silx/resources/gui/icons/zoom.png
new file mode 100755
index 0000000..7847c0a
--- /dev/null
+++ b/silx/resources/gui/icons/zoom.png
Binary files differ
diff --git a/silx/resources/gui/icons/zoom.svg b/silx/resources/gui/icons/zoom.svg
new file mode 100644
index 0000000..87f72a7
--- /dev/null
+++ b/silx/resources/gui/icons/zoom.svg
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="100%"
+ height="100%"
+ viewBox="0 0 32 32"
+ id="svg2"
+ xml:space="preserve"><metadata
+ id="metadata44"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs42" /><linearGradient
+ x1="20.886999"
+ y1="21.759001"
+ x2="23.374001"
+ y2="18.443001"
+ id="d"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop5"
+ style="stop-color:#280e19;stop-opacity:1"
+ offset="0" /><stop
+ id="stop7"
+ style="stop-color:#382229;stop-opacity:1"
+ offset="0.1053" /><stop
+ id="stop9"
+ style="stop-color:#f9edf5;stop-opacity:1"
+ offset="0.98390001" /></linearGradient><polygon
+ points="28.606,22.356 26.103,25.571 15.723,17.758 18.174,14.502 "
+ id="polygon11"
+ style="fill:url(#d);stroke:#808285;stroke-width:0.2;stroke-miterlimit:10" /><circle
+ cx="11.483"
+ cy="12.302"
+ r="7"
+ id="circle13"
+ style="fill:none;stroke:#776569;stroke-miterlimit:10" /><radialGradient
+ cx="13.206"
+ cy="8.4125996"
+ r="9.1344004"
+ id="c"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop16"
+ style="stop-color:#00aeef;stop-opacity:0.60000002"
+ offset="0" /><stop
+ id="stop18"
+ style="stop-color:#9bd1ea;stop-opacity:0.53170002"
+ offset="0.6832" /><stop
+ id="stop20"
+ style="stop-color:#e6e7e8;stop-opacity:0.5"
+ offset="1" /></radialGradient><linearGradient
+ x1="4.605"
+ y1="12.302"
+ x2="18.267"
+ y2="12.302"
+ id="b"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop23"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" /><stop
+ id="stop25"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1" /></linearGradient><path
+ d="m 17.967,12.302 c 0,3.594 -3.039,6.507 -6.518,6.507 -3.479,0 -6.544,-2.913 -6.544,-6.507 0,-3.594 3.065,-6.507 6.544,-6.507 3.479,0 6.518,2.913 6.518,6.507 z"
+ inkscape:connector-curvature="0"
+ id="path27"
+ style="fill:url(#c);stroke:url(#b);stroke-width:0.60000002;stroke-miterlimit:10" /><radialGradient
+ cx="22.443001"
+ cy="21.502001"
+ r="0"
+ id="a"
+ gradientUnits="userSpaceOnUse"><stop
+ id="stop30"
+ style="stop-color:#00aeef;stop-opacity:0.60000002"
+ offset="0" /><stop
+ id="stop32"
+ style="stop-color:#517180;stop-opacity:0.53170002"
+ offset="0.6832" /><stop
+ id="stop34"
+ style="stop-color:#414042;stop-opacity:0.5"
+ offset="1" /></radialGradient><path
+ d="M 22.443,21.502"
+ inkscape:connector-curvature="0"
+ id="path36"
+ style="fill:url(#a)" /><path
+ d="m 10.992,6.764 c 0,0 4.839,-0.584 5.992,4.366"
+ inkscape:connector-curvature="0"
+ id="path38"
+ style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-miterlimit:10" /></svg> \ No newline at end of file
diff --git a/silx/resources/opencl/addition.cl b/silx/resources/opencl/addition.cl
new file mode 100644
index 0000000..8ecfd4e
--- /dev/null
+++ b/silx/resources/opencl/addition.cl
@@ -0,0 +1,36 @@
+/*
+ * Project: SIFT: An algorithm for image alignement
+ *
+ * Copyright (C) 2013-2017 European Synchrotron Radiation Facility
+ * Grenoble, France
+ *
+ * Principal authors: J. Kieffer (kieffer@esrf.fr)
+ *
+ * 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.
+ */
+__kernel void addition(__global float* a, __global float* b, __global float* res, int N)
+{
+ unsigned int i = get_global_id(0);
+ if( i<N ){
+ res[i] = a[i] + b[i];
+ }
+} \ No newline at end of file
diff --git a/silx/resources/opencl/bitonic.cl b/silx/resources/opencl/bitonic.cl
new file mode 100644
index 0000000..f1cb55c
--- /dev/null
+++ b/silx/resources/opencl/bitonic.cl
@@ -0,0 +1,557 @@
+/*############################################################################
+# Sort elements within a vector by Matthew Scarpino,
+# Taken from his book "OpenCL in Action",
+# November 2011 ISBN 9781617290176
+# Original license for the code: "public domain"
+#
+# Originally this code is public domain. The MIT license has been added
+# by J. Kieffer (jerome.kieffer@esrf.eu) to provide a disclaimer.
+# J. Kieffer does not claim authorship of this code developed by .
+#
+# Copyright (c) 2011 Matthew Scarpino
+#
+# 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.
+#
+#############################################################################*/
+
+#define VECTOR_SORT_BOOK(input, dir) \
+ comp = abs(input > shuffle(input, mask2)) ^ dir; \
+ input = shuffle(input, comp * 2 + add2); \
+ comp = abs(input > shuffle(input, mask1)) ^ dir; \
+ input = shuffle(input, comp + add1); \
+
+
+#define VECTOR_SWAP_BOOK(in1, in2, dir) \
+ input1 = in1; input2 = in2; \
+ comp = (abs(input1 > input2) ^ dir) * 4 + add3; \
+ in1 = shuffle2(input1, input2, comp); \
+ in2 = shuffle2(input2, input1, comp); \
+
+
+// The _FILE extension correspond to the formula found in the "OpenCL in Action" supplementary files
+#define VECTOR_SORT_FILE(input, dir) \
+ comp = (input < shuffle(input, mask2)) ^ dir; \
+ input = shuffle(input, as_uint4(comp * 2 + add2)); \
+ comp = (input < shuffle(input, mask1)) ^ dir; \
+ input = shuffle(input, as_uint4(comp + add1)); \
+
+
+#define VECTOR_SWAP_FILE(input1, input2, dir) \
+ temp = input1; \
+ comp = ((input1 < input2) ^ dir) * 4 + add3; \
+ input1 = shuffle2(input1, input2, as_uint4(comp)); \
+ input2 = shuffle2(input2, temp, as_uint4(comp)); \
+
+
+
+// Functions to be called from an actual kernel.
+
+static float8 my_sort_file(uint local_id, uint group_id, uint local_size,
+ float8 input, __local float4 *l_data){
+ float4 input1, input2, temp;
+ float8 output;
+
+ int dir;
+ uint id, size, stride;
+ int4 comp;
+
+ uint4 mask1 = (uint4)(1, 0, 3, 2);
+ uint4 mask2 = (uint4)(2, 3, 0, 1);
+ uint4 mask3 = (uint4)(3, 2, 1, 0);
+
+ int4 add1 = (int4)(1, 1, 3, 3);
+ int4 add2 = (int4)(2, 3, 2, 3);
+ int4 add3 = (int4)(1, 2, 2, 3);
+
+ // retrieve input data
+ input1 = (float4)(input.s0, input.s1, input.s2, input.s3);
+ input2 = (float4)(input.s4, input.s5, input.s6, input.s7);
+
+ // Find global address
+ id = local_id * 2;
+
+ /* Sort input 1 - ascending */
+ comp = input1 < shuffle(input1, mask1);
+ input1 = shuffle(input1, as_uint4(comp + add1));
+ comp = input1 < shuffle(input1, mask2);
+ input1 = shuffle(input1, as_uint4(comp * 2 + add2));
+ comp = input1 < shuffle(input1, mask3);
+ input1 = shuffle(input1, as_uint4(comp + add3));
+
+ /* Sort input 2 - descending */
+ comp = input2 > shuffle(input2, mask1);
+ input2 = shuffle(input2, as_uint4(comp + add1));
+ comp = input2 > shuffle(input2, mask2);
+ input2 = shuffle(input2, as_uint4(comp * 2 + add2));
+ comp = input2 > shuffle(input2, mask3);
+ input2 = shuffle(input2, as_uint4(comp + add3));
+
+ /* Swap corresponding elements of input 1 and 2 */
+ add3 = (int4)(4, 5, 6, 7);
+ dir = - (int) (local_id % 2);
+ temp = input1;
+ comp = ((input1 < input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, as_uint4(comp));
+ input2 = shuffle2(input2, temp, as_uint4(comp));
+
+ /* Sort data and store in local memory */
+ VECTOR_SORT_FILE(input1, dir);
+ VECTOR_SORT_FILE(input2, dir);
+ l_data[id] = input1;
+ l_data[id+1] = input2;
+
+ /* Create bitonic set */
+ for(size = 2; size < local_size; size <<= 1) {
+ dir = - (int) (local_id/size & 1) ;
+
+ for(stride = size; stride > 1; stride >>= 1) {
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = local_id + (local_id/stride)*stride;
+ VECTOR_SWAP_FILE(l_data[id], l_data[id + stride], dir)
+ }
+
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = local_id * 2;
+ input1 = l_data[id];
+ input2 = l_data[id+1];
+ temp = input1;
+ comp = ((input1 < input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, as_uint4(comp));
+ input2 = shuffle2(input2, temp, as_uint4(comp));
+ VECTOR_SORT_FILE(input1, dir);
+ VECTOR_SORT_FILE(input2, dir);
+ l_data[id] = input1;
+ l_data[id+1] = input2;
+ }
+
+ /* Perform bitonic merge */
+ dir = - (int) (group_id % 2);
+ for(stride = local_size; stride > 1; stride >>= 1) {
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = local_id + (local_id/stride)*stride;
+ VECTOR_SWAP_FILE(l_data[id], l_data[id + stride], dir)
+ }
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ /* Perform final sort */
+ id = local_id * 2;
+ input1 = l_data[id]; input2 = l_data[id+1];
+ temp = input1;
+ comp = ((input1 < input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, as_uint4(comp));
+ input2 = shuffle2(input2, temp, as_uint4(comp));
+ VECTOR_SORT_FILE(input1, dir);
+ VECTOR_SORT_FILE(input2, dir);
+
+ // setup output and return it
+ output = (float8)(input1, input2);
+ return output;
+}
+
+static float8 my_sort_book(uint local_id, uint group_id, uint local_size,
+ float8 input, __local float4 *l_data){
+ float4 input1, input2, temp;
+ float8 output;
+ uint4 comp, swap, mask1, mask2, add1, add2, add3;
+ uint id, dir, size, stride;
+ mask1 = (uint4)(1, 0, 3, 2);
+ swap = (uint4)(0, 0, 1, 1);
+ add1 = (uint4)(0, 0, 2, 2);
+ mask2 = (uint4)(2, 3, 0, 1);
+ add2 = (uint4)(0, 1, 0, 1);
+ add3 = (uint4)(0, 1, 2, 3);
+
+ // retrieve input data
+ input1 = (float4)(input.s0, input.s1, input.s2, input.s3);
+ input2 = (float4)(input.s4, input.s5, input.s6, input.s7);
+
+ // Find global address
+ id = local_id * 2;
+
+ //Sort first vector
+
+ comp = abs(input1 > shuffle(input1, mask1));
+ input1 = shuffle(input1, comp ^ swap + add1);
+ comp = abs(input1 > shuffle(input1, mask2));
+ input1 = shuffle(input1, comp * 2 + add2);
+ comp = abs(input1 > shuffle(input1, mask1));
+ input1 = shuffle(input1, comp + add1);
+
+ //Sort second vector
+ comp = abs(input2 < shuffle(input2, mask1));
+ input2 = shuffle(input2, comp ^ swap + add1);
+ comp = abs(input2 < shuffle(input2, mask2));
+ input2 = shuffle(input2, comp * 2 + add2);
+ comp = abs(input2 < shuffle(input2, mask1));
+ input2 = shuffle(input2, comp + add1);
+
+ // Swap elements
+ dir = local_id % 2;
+ temp = input1;
+ comp = (abs(input1 > input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, comp);
+ input2 = shuffle2(input2, temp, comp);
+ VECTOR_SORT_BOOK(input1, dir);
+ VECTOR_SORT_BOOK(input2, dir);
+ l_data[id] = input1;
+ l_data[id+1] = input2;
+
+ // Perform upper stages
+ for(size = 2; size < local_size; size <<= 1) {
+ dir = local_id/size & 1;
+
+ //Perform lower stages
+ for(stride = size; stride > 1; stride >>= 1) {
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = local_id + (local_id/stride)*stride;
+ VECTOR_SWAP_BOOK(l_data[id], l_data[id + stride], dir)
+ }
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ id = local_id * 2;
+ input1 = l_data[id];
+ input2 = l_data[id+1];
+ temp = input1;
+ comp = (abs(input1 > input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, comp);
+ input2 = shuffle2(input2, temp, comp);
+ VECTOR_SORT_BOOK(input1, dir);
+ VECTOR_SORT_BOOK(input2, dir);
+ l_data[id] = input1;
+ l_data[id+1] = input2;
+ }
+ dir = group_id % 2;
+
+ // Perform bitonic merge
+ for(stride = local_size; stride > 1; stride >>= 1) {
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = local_id + (local_id/stride)*stride;
+ VECTOR_SWAP_BOOK(l_data[id], l_data[id + stride], dir)
+ }
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ id = local_id * 2;
+ input1 = l_data[id]; input2 = l_data[id+1];
+ temp = input1;
+ comp = (abs(input1 > input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, comp);
+ input2 = shuffle2(input2, temp, comp);
+ VECTOR_SORT_BOOK(input1, dir);
+ VECTOR_SORT_BOOK(input2, dir);
+
+ // setup output and return it
+ output = (float8)(input1, input2);
+ return output;
+}
+
+
+
+//////////////
+// Kernels
+//////////////
+
+// Perform the sort on the whole array
+// dim0: wg=number_of_element/8
+
+__kernel void bsort_all(__global float4 *g_data,
+ __local float4 *l_data) {
+ float4 input1, input2;
+ float8 input, output;
+ uint id, global_start;
+ // Find global address
+ id = get_local_id(0) * 2;
+ global_start = get_group_id(0) * get_local_size(0) * 2 + id;
+
+ input1 = g_data[global_start];
+ input2 = g_data[global_start+1];
+ input = (float8)(input1, input2);
+ output = my_sort_file(get_local_id(0), get_group_id(0), get_local_size(0),
+ input, l_data);
+ input1 = (float4) (output.s0, output.s1, output.s2, output.s3);
+ input2 = (float4) (output.s4, output.s5, output.s6, output.s7);
+ g_data[global_start] = input1;
+ g_data[global_start+1] = input2;
+}
+
+
+// Perform the sort along the horizontal axis of a 2D image
+// dim0 = y: wg=1
+// dim1 = x: wg=number_of_element/8
+__kernel void bsort_horizontal(__global float *g_data,
+ __local float4 *l_data) {
+ float8 input, output;
+ uint id, global_start, offset;
+
+ // Find global address
+ offset = get_global_size(1)*get_global_id(0)*8;
+ id = get_local_id(1) * 8;
+ global_start = offset + get_group_id(1) * get_local_size(1) * 8 + id;
+
+ input = (float8)(g_data[global_start ],
+ g_data[global_start + 1],
+ g_data[global_start + 2],
+ g_data[global_start + 3],
+ g_data[global_start + 4],
+ g_data[global_start + 5],
+ g_data[global_start + 6],
+ g_data[global_start + 7]);
+
+ output = my_sort_file(get_local_id(1), get_group_id(1), get_local_size(1),
+ input, l_data);
+
+ g_data[global_start ] = output.s0;
+ g_data[global_start + 1] = output.s1;
+ g_data[global_start + 2] = output.s2;
+ g_data[global_start + 3] = output.s3;
+ g_data[global_start + 4] = output.s4;
+ g_data[global_start + 5] = output.s5;
+ g_data[global_start + 6] = output.s6;
+ g_data[global_start + 7] = output.s7;
+}
+
+
+// Perform the sort along the vertical axis
+// dim0 = y: wg=number_of_element/8
+// dim1 = x: wg=1
+// check if transposing +bsort_horizontal is not more efficient ?
+
+__kernel void bsort_vertical(__global float *g_data,
+ __local float4 *l_data) {
+ // we need to read 8 float position along the vertical axis
+ float8 input, output;
+ uint id, global_start, padding;
+
+ // Find global address
+ padding = get_global_size(1);
+ id = get_local_id(0) * 8 * padding + get_global_id(1);
+ global_start = get_group_id(0) * get_local_size(0) * 8 * padding + id;
+
+ input = (float8)(g_data[global_start ],
+ g_data[global_start + padding ],
+ g_data[global_start + 2*padding],
+ g_data[global_start + 3*padding],
+ g_data[global_start + 4*padding],
+ g_data[global_start + 5*padding],
+ g_data[global_start + 6*padding],
+ g_data[global_start + 7*padding]);
+
+ output = my_sort_file(get_local_id(0), get_group_id(0), get_local_size(0),
+ input, l_data);
+ g_data[global_start ] = output.s0;
+ g_data[global_start + padding ] = output.s1;
+ g_data[global_start + 2*padding ] = output.s2;
+ g_data[global_start + 3*padding ] = output.s3;
+ g_data[global_start + 4*padding ] = output.s4;
+ g_data[global_start + 5*padding ] = output.s5;
+ g_data[global_start + 6*padding ] = output.s6;
+ g_data[global_start + 7*padding ] = output.s7;
+}
+
+
+//Tested working reference kernel frm the book. This only works under Linux
+__kernel void bsort_book(__global float4 *g_data,
+ __local float4 *l_data) {
+ float4 input1, input2, temp;
+ uint4 comp, swap, mask1, mask2, add1, add2, add3;
+ uint id, dir, global_start, size, stride;
+ mask1 = (uint4)(1, 0, 3, 2);
+ swap = (uint4)(0, 0, 1, 1);
+ add1 = (uint4)(0, 0, 2, 2);
+ mask2 = (uint4)(2, 3, 0, 1);
+ add2 = (uint4)(0, 1, 0, 1);
+ add3 = (uint4)(0, 1, 2, 3);
+
+ // Find global address
+ id = get_local_id(0) * 2;
+ global_start = get_group_id(0) * get_local_size(0) * 2 + id;
+
+ //Sort first vector
+ input1 = g_data[global_start];
+ input2 = g_data[global_start+1];
+ comp = abs(input1 > shuffle(input1, mask1));
+ input1 = shuffle(input1, comp ^ swap + add1);
+ comp = abs(input1 > shuffle(input1, mask2));
+ input1 = shuffle(input1, comp * 2 + add2);
+ comp = abs(input1 > shuffle(input1, mask1));
+ input1 = shuffle(input1, comp + add1);
+
+ //Sort second vector
+ comp = abs(input2 < shuffle(input2, mask1));
+ input2 = shuffle(input2, comp ^ swap + add1);
+ comp = abs(input2 < shuffle(input2, mask2));
+ input2 = shuffle(input2, comp * 2 + add2);
+ comp = abs(input2 < shuffle(input2, mask1));
+ input2 = shuffle(input2, comp + add1);
+
+ // Swap elements
+ dir = get_local_id(0) % 2;
+ temp = input1;
+ comp = (abs(input1 > input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, comp);
+ input2 = shuffle2(input2, temp, comp);
+ VECTOR_SORT_BOOK(input1, dir);
+ VECTOR_SORT_BOOK(input2, dir);
+ l_data[id] = input1;
+ l_data[id+1] = input2;
+
+ // Perform upper stages
+ for(size = 2; size < get_local_size(0); size <<= 1) {
+ dir = get_local_id(0)/size & 1;
+
+ //Perform lower stages
+ for(stride = size; stride > 1; stride >>= 1) {
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = get_local_id(0) +
+ (get_local_id(0)/stride)*stride;
+ VECTOR_SWAP_BOOK(l_data[id], l_data[id + stride], dir)
+ }
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ id = get_local_id(0) * 2;
+ input1 = l_data[id];
+ input2 = l_data[id+1];
+ temp = input1;
+ comp = (abs(input1 > input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, comp);
+ input2 = shuffle2(input2, temp, comp);
+ VECTOR_SORT_BOOK(input1, dir);
+ VECTOR_SORT_BOOK(input2, dir);
+ l_data[id] = input1;
+ l_data[id+1] = input2;
+ }
+ dir = get_group_id(0) % 2;
+ // Perform bitonic merge
+ for(stride = get_local_size(0); stride > 1; stride >>= 1) {
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = get_local_id(0) +
+ (get_local_id(0)/stride)*stride;
+ VECTOR_SWAP_BOOK(l_data[id], l_data[id + stride], dir)
+ }
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ id = get_local_id(0) * 2;
+ input1 = l_data[id]; input2 = l_data[id+1];
+ temp = input1;
+ comp = (abs(input1 > input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, comp);
+ input2 = shuffle2(input2, temp, comp);
+ VECTOR_SORT_BOOK(input1, dir);
+ VECTOR_SORT_BOOK(input2, dir);
+ g_data[global_start] = input1;
+ g_data[global_start+1] = input2;
+ }
+
+//Tested working reference kernel from the addition files. This only works under any operating system
+/* Perform initial sort */
+__kernel void bsort_file(__global float4 *g_data, __local float4 *l_data) {
+
+ int dir;
+ uint id, global_start, size, stride;
+ float4 input1, input2, temp;
+ int4 comp;
+
+ uint4 mask1 = (uint4)(1, 0, 3, 2);
+ uint4 mask2 = (uint4)(2, 3, 0, 1);
+ uint4 mask3 = (uint4)(3, 2, 1, 0);
+
+ int4 add1 = (int4)(1, 1, 3, 3);
+ int4 add2 = (int4)(2, 3, 2, 3);
+ int4 add3 = (int4)(1, 2, 2, 3);
+
+ id = get_local_id(0) * 2;
+ global_start = get_group_id(0) * get_local_size(0) * 2 + id;
+
+ input1 = g_data[global_start];
+ input2 = g_data[global_start+1];
+
+ /* Sort input 1 - ascending */
+ comp = input1 < shuffle(input1, mask1);
+ input1 = shuffle(input1, as_uint4(comp + add1));
+ comp = input1 < shuffle(input1, mask2);
+ input1 = shuffle(input1, as_uint4(comp * 2 + add2));
+ comp = input1 < shuffle(input1, mask3);
+ input1 = shuffle(input1, as_uint4(comp + add3));
+
+ /* Sort input 2 - descending */
+ comp = input2 > shuffle(input2, mask1);
+ input2 = shuffle(input2, as_uint4(comp + add1));
+ comp = input2 > shuffle(input2, mask2);
+ input2 = shuffle(input2, as_uint4(comp * 2 + add2));
+ comp = input2 > shuffle(input2, mask3);
+ input2 = shuffle(input2, as_uint4(comp + add3));
+
+ /* Swap corresponding elements of input 1 and 2 */
+ add3 = (int4)(4, 5, 6, 7);
+ dir = - (int)(get_local_id(0) % 2);
+ temp = input1;
+ comp = ((input1 < input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, as_uint4(comp));
+ input2 = shuffle2(input2, temp, as_uint4(comp));
+
+ /* Sort data and store in local memory */
+ VECTOR_SORT_FILE(input1, dir);
+ VECTOR_SORT_FILE(input2, dir);
+ l_data[id] = input1;
+ l_data[id+1] = input2;
+
+ /* Create bitonic set */
+ for(size = 2; size < get_local_size(0); size <<= 1) {
+ dir = - (int)(get_local_id(0)/size & 1);
+
+ for(stride = size; stride > 1; stride >>= 1) {
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = get_local_id(0) + (get_local_id(0)/stride)*stride;
+ VECTOR_SWAP_FILE(l_data[id], l_data[id + stride], dir)
+ }
+
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = get_local_id(0) * 2;
+ input1 = l_data[id]; input2 = l_data[id+1];
+ temp = input1;
+ comp = ((input1 < input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, as_uint4(comp));
+ input2 = shuffle2(input2, temp, as_uint4(comp));
+ VECTOR_SORT_FILE(input1, dir);
+ VECTOR_SORT_FILE(input2, dir);
+ l_data[id] = input1;
+ l_data[id+1] = input2;
+ }
+
+ /* Perform bitonic merge */
+ dir = - (int)(get_group_id(0) % 2);
+ for(stride = get_local_size(0); stride > 1; stride >>= 1) {
+ barrier(CLK_LOCAL_MEM_FENCE);
+ id = get_local_id(0) + (get_local_id(0)/stride)*stride;
+ VECTOR_SWAP_FILE(l_data[id], l_data[id + stride], dir)
+ }
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ /* Perform final sort */
+ id = get_local_id(0) * 2;
+ input1 = l_data[id]; input2 = l_data[id+1];
+ temp = input1;
+ comp = ((input1 < input2) ^ dir) * 4 + add3;
+ input1 = shuffle2(input1, input2, as_uint4(comp));
+ input2 = shuffle2(input2, temp, as_uint4(comp));
+ VECTOR_SORT_FILE(input1, dir);
+ VECTOR_SORT_FILE(input2, dir);
+ g_data[global_start] = input1;
+ g_data[global_start+1] = input2;
+}
+
diff --git a/silx/resources/opencl/medfilt.cl b/silx/resources/opencl/medfilt.cl
new file mode 100644
index 0000000..f1e342b
--- /dev/null
+++ b/silx/resources/opencl/medfilt.cl
@@ -0,0 +1,141 @@
+/*
+ * Project: Azimuthal regroupping OpenCL kernel for PyFAI.
+ * Median filter for 1D, 2D and 3D datasets, only 2D for now
+ *
+ *
+ * Copyright (C) 2017-2017 European Synchrotron Radiation Facility
+ * Grenoble, France
+ *
+ * Principal authors: J. Kieffer (kieffer@esrf.fr)
+ * Last revision: 07/02/2017
+ *
+ * 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.
+ *
+ */
+
+/*
+ * Needs to be concatenated with bitonic.cl prior to compilation
+*/
+
+/*
+ * Perform the 2D median filtering of an image 2D image
+ *
+ * dim0 => wg=number_of_element in the tile /8
+ * dim1 = x: wg=1
+
+ *
+ * Actually the workgoup size is a bit more complicated:
+ * if window size = 1,3,5,7: WG1=8
+ * if window size = 9,11,13,15: WG1=32
+ * if window size = 17, ...,21: WG1=64
+ *
+ * More Generally the workgroup size must be: at least: kfs2*(kfs1+7)/8
+ * Each thread treats 8 values aligned vertically, this allows (almost)
+ * coalesced reading between threads in one line of the tile.
+ *
+ * Later on it will be more efficient to re-use the same tile
+ * and slide it vertically by one line.
+ * The additionnal need for shared memory will be kfs2 floats and a float8 as register.
+ *
+ * Theoritically, it should be possible to handle up to windows-size 83x83
+ */
+__kernel void medfilt2d(__global float *image, // input image
+ __global float *result, // output array
+ __local float4 *l_data,// local storage 4x the number of threads
+ int khs1, // Kernel half-size along dim1 (nb lines)
+ int khs2, // Kernel half-size along dim2 (nb columns)
+ int height, // Image size along dim1 (nb lines)
+ int width) // Image size along dim2 (nb columns)
+{
+ int threadid = get_local_id(0);
+ int wg = get_local_size(0);
+ int x = get_global_id(1);
+
+ if (x < width)
+ {
+ union
+ {
+ float ary[8];
+ float8 vec;
+ } output, input;
+ input.vec = (float8)(MAXFLOAT, MAXFLOAT, MAXFLOAT, MAXFLOAT, MAXFLOAT, MAXFLOAT, MAXFLOAT, MAXFLOAT);
+ int kfs1 = 2 * khs1 + 1; //definition of kernel full size
+ int kfs2 = 2 * khs2 + 1;
+ int nbands = (kfs1 + 7) / 8; // 8 elements per thread, aligned vertically in 1 column
+ for (int y=0; y<height; y++)
+ {
+ //Select only the active threads, some may remain inactive
+ int nb_threads = (nbands * kfs2);
+ int band_nr = threadid / kfs2;
+ int band_id = threadid % kfs2;
+ int pos_x = clamp((int)(x + band_id - khs2), (int) 0, (int) width-1);
+ int max_vec = clamp(kfs1 - 8 * band_nr, 0, 8);
+ if (y == 0)
+ {
+ for (int i=0; i<max_vec; i++)
+ {
+ if (threadid<nb_threads)
+ {
+ int pos_y = clamp((int)(y + 8 * band_nr + i - khs1), (int) 0, (int) height-1);
+ input.ary[i] = image[pos_x + width * pos_y];
+ }
+ }
+ }
+ else
+ {
+ //store storage.s0 to some shared memory to retrieve it from another thread.
+ l_data[threadid].s0 = input.vec.s0;
+
+ //Offset to the bottom
+ input.vec = (float8)(input.vec.s1,
+ input.vec.s2,
+ input.vec.s3,
+ input.vec.s4,
+ input.vec.s5,
+ input.vec.s6,
+ input.vec.s7,
+ MAXFLOAT);
+
+ barrier(CLK_LOCAL_MEM_FENCE);
+
+ int read_from = threadid + kfs2;
+ if (read_from < nb_threads)
+ input.vec.s7 = l_data[read_from].s0;
+ else if (threadid < nb_threads) //we are on the last band
+ {
+ int pos_y = clamp((int)(y + 8 * band_nr + max_vec - 1 - khs1), (int) 0, (int) height-1);
+ input.ary[max_vec - 1] = image[pos_x + width * pos_y];
+ }
+
+ }
+
+ //This function is defined in bitonic.cl
+ output.vec = my_sort_file(get_local_id(0), get_group_id(0), get_local_size(0),
+ input.vec, l_data);
+
+ size_t target = (kfs1 * kfs2) / 2;
+ if (threadid == (target / 8))
+ {
+ result[y * width + x] = output.ary[target % 8];
+ }
+
+ }
+ }
+}
+
diff --git a/silx/resources/opencl/preprocess.cl b/silx/resources/opencl/preprocess.cl
new file mode 100644
index 0000000..de35c48
--- /dev/null
+++ b/silx/resources/opencl/preprocess.cl
@@ -0,0 +1,567 @@
+/*
+ * Project: Azimuthal regroupping OpenCL kernel for PyFAI.
+ * Preprocessing program
+ *
+ *
+ * Copyright (C) 2012-2017 European Synchrotron Radiation Facility
+ * Grenoble, France
+ *
+ * Principal authors: J. Kieffer (kieffer@esrf.fr)
+ * Last revision: 19/01/2017
+ *
+ * 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.
+ */
+
+/**
+ * \file
+ *
+ * \brief OpenCL kernels for image array casting, array mem-setting and normalizing
+ *
+ * Constant to be provided at build time:
+ * NIMAGE: size of the image
+ *
+ */
+
+#include "for_eclipse.h"
+
+/**
+ * \brief cast values of an array of int8 into a float output array.
+ *
+ * - array_s8: Pointer to global memory with the input data as signed8 array
+ * - array_float: Pointer to global memory with the output data as float array
+ */
+__kernel void
+s8_to_float(__global char *array_s8,
+ __global float *array_float
+)
+{
+ int i = get_global_id(0);
+ //Global memory guard for padding
+ if (i < NIMAGE)
+ array_float[i] = (float)array_s8[i];
+}
+
+
+/**
+ * \brief cast values of an array of uint8 into a float output array.
+ *
+ * - array_u8: Pointer to global memory with the input data as unsigned8 array
+ * - array_float: Pointer to global memory with the output data as float array
+ */
+__kernel void
+u8_to_float(__global unsigned char *array_u8,
+ __global float *array_float
+)
+{
+ int i = get_global_id(0);
+ //Global memory guard for padding
+ if (i < NIMAGE)
+ array_float[i] = (float)array_u8[i];
+}
+
+
+/**
+ * \brief cast values of an array of int16 into a float output array.
+ *
+ * - array_s16: Pointer to global memory with the input data as signed16 array
+ * - array_float: Pointer to global memory with the output data as float array
+ */
+__kernel void
+s16_to_float(__global short *array_s16,
+ __global float *array_float
+)
+{
+ int i = get_global_id(0);
+ //Global memory guard for padding
+ if (i < NIMAGE)
+ array_float[i] = (float)array_s16[i];
+}
+
+
+/**
+ * \brief cast values of an array of uint16 into a float output array.
+ *
+ * - array_u16: Pointer to global memory with the input data as unsigned16 array
+ * - array_float: Pointer to global memory with the output data as float array
+ */
+__kernel void
+u16_to_float(__global unsigned short *array_u16,
+ __global float *array_float
+)
+{
+ int i = get_global_id(0);
+ //Global memory guard for padding
+ if (i < NIMAGE)
+ array_float[i] = (float)array_u16[i];
+}
+
+/**
+ * \brief cast values of an array of uint32 into a float output array.
+ *
+ * - array_u32: Pointer to global memory with the input data as unsigned32 array
+ * - array_float: Pointer to global memory with the output data as float array
+ */
+__kernel void
+u32_to_float(__global unsigned int *array_u32,
+ __global float *array_float
+)
+{
+ int i = get_global_id(0);
+ //Global memory guard for padding
+ if (i < NIMAGE)
+ array_float[i] = (float)array_u32[i];
+}
+
+/**
+ * \brief convert values of an array of int32 into a float output array.
+ *
+ * - array_int: Pointer to global memory with the data as unsigned32 array
+ * - array_float: Pointer to global memory with the data float array
+ */
+__kernel void
+s32_to_float(__global int *array_int,
+ __global float *array_float
+)
+{
+ int i = get_global_id(0);
+ //Global memory guard for padding
+ if (i < NIMAGE)
+ array_float[i] = (float)(array_int[i]);
+}
+
+
+/**
+ * Functions to be called from an actual kernel.
+ * \brief Performs the normalization of input image by dark subtraction,
+ * variance is propagated to second member of the float3
+ * flatfield, solid angle, polarization and absorption are stored in
+ * third member of the float3 returned.
+ *
+ * Invalid/Dummy pixels will all have the third-member set to 0, i.e. no weight
+ *
+ * - image Float pointer to global memory storing the input image.
+ * - do_dark Bool/int: shall dark-current correction be applied ?
+ * - dark Float pointer to global memory storing the dark image.
+ * - do_flat Bool/int: shall flat-field correction be applied ?
+ * - flat Float pointer to global memory storing the flat image.
+ * - do_solidangle Bool/int: shall flat-field correction be applied ?
+ * - solidangle Float pointer to global memory storing the solid angle of each pixel.
+ * - do_polarization Bool/int: shall polarization correction be applied ?
+ * - polarization Float pointer to global memory storing the polarization of each pixel.
+ * - do_absorption Bool/int: shall absorption correction be applied ?
+ * - absorption Float pointer to global memory storing the effective absoption of each pixel.
+ * - do_mask perform mask correction ?
+ * - mask Bool/char pointer to mask array
+ * - do_dummy Bool/int: shall the dummy pixel be checked. Dummy pixel are pixels marked as bad and ignored
+ * - dummy Float: value for bad pixels
+ * - delta_dummy Float: precision for bad pixel value
+ * - normalization_factor : divide the input by this value
+ *
+**/
+
+static float3 _preproc3(const __global float *image,
+ const __global float *variance,
+ const char do_dark,
+ const __global float *dark,
+ const char do_dark_variance,
+ const __global float *dark_variance,
+ const char do_flat,
+ const __global float *flat,
+ const char do_solidangle,
+ const __global float *solidangle,
+ const char do_polarization,
+ const __global float *polarization,
+ const char do_absorption,
+ const __global float *absorption,
+ const char do_mask,
+ const __global char *mask,
+ const char do_dummy,
+ const float dummy,
+ const float delta_dummy,
+ const float normalization_factor)
+{
+ size_t i= get_global_id(0);
+ float3 result = (float3)(0.0, 0.0, 0.0);
+ if (i < NIMAGE)
+ {
+ if ((!do_mask) || (!mask[i]))
+ {
+ result.s0 = image[i];
+ if (variance != 0)
+ result.s1 = variance[i];
+ result.s2 = normalization_factor;
+ if ( (!do_dummy)
+ ||((delta_dummy != 0.0f) && (fabs(result.s0-dummy) > delta_dummy))
+ ||((delta_dummy == 0.0f) && (result.s0 != dummy)))
+ {
+ if (do_dark)
+ result.s0 -= dark[i];
+ if (do_dark_variance)
+ result.s1 += dark_variance[i];
+ if (do_flat)
+ {
+ float one_flat = flat[i];
+ if ( (!do_dummy)
+ ||((delta_dummy != 0.0f) && (fabs(one_flat-dummy) > delta_dummy))
+ ||((delta_dummy == 0.0f) && (one_flat != dummy)))
+ result.s2 *= one_flat;
+ else
+ result.s2 = 0.0f;
+ }
+ if (do_solidangle)
+ result.s2 *= solidangle[i];
+ if (do_polarization)
+ result.s2 *= polarization[i];
+ if (do_absorption)
+ result.s2 *= absorption[i];
+ if (isnan(result.s0) || isnan(result.s1) || isnan(result.s2) || (result.s2 == 0.0f))
+ result = (float3)(0.0, 0.0, 0.0);
+ }
+ else
+ {
+ result = (float3)(0.0, 0.0, 0.0);
+ }//end if do_dummy
+ } // end if mask
+ };//end if NIMAGE
+ return result;
+};//end function
+
+
+/**
+ * \brief Performs the normalization of input image by dark subtraction,
+ * flatfield, solid angle, polarization and absorption division.
+ *
+ * Intensities of images are corrected by:
+ * - dark (read-out) noise subtraction
+ * - Solid angle correction (division)
+ * - polarization correction (division)
+ * - flat fiels correction (division)
+ * Corrections are made in place unless the pixel is dummy.
+ * Dummy pixels are left untouched so that they remain dummy
+ *
+ * - image Float pointer to global memory storing the input image.
+ * - do_dark Bool/int: shall dark-current correction be applied ?
+ * - dark Float pointer to global memory storing the dark image.
+ * - do_flat Bool/int: shall flat-field correction be applied ?
+ * - flat Float pointer to global memory storing the flat image.
+ * - do_solidangle Bool/int: shall flat-field correction be applied ?
+ * - solidangle Float pointer to global memory storing the solid angle of each pixel.
+ * - do_polarization Bool/int: shall polarization correction be applied ?
+ * - polarization Float pointer to global memory storing the polarization of each pixel.
+ * - do_absorption Bool/int: shall absorption correction be applied ?
+ * - absorption Float pointer to global memory storing the effective absoption of each pixel.
+ * - do_mask perform mask correction ?
+ * - mask Bool/char pointer to mask array
+ * - do_dummy Bool/int: shall the dummy pixel be checked. Dummy pixel are pixels marked as bad and ignored
+ * - dummy Float: value for bad pixels
+ * - delta_dummy Float: precision for bad pixel value
+ * - normalization_factor : divide the input by this value
+ *
+**/
+
+__kernel void
+corrections(const __global float *image,
+ const char do_dark,
+ const __global float *dark,
+ const char do_flat,
+ const __global float *flat,
+ const char do_solidangle,
+ const __global float *solidangle,
+ const char do_polarization,
+ const __global float *polarization,
+ const char do_absorption,
+ const __global float *absorption,
+ const char do_mask,
+ const __global char *mask,
+ const char do_dummy,
+ const float dummy,
+ const float delta_dummy,
+ const float normalization_factor,
+ __global float *output
+ )
+{
+ size_t i= get_global_id(0);
+ float3 result = (float3)(0.0, 0.0, 0.0);
+ if (i < NIMAGE)
+ {
+ result = _preproc3(image,
+ 0,
+ do_dark,
+ dark,
+ 0,
+ 0,
+ do_flat,
+ flat,
+ do_solidangle,
+ solidangle,
+ do_polarization,
+ polarization,
+ do_absorption,
+ absorption,
+ do_mask,
+ mask,
+ do_dummy,
+ dummy,
+ delta_dummy,
+ normalization_factor);
+ if (result.s2 != 0.0f)
+ output[i] = result.s0 / result.s2;
+ else
+ output[i] = dummy;
+ };//end if NIMAGE
+
+};//end kernel
+
+
+/**
+ * \brief Performs Normalization of input image with float2 output (num,denom)
+ *
+ * Intensities of images are corrected by:
+ * - dark (read-out) noise subtraction for the data
+ * - Solid angle correction (denominator)
+ * - polarization correction (denominator)
+ * - flat fiels correction (denominator)
+ *
+ * Corrections are made out of place.
+ * Dummy pixels set both the numerator and denominator to 0
+ *
+ * - image Float pointer to global memory storing the input image.
+ * - do_dark Bool/int: shall dark-current correction be applied ?
+ * - dark Float pointer to global memory storing the dark image.
+ * - do_flat Bool/int: shall flat-field correction be applied ?
+ * - flat Float pointer to global memory storing the flat image.
+ * - do_solidangle Bool/int: shall flat-field correction be applied ?
+ * - solidangle Float pointer to global memory storing the solid angle of each pixel.
+ * - do_polarization Bool/int: shall flat-field correction be applied ?
+ * - polarization Float pointer to global memory storing the polarization of each pixel.
+ * - do_dummy Bool/int: shall the dummy pixel be checked. Dummy pixel are pixels marked as bad and ignored
+ * - dummy Float: value for bad pixels
+ * - delta_dummy Float: precision for bad pixel value
+ * - normalization_factor : divide the input by this value
+ *
+ *
+**/
+__kernel void
+corrections2(const __global float *image,
+ const char do_dark,
+ const __global float *dark,
+ const char do_flat,
+ const __global float *flat,
+ const char do_solidangle,
+ const __global float *solidangle,
+ const char do_polarization,
+ const __global float *polarization,
+ const char do_absorption,
+ const __global float *absorption,
+ const char do_mask,
+ const __global char *mask,
+ const char do_dummy,
+ const float dummy,
+ const float delta_dummy,
+ const float normalization_factor,
+ __global float2 *output
+ )
+{
+ size_t i= get_global_id(0);
+ float3 result = (float3)(0.0, 0.0, 0.0);
+ if (i < NIMAGE)
+ {
+ result = _preproc3(image,
+ 0,
+ do_dark,
+ dark,
+ 0,
+ 0,
+ do_flat,
+ flat,
+ do_solidangle,
+ solidangle,
+ do_polarization,
+ polarization,
+ do_absorption,
+ absorption,
+ do_mask,
+ mask,
+ do_dummy,
+ dummy,
+ delta_dummy,
+ normalization_factor);
+ output[i] = (float2)(result.s0, result.s2);
+ };//end if NIMAGE
+};//end kernel
+
+/**
+ * \brief Performs Normalization of input image with float3 output (signal, variance, normalization) assuming poissonian signal
+ *
+ * Intensities of images are corrected by:
+ * - dark (read-out) noise subtraction for the data
+ * - Solid angle correction (denominator)
+ * - polarization correction (denominator)
+ * - flat fiels correction (denominator)
+ *
+ * Corrections are made out of place.
+ * Dummy pixels set both the numerator and denominator to 0
+ *
+ * - image Float pointer to global memory storing the input image.
+ * - do_dark Bool/int: shall dark-current correction be applied ?
+ * - dark Float pointer to global memory storing the dark image.
+ * - do_flat Bool/int: shall flat-field correction be applied ?
+ * - flat Float pointer to global memory storing the flat image.
+ * - do_solidangle Bool/int: shall flat-field correction be applied ?
+ * - solidangle Float pointer to global memory storing the solid angle of each pixel.
+ * - do_polarization Bool/int: shall flat-field correction be applied ?
+ * - polarization Float pointer to global memory storing the polarization of each pixel.
+ * - do_dummy Bool/int: shall the dummy pixel be checked. Dummy pixel are pixels marked as bad and ignored
+ * - dummy Float: value for bad pixels
+ * - delta_dummy Float: precision for bad pixel value
+ * - normalization_factor : divide the input by this value
+ *
+ *
+**/
+__kernel void
+corrections3Poisson( const __global float *image,
+ const char do_dark,
+ const __global float *dark,
+ const char do_flat,
+ const __global float *flat,
+ const char do_solidangle,
+ const __global float *solidangle,
+ const char do_polarization,
+ const __global float *polarization,
+ const char do_absorption,
+ const __global float *absorption,
+ const char do_mask,
+ const __global char *mask,
+ const char do_dummy,
+ const float dummy,
+ const float delta_dummy,
+ const float normalization_factor,
+ __global float3 *output
+ )
+{
+ size_t i= get_global_id(0);
+ float3 result = (float3)(0.0, 0.0, 0.0);
+ if (i < NIMAGE)
+ {
+ result = _preproc3(image,
+ image,
+ do_dark,
+ dark,
+ do_dark,
+ dark,
+ do_flat,
+ flat,
+ do_solidangle,
+ solidangle,
+ do_polarization,
+ polarization,
+ do_absorption,
+ absorption,
+ do_mask,
+ mask,
+ do_dummy,
+ dummy,
+ delta_dummy,
+ normalization_factor);
+ output[i] = result;
+ };//end if NIMAGE
+};//end kernel
+
+
+/**
+ * \brief Performs Normalization of input image with float3 output (signal, variance, normalization)
+ *
+ * Intensities of images are corrected by:
+ * - dark (read-out) noise subtraction for the data
+ * - Solid angle correction (division)
+ * - polarization correction (division)
+ * - flat fiels correction (division)
+ * Corrections are made in place unless the pixel is dummy.
+ * Dummy pixels are left untouched so that they remain dummy
+ *
+ * - image Float pointer to global memory storing the input image.
+ * - do_dark Bool/int: shall dark-current correction be applied ?
+ * - dark Float pointer to global memory storing the dark image.
+ * - do_flat Bool/int: shall flat-field correction be applied ?
+ * - flat Float pointer to global memory storing the flat image.
+ * - do_solidangle Bool/int: shall flat-field correction be applied ?
+ * - solidangle Float pointer to global memory storing the solid angle of each pixel.
+ * - do_polarization Bool/int: shall flat-field correction be applied ?
+ * - polarization Float pointer to global memory storing the polarization of each pixel.
+ * - do_dummy Bool/int: shall the dummy pixel be checked. Dummy pixel are pixels marked as bad and ignored
+ * - dummy Float: value for bad pixels
+ * - delta_dummy Float: precision for bad pixel value
+ * - normalization_factor : divide the input by this value
+ *
+ *
+**/
+
+__kernel void
+corrections3(const __global float *image,
+ const __global float *variance,
+ const char do_dark,
+ const __global float *dark,
+ const char do_dark_variance,
+ const __global float *dark_variance,
+ const char do_flat,
+ const __global float *flat,
+ const char do_solidangle,
+ const __global float *solidangle,
+ const char do_polarization,
+ const __global float *polarization,
+ const char do_absorption,
+ const __global float *absorption,
+ const char do_mask,
+ const __global char *mask,
+ const char do_dummy,
+ const float dummy,
+ const float delta_dummy,
+ const float normalization_factor,
+ __global float3 *output
+ )
+{
+ size_t i= get_global_id(0);
+ float3 result = (float3)(0.0, 0.0, 0.0);
+ if (i < NIMAGE)
+ {
+ result = _preproc3( image,
+ variance,
+ do_dark,
+ dark,
+ do_dark_variance,
+ dark_variance,
+ do_flat,
+ flat,
+ do_solidangle,
+ solidangle,
+ do_polarization,
+ polarization,
+ do_absorption,
+ absorption,
+ do_mask,
+ mask,
+ do_dummy,
+ dummy,
+ delta_dummy,
+ normalization_factor);
+ output[i] = result;
+ };//end if NIMAGE
+};//end kernel
+
+
diff --git a/silx/setup.py b/silx/setup.py
new file mode 100644
index 0000000..4c0a883
--- /dev/null
+++ b/silx/setup.py
@@ -0,0 +1,53 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "30/03/2017"
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('silx', parent_package, top_path)
+ config.add_subpackage('gui')
+ config.add_subpackage('io')
+ config.add_subpackage('math')
+ config.add_subpackage('image')
+ config.add_subpackage('opencl')
+ config.add_subpackage('resources')
+ config.add_subpackage('sx')
+ config.add_subpackage('test')
+ config.add_subpackage('third_party')
+ config.add_subpackage('utils')
+ config.add_subpackage('app')
+
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/sx/__init__.py b/silx/sx/__init__.py
new file mode 100644
index 0000000..55fa40e
--- /dev/null
+++ b/silx/sx/__init__.py
@@ -0,0 +1,99 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Convenient module to use main features of silx from the console.
+
+Usage from (I)Python console or notebook:
+
+>>> from silx import sx
+
+With IPython/jupyter, this also runs %pylab.
+From the console, it sets-up Qt in order to allow using GUI widgets.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "16/01/2017"
+
+
+import logging
+import sys as _sys
+
+
+_logger = logging.getLogger(__name__)
+
+
+# Probe ipython
+try:
+ from IPython import get_ipython as _get_ipython
+except (NameError, ImportError):
+ _get_ipython = None
+
+# Probe ipython/jupyter notebook
+if _get_ipython is not None and _get_ipython() is not None:
+
+ # Notebook detection probably fragile
+ _IS_NOTEBOOK = ('parent_appname' in _get_ipython().config['IPKernelApp'] or
+ hasattr(_get_ipython(), 'kernel'))
+else:
+ _IS_NOTEBOOK = False
+
+
+# Load Qt and widgets only if running from console
+if _IS_NOTEBOOK:
+ _logger.warning(
+ 'Not loading silx.gui features: Running from the notebook')
+
+else:
+ from silx.gui import qt
+
+ if hasattr(_sys, 'ps1'): # If from console, make sure QApplication runs
+ qapp = qt.QApplication.instance() or qt.QApplication([])
+
+ # Change windows default icon
+ from silx.gui import icons as _icons
+ qapp.setWindowIcon(_icons.getQIcon('silx'))
+ del _icons # clean-up namespace
+
+ from silx.gui.plot import * # noqa
+ from ._plot import plot, imshow # noqa
+
+
+# %pylab
+if _get_ipython is not None and _get_ipython() is not None:
+ _get_ipython().enable_pylab(gui='inline' if _IS_NOTEBOOK else 'qt')
+
+
+# Clean-up
+del _sys
+del _get_ipython
+del _IS_NOTEBOOK
+
+
+# Load some silx stuff in namespace
+from silx import * # noqa
+from silx.io import open # noqa
+from silx.io import * # noqa
+from silx.math import Histogramnd, HistogramndLut # noqa
+from silx.math.fit import leastsq # noqa
diff --git a/silx/sx/_plot.py b/silx/sx/_plot.py
new file mode 100644
index 0000000..e672b1a
--- /dev/null
+++ b/silx/sx/_plot.py
@@ -0,0 +1,274 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""This module adds convenient functions to use plot widgets from the console.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+
+import logging
+import numpy
+
+from ..gui.plot import Plot1D, Plot2D
+from ..gui.plot.Colors import COLORDICT
+from silx.third_party import six
+
+
+_logger = logging.getLogger(__name__)
+
+
+def plot(*args, **kwargs):
+ """
+ Plot curves in a dedicated widget.
+
+ This function supports a subset of matplotlib.pyplot.plot arguments.
+ See: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot
+
+ It opens a silx PlotWindow with its associated tools.
+
+ Examples:
+
+ 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.')
+
+ Supported symbols:
+
+ - 'o' circle
+ - '.' point
+ - ',' pixel
+ - '+' cross
+ - 'x' x-cross
+ - 'd' diamond
+ - 's' square
+
+ Supported types of line:
+
+ - ' ' no line
+ - '-' solid line
+ - '--' dashed line
+ - '-.' dash-dot line
+ - ':' dotted line
+
+ Remark: The first curve will always be displayed in black no matter the
+ given color. This is because it is selected by default and this is shown
+ by using the black color.
+
+ If provided, the names arguments color, linestyle, linewidth and marker
+ override any style provided to a curve.
+
+ :param str color: Color to use for all curves (default: None)
+ :param str linestyle: Type of line to use for all curves (default: None)
+ :param float linewidth: With of all the curves (default: 1)
+ :param str marker: Symbol to use for all the curves (default: None)
+ :param str title: The title of the Plot widget (default: None)
+ :param str xlabel: The label of the X axis (default: None)
+ :param str ylabel: The label of the Y axis (default: None)
+ """
+ plt = Plot1D()
+ if 'title' in kwargs:
+ plt.setGraphTitle(kwargs['title'])
+ if 'xlabel' in kwargs:
+ plt.setGraphXLabel(kwargs['xlabel'])
+ if 'ylabel' in kwargs:
+ plt.setGraphYLabel(kwargs['ylabel'])
+
+ color = kwargs.get('color')
+ linestyle = kwargs.get('linestyle')
+ linewidth = kwargs.get('linewidth')
+ marker = kwargs.get('marker')
+
+ # Parse args and store curves as (x, y, style string)
+ args = list(args)
+ curves = []
+ while args:
+ first_arg = args.pop(0) # Process an arg
+
+ if len(args) == 0:
+ # Last curve defined as (y,)
+ curves.append((numpy.arange(len(first_arg)), first_arg, None))
+ else:
+ second_arg = args.pop(0)
+ if isinstance(second_arg, six.string_types):
+ # curve defined as (y, style)
+ y = first_arg
+ style = second_arg
+ curves.append((numpy.arange(len(y)), y, style))
+ else: # second_arg must be an array-like
+ x = first_arg
+ y = second_arg
+ if len(args) >= 1 and isinstance(args[0], six.string_types):
+ # Curve defined as (x, y, style)
+ style = args.pop(0)
+ curves.append((x, y, style))
+ else:
+ # Curve defined as (x, y)
+ curves.append((x, y, None))
+
+ for index, curve in enumerate(curves):
+ x, y, style = curve
+
+ # Default style
+ curve_symbol, curve_linestyle, curve_color = None, None, None
+
+ # Parse style
+ if style:
+ # Handle color first
+ possible_colors = [c for c in COLORDICT if style.startswith(c)]
+ if possible_colors: # Take the longest string matching a color name
+ curve_color = possible_colors[0]
+ for c in possible_colors[1:]:
+ if len(c) > len(curve_color):
+ curve_color = c
+ style = style[len(curve_color):]
+
+ if style:
+ # Run twice to handle inversion symbol/linestyle
+ for _i in range(2):
+ # Handle linestyle
+ for line in (' ', '--', '-', '-.', ':'):
+ if style.endswith(line):
+ curve_linestyle = line
+ style = style[:-len(line)]
+ break
+
+ # Handle symbol
+ for curve_marker in ('o', '.', ',', '+', 'x', 'd', 's'):
+ if style.endswith(curve_marker):
+ curve_symbol = style[-1]
+ style = style[:-1]
+ break
+
+ # As in matplotlib, marker, linestyle and color override other style
+ plt.addCurve(x, y,
+ legend=('curve_%d' % index),
+ symbol=marker or curve_symbol,
+ linestyle=linestyle or curve_linestyle,
+ linewidth=linewidth,
+ color=color or curve_color)
+
+ plt.show()
+ return plt
+
+
+def imshow(data=None, cmap=None, norm='linear',
+ vmin=None, vmax=None,
+ aspect=False,
+ origin=(0., 0.), scale=(1., 1.),
+ title='', xlabel='X', ylabel='Y'):
+ """Plot an image in a dedicated widget.
+
+ This function supports a subset of matplotlib.pyplot.imshow arguments.
+ See: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.imshow
+
+ It opens a silx PlotWindow with its associated tools.
+
+ Example to plot an image:
+
+ >>> from silx import sx
+ >>> import numpy
+
+ >>> data = numpy.random.random(1024 * 1024).reshape(1024, 1024)
+ >>> plt = sx.imshow(data, title='Random data')
+
+ :param data: data to plot as an image
+ :type data: numpy.ndarray-like with 2 dimensions
+ :param str cmap: The name of the colormap to use for the plot.
+ :param str norm: The normalization of the colormap:
+ 'linear' (default) or 'log'
+ :param float vmin: The value to use for the min of the colormap
+ :param float vmax: The value to use for the max of the colormap
+ :param bool aspect: True to keep aspect ratio (Default: False)
+ :param origin: (ox, oy) The coordinates of the image origin in the plot
+ :type origin: 2-tuple of floats
+ :param scale: (sx, sy) The scale of the image in the plot
+ (i.e., the size of the image's pixel in plot coordinates)
+ :type scale: 2-tuple of floats
+ :param str title: The title of the Plot widget
+ :param str xlabel: The label of the X axis
+ :param str ylabel: The label of the Y axis
+ """
+ plt = Plot2D()
+ plt.setGraphTitle(title)
+ plt.setGraphXLabel(xlabel)
+ plt.setGraphYLabel(ylabel)
+
+ # Update default colormap with input parameters
+ colormap = plt.getDefaultColormap()
+ if cmap is not None:
+ colormap['name'] = cmap
+ assert norm in ('linear', 'log')
+ colormap['normalization'] = norm
+ if vmin is not None:
+ colormap['vmin'] = vmin
+ if vmax is not None:
+ colormap['vmax'] = vmax
+ if vmin is not None and vmax is not None:
+ colormap['autoscale'] = False
+ plt.setDefaultColormap(colormap)
+
+ # Handle aspect
+ if aspect in (None, False, 'auto', 'normal'):
+ plt.setKeepDataAspectRatio(False)
+ elif aspect in (True, 'equal') or aspect == 1:
+ plt.setKeepDataAspectRatio(True)
+ else:
+ _logger.warning(
+ 'imshow: Unhandled aspect argument: %s', str(aspect))
+
+ if data is not None:
+ data = numpy.array(data, copy=True)
+
+ assert data.ndim in (2, 3) # data or RGB(A)
+ if data.ndim == 3:
+ assert data.shape[-1] in (3, 4) # RGB(A) image
+
+ plt.addImage(data, origin=origin, scale=scale)
+
+ plt.show()
+ return plt
diff --git a/silx/test/__init__.py b/silx/test/__init__.py
new file mode 100644
index 0000000..01ee8d1
--- /dev/null
+++ b/silx/test/__init__.py
@@ -0,0 +1,80 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-2017 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.
+#
+# ###########################################################################*/
+"""Full silx test suite.
+
+
+It is possible to disable tests depending on Qt by setting
+:envvar:`WITH_QT_TEST` environment variable to 'False'.
+It will skip all tests from :mod:`silx.test.gui`.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "20/04/2017"
+
+
+import logging
+import os
+import unittest
+
+
+logger = logging.getLogger(__name__)
+
+
+def suite():
+ from . import test_version
+ from . import test_resources
+ from . import test_sx
+ from ..io import test as test_io
+ from ..math import test as test_math
+ from ..image import test as test_image
+ from ..gui import test as test_gui
+ from ..utils import test as test_utils
+ from ..opencl import test as test_ocl
+ test_suite = unittest.TestSuite()
+ # test sx first cause qui tests load ipython module
+ test_suite.addTest(test_sx.suite())
+ test_suite.addTest(test_gui.suite())
+ # then test no-gui tests
+ test_suite.addTest(test_utils.suite())
+ test_suite.addTest(test_version.suite())
+ test_suite.addTest(test_resources.suite())
+ test_suite.addTest(test_utils.suite())
+ test_suite.addTest(test_io.suite())
+ test_suite.addTest(test_math.suite())
+ test_suite.addTest(test_image.suite())
+ test_suite.addTest(test_ocl.suite())
+ return test_suite
+
+
+def run_tests():
+ """Run test complete test_suite"""
+ runner = unittest.TextTestRunner()
+ if not runner.run(suite()).wasSuccessful():
+ print("Test suite failed")
+ return 1
+ else:
+ print("Test suite succeeded")
+ return 0
diff --git a/silx/test/test_resources.py b/silx/test/test_resources.py
new file mode 100644
index 0000000..9d3e277
--- /dev/null
+++ b/silx/test/test_resources.py
@@ -0,0 +1,97 @@
+# 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.
+#
+# ###########################################################################*/
+"""Test for resource files management."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "20/04/2017"
+
+
+import os
+import unittest
+
+import silx.resources
+from .utils import utilstest
+
+
+class TestResources(unittest.TestCase):
+ def test_resource_dir(self):
+ """Get a resource directory"""
+ icons_dirname = silx.resources.resource_filename('gui/icons/')
+ self.assertTrue(os.path.isdir(icons_dirname))
+
+ def test_resource_file(self):
+ """Get a resource file name"""
+ filename = silx.resources.resource_filename('gui/icons/colormap.png')
+ self.assertTrue(os.path.isfile(filename))
+
+ def test_resource_nonexistent(self):
+ """Get a non existent resource"""
+ filename = silx.resources.resource_filename('non_existent_file.txt')
+ self.assertFalse(os.path.exists(filename))
+
+
+class TestExternalResources(unittest.TestCase):
+ "This is a test for the TestResources"
+ def test_tempdir(self):
+ "test the temporary directory creation"
+ myutilstest = silx.resources.ExternalResources("toto", "http://www.silx.org")
+ d = myutilstest.tempdir
+ self.assertTrue(os.path.isdir(d))
+ self.assertEqual(d, myutilstest.tempdir, 'tmpdir is stable')
+ myutilstest.clean_up()
+ self.assertFalse(os.path.isdir(d))
+ e = myutilstest.tempdir
+ self.assertTrue(os.path.isdir(e))
+ self.assertEqual(e, myutilstest.tempdir, 'tmpdir is stable')
+ self.assertNotEqual(d, e, "tempdir changed")
+ myutilstest.clean_up()
+
+ def test_download(self):
+ "test the download from silx.org"
+ f = utilstest.getfile("lena.png")
+ self.assertTrue(os.path.exists(f))
+ f = utilstest.getdir("source.tar.gz")
+ self.assertTrue(os.path.isfile(f))
+ self.assertTrue(os.path.isdir(f[:-7]))
+
+ def test_dowload_all(self):
+ "test the download of all files from silx.org"
+ l = utilstest.download_all()
+ self.assertGreater(len(l), 1, "At least 2 items were downloaded")
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestResources))
+ test_suite.addTest(TestExternalResources("test_tempdir"))
+ test_suite.addTest(TestExternalResources("test_download")) # order matters !
+ test_suite.addTest(TestExternalResources("test_dowload_all"))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/test/test_sx.py b/silx/test/test_sx.py
new file mode 100644
index 0000000..0de3b35
--- /dev/null
+++ b/silx/test/test_sx.py
@@ -0,0 +1,174 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "05/12/2016"
+
+
+import logging
+import os
+import sys
+import unittest
+
+import numpy
+
+
+_logger = logging.getLogger(__name__)
+
+
+if sys.platform.startswith('linux') and not os.environ.get('DISPLAY', ''):
+ # On linux and no DISPLAY available (e.g., ssh without -X)
+ _logger.warning('silx.sx tests disabled (DISPLAY env. variable not set)')
+
+ class SkipSXTest(unittest.TestCase):
+ def runTest(self):
+ self.skipTest(
+ 'silx.sx tests disabled (DISPLAY env. variable not set)')
+
+ def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(SkipSXTest())
+ return suite
+
+elif os.environ.get('WITH_QT_TEST', 'True') == 'False':
+ # Explicitly disabled tests
+ _logger.warning(
+ "silx.sx tests disabled (env. variable WITH_QT_TEST=False)")
+
+ class SkipSXTest(unittest.TestCase):
+ def runTest(self):
+ self.skipTest(
+ "silx.sx tests disabled (env. variable WITH_QT_TEST=False)")
+
+ def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(SkipSXTest())
+ return suite
+
+else:
+ # Import here to avoid loading QT if tests are disabled
+
+ from silx.gui import qt
+ # load TestCaseQt before sx
+ from silx.gui.test.utils import TestCaseQt
+ from silx import sx
+
+ class SXTest(TestCaseQt):
+ """Test the sx module"""
+
+ def _expose_and_close(self, plot):
+ self.qWaitForWindowExposed(plot)
+ self.qapp.processEvents()
+ plot.setAttribute(qt.Qt.WA_DeleteOnClose)
+ plot.close()
+
+ def test_plot(self):
+ """Test plot function"""
+ y = numpy.random.random(100)
+ x = numpy.arange(len(y)) * 0.5
+
+ # Nothing
+ plt = sx.plot()
+ self._expose_and_close(plt)
+
+ # y
+ plt = sx.plot(y, title='y')
+ self._expose_and_close(plt)
+
+ # y, style
+ plt = sx.plot(y, 'blued ', title='y, "blued "')
+ self._expose_and_close(plt)
+
+ # x, y
+ plt = sx.plot(x, y, title='x, y')
+ self._expose_and_close(plt)
+
+ # x, y, style
+ plt = sx.plot(x, y, 'ro-', xlabel='x', title='x, y, "ro-"')
+ self._expose_and_close(plt)
+
+ # x, y, style, y
+ plt = sx.plot(x, y, 'ro-', y ** 2, xlabel='x', ylabel='y',
+ title='x, y, "ro-", y ** 2')
+ self._expose_and_close(plt)
+
+ # x, y, style, y, style
+ plt = sx.plot(x, y, 'ro-', y ** 2, 'b--',
+ title='x, y, "ro-", y ** 2, "b--"')
+ self._expose_and_close(plt)
+
+ # x, y, style, x, y, style
+ plt = sx.plot(x, y, 'ro-', x, y ** 2, 'b--',
+ title='x, y, "ro-", x, y ** 2, "b--"')
+ self._expose_and_close(plt)
+
+ # x, y, x, y
+ plt = sx.plot(x, y, x, y ** 2, title='x, y, x, y ** 2')
+ self._expose_and_close(plt)
+
+ def test_imshow(self):
+ """Test imshow function"""
+ img = numpy.arange(100.).reshape(10, 10) + 1
+
+ # Nothing
+ plt = sx.imshow()
+ self._expose_and_close(plt)
+
+ # image
+ plt = sx.imshow(img)
+ self._expose_and_close(plt)
+
+ # image, gray cmap
+ plt = sx.imshow(img, cmap='jet', title='jet cmap')
+ self._expose_and_close(plt)
+
+ # image, log cmap
+ plt = sx.imshow(img, norm='log', title='log cmap')
+ self._expose_and_close(plt)
+
+ # image, fixed range
+ plt = sx.imshow(img, vmin=10, vmax=20,
+ title='[10,20] cmap')
+ self._expose_and_close(plt)
+
+ # image, keep ratio
+ plt = sx.imshow(img, aspect=True,
+ title='keep ratio')
+ self._expose_and_close(plt)
+
+ # image, change origin and scale
+ plt = sx.imshow(img, origin=(10, 10), scale=(2, 2),
+ title='origin=(10, 10), scale=(2, 2)')
+ self._expose_and_close(plt)
+
+ def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(SXTest))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/test/test_version.py b/silx/test/test_version.py
new file mode 100644
index 0000000..bb91e4e
--- /dev/null
+++ b/silx/test/test_version.py
@@ -0,0 +1,49 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+"""Basic test of top-level package import and existence of version info."""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "26/02/2016"
+
+import unittest
+
+import silx
+
+
+class TestVersion(unittest.TestCase):
+ def test_version(self):
+ self.assertTrue(isinstance(silx.version, str))
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestVersion))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/test/utils.py b/silx/test/utils.py
new file mode 100644
index 0000000..ec86a2a
--- /dev/null
+++ b/silx/test/utils.py
@@ -0,0 +1,284 @@
+# 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.
+#
+# ###########################################################################*/
+"""Utilities for writing tests.
+
+- :class:`ParametricTestCase` provides a :meth:`TestCase.subTest` replacement
+ for Python < 3.4
+- :class:`TestLogging` with context or the :func:`test_logging` decorator
+ enables testing the number of logging messages of different levels.
+- :func:`temp_dir` provides a with context to create/delete a temporary
+ directory.
+"""
+
+__authors__ = ["T. Vincent"]
+__license__ = "MIT"
+__date__ = "20/04/2017"
+
+
+import os
+import contextlib
+import functools
+import logging
+import numpy
+import shutil
+import sys
+import tempfile
+import unittest
+from ..resources import ExternalResources
+
+logger = logging.getLogger(__name__)
+
+utilstest = ExternalResources(project="silx",
+ url_base="http://www.silx.org/pub/silx/",
+ env_key="SILX_DATA",
+ timeout=60)
+"This is the instance to be used. Singleton-like feature provided by module"
+
+# Parametric Test Base Class ##################################################
+
+if sys.hexversion >= 0x030400F0: # Python >= 3.4
+ class ParametricTestCase(unittest.TestCase):
+ pass
+
+else:
+ class ParametricTestCase(unittest.TestCase):
+ """TestCase with subTest support for Python < 3.4.
+
+ Add subTest method to support parametric tests.
+ API is the same, but behavior differs:
+ If a subTest fails, the following ones are not run.
+ """
+
+ _subtest_msg = None # Class attribute to provide a default value
+
+ @contextlib.contextmanager
+ def subTest(self, msg=None, **params):
+ """Use as unittest.TestCase.subTest method in Python >= 3.4."""
+ # Format arguments as: '[msg] (key=value, ...)'
+ param_str = ', '.join(['%s=%s' % (k, v) for k, v in params.items()])
+ self._subtest_msg = '[%s] (%s)' % (msg or '', param_str)
+ yield
+ self._subtest_msg = None
+
+ def shortDescription(self):
+ short_desc = super(ParametricTestCase, self).shortDescription()
+ if self._subtest_msg is not None:
+ # Append subTest message to shortDescription
+ short_desc = ' '.join(
+ [msg for msg in (short_desc, self._subtest_msg) if msg])
+
+ return short_desc if short_desc else None
+
+
+# Test logging messages #######################################################
+
+class TestLogging(logging.Handler):
+ """Context checking the number of logging messages from a specified Logger.
+
+ It disables propagation of logging message while running.
+
+ This is meant to be used as a with statement, for example:
+
+ >>> with TestLogging(logger, error=2, warning=0):
+ >>> pass # Run tests here expecting 2 ERROR and no WARNING from logger
+ ...
+
+ :param logger: Name or instance of the logger to test.
+ (Default: root logger)
+ :type logger: str or :class:`logging.Logger`
+ :param int critical: Expected number of CRITICAL messages.
+ Default: Do not check.
+ :param int error: Expected number of ERROR messages.
+ Default: Do not check.
+ :param int warning: Expected number of WARNING messages.
+ Default: Do not check.
+ :param int info: Expected number of INFO messages.
+ Default: Do not check.
+ :param int debug: Expected number of DEBUG messages.
+ Default: Do not check.
+ :param int notset: Expected number of NOTSET messages.
+ Default: Do not check.
+ :raises RuntimeError: If the message counts are the expected ones.
+ """
+
+ def __init__(self, logger=None, critical=None, error=None,
+ warning=None, info=None, debug=None, notset=None):
+ if logger is None:
+ logger = logging.getLogger()
+ elif not isinstance(logger, logging.Logger):
+ logger = logging.getLogger(logger)
+ self.logger = logger
+
+ self.records = []
+
+ self.count_by_level = {
+ logging.CRITICAL: critical,
+ logging.ERROR: error,
+ logging.WARNING: warning,
+ logging.INFO: info,
+ logging.DEBUG: debug,
+ logging.NOTSET: notset
+ }
+
+ super(TestLogging, self).__init__()
+
+ def __enter__(self):
+ """Context (i.e., with) support"""
+ self.records = [] # Reset recorded LogRecords
+ self.logger.addHandler(self)
+ self.logger.propagate = False
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ """Context (i.e., with) support"""
+ self.logger.removeHandler(self)
+ self.logger.propagate = True
+
+ for level, expected_count in self.count_by_level.items():
+ if expected_count is None:
+ continue
+
+ # Number of records for the specified level_str
+ count = len([r for r in self.records if r.levelno == level])
+ if count != expected_count: # That's an error
+ # Resend record logs through logger as they where masked
+ # to help debug
+ for record in self.records:
+ self.logger.handle(record)
+ raise RuntimeError(
+ 'Expected %d %s logging messages, got %d' % (
+ expected_count, logging.getLevelName(level), count))
+
+ def emit(self, record):
+ """Override :meth:`logging.Handler.emit`"""
+ self.records.append(record)
+
+
+def test_logging(logger=None, critical=None, error=None,
+ warning=None, info=None, debug=None, notset=None):
+ """Decorator checking number of logging messages.
+
+ Propagation of logging messages is disabled by this decorator.
+
+ In case the expected number of logging messages is not found, it raises
+ a RuntimeError.
+
+ >>> class Test(unittest.TestCase):
+ ... @test_logging('module_logger_name', error=2, warning=0)
+ ... def test(self):
+ ... pass # Test expecting 2 ERROR and 0 WARNING messages
+
+ :param logger: Name or instance of the logger to test.
+ (Default: root logger)
+ :type logger: str or :class:`logging.Logger`
+ :param int critical: Expected number of CRITICAL messages.
+ Default: Do not check.
+ :param int error: Expected number of ERROR messages.
+ Default: Do not check.
+ :param int warning: Expected number of WARNING messages.
+ Default: Do not check.
+ :param int info: Expected number of INFO messages.
+ Default: Do not check.
+ :param int debug: Expected number of DEBUG messages.
+ Default: Do not check.
+ :param int notset: Expected number of NOTSET messages.
+ Default: Do not check.
+ """
+ def decorator(func):
+ test_context = TestLogging(logger, critical, error,
+ warning, info, debug, notset)
+
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ with test_context:
+ result = func(*args, **kwargs)
+ return result
+ return wrapper
+ return decorator
+
+
+
+
+
+
+# Temporary directory context #################################################
+
+@contextlib.contextmanager
+def temp_dir():
+ """with context providing a temporary directory.
+
+ >>> import os.path
+ >>> with temp_dir() as tmp:
+ ... print(os.path.isdir(tmp)) # Use tmp directory
+ """
+ tmp_dir = tempfile.mkdtemp()
+ try:
+ yield tmp_dir
+ finally:
+ shutil.rmtree(tmp_dir)
+
+
+# Synthetic data and random noise #############################################
+def add_gaussian_noise(y, stdev=1., mean=0.):
+ """Add random gaussian noise to synthetic data.
+
+ :param ndarray y: Array of synthetic data
+ :param float mean: Mean of the gaussian distribution of noise.
+ :param float stdev: Standard deviation of the gaussian distribution of
+ noise.
+ :return: Array of data with noise added
+ """
+ noise = numpy.random.normal(mean, stdev, size=y.size)
+ noise.shape = y.shape
+ return y + noise
+
+
+def add_poisson_noise(y):
+ """Add random noise from a poisson distribution to synthetic data.
+
+ :param ndarray y: Array of synthetic data
+ :return: Array of data with noise added
+ """
+ yn = numpy.random.poisson(y)
+ yn.shape = y.shape
+ return yn
+
+
+def add_relative_noise(y, max_noise=5.):
+ """Add relative random noise to synthetic data. The maximum noise level
+ is given in percents.
+
+ An array of noise in the interval [-max_noise, max_noise] (continuous
+ uniform distribution) is generated, and applied to the data the
+ following way:
+
+ :math:`yn = y * (1. + noise / 100.)`
+
+ :param ndarray y: Array of synthetic data
+ :param float max_noise: Maximum percentage of noise
+ :return: Array of data with noise added
+ """
+ noise = max_noise * (2 * numpy.random.random(size=y.size) - 1)
+ noise.shape = y.shape
+ return y * (1. + noise / 100.)
diff --git a/silx/third_party/EdfFile.py b/silx/third_party/EdfFile.py
new file mode 100644
index 0000000..8a08c20
--- /dev/null
+++ b/silx/third_party/EdfFile.py
@@ -0,0 +1,1223 @@
+# /*##########################################################################
+#
+# Copyright (c) 2004-2017 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# 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.
+#
+# ############################################################################*/
+__author__ = "Alexandre Gobbo, V.A. Sole - ESRF Data Analysis"
+__contact__ = "sole@esrf.fr"
+__license__ = "MIT"
+__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
+"""
+ EdfFile.py
+ Generic class for Edf files manipulation.
+
+ Interface:
+ ===========================
+ class EdfFile:
+ __init__(self,FileName)
+ GetNumImages(self)
+ def GetData(self,Index, DataType="",Pos=None,Size=None):
+ GetPixel(self,Index,Position)
+ GetHeader(self,Index)
+ GetStaticHeader(self,Index)
+ WriteImage (self,Header,Data,Append=1,DataType="",WriteAsUnsigened=0,ByteOrder="")
+
+
+ Edf format assumptions:
+ ===========================
+ The following details were assumed for this implementation:
+ - Each Edf file contains a certain number of data blocks.
+ - Each data block represents data stored in an one, two or three-dimensional array.
+ - Each data block contains a header section, written in ASCII, and a data section of
+ binary information.
+ - The size of the header section in bytes is a multiple of 1024. The header is
+ padded with spaces (0x20). If the header is not padded to a multiple of 1024,
+ the file is recognized, but the output is always made in this format.
+ - The header section starts by '{' and finishes by '}'. It is composed by several
+ pairs 'keyword = value;'. The keywords are case insensitive, but the values are case
+ sensitive. Each pair is put in a new line (they are separeted by 0x0A). In the
+ end of each line, a semicolon (;) separes the pair of a comment, not interpreted.
+ Exemple:
+ {
+ ; Exemple Header
+ HeaderID = EH:000001:000000:000000 ; automatically generated
+ ByteOrder = LowByteFirst ;
+ DataType = FloatValue ; 4 bytes per pixel
+ Size = 4000000 ; size of data section
+ Dim_1= 1000 ; x coordinates
+ Dim_2 = 1000 ; y coordinates
+
+ (padded with spaces to complete 1024 bytes)
+ }
+ - There are some fields in the header that are required for this implementation. If any of
+ these is missing, or inconsistent, it will be generated an error:
+ Size: Represents size of data block
+ Dim_1: size of x coordinates (Dim_2 for 2-dimentional images, and also Dim_3 for 3d)
+ DataType
+ ByteOrder
+ - For the written images, these fields are automatically genereted:
+ Size,Dim_1 (Dim_2 and Dim_3, if necessary), Byte Order, DataType, HeaderID and Image
+ These fields are called here "static header", and can be retrieved by the method
+ GetStaticHeader. Other header components are taken by GetHeader. Both methods returns
+ a dictionary in which the key is the keyword of the pair. When writting an image through
+ WriteImage method, the Header parameter should not contain the static header information,
+ which is automatically generated.
+ - The indexing of images through these functions is based just on the 0-based position in
+ the file, the header items HeaderID and Image are not considered for referencing the
+ images.
+ - The data section contais a number of bytes equal to the value of Size keyword. Data
+ section is going to be translated into an 1D, 2D or 3D Numpy Array, and accessed
+ through GetData method call.
+"""
+DEBUG = 0
+################################################################################
+import sys
+import numpy
+import os.path
+try:
+ import gzip
+ GZIP = True
+except:
+ GZIP = False
+try:
+ import bz2
+ BZ2 = True
+except:
+ BZ2 = False
+
+MARCCD_SUPPORT = False
+PILATUS_CBF_SUPPORT = False
+CAN_USE_FASTEDF = False
+
+# Using local TiffIO
+from . import TiffIO
+TIFF_SUPPORT = True
+
+# Constants
+
+HEADER_BLOCK_SIZE = 1024
+STATIC_HEADER_ELEMENTS = (
+ "HeaderID",
+ "Image",
+ "ByteOrder",
+ "DataType",
+ "Dim_1",
+ "Dim_2",
+ "Dim_3",
+ "Offset_1",
+ "Offset_2",
+ "Offset_3",
+ "Size")
+
+STATIC_HEADER_ELEMENTS_CAPS = (
+ "HEADERID",
+ "IMAGE",
+ "BYTEORDER",
+ "DATATYPE",
+ "DIM_1",
+ "DIM_2",
+ "DIM_3",
+ "OFFSET_1",
+ "OFFSET_2",
+ "OFFSET_3",
+ "SIZE")
+
+LOWER_CASE = 0
+UPPER_CASE = 1
+
+KEYS = 1
+VALUES = 2
+
+
+class Image(object):
+ """
+ """
+ def __init__(self):
+ """ Constructor
+ """
+ self.Header = {}
+ self.StaticHeader = {}
+ self.HeaderPosition = 0
+ self.DataPosition = 0
+ self.Size = 0
+ self.NumDim = 1
+ self.Dim1 = 0
+ self.Dim2 = 0
+ self.Dim3 = 0
+ self.DataType = ""
+
+
+class EdfFile(object):
+ """
+ """
+ def __init__(self, FileName, access=None, fastedf=None):
+ """ Constructor
+
+ :param FileName: Name of the file (either existing or to be created)
+ :type FileName: string
+ :param access: access mode "r" for reading (the file should exist) or
+ "w" for writing (if the file does not exist, it does not matter).
+ :type access: string
+ :type fastedf: True to use the fastedf module
+ :param fastedf: bool
+ """
+ self.Images = []
+ self.NumImages = 0
+ self.FileName = FileName
+ self.File = 0
+ if fastedf is None:
+ fastedf = 0
+ self.fastedf = fastedf
+ self.ADSC = False
+ self.MARCCD = False
+ self.TIFF = False
+ self.PILATUS_CBF = False
+ self.SPE = False
+ if sys.byteorder == "big":
+ self.SysByteOrder = "HighByteFirst"
+ else:
+ self.SysByteOrder = "LowByteFirst"
+
+ if hasattr(FileName, "seek") and\
+ hasattr(FileName, "read"):
+ # this looks like a file descriptor ...
+ self.__ownedOpen = False
+ self.File = FileName
+ try:
+ self.FileName = self.File.name
+ except AttributeError:
+ self.FileName = self.File.filename
+ elif FileName.lower().endswith('.gz'):
+ if GZIP:
+ self.__ownedOpen = False
+ self.File = gzip.GzipFile(FileName)
+ else:
+ raise IOError("No gzip module support in this system")
+ elif FileName.lower().endswith('.bz2'):
+ if BZ2:
+ self.__ownedOpen = False
+ self.File = bz2.BZ2File(FileName)
+ else:
+ raise IOError("No bz2 module support in this system")
+ else:
+ self.__ownedOpen = True
+
+ if self.File in [0, None]:
+ if access is not None:
+ if access[0].upper() == "R":
+ if not os.path.isfile(self.FileName):
+ raise IOError("File %s not found" % FileName)
+ if 'b' not in access:
+ access += 'b'
+ if 1:
+ if not os.path.isfile(self.FileName):
+ # write access
+ if access is None:
+ # allow writing and reading
+ access = "ab+"
+ self.File = open(self.FileName, access)
+ self.File.seek(0, 0)
+ return
+ if 'b' not in access:
+ access += 'b'
+ self.File = open(self.FileName, access)
+ return
+ else:
+ if access is None:
+ if (os.access(self.FileName, os.W_OK)):
+ access = "r+b"
+ else:
+ access = "rb"
+ self.File = open(self.FileName, access)
+ self.File.seek(0, 0)
+ twoChars = self.File.read(2)
+ tiff = False
+ if sys.version < '3.0':
+ if twoChars in ["II", "MM"]:
+ tiff = True
+ elif twoChars in [eval('b"II"'), eval('b"MM"')]:
+ tiff = True
+ if tiff:
+ fileExtension = os.path.splitext(self.FileName)[-1]
+ if fileExtension.lower() in [".tif", ".tiff"] or\
+ sys.version > '2.9':
+ if not TIFF_SUPPORT:
+ raise IOError("TIFF support not implemented")
+ else:
+ self.TIFF = True
+ elif not MARCCD_SUPPORT:
+ if not TIFF_SUPPORT:
+ raise IOError("MarCCD support not implemented")
+ else:
+ self.TIFF = True
+ else:
+ self.MARCCD = True
+ basename = os.path.basename(FileName).upper()
+ if basename.endswith('.CBF'):
+ if not PILATUS_CBF_SUPPORT:
+ raise IOError("CBF support not implemented")
+ if twoChars[0] != "{":
+ self.PILATUS_CBF = True
+ elif basename.endswith('.SPE'):
+ if twoChars[0] != "$":
+ self.SPE = True
+ elif basename.endswith('EDF.GZ') or basename.endswith('CCD.GZ'):
+ self.GZIP = True
+ else:
+ try:
+ self.File.close()
+ except:
+ pass
+ raise IOError("EdfFile: Error opening file")
+
+ self.File.seek(0, 0)
+ if self.TIFF:
+ self._wrapTIFF()
+ self.File.close()
+ return
+ if self.MARCCD:
+ self._wrapMarCCD()
+ self.File.close()
+ return
+ if self.PILATUS_CBF:
+ self._wrapPilatusCBF()
+ self.File.close()
+ return
+ if self.SPE:
+ self._wrapSPE()
+ self.File.close()
+ return
+
+ Index = 0
+ line = self.File.readline()
+ selectedLines = [""]
+ if sys.version > '2.6':
+ selectedLines.append(eval('b""'))
+ parsingHeader = False
+ while line not in selectedLines:
+ # decode to make sure I have character string
+ # str to make sure python 2.x sees it as string and not unicode
+ if sys.version < '3.0':
+ if type(line) != type(str("")):
+ line = "%s" % line
+ else:
+ try:
+ line = str(line.decode())
+ except UnicodeDecodeError:
+ try:
+ line = str(line.decode('utf-8'))
+ except UnicodeDecodeError:
+ try:
+ line = str(line.decode('latin-1'))
+ except UnicodeDecodeError:
+ line = "%s" % line
+ if (line.count("{\n") >= 1) or (line.count("{\r\n") >= 1):
+ parsingHeader = True
+ Index = self.NumImages
+ self.NumImages = self.NumImages + 1
+ self.Images.append(Image())
+
+ if line.count("=") >= 1:
+ listItems = line.split("=", 1)
+ typeItem = listItems[0].strip()
+ listItems = listItems[1].split(";", 1)
+ valueItem = listItems[0].strip()
+ if (typeItem == "HEADER_BYTES") and (Index == 0):
+ self.ADSC = True
+ break
+
+ # if typeItem in self.Images[Index].StaticHeader.keys():
+ if typeItem.upper() in STATIC_HEADER_ELEMENTS_CAPS:
+ self.Images[Index].StaticHeader[typeItem] = valueItem
+ else:
+ self.Images[Index].Header[typeItem] = valueItem
+ if ((line.count("}\n") >= 1) or (line.count("}\r") >= 1)) and (parsingHeader):
+ parsingHeader = False
+ # for i in STATIC_HEADER_ELEMENTS_CAPS:
+ # if self.Images[Index].StaticHeader[i]=="":
+ # raise "Bad File Format"
+ self.Images[Index].DataPosition = self.File.tell()
+ # self.File.seek(int(self.Images[Index].StaticHeader["Size"]), 1)
+ StaticPar = SetDictCase(self.Images[Index].StaticHeader, UPPER_CASE, KEYS)
+ if "SIZE" in StaticPar.keys():
+ self.Images[Index].Size = int(StaticPar["SIZE"])
+ if self.Images[Index].Size <= 0:
+ self.NumImages = Index
+ line = self.File.readline()
+ continue
+ else:
+ raise TypeError("EdfFile: Image doesn't have size information")
+ if "DIM_1" in StaticPar.keys():
+ self.Images[Index].Dim1 = int(StaticPar["DIM_1"])
+ self.Images[Index].Offset1 = int(StaticPar.get("Offset_1", "0"))
+ else:
+ raise TypeError("EdfFile: Image doesn't have dimension information")
+ if "DIM_2" in StaticPar.keys():
+ self.Images[Index].NumDim = 2
+ self.Images[Index].Dim2 = int(StaticPar["DIM_2"])
+ self.Images[Index].Offset2 = int(StaticPar.get("Offset_2", "0"))
+ if "DIM_3" in StaticPar.keys():
+ self.Images[Index].NumDim = 3
+ self.Images[Index].Dim3 = int(StaticPar["DIM_3"])
+ self.Images[Index].Offset3 = int(StaticPar.get("Offset_3", "0"))
+ if "DATATYPE" in StaticPar.keys():
+ self.Images[Index].DataType = StaticPar["DATATYPE"]
+ else:
+ raise TypeError("EdfFile: Image doesn't have datatype information")
+ if "BYTEORDER" in StaticPar.keys():
+ self.Images[Index].ByteOrder = StaticPar["BYTEORDER"]
+ else:
+ raise TypeError("EdfFile: Image doesn't have byteorder information")
+
+ self.File.seek(self.Images[Index].Size, 1)
+
+ line = self.File.readline()
+
+ if self.ADSC:
+ self.File.seek(0, 0)
+ self.NumImages = 1
+ # this is a bad implementation of fabio adscimage
+ # please take a look at the fabio module of fable at sourceforge
+ infile = self.File
+ header_keys = []
+ header = {}
+ try:
+ """ read an adsc header """
+ line = infile.readline()
+ bytesread = len(line)
+ while '}' not in line:
+ if '=' in line:
+ (key, val) = line.split('=')
+ header_keys.append(key.strip())
+ header[key.strip()] = val.strip(' ;\n')
+ line = infile.readline()
+ bytesread = bytesread + len(line)
+ except:
+ raise Exception("Error processing adsc header")
+ # banned by bzip/gzip???
+ try:
+ infile.seek(int(header['HEADER_BYTES']), 0)
+ except TypeError:
+ # Gzipped does not allow a seek and read header is not
+ # promising to stop in the right place
+ infile.close()
+ infile = self._open(fname, "rb")
+ infile.read(int(header['HEADER_BYTES']))
+ binary = infile.read()
+ infile.close()
+
+ # now read the data into the array
+ self.Images[Index].Dim1 = int(header['SIZE1'])
+ self.Images[Index].Dim2 = int(header['SIZE2'])
+ self.Images[Index].NumDim = 2
+ self.Images[Index].DataType = 'UnsignedShort'
+ try:
+ self.__data = numpy.reshape(
+ numpy.fromstring(binary, numpy.uint16),
+ (self.Images[Index].Dim2, self.Images[Index].Dim1))
+ except ValueError:
+ msg = 'Size spec in ADSC-header does not match size of image data field'
+ raise IOError(msg)
+ if 'little' in header['BYTE_ORDER']:
+ self.Images[Index].ByteOrder = 'LowByteFirst'
+ else:
+ self.Images[Index].ByteOrder = 'HighByteFirst'
+ if self.SysByteOrder.upper() != self.Images[Index].ByteOrder.upper():
+ self.__data = self.__data.byteswap()
+ self.Images[Index].ByteOrder = self.SysByteOrder
+
+ self.Images[Index].StaticHeader['Dim_1'] = self.Images[Index].Dim1
+ self.Images[Index].StaticHeader['Dim_2'] = self.Images[Index].Dim2
+ self.Images[Index].StaticHeader['Offset_1'] = 0
+ self.Images[Index].StaticHeader['Offset_2'] = 0
+ self.Images[Index].StaticHeader['DataType'] = self.Images[Index].DataType
+
+ self.__makeSureFileIsClosed()
+
+ def _wrapTIFF(self):
+ self._wrappedInstance = TiffIO.TiffIO(self.File, cache_length=0, mono_output=True)
+ self.NumImages = self._wrappedInstance.getNumberOfImages()
+ if self.NumImages < 1:
+ return
+
+ # wrapped image objects have to provide getInfo and getData
+ # info = self._wrappedInstance.getInfo( index)
+ # data = self._wrappedInstance.getData( index)
+ # for the time being I am going to assume all the images
+ # in the file have the same data type type
+ data = None
+
+ for Index in range(self.NumImages):
+ info = self._wrappedInstance.getInfo(Index)
+ self.Images.append(Image())
+ self.Images[Index].Dim1 = info['nRows']
+ self.Images[Index].Dim2 = info['nColumns']
+ self.Images[Index].NumDim = 2
+ if data is None:
+ data = self._wrappedInstance.getData(0)
+ self.Images[Index].DataType = self.__GetDefaultEdfType__(data.dtype)
+ self.Images[Index].StaticHeader['Dim_1'] = self.Images[Index].Dim1
+ self.Images[Index].StaticHeader['Dim_2'] = self.Images[Index].Dim2
+ self.Images[Index].StaticHeader['Offset_1'] = 0
+ self.Images[Index].StaticHeader['Offset_2'] = 0
+ self.Images[Index].StaticHeader['DataType'] = self.Images[Index].DataType
+ self.Images[Index].Header.update(info)
+
+ def _wrapMarCCD(self):
+ raise NotImplementedError("Look at the module EdfFile from PyMca")
+
+ def _wrapPilatusCBF(self):
+ raise NotImplementedError("Look at the module EdfFile from PyMca")
+
+ def _wrapSPE(self):
+ if 0 and sys.version < '3.0':
+ self.File.seek(42)
+ xdim = numpy.int64(numpy.fromfile(self.File, numpy.int16, 1)[0])
+ self.File.seek(656)
+ ydim = numpy.int64(numpy.fromfile(self.File, numpy.int16, 1))
+ self.File.seek(4100)
+ self.__data = numpy.fromfile(self.File, numpy.uint16, int(xdim * ydim))
+ else:
+ import struct
+ self.File.seek(0)
+ a = self.File.read()
+ xdim = numpy.int64(struct.unpack('<h', a[42:44])[0])
+ ydim = numpy.int64(struct.unpack('<h', a[656:658])[0])
+ fmt = '<%dH' % int(xdim * ydim)
+ self.__data = numpy.array(struct.unpack(fmt, a[4100:int(4100 + int(2 * xdim * ydim))])).astype(numpy.uint16)
+ self.__data.shape = ydim, xdim
+ Index = 0
+ self.Images.append(Image())
+ self.NumImages = 1
+ self.Images[Index].Dim1 = ydim
+ self.Images[Index].Dim2 = xdim
+ self.Images[Index].NumDim = 2
+ self.Images[Index].DataType = 'UnsignedShort'
+ self.Images[Index].ByteOrder = 'LowByteFirst'
+ if self.SysByteOrder.upper() != self.Images[Index].ByteOrder.upper():
+ self.__data = self.__data.byteswap()
+ self.Images[Index].StaticHeader['Dim_1'] = self.Images[Index].Dim1
+ self.Images[Index].StaticHeader['Dim_2'] = self.Images[Index].Dim2
+ self.Images[Index].StaticHeader['Offset_1'] = 0
+ self.Images[Index].StaticHeader['Offset_2'] = 0
+ self.Images[Index].StaticHeader['DataType'] = self.Images[Index].DataType
+
+ def GetNumImages(self):
+ """ Returns number of images of the object (and associated file)
+ """
+ return self.NumImages
+
+ def GetData(self, *var, **kw):
+ try:
+ self.__makeSureFileIsOpen()
+ return self._GetData(*var, **kw)
+ finally:
+ self.__makeSureFileIsClosed()
+
+ def _GetData(self, Index, DataType="", Pos=None, Size=None):
+ """ Returns numpy array with image data
+ Index: The zero-based index of the image in the file
+ DataType: The edf type of the array to be returnd
+ If ommited, it is used the default one for the type
+ indicated in the image header
+ Attention to the absence of UnsignedShort,
+ UnsignedInteger and UnsignedLong types in
+ Numpy Python
+ Default relation between Edf types and NumPy's typecodes:
+ SignedByte int8 b
+ UnsignedByte uint8 B
+ SignedShort int16 h
+ UnsignedShort uint16 H
+ SignedInteger int32 i
+ UnsignedInteger uint32 I
+ SignedLong int32 i
+ UnsignedLong uint32 I
+ Signed64 int64 (l in 64bit, q in 32 bit)
+ Unsigned64 uint64 (L in 64bit, Q in 32 bit)
+ FloatValue float32 f
+ DoubleValue float64 d
+ Pos: Tuple (x) or (x,y) or (x,y,z) that indicates the begining
+ of data to be read. If ommited, set to the origin (0),
+ (0,0) or (0,0,0)
+ Size: Tuple, size of the data to be returned as x) or (x,y) or
+ (x,y,z) if ommited, is the distance from Pos to the end.
+
+ If Pos and Size not mentioned, returns the whole data.
+ """
+ fastedf = self.fastedf
+ if Index < 0 or Index >= self.NumImages:
+ raise ValueError("EdfFile: Index out of limit")
+ if fastedf is None:
+ fastedf = 0
+ if Pos is None and Size is None:
+ if self.ADSC or self.MARCCD or self.PILATUS_CBF or self.SPE:
+ return self.__data
+ elif self.TIFF:
+ data = self._wrappedInstance.getData(Index)
+ return data
+ else:
+ self.File.seek(self.Images[Index].DataPosition, 0)
+ datatype = self.__GetDefaultNumpyType__(self.Images[Index].DataType, index=Index)
+ try:
+ datasize = self.__GetSizeNumpyType__(datatype)
+ except TypeError:
+ print("What is the meaning of this error?")
+ datasize = 8
+ if self.Images[Index].NumDim == 3:
+ image = self.Images[Index]
+ sizeToRead = image.Dim1 * image.Dim2 * image.Dim3 * datasize
+ Data = numpy.fromstring(self.File.read(sizeToRead), datatype)
+ Data = numpy.reshape(Data, (self.Images[Index].Dim3, self.Images[Index].Dim2, self.Images[Index].Dim1))
+ elif self.Images[Index].NumDim == 2:
+ image = self.Images[Index]
+ sizeToRead = image.Dim1 * image.Dim2 * datasize
+ Data = numpy.fromstring(self.File.read(sizeToRead), datatype)
+ # print "datatype = ",datatype
+ # print "Data.type = ", Data.dtype.char
+ # print "self.Images[Index].DataType ", self.Images[Index].DataType
+ # print "Data.shape",Data.shape
+ # print "datasize = ",datasize
+ # print "sizeToRead ",sizeToRead
+ # print "lenData = ", len(Data)
+ Data = numpy.reshape(Data, (self.Images[Index].Dim2, self.Images[Index].Dim1))
+ elif self.Images[Index].NumDim == 1:
+ sizeToRead = self.Images[Index].Dim1 * datasize
+ Data = numpy.fromstring(self.File.read(sizeToRead), datatype)
+ elif self.ADSC or self.MARCCD or self.PILATUS_CBF or self.SPE:
+ return self.__data[Pos[1]:(Pos[1] + Size[1]),
+ Pos[0]:(Pos[0] + Size[0])]
+ elif self.TIFF:
+ data = self._wrappedInstance.getData(Index)
+ return data[Pos[1]:(Pos[1] + Size[1]), Pos[0]:(Pos[0] + Size[0])]
+ elif fastedf and CAN_USE_FASTEDF:
+ raise NotImplementedError("Look at the module EdfFile from PyMCA")
+ else:
+ if fastedf:
+ print("It could not use fast routines")
+ type_ = self.__GetDefaultNumpyType__(self.Images[Index].DataType, index=Index)
+ size_pixel = self.__GetSizeNumpyType__(type_)
+ Data = numpy.array([], type_)
+ if self.Images[Index].NumDim == 1:
+ if Pos is None:
+ Pos = (0,)
+ if Size is None:
+ Size = (0,)
+ sizex = self.Images[Index].Dim1
+ Size = list(Size)
+ if Size[0] == 0:
+ Size[0] = sizex - Pos[0]
+ self.File.seek((Pos[0] * size_pixel) + self.Images[Index].DataPosition, 0)
+ Data = numpy.fromstring(self.File.read(Size[0] * size_pixel), type_)
+ elif self.Images[Index].NumDim == 2:
+ if Pos is None:
+ Pos = (0, 0)
+ if Size is None:
+ Size = (0, 0)
+ Size = list(Size)
+ sizex, sizey = self.Images[Index].Dim1, self.Images[Index].Dim2
+ if Size[0] == 0:
+ Size[0] = sizex - Pos[0]
+ if Size[1] == 0:
+ Size[1] = sizey - Pos[1]
+ # print len(range(Pos[1],Pos[1]+Size[1])), "LECTURES OF ", Size[0], "POINTS"
+ # print "sizex = ", sizex, "sizey = ", sizey
+ Data = numpy.zeros((Size[1], Size[0]), type_)
+ dataindex = 0
+ for y in range(Pos[1], Pos[1] + Size[1]):
+ self.File.seek((((y * sizex) + Pos[0]) * size_pixel) + self.Images[Index].DataPosition, 0)
+ line = numpy.fromstring(self.File.read(Size[0] * size_pixel), type_)
+ Data[dataindex, :] = line[:]
+ # Data=numpy.concatenate((Data,line))
+ dataindex += 1
+ # print "DataSize = ",Data.shape
+ # print "Requested reshape = ",Size[1],'x',Size[0]
+ # Data = numpy.reshape(Data, (Size[1],Size[0]))
+ elif self.Images[Index].NumDim == 3:
+ if Pos is None:
+ Pos = (0, 0, 0)
+ if Size is None:
+ Size = (0, 0, 0)
+ Size = list(Size)
+ sizex, sizey, sizez = self.Images[Index].Dim1, self.Images[Index].Dim2, self.Images[Index].Dim3
+ if Size[0] == 0:
+ Size[0] = sizex - Pos[0]
+ if Size[1] == 0:
+ Size[1] = sizey - Pos[1]
+ if Size[2] == 0:
+ Size[2] = sizez - Pos[2]
+ for z in range(Pos[2], Pos[2] + Size[2]):
+ for y in range(Pos[1], Pos[1] + Size[1]):
+ self.File.seek(((((z * sizey + y) * sizex) + Pos[0]) * size_pixel) + self.Images[Index].DataPosition, 0)
+ line = numpy.fromstring(self.File.read(Size[0] * size_pixel), type_)
+ Data = numpy.concatenate((Data, line))
+ Data = numpy.reshape(Data, (Size[2], Size[1], Size[0]))
+
+ if self.SysByteOrder.upper() != self.Images[Index].ByteOrder.upper():
+ Data = Data.byteswap()
+ if DataType != "":
+ Data = self.__SetDataType__(Data, DataType)
+ return Data
+
+ def GetPixel(self, Index, Position):
+ """ Returns double value of the pixel, regardless the format of the array
+ Index: The zero-based index of the image in the file
+ Position: Tuple with the coordinete (x), (x,y) or (x,y,z)
+ """
+ if Index < 0 or Index >= self.NumImages:
+ raise ValueError("EdfFile: Index out of limit")
+ if len(Position) != self.Images[Index].NumDim:
+ raise ValueError("EdfFile: coordinate with wrong dimension ")
+
+ size_pixel = self.__GetSizeNumpyType__(self.__GetDefaultNumpyType__(self.Images[Index].DataType), index=Index)
+ offset = Position[0] * size_pixel
+ if self.Images[Index].NumDim > 1:
+ size_row = size_pixel * self.Images[Index].Dim1
+ offset = offset + (Position[1] * size_row)
+ if self.Images[Index].NumDim == 3:
+ size_img = size_row * self.Images[Index].Dim2
+ offset = offset + (Position[2] * size_img)
+ self.File.seek(self.Images[Index].DataPosition + offset, 0)
+ Data = numpy.fromstring(self.File.read(size_pixel), self.__GetDefaultNumpyType__(self.Images[Index].DataType, index=Index))
+ if self.SysByteOrder.upper() != self.Images[Index].ByteOrder.upper():
+ Data = Data.byteswap()
+ Data = self.__SetDataType__(Data, "DoubleValue")
+ return Data[0]
+
+ def GetHeader(self, Index):
+ """ Returns dictionary with image header fields.
+ Does not include the basic fields (static) defined by data shape,
+ type and file position. These are get with GetStaticHeader
+ method.
+ Index: The zero-based index of the image in the file
+ """
+ if Index < 0 or Index >= self.NumImages:
+ raise ValueError("Index out of limit")
+ # return self.Images[Index].Header
+ ret = {}
+ for i in self.Images[Index].Header.keys():
+ ret[i] = self.Images[Index].Header[i]
+ return ret
+
+ def GetStaticHeader(self, Index):
+ """ Returns dictionary with static parameters
+ Data format and file position dependent information
+ (dim1,dim2,size,datatype,byteorder,headerId,Image)
+ Index: The zero-based index of the image in the file
+ """
+ if Index < 0 or Index >= self.NumImages:
+ raise ValueError("Index out of limit")
+ # return self.Images[Index].StaticHeader
+ ret = {}
+ for i in self.Images[Index].StaticHeader.keys():
+ ret[i] = self.Images[Index].StaticHeader[i]
+ return ret
+
+ def WriteImage(self, *var, **kw):
+ try:
+ self.__makeSureFileIsOpen()
+ return self._WriteImage(*var, **kw)
+ finally:
+ self.__makeSureFileIsClosed()
+
+ def _WriteImage(self, Header, Data, Append=1, DataType="", ByteOrder=""):
+ """ Writes image to the file.
+ Header: Dictionary containing the non-static header
+ information (static information is generated
+ according to position of image and data format
+ Append: If equals to 0, overwrites the file. Otherwise, appends
+ to the end of the file
+ DataType: The data type to be saved to the file:
+ SignedByte
+ UnsignedByte
+ SignedShort
+ UnsignedShort
+ SignedInteger
+ UnsignedInteger
+ SignedLong
+ UnsignedLong
+ FloatValue
+ DoubleValue
+ Default: according to Data array typecode:
+ 1: SignedByte
+ b: UnsignedByte
+ s: SignedShort
+ w: UnsignedShort
+ i: SignedInteger
+ l: SignedLong
+ u: UnsignedLong
+ f: FloatValue
+ d: DoubleValue
+ ByteOrder: Byte order of the data in file:
+ HighByteFirst
+ LowByteFirst
+ Default: system's byte order
+ """
+ if Append == 0:
+ self.File.truncate(0)
+ self.Images = []
+ self.NumImages = 0
+ Index = self.NumImages
+ self.NumImages = self.NumImages + 1
+ self.Images.append(Image())
+
+ # self.Images[Index].StaticHeader["Dim_1"] = "%d" % Data.shape[1]
+ # self.Images[Index].StaticHeader["Dim_2"] = "%d" % Data.shape[0]
+ scalarSize = self.__GetSizeNumpyType__(Data.dtype)
+ if len(Data.shape) == 1:
+ self.Images[Index].Dim1 = Data.shape[0]
+ self.Images[Index].StaticHeader["Dim_1"] = "%d" % self.Images[Index].Dim1
+ self.Images[Index].Size = Data.shape[0] * scalarSize
+ elif len(Data.shape) == 2:
+ self.Images[Index].Dim1 = Data.shape[1]
+ self.Images[Index].Dim2 = Data.shape[0]
+ self.Images[Index].StaticHeader["Dim_1"] = "%d" % self.Images[Index].Dim1
+ self.Images[Index].StaticHeader["Dim_2"] = "%d" % self.Images[Index].Dim2
+ self.Images[Index].Size = Data.shape[0] * Data.shape[1] * scalarSize
+ self.Images[Index].NumDim = 2
+ elif len(Data.shape) == 3:
+ self.Images[Index].Dim1 = Data.shape[2]
+ self.Images[Index].Dim2 = Data.shape[1]
+ self.Images[Index].Dim3 = Data.shape[0]
+ self.Images[Index].StaticHeader["Dim_1"] = "%d" % self.Images[Index].Dim1
+ self.Images[Index].StaticHeader["Dim_2"] = "%d" % self.Images[Index].Dim2
+ self.Images[Index].StaticHeader["Dim_3"] = "%d" % self.Images[Index].Dim3
+ self.Images[Index].Size = Data.shape[0] * Data.shape[1] * Data.shape[2] * scalarSize
+ self.Images[Index].NumDim = 3
+ elif len(Data.shape) > 3:
+ raise TypeError("EdfFile: Data dimension not suported")
+
+ if DataType == "":
+ self.Images[Index].DataType = self.__GetDefaultEdfType__(Data.dtype)
+ else:
+ self.Images[Index].DataType = DataType
+ Data = self.__SetDataType__(Data, DataType)
+
+ if ByteOrder == "":
+ self.Images[Index].ByteOrder = self.SysByteOrder
+ else:
+ self.Images[Index].ByteOrder = ByteOrder
+
+ self.Images[Index].StaticHeader["Size"] = "%d" % self.Images[Index].Size
+ self.Images[Index].StaticHeader["Image"] = Index + 1
+ self.Images[Index].StaticHeader["HeaderID"] = "EH:%06d:000000:000000" % self.Images[Index].StaticHeader["Image"]
+ self.Images[Index].StaticHeader["ByteOrder"] = self.Images[Index].ByteOrder
+ self.Images[Index].StaticHeader["DataType"] = self.Images[Index].DataType
+
+ self.Images[Index].Header = {}
+ self.File.seek(0, 2)
+ StrHeader = "{\n"
+ for i in STATIC_HEADER_ELEMENTS:
+ if i in self.Images[Index].StaticHeader.keys():
+ StrHeader = StrHeader + ("%s = %s ;\n" % (i, self.Images[Index].StaticHeader[i]))
+ for i in Header.keys():
+ StrHeader = StrHeader + ("%s = %s ;\n" % (i, Header[i]))
+ self.Images[Index].Header[i] = Header[i]
+ newsize = (((len(StrHeader) + 1) / HEADER_BLOCK_SIZE) + 1) * HEADER_BLOCK_SIZE - 2
+ newsize = int(newsize)
+ StrHeader = StrHeader.ljust(newsize)
+ StrHeader = StrHeader + "}\n"
+
+ self.Images[Index].HeaderPosition = self.File.tell()
+ self.File.write(StrHeader.encode())
+ self.Images[Index].DataPosition = self.File.tell()
+
+ # if self.Images[Index].StaticHeader["ByteOrder"] != self.SysByteOrder:
+ if self.Images[Index].ByteOrder.upper() != self.SysByteOrder.upper():
+ self.File.write((Data.byteswap()).tostring())
+ else:
+ self.File.write(Data.tostring())
+
+ def __makeSureFileIsOpen(self):
+ if DEBUG:
+ print("Making sure file is open")
+ if not self.__ownedOpen:
+ return
+ if self.ADSC or self.MARCCD or self.PILATUS_CBF or self.SPE:
+ if DEBUG:
+ print("Special case. Image is buffered")
+ return
+ if self.File in [0, None]:
+ if DEBUG:
+ print("File is None")
+ elif self.File.closed:
+ if DEBUG:
+ print("Reopening closed file")
+ accessMode = self.File.mode
+ fileName = self.File.name
+ newFile = open(fileName, accessMode)
+ self.File = newFile
+ return
+
+ def __makeSureFileIsClosed(self):
+ if DEBUG:
+ print("Making sure file is closed")
+ if not self.__ownedOpen:
+ return
+ if self.ADSC or self.MARCCD or self.PILATUS_CBF or self.SPE:
+ if DEBUG:
+ print("Special case. Image is buffered")
+ return
+ if self.File in [0, None]:
+ if DEBUG:
+ print("File is None")
+ elif not self.File.closed:
+ if DEBUG:
+ print("Closing file")
+ self.File.close()
+ return
+
+ def __GetDefaultNumpyType__(self, EdfType, index=None):
+ """ Internal method: returns NumPy type according to Edf type
+ """
+ return self.GetDefaultNumpyType(EdfType, index)
+
+ def __GetDefaultEdfType__(self, NumpyType):
+ """ Internal method: returns Edf type according Numpy type
+ """
+ if NumpyType in ["b", numpy.int8]:
+ return "SignedByte"
+ elif NumpyType in ["B", numpy.uint8]:
+ return "UnsignedByte"
+ elif NumpyType in ["h", numpy.int16]:
+ return "SignedShort"
+ elif NumpyType in ["H", numpy.uint16]:
+ return "UnsignedShort"
+ elif NumpyType in ["i", numpy.int32]:
+ return "SignedInteger"
+ elif NumpyType in ["I", numpy.uint32]:
+ return "UnsignedInteger"
+ elif NumpyType == "l":
+ if sys.platform == 'linux2':
+ return "Signed64"
+ else:
+ return "SignedLong"
+ elif NumpyType == "L":
+ if sys.platform == 'linux2':
+ return "Unsigned64"
+ else:
+ return "UnsignedLong"
+ elif NumpyType == numpy.int64:
+ return "Signed64"
+ elif NumpyType == numpy.uint64:
+ return "Unsigned64"
+ elif NumpyType in ["f", numpy.float32]:
+ return "FloatValue"
+ elif NumpyType in ["d", numpy.float64]:
+ return "DoubleValue"
+ else:
+ raise TypeError("unknown NumpyType %s" % NumpyType)
+
+ def __GetSizeNumpyType__(self, NumpyType):
+ """ Internal method: returns size of NumPy's Array Types
+ """
+ if NumpyType in ["b", numpy.int8]:
+ return 1
+ elif NumpyType in ["B", numpy.uint8]:
+ return 1
+ elif NumpyType in ["h", numpy.int16]:
+ return 2
+ elif NumpyType in ["H", numpy.uint16]:
+ return 2
+ elif NumpyType in ["i", numpy.int32]:
+ return 4
+ elif NumpyType in ["I", numpy.uint32]:
+ return 4
+ elif NumpyType == "l":
+ if sys.platform == 'linux2':
+ return 8 # 64 bit
+ else:
+ return 4 # 32 bit
+ elif NumpyType == "L":
+ if sys.platform == 'linux2':
+ return 8 # 64 bit
+ else:
+ return 4 # 32 bit
+ elif NumpyType in ["f", numpy.float32]:
+ return 4
+ elif NumpyType in ["d", numpy.float64]:
+ return 8
+ elif NumpyType == "Q":
+ return 8 # unsigned 64 in 32 bit
+ elif NumpyType == "q":
+ return 8 # signed 64 in 32 bit
+ elif NumpyType == numpy.uint64:
+ return 8
+ elif NumpyType == numpy.int64:
+ return 8
+ else:
+ raise TypeError("unknown NumpyType %s" % NumpyType)
+
+ def __SetDataType__(self, Array, DataType):
+ """ Internal method: array type convertion
+ """
+ # AVOID problems not using FromEdfType= Array.dtype.char
+ FromEdfType = Array.dtype
+ ToEdfType = self.__GetDefaultNumpyType__(DataType)
+ if ToEdfType != FromEdfType:
+ aux = Array.astype(self.__GetDefaultNumpyType__(DataType))
+ return aux
+ return Array
+
+ def __del__(self):
+ try:
+ self.__makeSureFileIsClosed()
+ except:
+ pass
+
+ def GetDefaultNumpyType(self, EdfType, index=None):
+ """ Returns NumPy type according Edf type
+ """
+ if index is None:
+ return GetDefaultNumpyType(EdfType)
+ EdfType = EdfType.upper()
+ if EdfType in ['SIGNED64']:
+ return numpy.int64
+ if EdfType in ['UNSIGNED64']:
+ return numpy.uint64
+ if EdfType in ["SIGNEDLONG", "UNSIGNEDLONG"]:
+ dim1 = 1
+ dim2 = 1
+ dim3 = 1
+ if hasattr(self.Images[index], "Dim1"):
+ dim1 = self.Images[index].Dim1
+ if hasattr(self.Images[index], "Dim2"):
+ dim2 = self.Images[index].Dim2
+ if dim2 <= 0:
+ dim2 = 1
+ if hasattr(self.Images[index], "Dim3"):
+ dim3 = self.Images[index].Dim3
+ if dim3 <= 0:
+ dim3 = 1
+ if hasattr(self.Images[index], "Size"):
+ size = self.Images[index].Size
+ if size / (dim1 * dim2 * dim3) == 8:
+ if EdfType == "UNSIGNEDLONG":
+ return numpy.uint64
+ else:
+ return numpy.int64
+ if EdfType == "UNSIGNEDLONG":
+ return numpy.uint32
+ else:
+ return numpy.int32
+
+ return GetDefaultNumpyType(EdfType)
+
+
+def GetDefaultNumpyType(EdfType):
+ """ Returns NumPy type according Edf type
+ """
+ EdfType = EdfType.upper()
+ if EdfType == "SIGNEDBYTE":
+ return numpy.int8 # "b"
+ elif EdfType == "UNSIGNEDBYTE":
+ return numpy.uint8 # "B"
+ elif EdfType == "SIGNEDSHORT":
+ return numpy.int16 # "h"
+ elif EdfType == "UNSIGNEDSHORT":
+ return numpy.uint16 # "H"
+ elif EdfType == "SIGNEDINTEGER":
+ return numpy.int32 # "i"
+ elif EdfType == "UNSIGNEDINTEGER":
+ return numpy.uint32 # "I"
+ elif EdfType == "SIGNEDLONG":
+ return numpy.int32 # "i" #ESRF acquisition is made in 32bit
+ elif EdfType == "UNSIGNEDLONG":
+ return numpy.uint32 # "I" #ESRF acquisition is made in 32bit
+ elif EdfType == "SIGNED64":
+ return numpy.int64 # "l"
+ elif EdfType == "UNSIGNED64":
+ return numpy.uint64 # "L"
+ elif EdfType == "FLOATVALUE":
+ return numpy.float32 # "f"
+ elif EdfType == "FLOAT":
+ return numpy.float32 # "f"
+ elif EdfType == "DOUBLEVALUE":
+ return numpy.float64 # "d"
+ else:
+ raise TypeError("unknown EdfType %s" % EdfType)
+
+
+def SetDictCase(Dict, Case, Flag):
+ """ Returns dictionary with keys and/or values converted into upper or lowercase
+ Dict: input dictionary
+ Case: LOWER_CASE, UPPER_CASE
+ Flag: KEYS, VALUES or KEYS | VALUES
+ """
+ newdict = {}
+ for i in Dict.keys():
+ newkey = i
+ newvalue = Dict[i]
+ if Flag & KEYS:
+ if Case == LOWER_CASE:
+ newkey = newkey.lower()
+ else:
+ newkey = newkey.upper()
+ if Flag & VALUES:
+ if Case == LOWER_CASE:
+ newvalue = newvalue.lower()
+ else:
+ newvalue = newvalue.upper()
+ newdict[newkey] = newvalue
+ return newdict
+
+
+def GetRegion(Arr, Pos, Size):
+ """Returns array with refion of Arr.
+ Arr must be 1d, 2d or 3d
+ Pos and Size are tuples in the format (x) or (x,y) or (x,y,z)
+ Both parameters must have the same size as the dimention of Arr
+ """
+ Dim = len(Arr.shape)
+ if len(Pos) != Dim:
+ return None
+ if len(Size) != Dim:
+ return None
+
+ if (Dim == 1):
+ SizeX = Size[0]
+ if SizeX == 0:
+ SizeX = Arr.shape[0] - Pos[0]
+ ArrRet = numpy.take(Arr, range(Pos[0], Pos[0] + SizeX))
+ elif (Dim == 2):
+ SizeX = Size[0]
+ SizeY = Size[1]
+ if SizeX == 0:
+ SizeX = Arr.shape[1] - Pos[0]
+ if SizeY == 0:
+ SizeY = Arr.shape[0] - Pos[1]
+ ArrRet = numpy.take(Arr, range(Pos[1], Pos[1] + SizeY))
+ ArrRet = numpy.take(ArrRet, range(Pos[0], Pos[0] + SizeX), 1)
+ elif (Dim == 3):
+ SizeX = Size[0]
+ SizeY = Size[1]
+ SizeZ = Size[2]
+ if SizeX == 0:
+ SizeX = Arr.shape[2] - Pos[0]
+ if SizeY == 0:
+ SizeX = Arr.shape[1] - Pos[1]
+ if SizeZ == 0:
+ SizeZ = Arr.shape[0] - Pos[2]
+ ArrRet = numpy.take(Arr, range(Pos[2], Pos[2] + SizeZ))
+ ArrRet = numpy.take(ArrRet, range(Pos[1], Pos[1] + SizeY), 1)
+ ArrRet = numpy.take(ArrRet, range(Pos[0], Pos[0] + SizeX), 2)
+ else:
+ ArrRet = None
+ return ArrRet
+
+
+if __name__ == "__main__":
+ if 1:
+ a = numpy.zeros((5, 10))
+ for i in range(5):
+ for j in range(10):
+ a[i, j] = 10 * i + j
+ edf = EdfFile("armando.edf", access="ab+")
+ edf.WriteImage({}, a)
+ del edf # force to close the file
+ inp = EdfFile("armando.edf")
+ b = inp.GetData(0)
+ out = EdfFile("armando2.edf")
+ out.WriteImage({}, b)
+ del out # force to close the file
+ inp2 = EdfFile("armando2.edf")
+ c = inp2.GetData(0)
+ print("A SHAPE = ", a.shape)
+ print("B SHAPE = ", b.shape)
+ print("C SHAPE = ", c.shape)
+ for i in range(5):
+ print("A", a[i, :])
+ print("B", b[i, :])
+ print("C", c[i, :])
+
+ x = numpy.arange(100)
+ x.shape = 5, 20
+ for item in ["SignedByte", "UnsignedByte",
+ "SignedShort", "UnsignedShort",
+ "SignedLong", "UnsignedLong",
+ "Signed64", "Unsigned64",
+ "FloatValue", "DoubleValue"]:
+ fname = item + ".edf"
+ if os.path.exists(fname):
+ os.remove(fname)
+ towrite = EdfFile(fname)
+ towrite.WriteImage({}, x, DataType=item, Append=0)
+ sys.exit(0)
+
+ # Creates object based on file exe.edf
+ exe = EdfFile("images/test_image.edf")
+ x = EdfFile("images/test_getdata.edf")
+ # Gets unsigned short data, storing in an signed long
+ arr = exe.GetData(0, Pos=(100, 200), Size=(200, 400))
+ x.WriteImage({}, arr, 0)
+
+ arr = exe.GetData(0, Pos=(100, 200))
+ x.WriteImage({}, arr)
+
+ arr = exe.GetData(0, Size=(200, 400))
+ x.WriteImage({}, arr)
+
+ arr = exe.GetData(0)
+ x.WriteImage({}, arr)
+
+ sys.exit()
+
+ # Creates object based on file exe.edf
+ exe = EdfFile("images/.edf")
+
+ # Creates long array , filled with 0xFFFFFFFF(-1)
+ la = numpy.zeros((100, 100))
+ la = la - 1
+
+ # Creates a short array, filled with 0xFFFF
+ sa = numpy.zeros((100, 100))
+ sa = sa + 0xFFFF
+ sa = sa.astype("s")
+
+ # Writes long array, initializing file (append=0)
+ exe.WriteImage({}, la, 0, "")
+
+ # Appends short array with new header items
+ exe.WriteImage({'Name': 'Alexandre', 'Date': '16/07/2001'}, sa)
+
+ # Appends short array, in Edf type unsigned
+ exe.WriteImage({}, sa, DataType="UnsignedShort")
+
+ # Appends short array, in Edf type unsigned
+ exe.WriteImage({}, sa, DataType="UnsignedLong")
+
+ # Appends long array as a double, considering unsigned
+ exe.WriteImage({}, la, DataType="DoubleValue", WriteAsUnsigened=1)
+
+ # Gets unsigned short data, storing in an signed long
+ ushort = exe.GetData(2, "SignedLong")
+
+ # Makes an operation
+ ushort = ushort - 0x10
+
+ # Saves Result as signed long
+ exe.WriteImage({}, ushort)
+
+ # Saves in the original format (unsigned short)
+ OldHeader = exe.GetStaticHeader(2)
+ exe.WriteImage({}, ushort, 1, OldHeader["DataType"])
diff --git a/silx/third_party/TiffIO.py b/silx/third_party/TiffIO.py
new file mode 100644
index 0000000..156ae11
--- /dev/null
+++ b/silx/third_party/TiffIO.py
@@ -0,0 +1,1268 @@
+# /*##########################################################################
+#
+# The PyMca X-Ray Fluorescence Toolkit
+#
+# Copyright (c) 2004-2015 European Synchrotron Radiation Facility
+#
+# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
+# the ESRF by the Software group.
+#
+# 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.
+#
+# ############################################################################*/
+__author__ = "V.A. Sole - ESRF Data Analysis"
+__contact__ = "sole@esrf.fr"
+__license__ = "MIT"
+__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
+
+import sys
+import os
+import struct
+import numpy
+
+DEBUG = 0
+ALLOW_MULTIPLE_STRIPS = False
+
+TAG_ID = { 256:"NumberOfColumns", # S or L ImageWidth
+ 257:"NumberOfRows", # S or L ImageHeight
+ 258:"BitsPerSample", # S Number of bits per component
+ 259:"Compression", # SHORT (1 - NoCompression, ...
+ 262:"PhotometricInterpretation", # SHORT (0 - WhiteIsZero, 1 -BlackIsZero, 2 - RGB, 3 - Palette color
+ 270:"ImageDescription", # ASCII
+ 273:"StripOffsets", # S or L, for each strip, the byte offset of the strip
+ 277:"SamplesPerPixel", # SHORT (>=3) only for RGB images
+ 278:"RowsPerStrip", # S or L, number of rows in each back may be not for the last
+ 279:"StripByteCounts", # S or L, The number of bytes in the strip AFTER any compression
+ 305:"Software", # ASCII
+ 306:"Date", # ASCII
+ 320:"Colormap", # Colormap of Palette-color Images
+ 339:"SampleFormat", # SHORT Interpretation of data in each pixel
+ }
+
+#TILES ARE TO BE SUPPORTED TOO ...
+TAG_NUMBER_OF_COLUMNS = 256
+TAG_NUMBER_OF_ROWS = 257
+TAG_BITS_PER_SAMPLE = 258
+TAG_PHOTOMETRIC_INTERPRETATION = 262
+TAG_COMPRESSION = 259
+TAG_IMAGE_DESCRIPTION = 270
+TAG_STRIP_OFFSETS = 273
+TAG_SAMPLES_PER_PIXEL = 277
+TAG_ROWS_PER_STRIP = 278
+TAG_STRIP_BYTE_COUNTS = 279
+TAG_SOFTWARE = 305
+TAG_DATE = 306
+TAG_COLORMAP = 320
+TAG_SAMPLE_FORMAT = 339
+
+FIELD_TYPE = {1:('BYTE', "B"),
+ 2:('ASCII', "s"), #string ending with binary zero
+ 3:('SHORT', "H"),
+ 4:('LONG', "I"),
+ 5:('RATIONAL',"II"),
+ 6:('SBYTE', "b"),
+ 7:('UNDEFINED',"B"),
+ 8:('SSHORT', "h"),
+ 9:('SLONG', "i"),
+ 10:('SRATIONAL',"ii"),
+ 11:('FLOAT', "f"),
+ 12:('DOUBLE', "d")}
+
+FIELD_TYPE_OUT = { 'B': 1,
+ 's': 2,
+ 'H': 3,
+ 'I': 4,
+ 'II': 5,
+ 'b': 6,
+ 'h': 8,
+ 'i': 9,
+ 'ii': 10,
+ 'f': 11,
+ 'd': 12}
+
+#sample formats (http://www.awaresystems.be/imaging/tiff/tiffflags/sampleformat.html)
+SAMPLE_FORMAT_UINT = 1
+SAMPLE_FORMAT_INT = 2
+SAMPLE_FORMAT_FLOAT = 3 #floating point
+SAMPLE_FORMAT_VOID = 4 #undefined data, usually assumed UINT
+SAMPLE_FORMAT_COMPLEXINT = 5
+SAMPLE_FORMAT_COMPLEXIEEEFP = 6
+
+
+
+class TiffIO(object):
+ def __init__(self, filename, mode=None, cache_length=20, mono_output=False):
+ if mode is None:
+ mode = 'rb'
+ if 'b' not in mode:
+ mode = mode + 'b'
+ if 'a' in mode.lower():
+ raise IOError("Mode %s makes no sense on TIFF files. Consider 'rb+'" % mode)
+ if ('w' in mode):
+ if '+' not in mode:
+ mode += '+'
+
+ if hasattr(filename, "seek") and\
+ hasattr(filename, "read"):
+ fd = filename
+ self._access = None
+ else:
+ #the b is needed for windows and python 3
+ fd = open(filename, mode)
+ self._access = mode
+
+ self._initInternalVariables(fd)
+ self._maxImageCacheLength = cache_length
+ self._forceMonoOutput = mono_output
+
+ def _initInternalVariables(self, fd=None):
+ if fd is None:
+ fd = self.fd
+ else:
+ self.fd = fd
+ # read the order
+ fd.seek(0)
+ order = fd.read(2).decode()
+ if len(order):
+ if order == "II":
+ #intel, little endian
+ fileOrder = "little"
+ self._structChar = '<'
+ elif order == "MM":
+ #motorola, high endian
+ fileOrder = "big"
+ self._structChar = '>'
+ else:
+ raise IOError("File is not a Mar CCD file, nor a TIFF file")
+ a = fd.read(2)
+ fortyTwo = struct.unpack(self._structChar+"H",a)[0]
+ if fortyTwo != 42:
+ raise IOError("Invalid TIFF version %d" % fortyTwo)
+ else:
+ if DEBUG:
+ print("VALID TIFF VERSION")
+ if sys.byteorder != fileOrder:
+ swap = True
+ else:
+ swap = False
+ else:
+ if sys.byteorder == "little":
+ self._structChar = '<'
+ else:
+ self._structChar = '>'
+ swap = False
+ self._swap = swap
+ self._IFD = []
+ self._imageDataCacheIndex = []
+ self._imageDataCache = []
+ self._imageInfoCacheIndex = []
+ self._imageInfoCache = []
+ self.getImageFileDirectories(fd)
+
+ def __makeSureFileIsOpen(self):
+ if not self.fd.closed:
+ return
+ if DEBUG:
+ print("Reopening closed file")
+ fileName = self.fd.name
+ if self._access is None:
+ #we do not own the file
+ #open in read mode
+ newFile = open(fileName,'rb')
+ else:
+ newFile = open(fileName, self._access)
+ self.fd = newFile
+
+ def __makeSureFileIsClosed(self):
+ if self._access is None:
+ #we do not own the file
+ if DEBUG:
+ print("Not closing not owned file")
+ return
+
+ if not self.fd.closed:
+ self.fd.close()
+
+ def close(self):
+ return self.__makeSureFileIsClosed()
+
+ def getNumberOfImages(self):
+ #update for the case someone has done anything?
+ self._updateIFD()
+ return len(self._IFD)
+
+ def _updateIFD(self):
+ self.__makeSureFileIsOpen()
+ self.getImageFileDirectories()
+ self.__makeSureFileIsClosed()
+
+ def getImageFileDirectories(self, fd=None):
+ if fd is None:
+ fd = self.fd
+ else:
+ self.fd = fd
+ st = self._structChar
+ fd.seek(4)
+ self._IFD = []
+ nImages = 0
+ fmt = st + 'I'
+ inStr = fd.read(struct.calcsize(fmt))
+ if not len(inStr):
+ offsetToIFD = 0
+ else:
+ offsetToIFD = struct.unpack(fmt, inStr)[0]
+ if DEBUG:
+ print("Offset to first IFD = %d" % offsetToIFD)
+ while offsetToIFD != 0:
+ self._IFD.append(offsetToIFD)
+ nImages += 1
+ fd.seek(offsetToIFD)
+ fmt = st + 'H'
+ numberOfDirectoryEntries = struct.unpack(fmt,fd.read(struct.calcsize(fmt)))[0]
+ if DEBUG:
+ print("Number of directory entries = %d" % numberOfDirectoryEntries)
+
+ fmt = st + 'I'
+ fd.seek(offsetToIFD + 2 + 12 * numberOfDirectoryEntries)
+ offsetToIFD = struct.unpack(fmt,fd.read(struct.calcsize(fmt)))[0]
+ if DEBUG:
+ print("Next Offset to IFD = %d" % offsetToIFD)
+ #offsetToIFD = 0
+ if DEBUG:
+ print("Number of images found = %d" % nImages)
+ return nImages
+
+ def _parseImageFileDirectory(self, nImage):
+ offsetToIFD = self._IFD[nImage]
+ st = self._structChar
+ fd = self.fd
+ fd.seek(offsetToIFD)
+ fmt = st + 'H'
+ numberOfDirectoryEntries = struct.unpack(fmt,fd.read(struct.calcsize(fmt)))[0]
+ if DEBUG:
+ print("Number of directory entries = %d" % numberOfDirectoryEntries)
+
+ fmt = st + 'HHI4s'
+ tagIDList = []
+ fieldTypeList = []
+ nValuesList = []
+ valueOffsetList = []
+ for i in range(numberOfDirectoryEntries):
+ tagID, fieldType, nValues, valueOffset = struct.unpack(fmt, fd.read(12))
+ tagIDList.append(tagID)
+ fieldTypeList.append(fieldType)
+ nValuesList.append(nValues)
+ if nValues == 1:
+ ftype, vfmt = FIELD_TYPE[fieldType]
+ if ftype not in ['ASCII', 'RATIONAL', 'SRATIONAL']:
+ vfmt = st + vfmt
+ actualValue = struct.unpack(vfmt, valueOffset[0: struct.calcsize(vfmt)])[0]
+ valueOffsetList.append(actualValue)
+ else:
+ valueOffsetList.append(valueOffset)
+ elif (nValues < 5) and (fieldType == 2):
+ ftype, vfmt = FIELD_TYPE[fieldType]
+ vfmt = st + "%d%s" % (nValues,vfmt)
+ actualValue = struct.unpack(vfmt, valueOffset[0: struct.calcsize(vfmt)])[0]
+ valueOffsetList.append(actualValue)
+ else:
+ valueOffsetList.append(valueOffset)
+ if DEBUG:
+ if tagID in TAG_ID:
+ print("tagID = %s" % TAG_ID[tagID])
+ else:
+ print("tagID = %d" % tagID)
+ print("fieldType = %s" % FIELD_TYPE[fieldType][0])
+ print("nValues = %d" % nValues)
+ #if nValues == 1:
+ # print("valueOffset = %s" % valueOffset)
+ return tagIDList, fieldTypeList, nValuesList, valueOffsetList
+
+
+
+ def _readIFDEntry(self, tag, tagIDList, fieldTypeList, nValuesList, valueOffsetList):
+ fd = self.fd
+ st = self._structChar
+ idx = tagIDList.index(tag)
+ nValues = nValuesList[idx]
+ output = []
+ ftype, vfmt = FIELD_TYPE[fieldTypeList[idx]]
+ vfmt = st + "%d%s" % (nValues, vfmt)
+ requestedBytes = struct.calcsize(vfmt)
+ if nValues == 1:
+ output.append(valueOffsetList[idx])
+ elif requestedBytes < 5:
+ output.append(valueOffsetList[idx])
+ else:
+ fd.seek(struct.unpack(st+"I", valueOffsetList[idx])[0])
+ output = struct.unpack(vfmt, fd.read(requestedBytes))
+ return output
+
+ def getData(self, nImage, **kw):
+ if nImage >= len(self._IFD):
+ #update prior to raise an index error error
+ self._updateIFD()
+ return self._readImage(nImage, **kw)
+
+ def getImage(self, nImage):
+ return self.getData(nImage)
+
+ def getInfo(self, nImage, **kw):
+ if nImage >= len(self._IFD):
+ #update prior to raise an index error error
+ self._updateIFD()
+ # current = self._IFD[nImage]
+ return self._readInfo(nImage)
+
+ def _readInfo(self, nImage, close=True):
+ if nImage in self._imageInfoCacheIndex:
+ if DEBUG:
+ print("Reading info from cache")
+ return self._imageInfoCache[self._imageInfoCacheIndex.index(nImage)]
+
+ #read the header
+ self.__makeSureFileIsOpen()
+ tagIDList, fieldTypeList, nValuesList, valueOffsetList = self._parseImageFileDirectory(nImage)
+
+ #rows and columns
+ nColumns = valueOffsetList[tagIDList.index(TAG_NUMBER_OF_COLUMNS)]
+ nRows = valueOffsetList[tagIDList.index(TAG_NUMBER_OF_ROWS)]
+
+ #bits per sample
+ idx = tagIDList.index(TAG_BITS_PER_SAMPLE)
+ nBits = valueOffsetList[idx]
+ if nValuesList[idx] != 1:
+ #this happens with RGB and friends, nBits is not a single value
+ nBits = self._readIFDEntry(TAG_BITS_PER_SAMPLE,
+ tagIDList, fieldTypeList, nValuesList, valueOffsetList)
+
+
+ if TAG_COLORMAP in tagIDList:
+ idx = tagIDList.index(TAG_COLORMAP)
+ tmpColormap = self._readIFDEntry(TAG_COLORMAP,
+ tagIDList, fieldTypeList, nValuesList, valueOffsetList)
+ if max(tmpColormap) > 255:
+ tmpColormap = numpy.array(tmpColormap, dtype=numpy.uint16)
+ tmpColormap = (tmpColormap/256.).astype(numpy.uint8)
+ else:
+ tmpColormap = numpy.array(tmpColormap, dtype=numpy.uint8)
+ tmpColormap.shape = 3, -1
+ colormap = numpy.zeros((tmpColormap.shape[-1], 3), tmpColormap.dtype)
+ colormap[:,:] = tmpColormap.T
+ tmpColormap = None
+ else:
+ colormap = None
+
+ #sample format
+ if TAG_SAMPLE_FORMAT in tagIDList:
+ sampleFormat = valueOffsetList[tagIDList.index(TAG_SAMPLE_FORMAT)]
+ else:
+ #set to unknown
+ sampleFormat = SAMPLE_FORMAT_VOID
+
+ # compression
+ compression = False
+ compression_type = 1
+ if TAG_COMPRESSION in tagIDList:
+ compression_type = valueOffsetList[tagIDList.index(TAG_COMPRESSION)]
+ if compression_type == 1:
+ compression = False
+ else:
+ compression = True
+
+ #photometric interpretation
+ interpretation = 1
+ if TAG_PHOTOMETRIC_INTERPRETATION in tagIDList:
+ interpretation = valueOffsetList[tagIDList.index(TAG_PHOTOMETRIC_INTERPRETATION)]
+ else:
+ print("WARNING: Non standard TIFF. Photometric interpretation TAG missing")
+ helpString = ""
+ if sys.version > '2.6':
+ helpString = eval('b""')
+
+ if TAG_IMAGE_DESCRIPTION in tagIDList:
+ imageDescription = self._readIFDEntry(TAG_IMAGE_DESCRIPTION,
+ tagIDList, fieldTypeList, nValuesList, valueOffsetList)
+ if type(imageDescription) in [type([1]), type((1,))]:
+ imageDescription =helpString.join(imageDescription)
+ else:
+ imageDescription = "%d/%d" % (nImage+1, len(self._IFD))
+
+ if sys.version < '3.0':
+ defaultSoftware = "Unknown Software"
+ else:
+ defaultSoftware = bytes("Unknown Software",
+ encoding='utf-8')
+ if TAG_SOFTWARE in tagIDList:
+ software = self._readIFDEntry(TAG_SOFTWARE,
+ tagIDList, fieldTypeList, nValuesList, valueOffsetList)
+ if type(software) in [type([1]), type((1,))]:
+ software =helpString.join(software)
+ else:
+ software = defaultSoftware
+
+ if software == defaultSoftware:
+ try:
+ if sys.version < '3.0':
+ if imageDescription.upper().startswith("IMAGEJ"):
+ software = imageDescription.split("=")[0]
+ else:
+ tmpString = imageDescription.decode()
+ if tmpString.upper().startswith("IMAGEJ"):
+ software = bytes(tmpString.split("=")[0],
+ encoding='utf-8')
+ except:
+ pass
+
+ if TAG_DATE in tagIDList:
+ date = self._readIFDEntry(TAG_DATE,
+ tagIDList, fieldTypeList, nValuesList, valueOffsetList)
+ if type(date) in [type([1]), type((1,))]:
+ date =helpString.join(date)
+ else:
+ date = "Unknown Date"
+
+ stripOffsets = self._readIFDEntry(TAG_STRIP_OFFSETS,
+ tagIDList, fieldTypeList, nValuesList, valueOffsetList)
+ if TAG_ROWS_PER_STRIP in tagIDList:
+ rowsPerStrip = self._readIFDEntry(TAG_ROWS_PER_STRIP,
+ tagIDList, fieldTypeList, nValuesList, valueOffsetList)[0]
+ else:
+ rowsPerStrip = nRows
+ print("WARNING: Non standard TIFF. Rows per strip TAG missing")
+
+ if TAG_STRIP_BYTE_COUNTS in tagIDList:
+ stripByteCounts = self._readIFDEntry(TAG_STRIP_BYTE_COUNTS,
+ tagIDList, fieldTypeList, nValuesList, valueOffsetList)
+ else:
+ print("WARNING: Non standard TIFF. Strip byte counts TAG missing")
+ if hasattr(nBits, 'index'):
+ expectedSum = 0
+ for n in nBits:
+ expectedSum += int(nRows * nColumns * n / 8)
+ else:
+ expectedSum = int(nRows * nColumns * nBits / 8)
+ stripByteCounts = [expectedSum]
+
+ if close:
+ self.__makeSureFileIsClosed()
+
+ if self._forceMonoOutput and (interpretation > 1):
+ #color image but asked monochrome output
+ nBits = 32
+ colormap = None
+ sampleFormat = SAMPLE_FORMAT_FLOAT
+ interpretation = 1
+ #we cannot rely on any cache in this case
+ useInfoCache = False
+ if DEBUG:
+ print("FORCED MONO")
+ else:
+ useInfoCache = True
+
+ info = {}
+ info["nRows"] = nRows
+ info["nColumns"] = nColumns
+ info["nBits"] = nBits
+ info["compression"] = compression
+ info["compression_type"] = compression_type
+ info["imageDescription"] = imageDescription
+ info["stripOffsets"] = stripOffsets #This contains the file offsets to the data positions
+ info["rowsPerStrip"] = rowsPerStrip
+ info["stripByteCounts"] = stripByteCounts #bytes in strip since I do not support compression
+ info["software"] = software
+ info["date"] = date
+ info["colormap"] = colormap
+ info["sampleFormat"] = sampleFormat
+ info["photometricInterpretation"] = interpretation
+ infoDict = {}
+ if sys.version < '3.0':
+ testString = 'PyMca'
+ else:
+ testString = eval('b"PyMca"')
+ if software.startswith(testString):
+ #str to make sure python 2.x sees it as string and not unicode
+ if sys.version < '3.0':
+ descriptionString = imageDescription
+ else:
+ descriptionString = str(imageDescription.decode())
+ #interpret the image description in terms of supplied
+ #information at writing time
+ items = descriptionString.split('=')
+ for i in range(int(len(items)/2)):
+ key = "%s" % items[i*2]
+ #get rid of the \n at the end of the value
+ value = "%s" % items[i*2+1][:-1]
+ infoDict[key] = value
+ info['info'] = infoDict
+
+ if (self._maxImageCacheLength > 0) and useInfoCache:
+ self._imageInfoCacheIndex.insert(0,nImage)
+ self._imageInfoCache.insert(0, info)
+ if len(self._imageInfoCacheIndex) > self._maxImageCacheLength:
+ self._imageInfoCacheIndex = self._imageInfoCacheIndex[:self._maxImageCacheLength]
+ self._imageInfoCache = self._imageInfoCache[:self._maxImageCacheLength]
+ return info
+
+ def _readImage(self, nImage, **kw):
+ if DEBUG:
+ print("Reading image %d" % nImage)
+ if 'close' in kw:
+ close = kw['close']
+ else:
+ close = True
+ rowMin = kw.get('rowMin', None)
+ rowMax = kw.get('rowMax', None)
+ if nImage in self._imageDataCacheIndex:
+ if DEBUG:
+ print("Reading image data from cache")
+ return self._imageDataCache[self._imageDataCacheIndex.index(nImage)]
+
+ self.__makeSureFileIsOpen()
+ if self._forceMonoOutput:
+ oldMono = True
+ else:
+ oldMono = False
+ try:
+ self._forceMonoOutput = False
+ info = self._readInfo(nImage, close=False)
+ self._forceMonoOutput = oldMono
+ except:
+ self._forceMonoOutput = oldMono
+ raise
+ compression = info['compression']
+ compression_type = info['compression_type']
+ if compression:
+ if compression_type != 32773:
+ raise IOError("Compressed TIFF images not supported except packbits")
+ else:
+ #PackBits compression
+ if DEBUG:
+ print("Using PackBits compression")
+
+ interpretation = info["photometricInterpretation"]
+ if interpretation == 2:
+ #RGB
+ pass
+ #raise IOError("RGB Image. Only grayscale images supported")
+ elif interpretation == 3:
+ #Palette Color Image
+ pass
+ #raise IOError("Palette-color Image. Only grayscale images supported")
+ elif interpretation > 2:
+ #Palette Color Image
+ raise IOError("Only grayscale images supported")
+
+ nRows = info["nRows"]
+ nColumns = info["nColumns"]
+ nBits = info["nBits"]
+ colormap = info["colormap"]
+ sampleFormat = info["sampleFormat"]
+
+ if rowMin is None:
+ rowMin = 0
+
+ if rowMax is None:
+ rowMax = nRows - 1
+
+ if rowMin < 0:
+ rowMin = nRows - rowMin
+
+ if rowMax < 0:
+ rowMax = nRows - rowMax
+
+ if rowMax < rowMin:
+ txt = "Max Row smaller than Min Row. Reverse selection not supported"
+ raise NotImplementedError(txt)
+
+ if rowMin >= nRows:
+ raise IndexError("Image only has %d rows" % nRows)
+
+ if rowMax >= nRows:
+ raise IndexError("Image only has %d rows" % nRows)
+
+ if sampleFormat == SAMPLE_FORMAT_FLOAT:
+ if nBits == 32:
+ dtype = numpy.float32
+ elif nBits == 64:
+ dtype = numpy.float64
+ else:
+ raise ValueError("Unsupported number of bits for a float: %d" % nBits)
+ elif sampleFormat in [SAMPLE_FORMAT_UINT, SAMPLE_FORMAT_VOID]:
+ if nBits in [8, (8, 8, 8), [8, 8, 8]]:
+ dtype = numpy.uint8
+ elif nBits in [16, (16, 16, 16), [16, 16, 16]]:
+ dtype = numpy.uint16
+ elif nBits in [32, (32, 32, 32), [32, 32, 32]]:
+ dtype = numpy.uint32
+ elif nBits in [64, (64, 64, 64), [64, 64, 64]]:
+ dtype = numpy.uint64
+ else:
+ raise ValueError("Unsupported number of bits for unsigned int: %s" % (nBits,))
+ elif sampleFormat == SAMPLE_FORMAT_INT:
+ if nBits in [8, (8, 8, 8), [8, 8, 8]]:
+ dtype = numpy.int8
+ elif nBits in [16, (16, 16, 16), [16, 16, 16]]:
+ dtype = numpy.int16
+ elif nBits in [32, (32, 32, 32), [32, 32, 32]]:
+ dtype = numpy.int32
+ elif nBits in [64, (64, 64, 64), [64, 64, 64]]:
+ dtype = numpy.int64
+ else:
+ raise ValueError("Unsupported number of bits for signed int: %s" % (nBits,))
+ else:
+ raise ValueError("Unsupported combination. Bits = %s Format = %d" % (nBits, sampleFormat))
+ if hasattr(nBits, 'index'):
+ image = numpy.zeros((nRows, nColumns, len(nBits)), dtype=dtype)
+ elif colormap is not None:
+ #should I use colormap dtype?
+ image = numpy.zeros((nRows, nColumns, 3), dtype=dtype)
+ else:
+ image = numpy.zeros((nRows, nColumns), dtype=dtype)
+
+ fd = self.fd
+ st = self._structChar
+ stripOffsets = info["stripOffsets"] #This contains the file offsets to the data positions
+ rowsPerStrip = info["rowsPerStrip"]
+ stripByteCounts = info["stripByteCounts"] #bytes in strip since I do not support compression
+
+ rowStart = 0
+ if len(stripOffsets) == 1:
+ bytesPerRow = int(stripByteCounts[0]/rowsPerStrip)
+ if nRows == rowsPerStrip:
+ actualBytesPerRow = int(image.nbytes/nRows)
+ if actualBytesPerRow != bytesPerRow:
+ print("Warning: Bogus StripByteCounts information")
+ bytesPerRow = actualBytesPerRow
+ fd.seek(stripOffsets[0] + rowMin * bytesPerRow)
+ nBytes = (rowMax-rowMin+1) * bytesPerRow
+ if self._swap:
+ readout = numpy.fromstring(fd.read(nBytes), dtype).byteswap()
+ else:
+ readout = numpy.fromstring(fd.read(nBytes), dtype)
+ if hasattr(nBits, 'index'):
+ readout.shape = -1, nColumns, len(nBits)
+ elif info['colormap'] is not None:
+ readout = colormap[readout]
+ else:
+ readout.shape = -1, nColumns
+ image[rowMin:rowMax+1, :] = readout
+ else:
+ for i in range(len(stripOffsets)):
+ #the amount of rows
+ nRowsToRead = rowsPerStrip
+ rowEnd = int(min(rowStart+nRowsToRead, nRows))
+ if rowEnd < rowMin:
+ rowStart += nRowsToRead
+ continue
+ if (rowStart > rowMax):
+ break
+ #we are in position
+ fd.seek(stripOffsets[i])
+ #the amount of bytes to read
+ nBytes = stripByteCounts[i]
+ if compression_type == 32773:
+ try:
+ bufferBytes = bytes()
+ except:
+ #python 2.5 ...
+ bufferBytes = ""
+ #packBits
+ readBytes = 0
+ #intermediate buffer
+ tmpBuffer = fd.read(nBytes)
+ while readBytes < nBytes:
+ n = struct.unpack('b', tmpBuffer[readBytes:(readBytes+1)])[0]
+ readBytes += 1
+ if n >= 0:
+ #should I prevent reading more than the
+ #length of the chain? Let's python raise
+ #the exception...
+ bufferBytes += tmpBuffer[readBytes:\
+ readBytes+(n+1)]
+ readBytes += (n+1)
+ elif n > -128:
+ bufferBytes += (-n+1) * tmpBuffer[readBytes:(readBytes+1)]
+ readBytes += 1
+ else:
+ #if read -128 ignore the byte
+ continue
+ if self._swap:
+ readout = numpy.fromstring(bufferBytes, dtype).byteswap()
+ else:
+ readout = numpy.fromstring(bufferBytes, dtype)
+ if hasattr(nBits, 'index'):
+ readout.shape = -1, nColumns, len(nBits)
+ elif info['colormap'] is not None:
+ readout = colormap[readout]
+ readout.shape = -1, nColumns, 3
+ else:
+ readout.shape = -1, nColumns
+ image[rowStart:rowEnd, :] = readout
+ else:
+ if 1:
+ #use numpy
+ if self._swap:
+ readout = numpy.fromstring(fd.read(nBytes), dtype).byteswap()
+ else:
+ readout = numpy.fromstring(fd.read(nBytes), dtype)
+ if hasattr(nBits, 'index'):
+ readout.shape = -1, nColumns, len(nBits)
+ elif colormap is not None:
+ readout = colormap[readout]
+ readout.shape = -1, nColumns, 3
+ else:
+ readout.shape = -1, nColumns
+ image[rowStart:rowEnd, :] = readout
+ else:
+ #using struct
+ readout = numpy.array(struct.unpack(st+"%df" % int(nBytes/4), fd.read(nBytes)),
+ dtype=dtype)
+ if hasattr(nBits, 'index'):
+ readout.shape = -1, nColumns, len(nBits)
+ elif colormap is not None:
+ readout = colormap[readout]
+ readout.shape = -1, nColumns, 3
+ else:
+ readout.shape = -1, nColumns
+ image[rowStart:rowEnd, :] = readout
+ rowStart += nRowsToRead
+ if close:
+ self.__makeSureFileIsClosed()
+
+ if len(image.shape) == 3:
+ #color image
+ if self._forceMonoOutput:
+ #color image, convert to monochrome
+ image = (image[:,:,0] * 0.114 +\
+ image[:,:,1] * 0.587 +\
+ image[:,:,2] * 0.299).astype(numpy.float32)
+
+ if (rowMin == 0) and (rowMax == (nRows-1)):
+ self._imageDataCacheIndex.insert(0,nImage)
+ self._imageDataCache.insert(0, image)
+ if len(self._imageDataCacheIndex) > self._maxImageCacheLength:
+ self._imageDataCacheIndex = self._imageDataCacheIndex[:self._maxImageCacheLength]
+ self._imageDataCache = self._imageDataCache[:self._maxImageCacheLength]
+
+ return image
+
+ def writeImage(self, image0, info=None, software=None, date=None):
+ if software is None:
+ software = 'PyMca.TiffIO'
+ #if date is None:
+ # date = time.ctime()
+
+ self.__makeSureFileIsOpen()
+ fd = self.fd
+ #prior to do anything, perform some tests
+ if not len(image0.shape):
+ raise ValueError("Empty image")
+ if len(image0.shape) == 1:
+ #get a different view
+ image = image0[:]
+ image.shape = 1, -1
+ else:
+ image = image0
+
+ if image.dtype == numpy.float64:
+ image = image.astype(numpy.float32)
+ fd.seek(0)
+ mode = fd.mode
+ name = fd.name
+ if 'w' in mode:
+ #we have to overwrite the file
+ self.__makeSureFileIsClosed()
+ fd = None
+ if os.path.exists(name):
+ os.remove(name)
+ fd = open(name, mode='wb+')
+ self._initEmptyFile(fd)
+ self.fd = fd
+
+ #read the file size
+ self.__makeSureFileIsOpen()
+ fd = self.fd
+ fd.seek(0, os.SEEK_END)
+ endOfFile = fd.tell()
+ if fd.tell() == 0:
+ self._initEmptyFile(fd)
+ fd.seek(0, os.SEEK_END)
+ endOfFile = fd.tell()
+
+ #init internal variables
+ self._initInternalVariables(fd)
+ st = self._structChar
+
+ #get the image file directories
+ nImages = self.getImageFileDirectories()
+ if DEBUG:
+ print("File contains %d images" % nImages)
+ if nImages == 0:
+ fd.seek(4)
+ fmt = st + 'I'
+ fd.write(struct.pack(fmt, endOfFile))
+ else:
+ fd.seek(self._IFD[-1])
+ fmt = st + 'H'
+ numberOfDirectoryEntries = struct.unpack(fmt,fd.read(struct.calcsize(fmt)))[0]
+ fmt = st + 'I'
+ pos = self._IFD[-1] + 2 + 12 * numberOfDirectoryEntries
+ fd.seek(pos)
+ fmt = st + 'I'
+ fd.write(struct.pack(fmt, endOfFile))
+ fd.flush()
+
+ #and we can write at the end of the file, find out the file length
+ fd.seek(0, os.SEEK_END)
+
+ #get the description information from the input information
+ if info is None:
+ description = info
+ else:
+ description = "%s" % ""
+ for key in info.keys():
+ description += "%s=%s\n" % (key, info[key])
+
+ #get the image file directory
+ outputIFD = self._getOutputIFD(image, description=description,
+ software=software,
+ date=date)
+
+ #write the new IFD
+ fd.write(outputIFD)
+
+ #write the image
+ if self._swap:
+ fd.write(image.byteswap().tostring())
+ else:
+ fd.write(image.tostring())
+
+ fd.flush()
+ self.fd=fd
+ self.__makeSureFileIsClosed()
+
+ def _initEmptyFile(self, fd=None):
+ if fd is None:
+ fd = self.fd
+ if sys.byteorder == "little":
+ order = "II"
+ #intel, little endian
+ fileOrder = "little"
+ self._structChar = '<'
+ else:
+ order = "MM"
+ #motorola, high endian
+ fileOrder = "big"
+ self._structChar = '>'
+ st = self._structChar
+ if fileOrder == sys.byteorder:
+ self._swap = False
+ else:
+ self._swap = True
+ fd.seek(0)
+ if sys.version < '3.0':
+ fd.write(struct.pack(st+'2s', order))
+ fd.write(struct.pack(st+'H', 42))
+ fd.write(struct.pack(st+'I', 0))
+ else:
+ fd.write(struct.pack(st+'2s', bytes(order,'utf-8')))
+ fd.write(struct.pack(st+'H', 42))
+ fd.write(struct.pack(st+'I', 0))
+ fd.flush()
+
+ def _getOutputIFD(self, image, description=None, software=None, date=None):
+ #the tags have to be in order
+ #the very minimum is
+ #256:"NumberOfColumns", # S or L ImageWidth
+ #257:"NumberOfRows", # S or L ImageHeight
+ #258:"BitsPerSample", # S Number of bits per component
+ #259:"Compression", # SHORT (1 - NoCompression, ...
+ #262:"PhotometricInterpretation", # SHORT (0 - WhiteIsZero, 1 -BlackIsZero, 2 - RGB, 3 - Palette color
+ #270:"ImageDescription", # ASCII
+ #273:"StripOffsets", # S or L, for each strip, the byte offset of the strip
+ #277:"SamplesPerPixel", # SHORT (>=3) only for RGB images
+ #278:"RowsPerStrip", # S or L, number of rows in each back may be not for the last
+ #279:"StripByteCounts", # S or L, The number of bytes in the strip AFTER any compression
+ #305:"Software", # ASCII
+ #306:"Date", # ASCII
+ #339:"SampleFormat", # SHORT Interpretation of data in each pixel
+
+ nDirectoryEntries = 9
+ imageDescription = None
+ if description is not None:
+ descriptionLength = len(description)
+ while descriptionLength < 4:
+ description = description + " "
+ descriptionLength = len(description)
+ if sys.version >= '3.0':
+ description = bytes(description, 'utf-8')
+ elif type(description) != type(""):
+ try:
+ description = description.decode('utf-8')
+ except UnicodeDecodeError:
+ try:
+ description = description.decode('latin-1')
+ except UnicodeDecodeError:
+ description = "%s" % description
+ if sys.version > '2.6':
+ description=description.encode('utf-8', errors="ignore")
+ description = "%s" % description
+ descriptionLength = len(description)
+ imageDescription = struct.pack("%ds" % descriptionLength, description)
+ nDirectoryEntries += 1
+
+ #software
+ if software is not None:
+ softwareLength = len(software)
+ while softwareLength < 4:
+ software = software + " "
+ softwareLength = len(software)
+ if sys.version >= '3.0':
+ software = bytes(software, 'utf-8')
+ softwarePackedString = struct.pack("%ds" % softwareLength, software)
+ nDirectoryEntries += 1
+ else:
+ softwareLength = 0
+
+ if date is not None:
+ dateLength = len(date)
+ if sys.version >= '3.0':
+ date = bytes(date, 'utf-8')
+ datePackedString = struct.pack("%ds" % dateLength, date)
+ dateLength = len(datePackedString)
+ nDirectoryEntries += 1
+ else:
+ dateLength = 0
+
+ if len(image.shape) == 2:
+ nRows, nColumns = image.shape
+ nChannels = 1
+ elif len(image.shape) == 3:
+ nRows, nColumns, nChannels = image.shape
+ else:
+ raise RuntimeError("Image does not have the right shape")
+ dtype = image.dtype
+ bitsPerSample = int(dtype.str[-1]) * 8
+
+ #only uncompressed data
+ compression = 1
+
+ #interpretation, black is zero
+ if nChannels == 1:
+ interpretation = 1
+ bitsPerSampleLength = 0
+ elif nChannels == 3:
+ interpretation = 2
+ bitsPerSampleLength = 3 * 2 # To store 3 shorts
+ nDirectoryEntries += 1 # For SamplesPerPixel
+ else:
+ raise RuntimeError(
+ "Image with %d color channel(s) not supported" % nChannels)
+
+ #image description
+ if imageDescription is not None:
+ descriptionLength = len(imageDescription)
+ else:
+ descriptionLength = 0
+
+ #strip offsets
+ #we are putting them after the directory and the directory is
+ #at the end of the file
+ self.fd.seek(0, os.SEEK_END)
+ endOfFile = self.fd.tell()
+ if endOfFile == 0:
+ #empty file
+ endOfFile = 8
+
+ #rows per strip
+ if ALLOW_MULTIPLE_STRIPS:
+ #try to segment the image in several pieces
+ if not (nRows % 4):
+ rowsPerStrip = int(nRows/4)
+ elif not (nRows % 10):
+ rowsPerStrip = int(nRows/10)
+ elif not (nRows % 8):
+ rowsPerStrip = int(nRows/8)
+ elif not (nRows % 4):
+ rowsPerStrip = int(nRows/4)
+ elif not (nRows % 2):
+ rowsPerStrip = int(nRows/2)
+ else:
+ rowsPerStrip = nRows
+ else:
+ rowsPerStrip = nRows
+
+ #stripByteCounts
+ stripByteCounts = int(nColumns * rowsPerStrip *
+ bitsPerSample * nChannels / 8)
+
+ if descriptionLength > 4:
+ stripOffsets0 = endOfFile + dateLength + descriptionLength +\
+ 2 + 12 * nDirectoryEntries + 4
+ else:
+ stripOffsets0 = endOfFile + dateLength + \
+ 2 + 12 * nDirectoryEntries + 4
+
+ if softwareLength > 4:
+ stripOffsets0 += softwareLength
+
+ stripOffsets0 += bitsPerSampleLength
+
+ stripOffsets = [stripOffsets0]
+ stripOffsetsLength = 0
+ stripOffsetsString = None
+
+ st = self._structChar
+
+ if rowsPerStrip != nRows:
+ nStripOffsets = int(nRows/rowsPerStrip)
+ fmt = st + 'I'
+ stripOffsetsLength = struct.calcsize(fmt) * nStripOffsets
+ stripOffsets0 += stripOffsetsLength
+ #the length for the stripByteCounts will be the same
+ stripOffsets0 += stripOffsetsLength
+ stripOffsets = []
+ for i in range(nStripOffsets):
+ value = stripOffsets0 + i * stripByteCounts
+ stripOffsets.append(value)
+ if i == 0:
+ stripOffsetsString = struct.pack(fmt, value)
+ stripByteCountsString = struct.pack(fmt, stripByteCounts)
+ else:
+ stripOffsetsString += struct.pack(fmt, value)
+ stripByteCountsString += struct.pack(fmt, stripByteCounts)
+
+ if DEBUG:
+ print("IMAGE WILL START AT %d" % stripOffsets[0])
+
+ #sample format
+ if dtype in [numpy.float32, numpy.float64] or\
+ dtype.str[-2] == 'f':
+ sampleFormat = SAMPLE_FORMAT_FLOAT
+ elif dtype in [numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64]:
+ sampleFormat = SAMPLE_FORMAT_UINT
+ elif dtype in [numpy.int8, numpy.int16, numpy.int32, numpy.int64]:
+ sampleFormat = SAMPLE_FORMAT_INT
+ else:
+ raise ValueError("Unsupported data type %s" % dtype)
+
+ info = {}
+ info["nColumns"] = nColumns
+ info["nRows"] = nRows
+ info["nBits"] = bitsPerSample
+ info["compression"] = compression
+ info["photometricInterpretation"] = interpretation
+ info["stripOffsets"] = stripOffsets
+ if interpretation == 2:
+ info["samplesPerPixel"] = 3 # No support for extra samples
+ info["rowsPerStrip"] = rowsPerStrip
+ info["stripByteCounts"] = stripByteCounts
+ info["date"] = date
+ info["sampleFormat"] = sampleFormat
+
+ outputIFD = ""
+ if sys.version > '2.6':
+ outputIFD = eval('b""')
+
+ fmt = st + "H"
+ outputIFD += struct.pack(fmt, nDirectoryEntries)
+
+ fmt = st + "HHII"
+ outputIFD += struct.pack(fmt, TAG_NUMBER_OF_COLUMNS,
+ FIELD_TYPE_OUT['I'],
+ 1,
+ info["nColumns"])
+ outputIFD += struct.pack(fmt, TAG_NUMBER_OF_ROWS,
+ FIELD_TYPE_OUT['I'],
+ 1,
+ info["nRows"])
+
+ if info["photometricInterpretation"] == 1:
+ fmt = st + 'HHIHH'
+ outputIFD += struct.pack(fmt, TAG_BITS_PER_SAMPLE,
+ FIELD_TYPE_OUT['H'],
+ 1,
+ info["nBits"], 0)
+ elif info["photometricInterpretation"] == 2:
+ fmt = st + 'HHII'
+ outputIFD += struct.pack(fmt, TAG_BITS_PER_SAMPLE,
+ FIELD_TYPE_OUT['H'],
+ 3,
+ info["stripOffsets"][0] - \
+ 2 * stripOffsetsLength - \
+ descriptionLength - \
+ dateLength - \
+ softwareLength - \
+ bitsPerSampleLength)
+ else:
+ raise RuntimeError("Unsupported photometric interpretation")
+
+ fmt = st + 'HHIHH'
+ outputIFD += struct.pack(fmt, TAG_COMPRESSION,
+ FIELD_TYPE_OUT['H'],
+ 1,
+ info["compression"],0)
+ fmt = st + 'HHIHH'
+ outputIFD += struct.pack(fmt, TAG_PHOTOMETRIC_INTERPRETATION,
+ FIELD_TYPE_OUT['H'],
+ 1,
+ info["photometricInterpretation"],0)
+
+ if imageDescription is not None:
+ descriptionLength = len(imageDescription)
+ if descriptionLength > 4:
+ fmt = st + 'HHII'
+ outputIFD += struct.pack(fmt, TAG_IMAGE_DESCRIPTION,
+ FIELD_TYPE_OUT['s'],
+ descriptionLength,
+ info["stripOffsets"][0]-\
+ 2*stripOffsetsLength-\
+ descriptionLength)
+ else:
+ #it has to have length 4
+ fmt = st + 'HHI%ds' % descriptionLength
+ outputIFD += struct.pack(fmt, TAG_IMAGE_DESCRIPTION,
+ FIELD_TYPE_OUT['s'],
+ descriptionLength,
+ description)
+
+ if len(stripOffsets) == 1:
+ fmt = st + 'HHII'
+ outputIFD += struct.pack(fmt, TAG_STRIP_OFFSETS,
+ FIELD_TYPE_OUT['I'],
+ 1,
+ info["stripOffsets"][0])
+ else:
+ fmt = st + 'HHII'
+ outputIFD += struct.pack(fmt, TAG_STRIP_OFFSETS,
+ FIELD_TYPE_OUT['I'],
+ len(stripOffsets),
+ info["stripOffsets"][0]-2*stripOffsetsLength)
+
+ if info["photometricInterpretation"] == 2:
+ fmt = st + 'HHIHH'
+ outputIFD += struct.pack(fmt, TAG_SAMPLES_PER_PIXEL,
+ FIELD_TYPE_OUT['H'],
+ 1,
+ info["samplesPerPixel"], 0)
+
+ fmt = st + 'HHII'
+ outputIFD += struct.pack(fmt, TAG_ROWS_PER_STRIP,
+ FIELD_TYPE_OUT['I'],
+ 1,
+ info["rowsPerStrip"])
+
+ if len(stripOffsets) == 1:
+ fmt = st + 'HHII'
+ outputIFD += struct.pack(fmt, TAG_STRIP_BYTE_COUNTS,
+ FIELD_TYPE_OUT['I'],
+ 1,
+ info["stripByteCounts"])
+ else:
+ fmt = st + 'HHII'
+ outputIFD += struct.pack(fmt, TAG_STRIP_BYTE_COUNTS,
+ FIELD_TYPE_OUT['I'],
+ len(stripOffsets),
+ info["stripOffsets"][0]-stripOffsetsLength)
+
+ if software is not None:
+ if softwareLength > 4:
+ fmt = st + 'HHII'
+ outputIFD += struct.pack(fmt, TAG_SOFTWARE,
+ FIELD_TYPE_OUT['s'],
+ softwareLength,
+ info["stripOffsets"][0]-\
+ 2*stripOffsetsLength-\
+ descriptionLength-softwareLength-dateLength)
+ else:
+ #it has to have length 4
+ fmt = st + 'HHI%ds' % softwareLength
+ outputIFD += struct.pack(fmt, TAG_SOFTWARE,
+ FIELD_TYPE_OUT['s'],
+ softwareLength,
+ softwarePackedString)
+
+ if date is not None:
+ fmt = st + 'HHII'
+ outputIFD += struct.pack(fmt, TAG_DATE,
+ FIELD_TYPE_OUT['s'],
+ dateLength,
+ info["stripOffsets"][0]-\
+ 2*stripOffsetsLength-\
+ descriptionLength-dateLength)
+
+ fmt = st + 'HHIHH'
+ outputIFD += struct.pack(fmt, TAG_SAMPLE_FORMAT,
+ FIELD_TYPE_OUT['H'],
+ 1,
+ info["sampleFormat"],0)
+ fmt = st + 'I'
+ outputIFD += struct.pack(fmt, 0)
+
+ if info["photometricInterpretation"] == 2:
+ outputIFD += struct.pack('HHH', info["nBits"],
+ info["nBits"], info["nBits"])
+
+ if softwareLength > 4:
+ outputIFD += softwarePackedString
+
+ if date is not None:
+ outputIFD += datePackedString
+
+ if imageDescription is not None:
+ if descriptionLength > 4:
+ outputIFD += imageDescription
+
+ if stripOffsetsString is not None:
+ outputIFD += stripOffsetsString
+ outputIFD += stripByteCountsString
+
+ return outputIFD
+
+
+if __name__ == "__main__":
+ filename = sys.argv[1]
+ dtype = numpy.uint16
+ if not os.path.exists(filename):
+ print("Testing file creation")
+ tif = TiffIO(filename, mode = 'wb+')
+ data = numpy.arange(10000).astype(dtype)
+ data.shape = 100, 100
+ tif.writeImage(data, info={'Title':'1st'})
+ tif = None
+ if os.path.exists(filename):
+ print("Testing image appending")
+ tif = TiffIO(filename, mode = 'rb+')
+ tif.writeImage((data*2).astype(dtype), info={'Title':'2nd'})
+ tif = None
+ tif = TiffIO(filename)
+ print("Number of images = %d" % tif.getNumberOfImages())
+ for i in range(tif.getNumberOfImages()):
+ info = tif.getInfo(i)
+ for key in info:
+ if key not in ["colormap"]:
+ print("%s = %s" % (key, info[key]))
+ elif info['colormap'] is not None:
+ print("RED %s = %s" % (key, info[key][0:10, 0]))
+ print("GREEN %s = %s" % (key, info[key][0:10, 1]))
+ print("BLUE %s = %s" % (key, info[key][0:10, 2]))
+ data = tif.getImage(i)[0, 0:10]
+ print("data [0, 0:10] = ", data)
+
diff --git a/silx/third_party/__init__.py b/silx/third_party/__init__.py
new file mode 100644
index 0000000..5f31822
--- /dev/null
+++ b/silx/third_party/__init__.py
@@ -0,0 +1,28 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+
+__authors__ = ["Jérôme Kieffer"]
+__license__ = "MIT"
+__date__ = "09/10/2015"
diff --git a/silx/third_party/_local/__init__.py b/silx/third_party/_local/__init__.py
new file mode 100644
index 0000000..03973e5
--- /dev/null
+++ b/silx/third_party/_local/__init__.py
@@ -0,0 +1,36 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+"""
+Package containing external modules which can be available as it is as an
+external python library.
+
+They are stored here to reduce python library dependancies.
+
+This package can be removed if all dependancies are available in the target
+system as python libraries.
+"""
+__authors__ = ["Valentin Valls"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
diff --git a/silx/third_party/_local/six.py b/silx/third_party/_local/six.py
new file mode 100644
index 0000000..190c023
--- /dev/null
+++ b/silx/third_party/_local/six.py
@@ -0,0 +1,868 @@
+"""Utilities for writing code that runs on Python 2 and 3"""
+
+# Copyright (c) 2010-2015 Benjamin Peterson
+#
+# 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.
+
+from __future__ import absolute_import
+
+import functools
+import itertools
+import operator
+import sys
+import types
+
+__author__ = "Benjamin Peterson <benjamin@python.org>"
+__version__ = "1.10.0"
+
+
+# Useful for very coarse version differentiation.
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+PY34 = sys.version_info[0:2] >= (3, 4)
+
+if PY3:
+ string_types = str,
+ integer_types = int,
+ class_types = type,
+ text_type = str
+ binary_type = bytes
+
+ MAXSIZE = sys.maxsize
+else:
+ string_types = basestring,
+ integer_types = (int, long)
+ class_types = (type, types.ClassType)
+ text_type = unicode
+ binary_type = str
+
+ if sys.platform.startswith("java"):
+ # Jython always uses 32 bits.
+ MAXSIZE = int((1 << 31) - 1)
+ else:
+ # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
+ class X(object):
+
+ def __len__(self):
+ return 1 << 31
+ try:
+ len(X())
+ except OverflowError:
+ # 32-bit
+ MAXSIZE = int((1 << 31) - 1)
+ else:
+ # 64-bit
+ MAXSIZE = int((1 << 63) - 1)
+ del X
+
+
+def _add_doc(func, doc):
+ """Add documentation to a function."""
+ func.__doc__ = doc
+
+
+def _import_module(name):
+ """Import module, returning the module after the last dot."""
+ __import__(name)
+ return sys.modules[name]
+
+
+class _LazyDescr(object):
+
+ def __init__(self, name):
+ self.name = name
+
+ def __get__(self, obj, tp):
+ result = self._resolve()
+ setattr(obj, self.name, result) # Invokes __set__.
+ try:
+ # This is a bit ugly, but it avoids running this again by
+ # removing this descriptor.
+ delattr(obj.__class__, self.name)
+ except AttributeError:
+ pass
+ return result
+
+
+class MovedModule(_LazyDescr):
+
+ def __init__(self, name, old, new=None):
+ super(MovedModule, self).__init__(name)
+ if PY3:
+ if new is None:
+ new = name
+ self.mod = new
+ else:
+ self.mod = old
+
+ def _resolve(self):
+ return _import_module(self.mod)
+
+ def __getattr__(self, attr):
+ _module = self._resolve()
+ value = getattr(_module, attr)
+ setattr(self, attr, value)
+ return value
+
+
+class _LazyModule(types.ModuleType):
+
+ def __init__(self, name):
+ super(_LazyModule, self).__init__(name)
+ self.__doc__ = self.__class__.__doc__
+
+ def __dir__(self):
+ attrs = ["__doc__", "__name__"]
+ attrs += [attr.name for attr in self._moved_attributes]
+ return attrs
+
+ # Subclasses should override this
+ _moved_attributes = []
+
+
+class MovedAttribute(_LazyDescr):
+
+ def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
+ super(MovedAttribute, self).__init__(name)
+ if PY3:
+ if new_mod is None:
+ new_mod = name
+ self.mod = new_mod
+ if new_attr is None:
+ if old_attr is None:
+ new_attr = name
+ else:
+ new_attr = old_attr
+ self.attr = new_attr
+ else:
+ self.mod = old_mod
+ if old_attr is None:
+ old_attr = name
+ self.attr = old_attr
+
+ def _resolve(self):
+ module = _import_module(self.mod)
+ return getattr(module, self.attr)
+
+
+class _SixMetaPathImporter(object):
+
+ """
+ A meta path importer to import six.moves and its submodules.
+
+ This class implements a PEP302 finder and loader. It should be compatible
+ with Python 2.5 and all existing versions of Python3
+ """
+
+ def __init__(self, six_module_name):
+ self.name = six_module_name
+ self.known_modules = {}
+
+ def _add_module(self, mod, *fullnames):
+ for fullname in fullnames:
+ self.known_modules[self.name + "." + fullname] = mod
+
+ def _get_module(self, fullname):
+ return self.known_modules[self.name + "." + fullname]
+
+ def find_module(self, fullname, path=None):
+ if fullname in self.known_modules:
+ return self
+ return None
+
+ def __get_module(self, fullname):
+ try:
+ return self.known_modules[fullname]
+ except KeyError:
+ raise ImportError("This loader does not know module " + fullname)
+
+ def load_module(self, fullname):
+ try:
+ # in case of a reload
+ return sys.modules[fullname]
+ except KeyError:
+ pass
+ mod = self.__get_module(fullname)
+ if isinstance(mod, MovedModule):
+ mod = mod._resolve()
+ else:
+ mod.__loader__ = self
+ sys.modules[fullname] = mod
+ return mod
+
+ def is_package(self, fullname):
+ """
+ Return true, if the named module is a package.
+
+ We need this method to get correct spec objects with
+ Python 3.4 (see PEP451)
+ """
+ return hasattr(self.__get_module(fullname), "__path__")
+
+ def get_code(self, fullname):
+ """Return None
+
+ Required, if is_package is implemented"""
+ self.__get_module(fullname) # eventually raises ImportError
+ return None
+ get_source = get_code # same as get_code
+
+_importer = _SixMetaPathImporter(__name__)
+
+
+class _MovedItems(_LazyModule):
+
+ """Lazy loading of moved objects"""
+ __path__ = [] # mark as package
+
+
+_moved_attributes = [
+ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
+ MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
+ MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+ MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
+ MovedAttribute("intern", "__builtin__", "sys"),
+ MovedAttribute("map", "itertools", "builtins", "imap", "map"),
+ MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
+ MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+ MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
+ MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
+ MovedAttribute("reduce", "__builtin__", "functools"),
+ MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
+ MovedAttribute("StringIO", "StringIO", "io"),
+ MovedAttribute("UserDict", "UserDict", "collections"),
+ MovedAttribute("UserList", "UserList", "collections"),
+ MovedAttribute("UserString", "UserString", "collections"),
+ MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
+ MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
+ MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
+ MovedModule("builtins", "__builtin__"),
+ MovedModule("configparser", "ConfigParser"),
+ MovedModule("copyreg", "copy_reg"),
+ MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
+ MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
+ MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
+ MovedModule("http_cookies", "Cookie", "http.cookies"),
+ MovedModule("html_entities", "htmlentitydefs", "html.entities"),
+ MovedModule("html_parser", "HTMLParser", "html.parser"),
+ MovedModule("http_client", "httplib", "http.client"),
+ MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
+ MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
+ MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
+ MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+ MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
+ MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
+ MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
+ MovedModule("cPickle", "cPickle", "pickle"),
+ MovedModule("queue", "Queue"),
+ MovedModule("reprlib", "repr"),
+ MovedModule("socketserver", "SocketServer"),
+ MovedModule("_thread", "thread", "_thread"),
+ MovedModule("tkinter", "Tkinter"),
+ MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
+ MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
+ MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
+ MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
+ MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
+ MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
+ MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
+ MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
+ MovedModule("tkinter_colorchooser", "tkColorChooser",
+ "tkinter.colorchooser"),
+ MovedModule("tkinter_commondialog", "tkCommonDialog",
+ "tkinter.commondialog"),
+ MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
+ MovedModule("tkinter_font", "tkFont", "tkinter.font"),
+ MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
+ MovedModule("tkinter_tksimpledialog", "tkSimpleDialog",
+ "tkinter.simpledialog"),
+ MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
+ MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
+ MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
+ MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
+ MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
+ MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
+]
+# Add windows specific modules.
+if sys.platform == "win32":
+ _moved_attributes += [
+ MovedModule("winreg", "_winreg"),
+ ]
+
+for attr in _moved_attributes:
+ setattr(_MovedItems, attr.name, attr)
+ if isinstance(attr, MovedModule):
+ _importer._add_module(attr, "moves." + attr.name)
+del attr
+
+_MovedItems._moved_attributes = _moved_attributes
+
+moves = _MovedItems(__name__ + ".moves")
+_importer._add_module(moves, "moves")
+
+
+class Module_six_moves_urllib_parse(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_parse"""
+
+
+_urllib_parse_moved_attributes = [
+ MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
+ MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
+ MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
+ MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
+ MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
+ MovedAttribute("urljoin", "urlparse", "urllib.parse"),
+ MovedAttribute("urlparse", "urlparse", "urllib.parse"),
+ MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
+ MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
+ MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
+ MovedAttribute("quote", "urllib", "urllib.parse"),
+ MovedAttribute("quote_plus", "urllib", "urllib.parse"),
+ MovedAttribute("unquote", "urllib", "urllib.parse"),
+ MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+ MovedAttribute("urlencode", "urllib", "urllib.parse"),
+ MovedAttribute("splitquery", "urllib", "urllib.parse"),
+ MovedAttribute("splittag", "urllib", "urllib.parse"),
+ MovedAttribute("splituser", "urllib", "urllib.parse"),
+ MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_params", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_query", "urlparse", "urllib.parse"),
+ MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
+]
+for attr in _urllib_parse_moved_attributes:
+ setattr(Module_six_moves_urllib_parse, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
+ "moves.urllib_parse", "moves.urllib.parse")
+
+
+class Module_six_moves_urllib_error(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_error"""
+
+
+_urllib_error_moved_attributes = [
+ MovedAttribute("URLError", "urllib2", "urllib.error"),
+ MovedAttribute("HTTPError", "urllib2", "urllib.error"),
+ MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
+]
+for attr in _urllib_error_moved_attributes:
+ setattr(Module_six_moves_urllib_error, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
+ "moves.urllib_error", "moves.urllib.error")
+
+
+class Module_six_moves_urllib_request(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_request"""
+
+
+_urllib_request_moved_attributes = [
+ MovedAttribute("urlopen", "urllib2", "urllib.request"),
+ MovedAttribute("install_opener", "urllib2", "urllib.request"),
+ MovedAttribute("build_opener", "urllib2", "urllib.request"),
+ MovedAttribute("pathname2url", "urllib", "urllib.request"),
+ MovedAttribute("url2pathname", "urllib", "urllib.request"),
+ MovedAttribute("getproxies", "urllib", "urllib.request"),
+ MovedAttribute("Request", "urllib2", "urllib.request"),
+ MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
+ MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
+ MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
+ MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
+ MovedAttribute("FileHandler", "urllib2", "urllib.request"),
+ MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
+ MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
+ MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
+ MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
+ MovedAttribute("urlretrieve", "urllib", "urllib.request"),
+ MovedAttribute("urlcleanup", "urllib", "urllib.request"),
+ MovedAttribute("URLopener", "urllib", "urllib.request"),
+ MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
+ MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+]
+for attr in _urllib_request_moved_attributes:
+ setattr(Module_six_moves_urllib_request, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
+ "moves.urllib_request", "moves.urllib.request")
+
+
+class Module_six_moves_urllib_response(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_response"""
+
+
+_urllib_response_moved_attributes = [
+ MovedAttribute("addbase", "urllib", "urllib.response"),
+ MovedAttribute("addclosehook", "urllib", "urllib.response"),
+ MovedAttribute("addinfo", "urllib", "urllib.response"),
+ MovedAttribute("addinfourl", "urllib", "urllib.response"),
+]
+for attr in _urllib_response_moved_attributes:
+ setattr(Module_six_moves_urllib_response, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
+ "moves.urllib_response", "moves.urllib.response")
+
+
+class Module_six_moves_urllib_robotparser(_LazyModule):
+
+ """Lazy loading of moved objects in six.moves.urllib_robotparser"""
+
+
+_urllib_robotparser_moved_attributes = [
+ MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
+]
+for attr in _urllib_robotparser_moved_attributes:
+ setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
+del attr
+
+Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes
+
+_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
+ "moves.urllib_robotparser", "moves.urllib.robotparser")
+
+
+class Module_six_moves_urllib(types.ModuleType):
+
+ """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
+ __path__ = [] # mark as package
+ parse = _importer._get_module("moves.urllib_parse")
+ error = _importer._get_module("moves.urllib_error")
+ request = _importer._get_module("moves.urllib_request")
+ response = _importer._get_module("moves.urllib_response")
+ robotparser = _importer._get_module("moves.urllib_robotparser")
+
+ def __dir__(self):
+ return ['parse', 'error', 'request', 'response', 'robotparser']
+
+_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"),
+ "moves.urllib")
+
+
+def add_move(move):
+ """Add an item to six.moves."""
+ setattr(_MovedItems, move.name, move)
+
+
+def remove_move(name):
+ """Remove item from six.moves."""
+ try:
+ delattr(_MovedItems, name)
+ except AttributeError:
+ try:
+ del moves.__dict__[name]
+ except KeyError:
+ raise AttributeError("no such move, %r" % (name,))
+
+
+if PY3:
+ _meth_func = "__func__"
+ _meth_self = "__self__"
+
+ _func_closure = "__closure__"
+ _func_code = "__code__"
+ _func_defaults = "__defaults__"
+ _func_globals = "__globals__"
+else:
+ _meth_func = "im_func"
+ _meth_self = "im_self"
+
+ _func_closure = "func_closure"
+ _func_code = "func_code"
+ _func_defaults = "func_defaults"
+ _func_globals = "func_globals"
+
+
+try:
+ advance_iterator = next
+except NameError:
+ def advance_iterator(it):
+ return it.next()
+next = advance_iterator
+
+
+try:
+ callable = callable
+except NameError:
+ def callable(obj):
+ return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
+
+
+if PY3:
+ def get_unbound_function(unbound):
+ return unbound
+
+ create_bound_method = types.MethodType
+
+ def create_unbound_method(func, cls):
+ return func
+
+ Iterator = object
+else:
+ def get_unbound_function(unbound):
+ return unbound.im_func
+
+ def create_bound_method(func, obj):
+ return types.MethodType(func, obj, obj.__class__)
+
+ def create_unbound_method(func, cls):
+ return types.MethodType(func, None, cls)
+
+ class Iterator(object):
+
+ def next(self):
+ return type(self).__next__(self)
+
+ callable = callable
+_add_doc(get_unbound_function,
+ """Get the function out of a possibly unbound function""")
+
+
+get_method_function = operator.attrgetter(_meth_func)
+get_method_self = operator.attrgetter(_meth_self)
+get_function_closure = operator.attrgetter(_func_closure)
+get_function_code = operator.attrgetter(_func_code)
+get_function_defaults = operator.attrgetter(_func_defaults)
+get_function_globals = operator.attrgetter(_func_globals)
+
+
+if PY3:
+ def iterkeys(d, **kw):
+ return iter(d.keys(**kw))
+
+ def itervalues(d, **kw):
+ return iter(d.values(**kw))
+
+ def iteritems(d, **kw):
+ return iter(d.items(**kw))
+
+ def iterlists(d, **kw):
+ return iter(d.lists(**kw))
+
+ viewkeys = operator.methodcaller("keys")
+
+ viewvalues = operator.methodcaller("values")
+
+ viewitems = operator.methodcaller("items")
+else:
+ def iterkeys(d, **kw):
+ return d.iterkeys(**kw)
+
+ def itervalues(d, **kw):
+ return d.itervalues(**kw)
+
+ def iteritems(d, **kw):
+ return d.iteritems(**kw)
+
+ def iterlists(d, **kw):
+ return d.iterlists(**kw)
+
+ viewkeys = operator.methodcaller("viewkeys")
+
+ viewvalues = operator.methodcaller("viewvalues")
+
+ viewitems = operator.methodcaller("viewitems")
+
+_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
+_add_doc(itervalues, "Return an iterator over the values of a dictionary.")
+_add_doc(iteritems,
+ "Return an iterator over the (key, value) pairs of a dictionary.")
+_add_doc(iterlists,
+ "Return an iterator over the (key, [values]) pairs of a dictionary.")
+
+
+if PY3:
+ def b(s):
+ return s.encode("latin-1")
+
+ def u(s):
+ return s
+ unichr = chr
+ import struct
+ int2byte = struct.Struct(">B").pack
+ del struct
+ byte2int = operator.itemgetter(0)
+ indexbytes = operator.getitem
+ iterbytes = iter
+ import io
+ StringIO = io.StringIO
+ BytesIO = io.BytesIO
+ _assertCountEqual = "assertCountEqual"
+ if sys.version_info[1] <= 1:
+ _assertRaisesRegex = "assertRaisesRegexp"
+ _assertRegex = "assertRegexpMatches"
+ else:
+ _assertRaisesRegex = "assertRaisesRegex"
+ _assertRegex = "assertRegex"
+else:
+ def b(s):
+ return s
+ # Workaround for standalone backslash
+
+ def u(s):
+ return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape")
+ unichr = unichr
+ int2byte = chr
+
+ def byte2int(bs):
+ return ord(bs[0])
+
+ def indexbytes(buf, i):
+ return ord(buf[i])
+ iterbytes = functools.partial(itertools.imap, ord)
+ import StringIO
+ StringIO = BytesIO = StringIO.StringIO
+ _assertCountEqual = "assertItemsEqual"
+ _assertRaisesRegex = "assertRaisesRegexp"
+ _assertRegex = "assertRegexpMatches"
+_add_doc(b, """Byte literal""")
+_add_doc(u, """Text literal""")
+
+
+def assertCountEqual(self, *args, **kwargs):
+ return getattr(self, _assertCountEqual)(*args, **kwargs)
+
+
+def assertRaisesRegex(self, *args, **kwargs):
+ return getattr(self, _assertRaisesRegex)(*args, **kwargs)
+
+
+def assertRegex(self, *args, **kwargs):
+ return getattr(self, _assertRegex)(*args, **kwargs)
+
+
+if PY3:
+ exec_ = getattr(moves.builtins, "exec")
+
+ def reraise(tp, value, tb=None):
+ if value is None:
+ value = tp()
+ if value.__traceback__ is not tb:
+ raise value.with_traceback(tb)
+ raise value
+
+else:
+ def exec_(_code_, _globs_=None, _locs_=None):
+ """Execute code in a namespace."""
+ if _globs_ is None:
+ frame = sys._getframe(1)
+ _globs_ = frame.f_globals
+ if _locs_ is None:
+ _locs_ = frame.f_locals
+ del frame
+ elif _locs_ is None:
+ _locs_ = _globs_
+ exec("""exec _code_ in _globs_, _locs_""")
+
+ exec_("""def reraise(tp, value, tb=None):
+ raise tp, value, tb
+""")
+
+
+if sys.version_info[:2] == (3, 2):
+ exec_("""def raise_from(value, from_value):
+ if from_value is None:
+ raise value
+ raise value from from_value
+""")
+elif sys.version_info[:2] > (3, 2):
+ exec_("""def raise_from(value, from_value):
+ raise value from from_value
+""")
+else:
+ def raise_from(value, from_value):
+ raise value
+
+
+print_ = getattr(moves.builtins, "print", None)
+if print_ is None:
+ def print_(*args, **kwargs):
+ """The new-style print function for Python 2.4 and 2.5."""
+ fp = kwargs.pop("file", sys.stdout)
+ if fp is None:
+ return
+
+ def write(data):
+ if not isinstance(data, basestring):
+ data = str(data)
+ # If the file has an encoding, encode unicode with it.
+ if (isinstance(fp, file) and
+ isinstance(data, unicode) and
+ fp.encoding is not None):
+ errors = getattr(fp, "errors", None)
+ if errors is None:
+ errors = "strict"
+ data = data.encode(fp.encoding, errors)
+ fp.write(data)
+ want_unicode = False
+ sep = kwargs.pop("sep", None)
+ if sep is not None:
+ if isinstance(sep, unicode):
+ want_unicode = True
+ elif not isinstance(sep, str):
+ raise TypeError("sep must be None or a string")
+ end = kwargs.pop("end", None)
+ if end is not None:
+ if isinstance(end, unicode):
+ want_unicode = True
+ elif not isinstance(end, str):
+ raise TypeError("end must be None or a string")
+ if kwargs:
+ raise TypeError("invalid keyword arguments to print()")
+ if not want_unicode:
+ for arg in args:
+ if isinstance(arg, unicode):
+ want_unicode = True
+ break
+ if want_unicode:
+ newline = unicode("\n")
+ space = unicode(" ")
+ else:
+ newline = "\n"
+ space = " "
+ if sep is None:
+ sep = space
+ if end is None:
+ end = newline
+ for i, arg in enumerate(args):
+ if i:
+ write(sep)
+ write(arg)
+ write(end)
+if sys.version_info[:2] < (3, 3):
+ _print = print_
+
+ def print_(*args, **kwargs):
+ fp = kwargs.get("file", sys.stdout)
+ flush = kwargs.pop("flush", False)
+ _print(*args, **kwargs)
+ if flush and fp is not None:
+ fp.flush()
+
+_add_doc(reraise, """Reraise an exception.""")
+
+if sys.version_info[0:2] < (3, 4):
+ def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
+ updated=functools.WRAPPER_UPDATES):
+ def wrapper(f):
+ f = functools.wraps(wrapped, assigned, updated)(f)
+ f.__wrapped__ = wrapped
+ return f
+ return wrapper
+else:
+ wraps = functools.wraps
+
+
+def with_metaclass(meta, *bases):
+ """Create a base class with a metaclass."""
+ # This requires a bit of explanation: the basic idea is to make a dummy
+ # metaclass for one level of class instantiation that replaces itself with
+ # the actual metaclass.
+ class metaclass(meta):
+
+ def __new__(cls, name, this_bases, d):
+ return meta(name, bases, d)
+ return type.__new__(metaclass, 'temporary_class', (), {})
+
+
+def add_metaclass(metaclass):
+ """Class decorator for creating a class with a metaclass."""
+ def wrapper(cls):
+ orig_vars = cls.__dict__.copy()
+ slots = orig_vars.get('__slots__')
+ if slots is not None:
+ if isinstance(slots, str):
+ slots = [slots]
+ for slots_var in slots:
+ orig_vars.pop(slots_var)
+ orig_vars.pop('__dict__', None)
+ orig_vars.pop('__weakref__', None)
+ return metaclass(cls.__name__, cls.__bases__, orig_vars)
+ return wrapper
+
+
+def python_2_unicode_compatible(klass):
+ """
+ A decorator that defines __unicode__ and __str__ methods under Python 2.
+ Under Python 3 it does nothing.
+
+ To support Python 2 and 3 with a single code base, define a __str__ method
+ returning text and apply this decorator to the class.
+ """
+ if PY2:
+ if '__str__' not in klass.__dict__:
+ raise ValueError("@python_2_unicode_compatible cannot be applied "
+ "to %s because it doesn't define __str__()." %
+ klass.__name__)
+ klass.__unicode__ = klass.__str__
+ klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
+ return klass
+
+
+# Complete the moves implementation.
+# This code is at the end of this module to speed up module loading.
+# Turn this module into a package.
+__path__ = [] # required for PEP 302 and PEP 451
+__package__ = __name__ # see PEP 366 @ReservedAssignment
+if globals().get("__spec__") is not None:
+ __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
+# Remove other six meta path importers, since they cause problems. This can
+# happen if six is removed from sys.modules and then reloaded. (Setuptools does
+# this for some reason.)
+if sys.meta_path:
+ for i, importer in enumerate(sys.meta_path):
+ # Here's some real nastiness: Another "instance" of the six module might
+ # be floating around. Therefore, we can't use isinstance() to check for
+ # the six meta path importer, since the other six instance will have
+ # inserted an importer with different class.
+ if (type(importer).__name__ == "_SixMetaPathImporter" and
+ importer.name == __name__):
+ del sys.meta_path[i]
+ break
+ del i, importer
+# Finally, add the importer to the meta path import hook.
+sys.meta_path.append(_importer)
diff --git a/silx/third_party/setup.py b/silx/third_party/setup.py
new file mode 100644
index 0000000..7477456
--- /dev/null
+++ b/silx/third_party/setup.py
@@ -0,0 +1,48 @@
+# coding: ascii
+#
+# JK: Numpy.distutils which imports this does not handle utf-8 in version<1.12
+#
+# /*##########################################################################
+#
+# 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.
+#
+# ###########################################################################*/
+
+__authors__ = ["Valentin Valls"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+import os
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('third_party', parent_package, top_path)
+ # includes _local only if it is available
+ local_path = os.path.join(top_path, parent_package, "third_party", "_local")
+ if os.path.exists(local_path):
+ config.add_subpackage('_local')
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+ setup(configuration=configuration)
diff --git a/silx/third_party/six.py b/silx/third_party/six.py
new file mode 100644
index 0000000..a1fe786
--- /dev/null
+++ b/silx/third_party/six.py
@@ -0,0 +1,49 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+"""Wrapper module for the `six` library.
+
+Feed this module using a local silx copy of `six` if it exists.
+Else it expect to have an available `six` library installed in the Python path.
+
+It should be used like that:
+
+.. code-block::
+
+ from silx.third_party import six
+
+"""
+
+from __future__ import absolute_import
+
+__authors__ = ["Valentin Valls"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+try:
+ # try to import our local version of six
+ from ._local.six import * # noqa
+except ImportError:
+ # else try to import it from the python path
+ from six import * # noqa
diff --git a/silx/utils/__init__.py b/silx/utils/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/silx/utils/__init__.py
diff --git a/silx/utils/array_like.py b/silx/utils/array_like.py
new file mode 100644
index 0000000..f4c85bf
--- /dev/null
+++ b/silx/utils/array_like.py
@@ -0,0 +1,593 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Functions and classes for array-like objects, implementing common numpy
+array features for datasets or nested sequences, while trying to avoid copying
+data.
+
+Classes:
+
+ - :class:`DatasetView`: Similar to a numpy view, to access
+ a h5py dataset as if it was transposed, without casting it into a
+ numpy array (this lets h5py handle reading the data from the
+ file into memory, as needed).
+ - :class:`ListOfImages`: Similar to a numpy view, to access
+ a list of 2D numpy arrays as if it was a 3D array (possibly transposed),
+ without casting it into a numpy array.
+
+Functions:
+
+ - :func:`is_array`
+ - :func:`is_list_of_arrays`
+ - :func:`is_nested_sequence`
+ - :func:`get_shape`
+ - :func:`get_dtype`
+ - :func:`get_concatenated_dtype`
+
+"""
+
+from __future__ import absolute_import, print_function, division
+import numpy
+import sys
+from silx.third_party import six
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "26/04/2017"
+
+
+def is_array(obj):
+ """Return True if object implements necessary attributes to be
+ considered similar to a numpy array.
+
+ Attributes needed are "shape", "dtype", "__getitem__"
+ and "__array__".
+
+ :param obj: Array-like object (numpy array, h5py dataset...)
+ :return: boolean
+ """
+ # add more required attribute if necessary
+ for attr in ("shape", "dtype", "__array__", "__getitem__"):
+ if not hasattr(obj, attr):
+ return False
+ return True
+
+
+def is_list_of_arrays(obj):
+ """Return True if object is a sequence of numpy arrays,
+ e.g. a list of images as 2D arrays.
+
+ :param obj: list of arrays
+ :return: boolean"""
+ # object must not be a numpy array
+ if is_array(obj):
+ return False
+
+ # object must have a __len__ method
+ if not hasattr(obj, "__len__"):
+ return False
+
+ # all elements in sequence must be arrays
+ for arr in obj:
+ if not is_array(arr):
+ return False
+
+ return True
+
+
+def is_nested_sequence(obj):
+ """Return True if object is a nested sequence.
+
+ A simple 1D sequence is considered to be a nested sequence.
+
+ Numpy arrays and h5py datasets are not considered to be nested sequences.
+
+ To test if an object is a nested sequence in a more general sense,
+ including arrays and datasets, use::
+
+ is_nested_sequence(obj) or is_array(obj)
+
+ :param obj: nested sequence (numpy array, h5py dataset...)
+ :return: boolean"""
+ # object must not be a numpy array
+ if is_array(obj):
+ return False
+
+ if not hasattr(obj, "__len__"):
+ return False
+
+ # obj must not be a list of (lists of) numpy arrays
+ subsequence = obj
+ while hasattr(subsequence, "__len__"):
+ if is_array(subsequence):
+ return False
+ # strings cause infinite loops
+ if isinstance(subsequence, six.string_types + (six.binary_type, )):
+ return True
+ subsequence = subsequence[0]
+
+ # object has __len__ and is not an array
+ return True
+
+
+def get_shape(array_like):
+ """Return shape of an array like object.
+
+ In case the object is a nested sequence but not an array or dataset
+ (list of lists, tuples...), the size of each dimension is assumed to be
+ uniform, and is deduced from the length of the first sequence.
+
+ :param array_like: Array like object: numpy array, hdf5 dataset,
+ multi-dimensional sequence
+ :return: Shape of array, as a tuple of integers
+ """
+ if hasattr(array_like, "shape"):
+ return array_like.shape
+
+ shape = []
+ subsequence = array_like
+ while hasattr(subsequence, "__len__"):
+ shape.append(len(subsequence))
+ # strings cause infinite loops
+ if isinstance(subsequence, six.string_types + (six.binary_type, )):
+ break
+ subsequence = subsequence[0]
+
+ return tuple(shape)
+
+
+def get_dtype(array_like):
+ """Return dtype of an array like object.
+
+ In the case of a nested sequence, the type of the first value
+ is inspected.
+
+ :param array_like: Array like object: numpy array, hdf5 dataset,
+ multi-dimensional nested sequence
+ :return: numpy dtype of object
+ """
+ if hasattr(array_like, "dtype"):
+ return array_like.dtype
+
+ subsequence = array_like
+ while hasattr(subsequence, "__len__"):
+ # strings cause infinite loops
+ if isinstance(subsequence, six.string_types + (six.binary_type, )):
+ break
+ subsequence = subsequence[0]
+
+ return numpy.dtype(type(subsequence))
+
+
+def get_concatenated_dtype(arrays):
+ """Return dtype of array resulting of concatenation
+ of a list of arrays (without actually concatenating
+ them).
+
+ :param arrays: list of numpy arrays
+ :return: resulting dtype after concatenating arrays
+ """
+ dtypes = {a.dtype for a in arrays}
+ dummy = []
+ for dt in dtypes:
+ dummy.append(numpy.zeros((1, 1), dtype=dt))
+ return numpy.array(dummy).dtype
+
+
+class ListOfImages(object):
+ """This class provides a way to access values and slices in a stack of
+ images stored as a list of 2D numpy arrays, without creating a 3D numpy
+ array first.
+
+ A transposition can be specified, as a 3-tuple of dimensions in the wanted
+ order. For example, to transpose from ``xyz`` ``(0, 1, 2)`` into ``yzx``,
+ the transposition tuple is ``(1, 2, 0)``
+
+ All the 2D arrays in the list must have the same shape.
+
+ The global dtype of the stack of images is the one that would be obtained
+ by casting the list of 2D arrays into a 3D numpy array.
+
+ :param images: list of 2D numpy arrays, or :class:`ListOfImages` object
+ :param transposition: Tuple of dimension numbers in the wanted order
+ """
+ def __init__(self, images, transposition=None):
+ """
+
+ """
+ super(ListOfImages, self).__init__()
+
+ # if images is a ListOfImages instance, get the underlying data
+ # as a list of 2D arrays
+ if isinstance(images, ListOfImages):
+ images = images.images
+
+ # test stack of images is as expected
+ assert is_list_of_arrays(images), \
+ "Image stack must be a list of arrays"
+ image0_shape = images[0].shape
+ for image in images:
+ assert image.ndim == 2, \
+ "Images must be 2D numpy arrays"
+ assert image.shape == image0_shape, \
+ "All images must have the same shape"
+
+ self.images = images
+ """List of images"""
+
+ self.shape = (len(images), ) + image0_shape
+ """Tuple of array dimensions"""
+ self.dtype = get_concatenated_dtype(images)
+ """Data-type of the global array"""
+ self.ndim = 3
+ """Number of array dimensions"""
+
+ self.size = len(images) * image0_shape[0] * image0_shape[1]
+ """Number of elements in the array."""
+
+ self.transposition = list(range(self.ndim))
+ """List of dimension indices, in an order depending on the
+ specified transposition. By default this is simply
+ [0, ..., self.ndim], but it can be changed by specifying a different
+ ``transposition`` parameter at initialization.
+
+ Use :meth:`transpose`, to create a new :class:`ListOfImages`
+ with a different :attr:`transposition`.
+ """
+
+ if transposition is not None:
+ assert len(transposition) == self.ndim
+ assert set(transposition) == set(list(range(self.ndim))), \
+ "Transposition must be a sequence containing all dimensions"
+ self.transposition = transposition
+ self.__sort_shape()
+
+ def __sort_shape(self):
+ """Sort shape in the order defined in :attr:`transposition`
+ """
+ new_shape = tuple(self.shape[dim] for dim in self.transposition)
+ self.shape = new_shape
+
+ def __sort_indices(self, indices):
+ """Return array indices sorted in the order needed
+ to access data in the original non-transposed images.
+
+ :param indices: Tuple of ndim indices, in the order needed
+ to access the transposed view
+ :return: Sorted tuple of indices, to access original data
+ """
+ assert len(indices) == self.ndim
+ sorted_indices = tuple(idx for (_, idx) in
+ sorted(zip(self.transposition, indices)))
+ return sorted_indices
+
+ def __array__(self, dtype=None):
+ """Cast the images into a numpy array, and return it.
+
+ If a transposition has been done on this images, return
+ a transposed view of a numpy array."""
+ return numpy.transpose(numpy.array(self.images, dtype=dtype),
+ self.transposition)
+
+ def __len__(self):
+ return self.shape[0]
+
+ def transpose(self, transposition=None):
+ """Return a re-ordered (dimensions permutated)
+ :class:`ListOfImages`.
+
+ The returned object refers to
+ the same images but with a different :attr:`transposition`.
+
+ :param list[int] transposition: List/tuple of dimension numbers in the
+ wanted order.
+ If ``None`` (default), reverse the dimensions.
+ :return: new :class:`ListOfImages` object
+ """
+ # by default, reverse the dimensions
+ if transposition is None:
+ transposition = list(reversed(self.transposition))
+
+ # If this ListOfImages is already transposed, sort new transposition
+ # relative to old transposition
+ elif list(self.transposition) != list(range(self.ndim)):
+ transposition = [self.transposition[i] for i in transposition]
+
+ return ListOfImages(self.images,
+ transposition)
+
+ @property
+ def T(self):
+ """
+ Same as self.transpose()
+
+ :return: DatasetView with dimensions reversed."""
+ return self.transpose()
+
+ def __getitem__(self, item):
+ """Handle a subset of numpy indexing with regards to the dimension
+ order as specified in :attr:`transposition`
+
+ Following features are **not supported**:
+
+ - fancy indexing using numpy arrays
+ - using ellipsis objects
+
+ :param item: Index
+ :return: value or slice as a numpy array
+ """
+ # 1-D slicing -> n-D slicing (n=1)
+ if not hasattr(item, "__len__"):
+ # first dimension index is given
+ item = [item]
+ # following dimensions are indexed with : (all elements)
+ item += [slice(None) for _i in range(self.ndim - 1)]
+
+ # n-dimensional slicing
+ if len(item) != self.ndim:
+ raise IndexError(
+ "N-dim slicing requires a tuple of N indices/slices. " +
+ "Needed dimensions: %d" % self.ndim)
+
+ # get list of indices sorted in the original images order
+ sorted_indices = self.__sort_indices(item)
+ list_idx, array_idx = sorted_indices[0], sorted_indices[1:]
+
+ images_selection = self.images[list_idx]
+
+ # now we must transpose the output data
+ output_dimensions = []
+ frozen_dimensions = []
+ for i, idx in enumerate(item):
+ # slices and sequences
+ if not isinstance(idx, int):
+ output_dimensions.append(self.transposition[i])
+ # regular integer index
+ else:
+ # whenever a dimension is fixed (indexed by an integer)
+ # the number of output dimension is reduced
+ frozen_dimensions.append(self.transposition[i])
+
+ # decrement output dimensions that are above frozen dimensions
+ for frozen_dim in reversed(sorted(frozen_dimensions)):
+ for i, out_dim in enumerate(output_dimensions):
+ if out_dim > frozen_dim:
+ output_dimensions[i] -= 1
+
+ assert (len(output_dimensions) + len(frozen_dimensions)) == self.ndim
+ assert set(output_dimensions) == set(range(len(output_dimensions)))
+
+ # single list elements selected
+ if isinstance(images_selection, numpy.ndarray):
+ return numpy.transpose(images_selection[array_idx],
+ axes=output_dimensions)
+ # muliple list elements selected
+ else:
+ # apply selection first
+ output_stack = []
+ for img in images_selection:
+ output_stack.append(img[array_idx])
+ # then cast into a numpy array, and transpose
+ return numpy.transpose(numpy.array(output_stack),
+ axes=output_dimensions)
+
+ def min(self):
+ """
+ :return: Global minimum value
+ """
+ min_value = self.images[0].min()
+ if len(self.images) > 1:
+ for img in self.images[1:]:
+ min_value = min(min_value, img.min())
+ return min_value
+
+ def max(self):
+ """
+ :return: Global maximum value
+ """
+ max_value = self.images[0].max()
+ if len(self.images) > 1:
+ for img in self.images[1:]:
+ max_value = max(max_value, img.max())
+ return max_value
+
+
+class DatasetView(object):
+ """This class provides a way to transpose a dataset without
+ casting it into a numpy array. This way, the dataset in a file need not
+ necessarily be integrally read into memory to view it in a different
+ transposition.
+
+ .. note::
+ The performances depend a lot on the way the dataset was written
+ to file. Depending on the chunking strategy, reading a complete 2D slice
+ in an unfavorable direction may still require the entire dataset to
+ be read from disk.
+
+ :param dataset: h5py dataset
+ :param transposition: List of dimensions sorted in the order of
+ transposition (relative to the original h5py dataset)
+ """
+ def __init__(self, dataset, transposition=None):
+ """
+
+ """
+ super(DatasetView, self).__init__()
+ self.dataset = dataset
+ """original dataset"""
+
+ self.shape = dataset.shape
+ """Tuple of array dimensions"""
+ self.dtype = dataset.dtype
+ """Data-type of the array’s element"""
+ self.ndim = len(dataset.shape)
+ """Number of array dimensions"""
+
+ size = 0
+ if self.ndim:
+ size = 1
+ for dimsize in self.shape:
+ size *= dimsize
+ self.size = size
+ """Number of elements in the array."""
+
+ self.transposition = list(range(self.ndim))
+ """List of dimension indices, in an order depending on the
+ specified transposition. By default this is simply
+ [0, ..., self.ndim], but it can be changed by specifying a different
+ `transposition` parameter at initialization.
+
+ Use :meth:`transpose`, to create a new :class:`DatasetView`
+ with a different :attr:`transposition`.
+ """
+
+ if transposition is not None:
+ assert len(transposition) == self.ndim
+ assert set(transposition) == set(list(range(self.ndim))), \
+ "Transposition must be a list containing all dimensions"
+ self.transposition = transposition
+ self.__sort_shape()
+
+ def __sort_shape(self):
+ """Sort shape in the order defined in :attr:`transposition`
+ """
+ new_shape = tuple(self.shape[dim] for dim in self.transposition)
+ self.shape = new_shape
+
+ def __sort_indices(self, indices):
+ """Return array indices sorted in the order needed
+ to access data in the original non-transposed dataset.
+
+ :param indices: Tuple of ndim indices, in the order needed
+ to access the view
+ :return: Sorted tuple of indices, to access original data
+ """
+ assert len(indices) == self.ndim
+ sorted_indices = tuple(idx for (_, idx) in
+ sorted(zip(self.transposition, indices)))
+ return sorted_indices
+
+ def __getitem__(self, item):
+ """Handle fancy indexing with regards to the dimension order as
+ specified in :attr:`transposition`
+
+ The supported fancy-indexing syntax is explained at
+ http://docs.h5py.org/en/latest/high/dataset.html#fancy-indexing.
+
+ Additional restrictions exist if the data has been transposed:
+
+ - numpy boolean array indexing is not supported
+ - ellipsis objects are not supported
+
+ :param item: Index, possibly fancy index (must be supported by h5py)
+ :return: Sliced numpy array or numpy scalar
+ """
+ # no transposition, let the original dataset handle indexing
+ if self.transposition == list(range(self.ndim)):
+ return self.dataset[item]
+
+ # 1-D slicing: create a list of indices to switch to n-D slicing
+ if not hasattr(item, "__len__"):
+ # first dimension index (list index) is given
+ item = [item]
+ # following dimensions are indexed with slices representing all elements
+ item += [slice(None) for _i in range(self.ndim - 1)]
+
+ # n-dimensional slicing
+ if len(item) != self.ndim:
+ raise IndexError(
+ "N-dim slicing requires a tuple of N indices/slices. " +
+ "Needed dimensions: %d" % self.ndim)
+
+ # get list of indices sorted in the original dataset order
+ sorted_indices = self.__sort_indices(item)
+
+ output_data_not_transposed = self.dataset[sorted_indices]
+
+ # now we must transpose the output data
+ output_dimensions = []
+ frozen_dimensions = []
+ for i, idx in enumerate(item):
+ # slices and sequences
+ if not isinstance(idx, int):
+ output_dimensions.append(self.transposition[i])
+ # regular integer index
+ else:
+ # whenever a dimension is fixed (indexed by an integer)
+ # the number of output dimension is reduced
+ frozen_dimensions.append(self.transposition[i])
+
+ # decrement output dimensions that are above frozen dimensions
+ for frozen_dim in reversed(sorted(frozen_dimensions)):
+ for i, out_dim in enumerate(output_dimensions):
+ if out_dim > frozen_dim:
+ output_dimensions[i] -= 1
+
+ assert (len(output_dimensions) + len(frozen_dimensions)) == self.ndim
+ assert set(output_dimensions) == set(range(len(output_dimensions)))
+
+ return numpy.transpose(output_data_not_transposed,
+ axes=output_dimensions)
+
+ def __array__(self, dtype=None):
+ """Cast the dataset into a numpy array, and return it.
+
+ If a transposition has been done on this dataset, return
+ a transposed view of a numpy array."""
+ return numpy.transpose(numpy.array(self.dataset, dtype=dtype),
+ self.transposition)
+
+ def __len__(self):
+ return self.shape[0]
+
+ def transpose(self, transposition=None):
+ """Return a re-ordered (dimensions permutated)
+ :class:`DatasetView`.
+
+ The returned object refers to
+ the same dataset but with a different :attr:`transposition`.
+
+ :param list[int] transposition: List of dimension numbers in the wanted order.
+ If ``None`` (default), reverse the dimensions.
+ :return: Transposed DatasetView
+ """
+ # by default, reverse the dimensions
+ if transposition is None:
+ transposition = list(reversed(self.transposition))
+
+ # If this DatasetView is already transposed, sort new transposition
+ # relative to old transposition
+ elif list(self.transposition) != list(range(self.ndim)):
+ transposition = [self.transposition[i] for i in transposition]
+
+ return DatasetView(self.dataset,
+ transposition)
+
+ @property
+ def T(self):
+ """
+ Same as self.transpose()
+
+ :return: DatasetView with dimensions reversed."""
+ return self.transpose()
diff --git a/silx/utils/decorators.py b/silx/utils/decorators.py
new file mode 100644
index 0000000..ff70e38
--- /dev/null
+++ b/silx/utils/decorators.py
@@ -0,0 +1,71 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Bunch of useful decorators"""
+
+from __future__ import absolute_import, print_function, division
+
+__authors__ = ["Jerome Kieffer"]
+__license__ = "MIT"
+__date__ = "01/03/2017"
+
+import os
+import sys
+import traceback
+import logging
+import functools
+
+
+depreclog = logging.getLogger("DEPRECATION")
+
+
+def deprecated(func=None, reason=None, replacement=None, since_version=None):
+ """
+ Decorator that deprecates the use of a function
+
+ :param str reason: Reason for deprecating this function
+ (e.g. "feature no longer provided",
+ :param str replacement: Name of replacement function (if the reason for
+ deprecating was to rename the function)
+ :param str since_version: First *silx* version for which the function was
+ deprecated (e.g. "0.5.0").
+ """
+ def decorator(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ name = func.func_name if sys.version_info[0] < 3 else func.__name__
+ msg = "%s is deprecated"
+ if since_version is not None:
+ msg += " since silx version %s" % since_version
+ msg += "!"
+ if reason is not None:
+ msg += " Reason: %s." % reason
+ if replacement is not None:
+ msg += " Use '%s' instead." % replacement
+ depreclog.warning(msg + " %s", name, os.linesep.join([""] + traceback.format_stack()[:-1]))
+ return func(*args, **kwargs)
+ return wrapper
+ if func is not None:
+ return decorator(func)
+ return decorator
diff --git a/silx/utils/html.py b/silx/utils/html.py
new file mode 100644
index 0000000..aab25f2
--- /dev/null
+++ b/silx/utils/html.py
@@ -0,0 +1,60 @@
+# 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.
+#
+# ###########################################################################*/
+"""Utils function relative to HTML
+"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "19/09/2016"
+
+
+def escape(string, quote=True):
+ """Returns a string where HTML metacharacters are properly escaped.
+
+ Compatibility layer to avoid incompatibilities between Python versions,
+ Qt versions and Qt bindings.
+
+ >>> import silx.utils.html
+ >>> silx.utils.html.escape("<html>")
+ >>> "&lt;html&gt;"
+
+ .. note:: Since Python 3.3 you can use the `html` module. For previous
+ version, it is provided by `sgi` module.
+ .. note:: Qt4 provides it with `Qt.escape` while Qt5 provide it with
+ `QString.toHtmlEscaped`. But `QString` is not exposed by `PyQt` or
+ `PySide`.
+
+ :param str string: Human readable string.
+ :param bool quote: Escape quote and double quotes (default behaviour).
+ :returns: Valid HTML syntax to display the input string.
+ :rtype: str
+ """
+ string = string.replace("&", "&amp;") # must be done first
+ string = string.replace("<", "&lt;")
+ string = string.replace(">", "&gt;")
+ if quote:
+ string = string.replace("'", "&apos;")
+ string = string.replace("\"", "&quot;")
+ return string
diff --git a/silx/utils/launcher.py b/silx/utils/launcher.py
new file mode 100644
index 0000000..8d2c81c
--- /dev/null
+++ b/silx/utils/launcher.py
@@ -0,0 +1,303 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-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.
+#
+# ###########################################################################*/
+"""This module define silx application available throug the silx launcher.
+"""
+
+__authors__ = ["P. Knobel", "V. Valls"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import sys
+import importlib
+import contextlib
+import argparse
+import logging
+
+
+_logger = logging.getLogger(__name__)
+
+
+class LauncherCommand():
+ """Description of a command"""
+
+ def __init__(self, name, description=None, module_name=None, function=None):
+ """
+ Constructor
+
+ :param str name: Name of the command
+ :param str description: Description of the command
+ :param str module_name: Module name to execute
+ :param callable function: Python function to execute
+ """
+ self.name = name
+ self.module_name = module_name
+ if description is None:
+ description = "A command"
+ self.description = description
+ self.function = function
+
+ def get_module(self):
+ """Returns the python module to execute. If any.
+
+ :rtype: module
+ """
+ try:
+ module = importlib.import_module(self.module_name)
+ return module
+ except ImportError as e:
+ if "No module name" in e.args[0]:
+ msg = "Error while reaching module '%s'"
+ _logger.debug(msg, self.module_name, exc_info=True)
+ missing_module = e.args[0].split("'")[1]
+ msg = "Module '%s' is not installed but is mandatory."\
+ + " You can install it using \"pip install %s\"."
+ _logger.error(msg, missing_module, missing_module)
+ else:
+ msg = "Error while reaching module '%s'"
+ _logger.error(msg, self.module_name, exc_info=True)
+ return None
+
+ def get_function(self):
+ """Returns the main function to execute.
+
+ :rtype: callable
+ """
+ if self.function is not None:
+ return self.function
+ else:
+ module = self.get_module()
+ if module is None:
+ _logger.error("Imposible to load module name '%s'" % self.module_name)
+ return None
+
+ # reach the 'main' function
+ if not hasattr(module, "main"):
+ raise TypeError("Module excpect to have a 'main' function")
+ else:
+ main = getattr(module, "main")
+ return main
+
+ @contextlib.contextmanager
+ def get_env(self, argv):
+ """Fix the environement before and after executing the command.
+
+ :param list argv: The list of arguments (the first one is the name of
+ the application and command)
+ :rtype: int
+ """
+
+ # fix the context
+ old_argv = sys.argv
+ sys.argv = argv
+
+ try:
+ yield
+ finally:
+ # clean up the context
+ sys.argv = old_argv
+
+ def execute(self, argv):
+ """Execute the command.
+
+ :param list[str] argv: The list of arguments (the first one is the
+ name of the application and command)
+ :rtype: int
+ :returns: The execution status
+ """
+ with self.get_env(argv):
+ func = self.get_function()
+ if func is None:
+ _logger.error("Imposible to execute the command '%s'" % self.name)
+ return -1
+ try:
+ status = func(argv)
+ except SystemExit as e:
+ # ArgumentParser likes to finish with a sys.exit
+ status = e.args[0]
+ return status
+
+
+class Launcher(object):
+ """
+ Manage launch of module.
+
+ Provides an API to describe available commands and feature to display help
+ and execute the commands.
+ """
+
+ def __init__(self,
+ prog=None,
+ usage=None,
+ description=None,
+ epilog=None,
+ version=None):
+ """
+ :param str prog: Name of the program. If it is not defined it uses the
+ first argument of `sys.argv`
+ :param str usage: Custom the string explaining the usage. Else it is
+ autogenerated.
+ :param str description: Description of the application displayed after the
+ usage.
+ :param str epilog: Custom the string displayed at the end of the help.
+ :param str version: Define the version of the application.
+ """
+ if prog is None:
+ prog = sys.argv[0]
+ self.prog = prog
+ self.usage = usage
+ self.description = description
+ self.epilog = epilog
+ self.version = version
+ self._commands = {}
+
+ help_command = LauncherCommand(
+ "help",
+ description="Show help of the following command",
+ function=self.execute_help)
+ self.add_command(command=help_command)
+
+ def add_command(self, name=None, module_name=None, description=None, command=None):
+ """
+ Add a command to the launcher.
+
+ See also `LauncherCommand`.
+
+ :param str name: Name of the command
+ :param str module_name: Module to execute
+ :param str description: Description of the command
+ :param LauncherCommand command: A `LauncherCommand`
+ """
+ if command is not None:
+ assert(name is None and module_name is None and description is None)
+ else:
+ command = LauncherCommand(
+ name=name,
+ description=description,
+ module_name=module_name)
+ self._commands[command.name] = command
+
+ def print_help(self):
+ """Print the help to stdout.
+ """
+ usage = self.usage
+ if usage is None:
+ usage = "usage: {0.prog} [--version|--help] <command> [<args>]"
+ description = self.description
+ epilog = self.epilog
+ if epilog is None:
+ epilog = "See '{0.prog} help <command>' to read about a specific subcommand"
+
+ print(usage.format(self))
+ print("")
+ if description is not None:
+ print(description)
+ print("")
+ print("The {0.prog} commands are:".format(self))
+ commands = sorted(self._commands.keys())
+ for command in commands:
+ command = self._commands[command]
+ print(" {:10s} {:s}".format(command.name, command.description))
+ print("")
+ print(epilog.format(self))
+
+ def execute_help(self, argv):
+ """Execute the help command.
+
+ :param list[str] argv: The list of arguments (the first one is the
+ name of the application with the help command)
+ :rtype: int
+ :returns: The execution status
+ """
+ description = "Display help information about %s" % self.prog
+ parser = argparse.ArgumentParser(description=description)
+ parser.add_argument(
+ 'command',
+ default=None,
+ nargs=argparse.OPTIONAL,
+ help='Command in which aving help')
+
+ try:
+ options = parser.parse_args(argv[1:])
+ except SystemExit as e:
+ # ArgumentParser likes to finish with a sys.exit
+ return e.args[0]
+
+ command_name = options.command
+ if command_name is None:
+ self.print_help()
+ return 0
+
+ if command_name not in self._commands:
+ print("Unknown command: %s", command_name)
+ self.print_help()
+ return -1
+
+ command = self._commands[command_name]
+ prog = "%s %s" % (self.prog, command.name)
+ return command.execute([prog, "--help"])
+
+ def execute(self, argv=None):
+ """Execute the launcher.
+
+ :param list[str] argv: The list of arguments (the first one is the
+ name of the application)
+ :rtype: int
+ :returns: The execution status
+ """
+ if argv is None:
+ argv = sys.argv
+
+ if len(argv) <= 1:
+ self.print_help()
+ return 0
+
+ command_name = argv[1]
+
+ if command_name == "--version":
+ print("%s version %s" % (self.prog, str(self.version)))
+ return 0
+
+ if command_name in ["--help", "-h"]:
+ # Special help command
+ if len(argv) == 2:
+ self.print_help()
+ return 0
+ else:
+ command_name = argv[2]
+ command_argv = argv[2:] + ["--help"]
+ command_argv[0] = "%s %s" % (self.prog, command_argv[0])
+ else:
+ command_argv = argv[1:]
+ command_argv[0] = "%s %s" % (self.prog, command_argv[0])
+
+ if command_name not in self._commands:
+ print("Unknown command: %s" % command_name)
+ self.print_help()
+ return -1
+
+ command = self._commands[command_name]
+ return command.execute(command_argv)
diff --git a/silx/utils/setup.py b/silx/utils/setup.py
new file mode 100644
index 0000000..1f3e09a
--- /dev/null
+++ b/silx/utils/setup.py
@@ -0,0 +1,43 @@
+# 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.
+#
+# ###########################################################################*/
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "24/08/2016"
+
+
+from numpy.distutils.misc_util import Configuration
+
+
+def configuration(parent_package='', top_path=None):
+ config = Configuration('utils', parent_package, top_path)
+ config.add_subpackage('test')
+
+ return config
+
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+
+ setup(configuration=configuration)
diff --git a/silx/utils/test/__init__.py b/silx/utils/test/__init__.py
new file mode 100644
index 0000000..68e7412
--- /dev/null
+++ b/silx/utils/test/__init__.py
@@ -0,0 +1,43 @@
+# 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.
+#
+# ###########################################################################*/
+__authors__ = ["T. Vincent", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import unittest
+from .test_weakref import suite as test_weakref_suite
+from .test_html import suite as test_html_suite
+from .test_array_like import suite as test_array_like_suite
+from .test_launcher import suite as test_launcher_suite
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(test_weakref_suite())
+ test_suite.addTest(test_html_suite())
+ test_suite.addTest(test_array_like_suite())
+ test_suite.addTest(test_launcher_suite())
+ return test_suite
diff --git a/silx/utils/test/test_array_like.py b/silx/utils/test/test_array_like.py
new file mode 100644
index 0000000..7cd004c
--- /dev/null
+++ b/silx/utils/test/test_array_like.py
@@ -0,0 +1,453 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 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.
+#
+# ###########################################################################*/
+"""Tests for array_like module"""
+
+__authors__ = ["P. Knobel"]
+__license__ = "MIT"
+__date__ = "09/01/2017"
+
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+import numpy
+import os
+import tempfile
+import unittest
+
+from ..array_like import DatasetView, ListOfImages
+from ..array_like import get_dtype, get_concatenated_dtype, get_shape,\
+ is_array, is_nested_sequence, is_list_of_arrays
+
+
+@unittest.skipIf(h5py is None,
+ "h5py is needed to test DatasetView")
+class TestTransposedDatasetView(unittest.TestCase):
+
+ def setUp(self):
+ # dataset attributes
+ self.ndim = 3
+ self.original_shape = (5, 10, 20)
+ self.size = 1
+ for dim in self.original_shape:
+ self.size *= dim
+
+ self.volume = numpy.arange(self.size).reshape(self.original_shape)
+
+ self.tempdir = tempfile.mkdtemp()
+ self.h5_fname = os.path.join(self.tempdir, "tempfile.h5")
+ with h5py.File(self.h5_fname, "w") as f:
+ f["volume"] = self.volume
+
+ self.h5f = h5py.File(self.h5_fname, "r")
+
+ self.all_permutations = [(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0),
+ (2, 0, 1), (2, 1, 0)]
+
+ def tearDown(self):
+ self.h5f.close()
+ os.unlink(self.h5_fname)
+ os.rmdir(self.tempdir)
+
+ def _testSize(self, obj):
+ """These assertions apply to all following test cases"""
+ self.assertEqual(obj.ndim, self.ndim)
+ self.assertEqual(obj.size, self.size)
+ size_from_shape = 1
+ for dim in obj.shape:
+ size_from_shape *= dim
+ self.assertEqual(size_from_shape, self.size)
+
+ for dim in self.original_shape:
+ self.assertIn(dim, obj.shape)
+
+ def testNoTransposition(self):
+ """no transposition (transposition = (0, 1, 2))"""
+ a = DatasetView(self.h5f["volume"])
+
+ self.assertEqual(a.shape, self.original_shape)
+ self._testSize(a)
+
+ # reversing the dimensions twice results in no change
+ rtrans = list(reversed(range(self.ndim)))
+ self.assertTrue(numpy.array_equal(
+ a,
+ a.transpose(rtrans).transpose(rtrans)))
+
+ for i in range(a.shape[0]):
+ for j in range(a.shape[1]):
+ for k in range(a.shape[2]):
+ self.assertEqual(self.h5f["volume"][i, j, k],
+ a[i, j, k])
+
+ def _testTransposition(self, transposition):
+ """test transposed dataset
+
+ :param tuple transposition: List of dimensions (0... n-1) sorted
+ in the desired order
+ """
+ a = DatasetView(self.h5f["volume"],
+ transposition=transposition)
+ self._testSize(a)
+
+ # sort shape of transposed object, to hopefully find the original shape
+ sorted_shape = tuple(dim_size for (_, dim_size) in
+ sorted(zip(transposition, a.shape)))
+ self.assertEqual(sorted_shape, self.original_shape)
+
+ a_as_array = numpy.array(self.h5f["volume"]).transpose(transposition)
+
+ # test the __array__ method
+ self.assertTrue(numpy.array_equal(
+ numpy.array(a),
+ a_as_array))
+
+ # test slicing
+ for selection in [(2, slice(None), slice(None)),
+ (slice(None), 1, slice(0, 8)),
+ (slice(0, 3), slice(None), 3),
+ (1, 3, slice(None)),
+ (slice(None), 2, 1),
+ (4, slice(1, 9, 2), 2)]:
+ self.assertIsInstance(a[selection], numpy.ndarray)
+ self.assertTrue(numpy.array_equal(
+ a[selection],
+ a_as_array[selection]))
+
+ # test the DatasetView.__getitem__ for single values
+ # (step adjusted to test at least 3 indices in each dimension)
+ for i in range(0, a.shape[0], a.shape[0] // 3):
+ for j in range(0, a.shape[1], a.shape[1] // 3):
+ for k in range(0, a.shape[2], a.shape[2] // 3):
+ sorted_indices = tuple(idx for (_, idx) in
+ sorted(zip(transposition, [i, j, k])))
+ viewed_value = a[i, j, k]
+ corresponding_original_value = self.h5f["volume"][sorted_indices]
+ self.assertEqual(viewed_value,
+ corresponding_original_value)
+
+ # reversing the dimensions twice results in no change
+ rtrans = list(reversed(range(self.ndim)))
+ self.assertTrue(numpy.array_equal(
+ a,
+ a.transpose(rtrans).transpose(rtrans)))
+
+ # test .T property
+ self.assertTrue(numpy.array_equal(
+ a.T,
+ a.transpose(rtrans)))
+
+ def testTransposition012(self):
+ """transposition = (0, 1, 2)
+ (should be the same as testNoTransposition)"""
+ self._testTransposition((0, 1, 2))
+
+ def testTransposition021(self):
+ """transposition = (0, 2, 1)"""
+ self._testTransposition((0, 2, 1))
+
+ def testTransposition102(self):
+ """transposition = (1, 0, 2)"""
+ self._testTransposition((1, 0, 2))
+
+ def testTransposition120(self):
+ """transposition = (1, 2, 0)"""
+ self._testTransposition((1, 2, 0))
+
+ def testTransposition201(self):
+ """transposition = (2, 0, 1)"""
+ self._testTransposition((2, 0, 1))
+
+ def testTransposition210(self):
+ """transposition = (2, 1, 0)"""
+ self._testTransposition((2, 1, 0))
+
+ def testAllDoubleTranspositions(self):
+ for trans1 in self.all_permutations:
+ for trans2 in self.all_permutations:
+ self._testDoubleTransposition(trans1, trans2)
+
+ def _testDoubleTransposition(self, transposition1, transposition2):
+ a = DatasetView(self.h5f["volume"],
+ transposition=transposition1).transpose(transposition2)
+
+ b = self.volume.transpose(transposition1).transpose(transposition2)
+
+ self.assertTrue(numpy.array_equal(a, b),
+ "failed with double transposition %s %s" % (transposition1, transposition2))
+
+ def test1DIndex(self):
+ a = DatasetView(self.h5f["volume"])
+ self.assertTrue(numpy.array_equal(self.volume[1],
+ a[1]))
+
+ b = DatasetView(self.h5f["volume"], transposition=(1, 0, 2))
+ self.assertTrue(numpy.array_equal(self.volume[:, 1, :],
+ b[1]))
+
+
+class TestTransposedListOfImages(unittest.TestCase):
+ def setUp(self):
+ # images attributes
+ self.ndim = 3
+ self.original_shape = (5, 10, 20)
+ self.size = 1
+ for dim in self.original_shape:
+ self.size *= dim
+
+ volume = numpy.arange(self.size).reshape(self.original_shape)
+
+ self.images = []
+ for i in range(self.original_shape[0]):
+ self.images.append(
+ volume[i])
+
+ self.images_as_3D_array = numpy.array(self.images)
+
+ self.all_permutations = [(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0),
+ (2, 0, 1), (2, 1, 0)]
+
+ def tearDown(self):
+ pass
+
+ def _testSize(self, obj):
+ """These assertions apply to all following test cases"""
+ self.assertEqual(obj.ndim, self.ndim)
+ self.assertEqual(obj.size, self.size)
+ size_from_shape = 1
+ for dim in obj.shape:
+ size_from_shape *= dim
+ self.assertEqual(size_from_shape, self.size)
+
+ for dim in self.original_shape:
+ self.assertIn(dim, obj.shape)
+
+ def testNoTransposition(self):
+ """no transposition (transposition = (0, 1, 2))"""
+ a = ListOfImages(self.images)
+
+ self.assertEqual(a.shape, self.original_shape)
+ self._testSize(a)
+
+ for i in range(a.shape[0]):
+ for j in range(a.shape[1]):
+ for k in range(a.shape[2]):
+ self.assertEqual(self.images[i][j, k],
+ a[i, j, k])
+
+ # reversing the dimensions twice results in no change
+ rtrans = list(reversed(range(self.ndim)))
+ self.assertTrue(numpy.array_equal(
+ a,
+ a.transpose(rtrans).transpose(rtrans)))
+
+ # test .T property
+ self.assertTrue(numpy.array_equal(
+ a.T,
+ a.transpose(rtrans)))
+
+ def _testTransposition(self, transposition):
+ """test transposed dataset
+
+ :param tuple transposition: List of dimensions (0... n-1) sorted
+ in the desired order
+ """
+ a = ListOfImages(self.images,
+ transposition=transposition)
+ self._testSize(a)
+
+ # sort shape of transposed object, to hopefully find the original shape
+ sorted_shape = tuple(dim_size for (_, dim_size) in
+ sorted(zip(transposition, a.shape)))
+ self.assertEqual(sorted_shape, self.original_shape)
+
+ a_as_array = numpy.array(self.images).transpose(transposition)
+
+ # test the DatasetView.__array__ method
+ self.assertTrue(numpy.array_equal(
+ numpy.array(a),
+ a_as_array))
+
+ # test slicing
+ for selection in [(2, slice(None), slice(None)),
+ (slice(None), 1, slice(0, 8)),
+ (slice(0, 3), slice(None), 3),
+ (1, 3, slice(None)),
+ (slice(None), 2, 1),
+ (4, slice(1, 9, 2), 2)]:
+ self.assertIsInstance(a[selection], numpy.ndarray)
+ self.assertTrue(numpy.array_equal(
+ a[selection],
+ a_as_array[selection]))
+
+ # test the DatasetView.__getitem__ for single values
+ # (step adjusted to test at least 3 indices in each dimension)
+ for i in range(0, a.shape[0], a.shape[0] // 3):
+ for j in range(0, a.shape[1], a.shape[1] // 3):
+ for k in range(0, a.shape[2], a.shape[2] // 3):
+ viewed_value = a[i, j, k]
+ sorted_indices = tuple(idx for (_, idx) in
+ sorted(zip(transposition, [i, j, k])))
+ corresponding_original_value = self.images[sorted_indices[0]][sorted_indices[1:]]
+ self.assertEqual(viewed_value,
+ corresponding_original_value)
+
+ # reversing the dimensions twice results in no change
+ rtrans = list(reversed(range(self.ndim)))
+ self.assertTrue(numpy.array_equal(
+ a,
+ a.transpose(rtrans).transpose(rtrans)))
+
+ # test .T property
+ self.assertTrue(numpy.array_equal(
+ a.T,
+ a.transpose(rtrans)))
+
+ def _testDoubleTransposition(self, transposition1, transposition2):
+ a = ListOfImages(self.images,
+ transposition=transposition1).transpose(transposition2)
+
+ b = self.images_as_3D_array.transpose(transposition1).transpose(transposition2)
+
+ self.assertTrue(numpy.array_equal(a, b),
+ "failed with double transposition %s %s" % (transposition1, transposition2))
+
+ def testTransposition012(self):
+ """transposition = (0, 1, 2)
+ (should be the same as testNoTransposition)"""
+ self._testTransposition((0, 1, 2))
+
+ def testTransposition021(self):
+ """transposition = (0, 2, 1)"""
+ self._testTransposition((0, 2, 1))
+
+ def testTransposition102(self):
+ """transposition = (1, 0, 2)"""
+ self._testTransposition((1, 0, 2))
+
+ def testTransposition120(self):
+ """transposition = (1, 2, 0)"""
+ self._testTransposition((1, 2, 0))
+
+ def testTransposition201(self):
+ """transposition = (2, 0, 1)"""
+ self._testTransposition((2, 0, 1))
+
+ def testTransposition210(self):
+ """transposition = (2, 1, 0)"""
+ self._testTransposition((2, 1, 0))
+
+ def testAllDoubleTranspositions(self):
+ for trans1 in self.all_permutations:
+ for trans2 in self.all_permutations:
+ self._testDoubleTransposition(trans1, trans2)
+
+ def test1DIndex(self):
+ a = ListOfImages(self.images)
+ self.assertTrue(numpy.array_equal(self.images[1],
+ a[1]))
+
+ b = ListOfImages(self.images, transposition=(1, 0, 2))
+ self.assertTrue(numpy.array_equal(self.images_as_3D_array[:, 1, :],
+ b[1]))
+
+
+class TestFunctions(unittest.TestCase):
+ """Test functions to guess the dtype and shape of an array_like
+ object"""
+ def testListOfLists(self):
+ l = [[0, 1, 2], [2, 3, 4]]
+ self.assertEqual(get_dtype(l),
+ numpy.dtype(int))
+ self.assertEqual(get_shape(l),
+ (2, 3))
+ self.assertTrue(is_nested_sequence(l))
+ self.assertFalse(is_array(l))
+ self.assertFalse(is_list_of_arrays(l))
+
+ l = [[0., 1.], [2., 3.]]
+ self.assertEqual(get_dtype(l),
+ numpy.dtype(float))
+ self.assertEqual(get_shape(l),
+ (2, 2))
+ self.assertTrue(is_nested_sequence(l))
+ self.assertFalse(is_array(l))
+ self.assertFalse(is_list_of_arrays(l))
+
+ # concatenated dtype of int and float
+ l = [numpy.array([[0, 1, 2], [2, 3, 4]]),
+ numpy.array([[0., 1., 2.], [2., 3., 4.]])]
+
+ self.assertEqual(get_concatenated_dtype(l),
+ numpy.array(l).dtype)
+ self.assertEqual(get_shape(l),
+ (2, 2, 3))
+ self.assertFalse(is_nested_sequence(l))
+ self.assertFalse(is_array(l))
+ self.assertTrue(is_list_of_arrays(l))
+
+ def testNumpyArray(self):
+ a = numpy.array([[0, 1], [2, 3]])
+ self.assertEqual(get_dtype(a),
+ a.dtype)
+ self.assertFalse(is_nested_sequence(a))
+ self.assertTrue(is_array(a))
+ self.assertFalse(is_list_of_arrays(a))
+
+ @unittest.skipIf(h5py is None,
+ "h5py is needed for this test")
+ def testH5pyDataset(self):
+ a = numpy.array([[0, 1], [2, 3]])
+
+ tempdir = tempfile.mkdtemp()
+ h5_fname = os.path.join(tempdir, "tempfile.h5")
+ with h5py.File(h5_fname, "w") as h5f:
+ h5f["dataset"] = a
+ d = h5f["dataset"]
+
+ self.assertEqual(get_dtype(d),
+ numpy.dtype(int))
+ self.assertFalse(is_nested_sequence(d))
+ self.assertTrue(is_array(d))
+ self.assertFalse(is_list_of_arrays(d))
+
+ os.unlink(h5_fname)
+ os.rmdir(tempdir)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestTransposedDatasetView))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestTransposedListOfImages))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestFunctions))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/utils/test/test_html.py b/silx/utils/test/test_html.py
new file mode 100644
index 0000000..2d0387b
--- /dev/null
+++ b/silx/utils/test/test_html.py
@@ -0,0 +1,61 @@
+# 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.
+#
+# ###########################################################################*/
+"""Tests for html module"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "19/09/2016"
+
+
+import unittest
+from .. import html
+
+
+class TestHtml(unittest.TestCase):
+ """Tests for html module."""
+
+ def testLtGt(self):
+ result = html.escape("<html>'\"")
+ self.assertEquals("&lt;html&gt;&apos;&quot;", result)
+
+ def testLtAmpGt(self):
+ # '&' have to be escaped first
+ result = html.escape("<&>")
+ self.assertEquals("&lt;&amp;&gt;", result)
+
+ def testNoQuotes(self):
+ result = html.escape("\"m&m's\"", quote=False)
+ self.assertEquals("\"m&amp;m's\"", result)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestHtml))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/utils/test/test_launcher.py b/silx/utils/test/test_launcher.py
new file mode 100644
index 0000000..b3b6f98
--- /dev/null
+++ b/silx/utils/test/test_launcher.py
@@ -0,0 +1,204 @@
+# 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.
+#
+# ###########################################################################*/
+"""Tests for html module"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import sys
+import unittest
+from silx.test.utils import ParametricTestCase
+from .. import launcher
+
+
+class CallbackMock():
+
+ def __init__(self, result=None):
+ self._execute_count = 0
+ self._execute_argv = None
+ self._result = result
+
+ def execute(self, argv):
+ self._execute_count = self._execute_count + 1
+ self._execute_argv = argv
+ return self._result
+
+ def __call__(self, argv):
+ return self.execute(argv)
+
+
+class TestLauncherCommand(unittest.TestCase):
+ """Tests for launcher class."""
+
+ def testEnv(self):
+ command = launcher.LauncherCommand("foo")
+ old = sys.argv
+ params = ["foo", "bar"]
+ with command.get_env(params):
+ self.assertEqual(params, sys.argv)
+ self.assertEqual(sys.argv, old)
+
+ def testEnvWhileException(self):
+ command = launcher.LauncherCommand("foo")
+ old = sys.argv
+ params = ["foo", "bar"]
+ try:
+ with command.get_env(params):
+ raise RuntimeError()
+ except RuntimeError:
+ pass
+ self.assertEqual(sys.argv, old)
+
+ def testExecute(self):
+ params = ["foo", "bar"]
+ callback = CallbackMock(result=42)
+ command = launcher.LauncherCommand("foo", function=callback)
+ status = command.execute(params)
+ self.assertEqual(callback._execute_count, 1)
+ self.assertEqual(callback._execute_argv, params)
+ self.assertEqual(status, 42)
+
+
+class TestModuleCommand(ParametricTestCase):
+
+ def setUp(self):
+ module_name = "silx.utils.test.test_launcher_command"
+ command = launcher.LauncherCommand("foo", module_name=module_name)
+ self.command = command
+
+ def testHelp(self):
+ status = self.command.execute(["--help"])
+ self.assertEqual(status, 0)
+
+ def testException(self):
+ try:
+ self.command.execute(["exception"])
+ self.fail()
+ except RuntimeError:
+ pass
+
+ def testCall(self):
+ status = self.command.execute([])
+ self.assertEqual(status, 0)
+
+ def testError(self):
+ status = self.command.execute(["error"])
+ self.assertEqual(status, -1)
+
+
+class TestLauncher(ParametricTestCase):
+ """Tests for launcher class."""
+
+ def testCallCommand(self):
+ callback = CallbackMock(result=42)
+ runner = launcher.Launcher(prog="prog")
+ command = launcher.LauncherCommand("foo", function=callback)
+ runner.add_command(command=command)
+ status = runner.execute(["prog", "foo", "param1", "param2"])
+ self.assertEquals(status, 42)
+ self.assertEquals(callback._execute_argv, ["prog foo", "param1", "param2"])
+ self.assertEquals(callback._execute_count, 1)
+
+ def testAddCommand(self):
+ runner = launcher.Launcher(prog="prog")
+ module_name = "silx.utils.test.test_launcher_command"
+ runner.add_command("foo", module_name=module_name)
+ status = runner.execute(["prog", "foo"])
+ self.assertEquals(status, 0)
+
+ def testCallHelpOnCommand(self):
+ callback = CallbackMock(result=42)
+ runner = launcher.Launcher(prog="prog")
+ command = launcher.LauncherCommand("foo", function=callback)
+ runner.add_command(command=command)
+ status = runner.execute(["prog", "--help", "foo"])
+ self.assertEquals(status, 42)
+ self.assertEquals(callback._execute_argv, ["prog foo", "--help"])
+ self.assertEquals(callback._execute_count, 1)
+
+ def testCallHelpOnCommand2(self):
+ callback = CallbackMock(result=42)
+ runner = launcher.Launcher(prog="prog")
+ command = launcher.LauncherCommand("foo", function=callback)
+ runner.add_command(command=command)
+ status = runner.execute(["prog", "help", "foo"])
+ self.assertEquals(status, 42)
+ self.assertEquals(callback._execute_argv, ["prog foo", "--help"])
+ self.assertEquals(callback._execute_count, 1)
+
+ def testCallHelpOnUnknownCommand(self):
+ callback = CallbackMock(result=42)
+ runner = launcher.Launcher(prog="prog")
+ command = launcher.LauncherCommand("foo", function=callback)
+ runner.add_command(command=command)
+ status = runner.execute(["prog", "help", "foo2"])
+ self.assertEquals(status, -1)
+
+ def testNotAvailableCommand(self):
+ callback = CallbackMock(result=42)
+ runner = launcher.Launcher(prog="prog")
+ command = launcher.LauncherCommand("foo", function=callback)
+ runner.add_command(command=command)
+ status = runner.execute(["prog", "foo2", "param1", "param2"])
+ self.assertEquals(status, -1)
+ self.assertEquals(callback._execute_count, 0)
+
+ def testCallHelp(self):
+ callback = CallbackMock(result=42)
+ runner = launcher.Launcher(prog="prog")
+ command = launcher.LauncherCommand("foo", function=callback)
+ runner.add_command(command=command)
+ status = runner.execute(["prog", "help"])
+ self.assertEquals(status, 0)
+ self.assertEquals(callback._execute_count, 0)
+
+ def testCommonCommands(self):
+ runner = launcher.Launcher()
+ tests = [
+ ["prog"],
+ ["prog", "--help"],
+ ["prog", "--version"],
+ ["prog", "help", "--help"],
+ ["prog", "help", "help"],
+ ]
+ for arguments in tests:
+ with self.subTest(args=tests):
+ status = runner.execute(arguments)
+ self.assertEquals(status, 0)
+
+
+def suite():
+ loader = unittest.defaultTestLoader.loadTestsFromTestCase
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(loader(TestLauncherCommand))
+ test_suite.addTest(loader(TestLauncher))
+ test_suite.addTest(loader(TestModuleCommand))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/utils/test/test_launcher_command.py b/silx/utils/test/test_launcher_command.py
new file mode 100644
index 0000000..ccf4601
--- /dev/null
+++ b/silx/utils/test/test_launcher_command.py
@@ -0,0 +1,47 @@
+# 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.
+#
+# ###########################################################################*/
+"""Tests for html module"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "03/04/2017"
+
+
+import sys
+
+
+def main(argv):
+
+ if "--help" in argv:
+ # Common behaviour of ArgumentParser
+ sys.exit(0)
+
+ if "exception" in argv:
+ raise RuntimeError("Simulated exception")
+
+ if "error" in argv:
+ return -1
+
+ return 0
diff --git a/silx/utils/test/test_weakref.py b/silx/utils/test/test_weakref.py
new file mode 100644
index 0000000..7175863
--- /dev/null
+++ b/silx/utils/test/test_weakref.py
@@ -0,0 +1,330 @@
+# 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.
+#
+# ###########################################################################*/
+"""Tests for weakref module"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "15/09/2016"
+
+
+import unittest
+from .. import weakref
+
+
+class Dummy(object):
+ """Dummy class to use it as geanie pig"""
+ def inc(self, a):
+ return a + 1
+
+ def __lt__(self, other):
+ return True
+
+
+def dummy_inc(a):
+ """Dummy function to use it as geanie pig"""
+ return a + 1
+
+
+class TestWeakMethod(unittest.TestCase):
+ """Tests for weakref.WeakMethod"""
+
+ def testMethod(self):
+ dummy = Dummy()
+ callable_ = weakref.WeakMethod(dummy.inc)
+ self.assertEquals(callable_()(10), 11)
+
+ def testMethodWithDeadObject(self):
+ dummy = Dummy()
+ callable_ = weakref.WeakMethod(dummy.inc)
+ dummy = None
+ self.assertIsNone(callable_())
+
+ def testMethodWithDeadFunction(self):
+ dummy = Dummy()
+ dummy.inc2 = lambda self, a: a + 1
+ callable_ = weakref.WeakMethod(dummy.inc2)
+ dummy.inc2 = None
+ self.assertIsNone(callable_())
+
+ def testFunction(self):
+ callable_ = weakref.WeakMethod(dummy_inc)
+ self.assertEquals(callable_()(10), 11)
+
+ def testDeadFunction(self):
+ def inc(a):
+ return a + 1
+ callable_ = weakref.WeakMethod(inc)
+ inc = None
+ self.assertIsNone(callable_())
+
+ def testLambda(self):
+ store = lambda a: a + 1 # noqa: E731
+ callable_ = weakref.WeakMethod(store)
+ self.assertEquals(callable_()(10), 11)
+
+ def testDeadLambda(self):
+ callable_ = weakref.WeakMethod(lambda a: a + 1)
+ self.assertIsNone(callable_())
+
+ def testCallbackOnDeadObject(self):
+ self.__count = 0
+
+ def callback(ref):
+ self.__count += 1
+ self.assertIs(callable_, ref)
+ dummy = Dummy()
+ callable_ = weakref.WeakMethod(dummy.inc, callback)
+ dummy = None
+ self.assertEquals(self.__count, 1)
+
+ def testCallbackOnDeadMethod(self):
+ self.__count = 0
+
+ def callback(ref):
+ self.__count += 1
+ self.assertIs(callable_, ref)
+ dummy = Dummy()
+ dummy.inc2 = lambda self, a: a + 1
+ callable_ = weakref.WeakMethod(dummy.inc2, callback)
+ dummy.inc2 = None
+ self.assertEquals(self.__count, 1)
+
+ def testCallbackOnDeadFunction(self):
+ self.__count = 0
+
+ def callback(ref):
+ self.__count += 1
+ self.assertIs(callable_, ref)
+ store = lambda a: a + 1 # noqa: E731
+ callable_ = weakref.WeakMethod(store, callback)
+ store = None
+ self.assertEquals(self.__count, 1)
+
+ def testEquals(self):
+ dummy = Dummy()
+ callable1 = weakref.WeakMethod(dummy.inc)
+ callable2 = weakref.WeakMethod(dummy.inc)
+ self.assertEquals(callable1, callable2)
+
+ def testInSet(self):
+ callable_set = set([])
+ dummy = Dummy()
+ callable_set.add(weakref.WeakMethod(dummy.inc))
+ callable_ = weakref.WeakMethod(dummy.inc)
+ self.assertIn(callable_, callable_set)
+
+ def testInDict(self):
+ callable_dict = {}
+ dummy = Dummy()
+ callable_dict[weakref.WeakMethod(dummy.inc)] = 10
+ callable_ = weakref.WeakMethod(dummy.inc)
+ self.assertEquals(callable_dict.get(callable_), 10)
+
+
+class TestWeakMethodProxy(unittest.TestCase):
+
+ def testMethod(self):
+ dummy = Dummy()
+ callable_ = weakref.WeakMethodProxy(dummy.inc)
+ self.assertEquals(callable_(10), 11)
+
+ def testMethodWithDeadObject(self):
+ dummy = Dummy()
+ method = weakref.WeakMethodProxy(dummy.inc)
+ dummy = None
+ self.assertRaises(ReferenceError, method, 9)
+
+
+class TestWeakList(unittest.TestCase):
+ """Tests for weakref.WeakList"""
+
+ def setUp(self):
+ self.list = weakref.WeakList()
+ self.object1 = Dummy()
+ self.object2 = Dummy()
+ self.list.append(self.object1)
+ self.list.append(self.object2)
+
+ def testAppend(self):
+ obj = Dummy()
+ self.list.append(obj)
+ self.assertEquals(len(self.list), 3)
+ obj = None
+ self.assertEquals(len(self.list), 2)
+
+ def testRemove(self):
+ self.list.remove(self.object1)
+ self.assertEquals(len(self.list), 1)
+
+ def testPop(self):
+ obj = self.list.pop(0)
+ self.assertIs(obj, self.object1)
+ self.assertEquals(len(self.list), 1)
+
+ def testGetItem(self):
+ self.assertIs(self.object1, self.list[0])
+
+ def testGetItemSlice(self):
+ objects = self.list[:]
+ self.assertEquals(len(objects), 2)
+ self.assertIs(self.object1, objects[0])
+ self.assertIs(self.object2, objects[1])
+
+ def testIter(self):
+ obj_list = list(self.list)
+ self.assertEquals(len(obj_list), 2)
+ self.assertIs(self.object1, obj_list[0])
+
+ def testLen(self):
+ self.assertEquals(len(self.list), 2)
+
+ def testSetItem(self):
+ obj = Dummy()
+ self.list[0] = obj
+ self.assertIsNot(self.object1, self.list[0])
+ obj = None
+ self.assertEquals(len(self.list), 1)
+
+ def testSetItemSlice(self):
+ obj = Dummy()
+ self.list[:] = [obj, obj]
+ self.assertEquals(len(self.list), 2)
+ self.assertIs(obj, self.list[0])
+ self.assertIs(obj, self.list[1])
+ obj = None
+ self.assertEquals(len(self.list), 0)
+
+ def testDelItem(self):
+ del self.list[0]
+ self.assertEquals(len(self.list), 1)
+ self.assertIs(self.object2, self.list[0])
+
+ def testDelItemSlice(self):
+ del self.list[:]
+ self.assertEquals(len(self.list), 0)
+
+ def testContains(self):
+ self.assertIn(self.object1, self.list)
+
+ def testAdd(self):
+ others = [Dummy()]
+ l = self.list + others
+ self.assertIs(l[0], self.object1)
+ self.assertEquals(len(l), 3)
+ others = None
+ self.assertEquals(len(l), 2)
+
+ def testExtend(self):
+ others = [Dummy()]
+ self.list.extend(others)
+ self.assertIs(self.list[0], self.object1)
+ self.assertEquals(len(self.list), 3)
+ others = None
+ self.assertEquals(len(self.list), 2)
+
+ def testIadd(self):
+ others = [Dummy()]
+ self.list += others
+ self.assertIs(self.list[0], self.object1)
+ self.assertEquals(len(self.list), 3)
+ others = None
+ self.assertEquals(len(self.list), 2)
+
+ def testMul(self):
+ l = self.list * 2
+ self.assertIs(l[0], self.object1)
+ self.assertEquals(len(l), 4)
+ self.object1 = None
+ self.assertEquals(len(l), 2)
+ self.assertIs(l[0], self.object2)
+ self.assertIs(l[1], self.object2)
+
+ def testImul(self):
+ self.list *= 2
+ self.assertIs(self.list[0], self.object1)
+ self.assertEquals(len(self.list), 4)
+ self.object1 = None
+ self.assertEquals(len(self.list), 2)
+ self.assertIs(self.list[0], self.object2)
+ self.assertIs(self.list[1], self.object2)
+
+ def testCount(self):
+ self.list.append(self.object2)
+ self.assertEquals(self.list.count(self.object1), 1)
+ self.assertEquals(self.list.count(self.object2), 2)
+
+ def testIndex(self):
+ self.assertEquals(self.list.index(self.object1), 0)
+ self.assertEquals(self.list.index(self.object2), 1)
+
+ def testInsert(self):
+ obj = Dummy()
+ self.list.insert(1, obj)
+ self.assertEquals(len(self.list), 3)
+ self.assertIs(self.list[1], obj)
+ obj = None
+ self.assertEquals(len(self.list), 2)
+
+ def testReverse(self):
+ self.list.reverse()
+ self.assertEquals(len(self.list), 2)
+ self.assertIs(self.list[0], self.object2)
+ self.assertIs(self.list[1], self.object1)
+
+ def testReverted(self):
+ new_list = reversed(self.list)
+ self.assertEquals(len(new_list), 2)
+ self.assertIs(self.list[1], self.object2)
+ self.assertIs(self.list[0], self.object1)
+ self.assertIs(new_list[0], self.object2)
+ self.assertIs(new_list[1], self.object1)
+ self.object1 = None
+ self.assertEquals(len(new_list), 1)
+
+ def testStr(self):
+ self.assertNotEquals(self.list.__str__(), "[]")
+
+ def testRepr(self):
+ self.assertNotEquals(self.list.__repr__(), "[]")
+
+ def testSort(self):
+ # only a coverage
+ self.list.sort()
+ self.assertEquals(len(self.list), 2)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestWeakMethod))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestWeakMethodProxy))
+ test_suite.addTest(
+ unittest.defaultTestLoader.loadTestsFromTestCase(TestWeakList))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')
diff --git a/silx/utils/weakref.py b/silx/utils/weakref.py
new file mode 100644
index 0000000..42d7392
--- /dev/null
+++ b/silx/utils/weakref.py
@@ -0,0 +1,361 @@
+# 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.
+#
+# ###########################################################################*/
+"""Weakref utils for compatibility between Python 2 and Python 3 or for
+extended features.
+"""
+from __future__ import absolute_import
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "15/09/2016"
+
+
+import weakref
+import types
+import inspect
+
+
+def ref(object, callback=None):
+ """Returns a weak reference to object. The original object can be retrieved
+ by calling the reference object if the referent is still alive. If the
+ referent is no longer alive, calling the reference object will cause None
+ to be returned.
+
+ The signature is the same as the standard `weakref` library, but it returns
+ `WeakMethod` if the object is a bound method.
+
+ :param object: An object
+ :param func callback: If provided, and the returned weakref object is
+ still alive, the callback will be called when the object is about to
+ be finalized. The weak reference object will be passed as the only
+ parameter to the callback. Then the referent will no longer be
+ available.
+ :return: A weak reference to the object
+ """
+ if inspect.ismethod(object):
+ return WeakMethod(object, callback)
+ else:
+ return weakref.ref(object, callback)
+
+
+def proxy(object, callback=None):
+ """Return a proxy to object which uses a weak reference. This supports use
+ of the proxy in most contexts instead of requiring the explicit
+ dereferencing used with weak reference objects.
+
+ The signature is the same as the standard `weakref` library, but it returns
+ `WeakMethodProxy` if the object is a bound method.
+
+ :param object: An object
+ :param func callback: If provided, and the returned weakref object is
+ still alive, the callback will be called when the object is about to
+ be finalized. The weak reference object will be passed as the only
+ parameter to the callback. Then the referent will no longer be
+ available.
+ :return: A proxy to a weak reference of the object
+ """
+ if inspect.ismethod(object):
+ return WeakMethodProxy(object, callback)
+ else:
+ return weakref.proxy(object, callback)
+
+
+class WeakMethod(object):
+ """Wraps a callable object like a function or a bound method.
+ Feature callback when the object is about to be finalized.
+ Provids the same interface as a normal weak reference.
+ """
+
+ def __init__(self, function, callback=None):
+ """
+ Constructor
+ :param function: Function/method to be called
+ :param callback: If callback is provided and not None,
+ and the returned weakref object is still alive, the
+ callback will be called when the object is about to
+ be finalized; the weak reference object will be passed
+ as the only parameter to the callback; the referent will
+ no longer be available
+ """
+ self.__callback = callback
+
+ if inspect.ismethod(function):
+ # it is a bound method
+ self.__obj = weakref.ref(function.__self__, self.__call_callback)
+ self.__method = weakref.ref(function.__func__, self.__call_callback)
+ else:
+ self.__obj = None
+ self.__method = weakref.ref(function, self.__call_callback)
+
+ def __call_callback(self, ref):
+ """Called when the object is about to be finalized"""
+ if not self.is_alive():
+ return
+ self.__obj = None
+ self.__method = None
+ if self.__callback is not None:
+ self.__callback(self)
+
+ def __call__(self):
+ """Return a callable function or None if the WeakMethod is dead."""
+ if self.__obj is not None:
+ method = self.__method()
+ obj = self.__obj()
+ if method is None or obj is None:
+ return None
+ return types.MethodType(method, obj)
+ elif self.__method is not None:
+ return self.__method()
+ else:
+ return None
+
+ def is_alive(self):
+ """True if the WeakMethod is still alive"""
+ return self.__method is not None
+
+ def __eq__(self, other):
+ """Check it another obect is equal to this.
+
+ :param object other: Object to compare with
+ """
+ if isinstance(other, WeakMethod):
+ if not self.is_alive():
+ return False
+ return self.__obj == other.__obj and self.__method == other.__method
+ return False
+
+ def __ne__(self, other):
+ """Check it another obect is not equal to this.
+
+ :param object other: Object to compare with
+ """
+ if isinstance(other, WeakMethod):
+ if not self.is_alive():
+ return False
+ return self.__obj != other.__obj or self.__method != other.__method
+ return True
+
+ def __hash__(self):
+ """Returns the hash for the object."""
+ return self.__obj.__hash__() ^ self.__method.__hash__()
+
+
+class WeakMethodProxy(WeakMethod):
+ """Wraps a callable object like a function or a bound method
+ with a weakref proxy.
+ """
+ def __call__(self, *args, **kwargs):
+ """Dereference the method and call it if the method is still alive.
+ Else raises an ReferenceError.
+
+ :raises: ReferenceError, if the method is not alive
+ """
+ fn = super(WeakMethodProxy, self).__call__()
+ if fn is None:
+ raise ReferenceError("weakly-referenced object no longer exists")
+ return fn(*args, **kwargs)
+
+
+class WeakList(list):
+ """Manage a list of weaked references.
+ When an object is dead, the list is flaged as invalid.
+ If expected the list is cleaned up to remove dead objects.
+ """
+
+ def __init__(self, enumerator=()):
+ """Create a WeakList
+
+ :param iterator enumerator: A list of object to initialize the
+ list
+ """
+ list.__init__(self)
+ self.__list = []
+ self.__is_valid = True
+ for obj in enumerator:
+ self.append(obj)
+
+ def __invalidate(self, ref):
+ """Flag the list as invalidated. The list contains dead references."""
+ self.__is_valid = False
+
+ def __create_ref(self, obj):
+ """Create a weakref from an object. It uses the `ref` module function.
+ """
+ return ref(obj, self.__invalidate)
+
+ def __clean(self):
+ """Clean the list from dead references"""
+ if self.__is_valid:
+ return
+ self.__list = [ref for ref in self.__list if ref() is not None]
+ self.__is_valid = True
+
+ def __iter__(self):
+ """Iterate over objects of the list"""
+ for ref in self.__list:
+ obj = ref()
+ if obj is not None:
+ yield obj
+
+ def __len__(self):
+ """Count item on the list"""
+ self.__clean()
+ return len(self.__list)
+
+ def __getitem__(self, key):
+ """Returns the object at the requested index
+
+ :param key: Indexes to get
+ :type key: int or slice
+ """
+ self.__clean()
+ data = self.__list[key]
+ if isinstance(data, list):
+ result = [ref() for ref in data]
+ else:
+ result = data()
+ return result
+
+ def __setitem__(self, key, obj):
+ """Set an item at an index
+
+ :param key: Indexes to set
+ :type key: int or slice
+ """
+ self.__clean()
+ if isinstance(key, slice):
+ objs = [self.__create_ref(o) for o in obj]
+ self.__list[key] = objs
+ else:
+ obj_ref = self.__create_ref(obj)
+ self.__list[key] = obj_ref
+
+ def __delitem__(self, key):
+ """Delete an Indexes item of this list
+
+ :param key: Index to delete
+ :type key: int or slice
+ """
+ self.__clean()
+ del self.__list[key]
+
+ def __delslice__(self, i, j):
+ """Looks to be used in Python 2.7"""
+ self.__delitem__(slice(i, j, None))
+
+ def __setslice__(self, i, j, sequence):
+ """Looks to be used in Python 2.7"""
+ self.__setitem__(slice(i, j, None), sequence)
+
+ def __getslice__(self, i, j):
+ """Looks to be used in Python 2.7"""
+ return self.__getitem__(slice(i, j, None))
+
+ def __reversed__(self):
+ """Returns a copy of the reverted list"""
+ reversed_list = reversed(list(self))
+ return WeakList(reversed_list)
+
+ def __contains__(self, obj):
+ """Returns true if the object is in the list"""
+ ref = self.__create_ref(obj)
+ return ref in self.__list
+
+ def __add__(self, other):
+ """Returns a WeakList containing this list an the other"""
+ l = WeakList(self)
+ l.extend(other)
+ return l
+
+ def __iadd__(self, other):
+ """Add objects to this list inplace"""
+ self.extend(other)
+ return self
+
+ def __mul__(self, n):
+ """Returns a WeakList containing n-duplication object of this list"""
+ return WeakList(list(self) * n)
+
+ def __imul__(self, n):
+ """N-duplication of the objects to this list inplace"""
+ self.__list *= n
+ return self
+
+ def append(self, obj):
+ """Add an object at the end of the list"""
+ ref = self.__create_ref(obj)
+ self.__list.append(ref)
+
+ def count(self, obj):
+ """Returns the number of occurencies of an object"""
+ ref = self.__create_ref(obj)
+ return self.__list.count(ref)
+
+ def extend(self, other):
+ """Append the list with all objects from another list"""
+ for obj in other:
+ self.append(obj)
+
+ def index(self, obj):
+ """Returns the index of an object"""
+ ref = self.__create_ref(obj)
+ return self.__list.index(ref)
+
+ def insert(self, index, obj):
+ """Insert an object at the requested index"""
+ ref = self.__create_ref(obj)
+ self.__list.insert(index, ref)
+
+ def pop(self, index):
+ """Remove and return an object at the requested index"""
+ self.__clean()
+ obj = self.__list.pop(index)()
+ return obj
+
+ def remove(self, obj):
+ """Remove an object from the list"""
+ ref = self.__create_ref(obj)
+ self.__list.remove(ref)
+
+ def reverse(self):
+ """Reverse the list inplace"""
+ self.__list.reverse()
+
+ def sort(self, key=None, reverse=False):
+ """Sort the list inplace.
+ Not very efficient.
+ """
+ sorted_list = list(self)
+ sorted_list.sort(key=key, reverse=reverse)
+ self.__list = []
+ self.extend(sorted_list)
+
+ def __str__(self):
+ unref_list = list(self)
+ return "WeakList(%s)" % str(unref_list)
+
+ def __repr__(self):
+ unref_list = list(self)
+ return "WeakList(%s)" % repr(unref_list)
diff --git a/stdeb.cfg b/stdeb.cfg
new file mode 100644
index 0000000..f3437c4
--- /dev/null
+++ b/stdeb.cfg
@@ -0,0 +1,4 @@
+[DEFAULT]
+Depends: python-numpy
+XS-Python-Version: >= 2.7
+Debian-Version: 7
diff --git a/version.py b/version.py
new file mode 100644
index 0000000..10dbff1
--- /dev/null
+++ b/version.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2015-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.
+#
+# ###########################################################################*/
+"""Unique place where the version number is defined.
+
+provides:
+* version = "1.2.3" or "1.2.3-beta4"
+* version_info = named tuple (1,2,3,"beta",4)
+* hexversion: 0x010203B4
+* strictversion = "1.2.3b4
+* debianversion = "1.2.3~beta4"
+* calc_hexversion: the function to transform a version_tuple into an integer
+
+This is called hexversion since it only really looks meaningful when viewed as the
+result of passing it to the built-in hex() function.
+The version_info value may be used for a more human-friendly encoding of the same information.
+
+The hexversion is a 32-bit number with the following layout:
+Bits (big endian order) Meaning
+1-8 PY_MAJOR_VERSION (the 2 in 2.1.0a3)
+9-16 PY_MINOR_VERSION (the 1 in 2.1.0a3)
+17-24 PY_MICRO_VERSION (the 0 in 2.1.0a3)
+25-28 PY_RELEASE_LEVEL (0xA for alpha, 0xB for beta, 0xC for release candidate and 0xF for final)
+29-32 PY_RELEASE_SERIAL (the 3 in 2.1.0a3, zero for final releases)
+
+Thus 2.1.0a3 is hexversion 0x020100a3.
+
+"""
+
+from __future__ import absolute_import, print_function, division
+__authors__ = ["Jérôme Kieffer"]
+__license__ = "MIT"
+__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
+__date__ = "15/09/2016"
+__status__ = "production"
+__docformat__ = 'restructuredtext'
+__all__ = ["date", "version_info", "strictversion", "hexversion", "debianversion", "calc_hexversion"]
+
+
+RELEASE_LEVEL_VALUE = {"dev": 0,
+ "alpha": 10,
+ "beta": 11,
+ "gamma": 11,
+ "rc": 12,
+ "final": 15}
+
+MAJOR = 0
+MINOR = 5
+MICRO = 0
+RELEV = "final" # <16
+SERIAL = 0 # <16
+
+date = __date__
+
+from collections import namedtuple
+_version_info = namedtuple("version_info", ["major", "minor", "micro", "releaselevel", "serial"])
+
+version_info = _version_info(MAJOR, MINOR, MICRO, RELEV, SERIAL)
+
+strictversion = version = debianversion = "%d.%d.%d" % version_info[:3]
+if version_info.releaselevel != "final":
+ version += "-%s%s" % version_info[-2:]
+ debianversion += "~adev%i" % version_info[-1] if RELEV == "dev" else "~%s%i" % version_info[-2:]
+ prerel = "a" if RELEASE_LEVEL_VALUE.get(version_info[3], 0) < 10 else "b"
+ if prerel not in "ab":
+ prerel = "a"
+ strictversion += prerel + str(version_info[-1])
+
+
+def calc_hexversion(major=0, minor=0, micro=0, releaselevel="dev", serial=0):
+ """Calculate the hexadecimal version number from the tuple version_info:
+
+ :param major: integer
+ :param minor: integer
+ :param micro: integer
+ :param relev: integer or string
+ :param serial: integer
+ :return: integerm always increasing with revision numbers
+ """
+ try:
+ releaselevel = int(releaselevel)
+ except ValueError:
+ releaselevel = RELEASE_LEVEL_VALUE.get(releaselevel, 0)
+
+ hex_version = int(serial)
+ hex_version |= releaselevel * 1 << 4
+ hex_version |= int(micro) * 1 << 8
+ hex_version |= int(minor) * 1 << 16
+ hex_version |= int(major) * 1 << 24
+ return hex_version
+
+
+hexversion = calc_hexversion(*version_info)
+
+if __name__ == "__main__":
+ print(version)